TV World

TV World

Make your way through the nine channels of the TV World!

Official Videos


Post Mortem

For each Ludum Dare, I like to change genres to keep things interesting. This time, I decided to create a classic shoot-em-up (aka shmup), since I’ve never developed one before. Since the theme was “Everything on One Screen”, I decided to make a television screen the protagonist of the game. I made the entire game based on adventuring through various television channels. I don’t believe anyone has ever done a television themed game before.

I started with the weather channel, which included snowmen as enemies, since the “Unicode Snowman” seemed to be a lock for the Ludum Dare 31 theme. Then after defeating the last snowman boss, you get a gray remote which takes you to the next channel, which is the “Sportsmania” sports channel. In this channel you must blast the numerous footballs which approach you. Defeating the mega sized football at the end grants another gray remote which takes you to the next channel. In the classic movie channel, it is entirely black and white themed and movie reels are the hazard. Along with the classic look, there is also classical styled music that plays in the background. The remaining channels are the 24 Hour News, Kids Club, Out of this World (sci-fi), American Pickers (country music), Ultimate Chef (cooking), and Furry Buddies (animals and pets). Each channel has its appropriate enemy types, which include dollar bills, lollipops, UFOs, cowboy boots, pizza slices, and kitties.

There are two power-ups in the game, which can be acquired by defeating enemies. The red remote will increase the player’s fire rate. This ability can be upgraded five times. The magenta remote will increase the player’s fire spread, which can be upgraded twice so that three projectiles are fired at once.

What Went Right

This was the first time I used the Playmaker addon for Unity for an official Ludum Dare entry. I did use Playmaker to create my Bag Boy warm-up entry, which I think turned out quite well for the amount of time that I spent on it. There is a steep learning curve to using Playmaker, but once you know how to use it, creating a game becomes much easier (especially 3D games). I didn’t write a single line of code for this game, which really makes the game development process less stressful. I was able to spend more time coming up with ideas, and implementing those ideas took much less time than if I was writing code. Managing the game engine is much simpler by creating the FSM diagrams and adding the appropriate actions. I used Taron’s Verve Painter again for creating the background, but I applied a pixel filter in Gimp to make to appear more television-like.

This time I also used an online tool called Trello, which was recommended in one of our local Knoxville Game Design meetings. It provides an efficient interface for recording tasks and ideas, and it allows you to mark which features have been implemented and completed. I think it’s more targeted towards team development, but I found it to be a useful tool while working solo.

I did a webcast to Twitch during the entire game development process. I am really happy with the results of my time-lapse video. My development desktop is on the left, with the current date and time below. On the right side, you can see me on the webcam and the IRC chatroom of my Twitch channel. I think displaying the chat room in the stream encourages people to comment on the status of my game.

What Went Wrong

The night before the competition started, I upgraded my Unity development environment to the latest version. This new version had a completely new UI system added, so I wasted a few hours trying to figure out how to get it to work. Then I discovered that the old GUIText and TextMesh components weren’t easily accessible, and the new UI components were not compatible with Playmaker. Therefore, I wasted even more time downgrading my Unity development environment to the previous version.

After that happened, things were going fairly smoothly. I did have a small problem getting the scrolling background working, because I forgot that the background plane size is 10×10 units. However, I had done a scrolling background for one of my previous games, so I was eventually able to figure it out.

Getting the bullets shooting correctly also took more time that I had anticipated. The bullets were shooting into the screen. Eventually, I took the approach where I set the initial rotation of a bullet, and then just translated it forward in the bullet’s local Z-coordinate.

I left all of the modeling for the last few hours of the competition. Honestly, I was proud of the number of models (the television model for the player and nine different enemies) that I was able to churn out in two to three hours. However, none of the models were animated.

The enemy AI is probably the most glaring flaw in the game. The enemies just basically go from right to left on the screen at a constant rate. I could have easily made the enemies move at different speeds. Making the enemies movie in different patterns, and having the enemies shoot back are definitely features I would like to add in an upcoming release.

The power-up system was completely unbalanced as well. I used a simple random variable to determine if an enemy would drop a power-up. This meant that sometimes you could go long stretches without getting a power-up, and then other times you may get multiple power-ups in a row. Additionally, after maxing out your power-ups, you would complete the game by simply holding down the spacebar. For the next competition, I will try to devote a little more time towards balancing the game.

I liked the music that I made for the game, however I could have spent more time on it. I basically combined various Apple loops in Garage Band, while also modifying the speed and pitch. I read the Ludum Dare rules and this is apparently acceptable, but I really like to be the one entering the notes for it to feel like my own.

How Did I Do?

I don’t know. After Ludum Dare 27 I quit checking my rankings. I check the top 100 winners list, so if I’m not on there it really doesn’t matter to me.

Where to Go From Here

I think I’ve developed a solid shoot-em-up engine, so I just need to add new power-ups, more enemies, smarter artificial intelligence, and increase the length of the channels (levels). I would like to add a money system to the game so that the player can buy new power-ups and abilities.

Earlier this month, I released One Gunman, another one of my Ludum Dare games, on the Windows Store. That’s definitely a platform I would consider releasing TV World. I already know the process for putting a Unity game on the Windows Store, which isn’t too difficult. However, I found that it is really easy to get lost in the shuffle on that platform and getting sales can be tough.

I would definitely like to release the game on the XBox One, since the XBox Live Indie Game (XBLIG) marketplace is pretty much dead. However, getting approved to develop for the XBox One is much more cumbersome than XBLIG, since you’ve got to pitch your idea and go through a lengthy approval process to get a development kit. However, I’m hoping that my experience with publishing to the Windows Store will prove useful for publishing on the XBox One, since they are supposedly based on similar operating systems.

There’s always mobile platforms, such as iOS and Android. I’ve made a simple build for my Nexus Android tablet, but the controls really need some work, which requires more time. I created some simple virtual buttons, since obviously a tablet doesn’t have a keyboard. However, virtual buttons work differently than a mouse, keyboard, or joystick because they are touch based.

I know others have had success with publishing games to the Playstation Vita, so that is another paltform I may give a try. There’s also other less popular consoles like the Ouya, but the cost of the developer’s license is usually my deciding factor.

Then there’s always ad revenue sharing sites like Game Jolt and Kongregate. These web sites are fine, but I’ve never made any serious profit from them. Thefore, I’ll probably release the compo version on those sites, and save the improved version for other platforms.

I am also considering Desura, since the cost to publish on their service is low or free if I remember correctly. I would consider submitting to Steam Greenlight, but honestly 100 dollars is a lot to invest if there’s no guarantee that your game will ever get published on the service. However, that money is supposed to go to charity, so I wouldn’t feel to bad about making that investment.

You can play the compo version of TV World from my page.


TV World on

TV World on GameJolt

TV World Ludum Dare entry

Creating My First NES Game

For this mini-LD challenge, I decided to try to create a game for the original 8-bit Nintendo Entertainment System (NES). This was the first game console that I ever owned as a kid, so creating a game for it was something that I had always wanted to do.

Unfortunately, to create an NES game, everything has to be written in assembly. When I was at Georgia Tech working on my computer science undergraduate degree, I did have one project where I had to write assembly code for an emulated MIPS system. The emulator was called SPIM (MIPS spelled backwards), and it looks like it is still available for download today. While writing assembly is not completely foreign to me, it definitely is not one of my favorite things to do. However, it was my only option for creating an NES game, and it was a nice refresher since I had not written any assembly code in years.

Getting a 4x4 tile sprite moving around on the screen
Running NES assembler to get a sprite to move on the screen in the NES emulator

The good news is that I found a great series of tutorials on the basics of creating a NES game written by bunnyboy at NintendoAge. He also has a wide variety of NES homebrew games available on his site, and an adapter for sale which allows compiled NES games to be played on actual NES hardware using a flash drive.

I started by working through weeks 1 to 5 of the “Nerdy Nights” tutorials. The first tutorial is the basics of binary and hexadecimal number systems. The second tutorial goes over the architecture of the NES, and provides a barebones example of an NES game with assembly code and example CHR ROM dump. I liked this incremental example approach, which allowed me to just to get something to compile and run, before tackling things like sprites and sounds. I tried a few different NES emulators, but FCEUX seemed to be the one that most people recommended these days. It was also available for download from the Ubuntu software center, so the installation was simple. However, the program that is used to compile the NES assembly code called NESASM3 is only offered as a Windows executable, so I had to install Wine to run it. After the setup was complete, I was successfully able to generate a .NES file, which ran in my NES emulator. However, it only displayed a blank screen, but it didn’t crash which was a start.

In the third tutorial, it goes into the details of the 6502 assembly code, which is the instruction set used by the NES assembler. It has all of the standard operators that you would expect, like “load” and “store” for writing to registers and memory. The NES is a fairly simplistic system, which only has three registers which are the Accumulator, Register X, and Register Y. The instruction set also has simple math functions like “add” and “subtract”, and control operators like “jump” and “branch”. The example of this lesson gave enough to get started to change the color of the screen based on the selected palette value. I tested by changing the screen color to different combinations of red, green, and blue by modifying the binary code of the byte which controls the screen color.

The fourth tutorial made things a little more interesting, as it taught me how to display a sprite to the screen and change its colors by modifying the color palette values. The color code chart at the top of the page was a very helpful reference. The fifth tutorial shows how to display even more sprites, and how to move them around on the screen using the controller. The example code just shows how to detect input from the A and B buttons, so I extended that code to detect all buttons on the NES controller. The test for the other buttons are just detected by additional “loads” from the from the address of the controller port ($4016). It also only moved the sprite in the left and right direction, so by writing to the sprite’s Y memory location, I was able to make the sprite move vertically when the up and down buttons are pressed on the virtual D-pad. The example only moved one “tile” of the sprite, so I extended the assembly code so that it moved all four tiles together.

In order to make the sprites for my game, I used a program called YY-CHR. It is another Windows executable, but it also runs well under Ubuntu using Wine. The only issue that I encountered was that I was not able to create a bitmap in Gimp, and then copy and paste it into YY-CHR. Therefore, I created my own “hand drawn” smiley face sprite, which is made up of four 8×8 pixel tiles.

I quickly discovered that writing everything in assembly was going to be a real pain. Therefore, I started writing a simple script that would read some parameters out of a file. Since this is going to be simple, I decided to write the script in Ruby. First, I took the 6502 assembly that I wrote and broke it into five pieces: the header (which doesn’t change), controls (player input), palette, sprites, and footer (also doesn’t change). I put each section of assembly into its own text file, and the main nesc.rb script just reads the contents of those files, and then calls NESASM3.exe at the end. I tested my script, and it successfully compiled an .NES image which I could play in my FCEUX emulator.

However, that isn’t very interesting since it always just compiles into the same game. As a starting point, I created a game.xml file, and defined four colors which define the four colors of the current palette. In the included nes_palette.rb file, I started defining colors based on the tutorial table, and stored those color constants and the corresponding hex values into a Hash. Then, in another script which reads the game.xml file using REXML and XPath, I stored the user’s defined palette colors in array. Then the palette code just looks up those values in the Hash to get the correct hex values to write palette data using the .db directive. Finally, I added a <palette> tag to contain these <color> elements.


Changing the palette colors of a sprite using user defined values in an XML file
Changing the palette colors of a sprite using user defined values in an XML file


I expanded my XML file specification format by adding a <player> tag for player attributes. The first player attribute I added was <speed>, which controls how fast the player moves around on the screen. This is currently a hexadecimal value, which is either added or subtracted (ADC / SBC) from from the x and y memory locations of the player’s tiles. In my original code, it only moved one of the player’s tiles, however with my Ruby compiler script I was able to create a simple loop to apply the add or subtract to each tile in the player sprite. In my user input code, I made a hash table of the user defined values so that it can be passed around to each of the functions. One issue I had was sometimes the tiles would not move at the correct speed. I found that this was because I was not clearing the carry flag. CLC must be called before every ADC, and SEC must be called before every SBC.

Creating a simple sprite in YY-CHR
Creating a simple sprite in YY-CHR

Now that I had a way to display a sprite to the screen, I needed a way to change the sprite displayed on the screen. I created a simple rocketship sprite which is four tiles in YY-CHR and saved it to gatechgrad.chr. In my game.xml file, I created a new tag element called <spritesheet>, which holds the name of the CHR file containing the sprites to use for the game. I updated my nesc_userinput.rb script to store this value into the userOptions hash table, which is passed to the new nesc_footer.rb which generates the 6502 assembly to read the data from that CHR file. The NESASM3 assembler will throw a compile time error if the CHR file name is invalid.

While making these updates, I created a Makefile which simply recompiles everything (ruby nesc.rb; wine NESASM3 temp.asm) whenever the game.xml file is updated.

game.xml which defines various properties of the NES game

In the game.xml file, I added a new <sprite> tag inside of the <player> tags, and the <sprite> tag contains multiple <tile> tags which have “row” and “col” as attributes and the tile number (in hexadecimal) as text. I updated the nesc_userinput.rb again to load all of these values into the user option hash table. That data then gets used by the nesc_sprites.rb file to write the assembly for the sprite data. After this was completed, I was successfully able to change which tiles composed the player sprite through the game.xml file. It is interesting that most sprites for NES games use sequential tiles, where the head may be tiles 0 and 1, body 2 and 3, and feet 4 and 5. This makes the reads sequential, but it is more difficult to edit a sprite sheet that way since the head, body, and feet are all of the same tile row. For my game, I just specified 0 and 1 ($00 and $01) as the top part of my ship and 16 and 17 ($10 and $11) as the bottom, that way the sprite is easily editable in the sprite sheet.

The next step is to get the ship shooting. I added a new bullet tile to the spritesheet using YY-CHR. In the nes_sprites.rb script, I added a new line to load the bullet sprite. Then I increased the loop counter in the header to read the new sprite by increasing the CPX value to #$30. This should actually load 12 tiles, since each tile is defined by 4 bytes (x, attributes, tile index, y). In the controller code, under the ReadA: label, which is executed when the A button is pressed, I set bullet’s x and y location values to the position of the spaceship. I used the values of the first spaceship tile, to make things simple for now. After the control handling code, I added a section to add (CLC/ADC) the bullet speed to the x position of the bullet. Now, the bullet’s position will fly from left to right on the screen. In the game.xml file, I added a <bullet> tag which contains <speed> containing the speed of the bullet in hexadecimal, just like the player speed. This value is read and used to determine the bullet speed in the game.

Unfortunately, when the bullet reaches the right edge of the screen, it will loop back to the left side. Also, if the A button is repeatedly pressed, the one bullet will reset back to the location of the spaceship. I created a variable in the assembly code to hold the “alive” flag. When the A button is pressed, I load a 1 (LDA #$01) and store it in the alive flag. In the UpdateBullets section, I load the bullet alive flag and compare it with 1 (CMP #$01) and jump to the end of the section if it is not equal (BNE). This will make the bullet stop if it is not alive. Using this reference I learned how to check if a value is greater than or less than a number by using the BCC and BCS (“branch carry clear” and “branch carry set”) instructions. Using BCC, if the bullet’s x location is less than 240 (#$F0) then it will jump to the end of the section, otherwise it will set the alive flag to zero. I used 240 instead of 255, due to the values looping back around to zero when value exceeds the 255 limit for a byte. As long as the bullet speed is less than 15 there should be no problems. There are techniques for checking if the summed value exceeds 255, which is used for 16-bit numbers, so I will investigate that later. To fix the other bullet position reset problem when A is repeatedly pressed, after the A button is read I simply loaded the bullet alive flag, compared it with one and jumped to the end if it is equal.

Displaying player ship, missile, enemy ship, and score on the game screen.

The next step was to get an enemy on the screen. I used YY-CHR to create a new enemy ship sprite on my spritesheet, which is another four tile sprite. I added a new <enemy> tag to my XML file, which contains all of the properties of the enemy. In the Ruby code, I added an array to hold all of the enemies, and an Enemy class which contains the memory locations of the X and Y position of the enemy. I also defined an “alive” flag variable for the enemy, so that I can set it to dead when it is destroyed. In the future, I could also add a life value, if the enemy takes multiple hits to be killed. To get the enemy moving, I just simply keep subtracting the ship’s speed value to the x location variable, so the enemy will continually keep moving toward the left side of the screen. This isn’t really impressive, but at least it’s moving which gives the game a bit of a challenge. When the ship’s “alive” flag is set to zero (#$00), then the enemy ship stops moving.

Displaying text in the game is done by writing the text tiles to background name table. For my spritesheet, “0” starts at tile $00 and goes up to “9” at tile $09. The letter “A” starts at tile $0A and goes up to “Z” at $23. The letter mappings can be seen in the PPU viewer of FCEUX. Using the technique explained in the tutorial, I was able to display the score up to six digits at the top of the screen. I created a Hash in the script to map all of the letters to the equivalent tile numbers. It may be possible to write a function to do this conversion, but I will leave that to do later.

I separated all of the object code into its own Ruby script, which held the memory locations of all of the tiles for each of the objects. The update code for each of the objects was also moved to another script containing update subroutines. In the update script, the locations of the tiles are set based on the location of the object, plus an offset which is added based on the tile’s row and column in the sprite.

Next, I added collision detection between the bullet and the enemy ship. This was accomplished through a series of CMP, BCS, and BCC statements which check to see if the bullet’s x and y position are within the enemy sprite. I subtracted 4 from the left and top bounds of the enemy ship, so that a collision is detected when the bullet’s x or y is equal to the enemy ship’s x or y, since there is no “greater than or equal to” operator. When the bullet collides with the enemy ship, the bullet alive variable is set to #$00. Then JSR is called to execute the code to increment the player’s score. This collision code just checks to see if the bullet’s x, y location is inside the enemy ship rectangle to make things simple. Modifying the code to do rectangle/rectangle would complicate things too much for this simple game.

The next step was to get a simple sound to play when a bullet is shot, which I got working by following this tutorial. This just plays a simple beep, and I modified it so that it doesn’t continually play by enabling the length counter and setting it to 0001.

Two enemies on screen with six digit score
Two enemies on screen with six digit score

I added a second enemy by adding to the enemy array defined in the object script, and set the appropriate address values for the x, y, and tile index values. For now, I just duplicated all of the bullet collision and enemy movement code for the second enemy. I added a new “gametime” varaible that gets incremented on every NMI interrupt break. When the gametime variable is equal to #$FF, then both enemies are set to alive and their y position are set back to a position on screen. This gives the appearance of new enemy ships spawning.

In order to have a game over state, I added a new variable to track the player’s lives. Whenever the player’s ship collides with an enemy ship, a new subroutine is called which subtracts one from the player’s lives, and set the game state to “GAME OVER” if the number of lives are equal to zero.

Using my sprite editor, I created a title graphic for the game. However, I quickly found that it isn’t so easy to change all of the background tiles on the screen at once. I tried a few things, but I had little luck. After digging around on some forums, I found that it really isn’t possible to update the entire background in one update, like updating the screen in modern game programming environments. One poster said that it’s only possible to update 3 rows or columns in one update, or the game will start to slow down. For now I’m leaving the title screen out, but I’m hoping to eventually get it working in the game.

Title screen… to be added… hopefully.

Overall, I’m happy with what I was able to accomplish in a relatively short period of time. I’ve decided to give a 20 minute Lightning Talk on the process of creating a NES game using 6502 assembly at the CodeStock technical conference in Knoxville next month (July 2014).

Download and play Space Dude here


Nerdy Nights at NintendoAge

NesDev : Wiki, NES Coding Competition, NES Tech FAQ

Programming M.C. Kids

Knoxville Devs and LD featured in Local Paper

Our Knoxville Game Design group is featured in the cover story of our local Knoxville entertainment paper, Metro Pulse. The seven page article gives our thoughts on the current Indie Game community, and describes our participation in the recent Ludum Dare 28 competition. The article features interviews with Knoxville Ludum Dare participants ViNull, DylanWolf, Insane66, and myself (GaTechGrad) along with Chaosoft Games.


This paper is available for free at numerous newsstands in East Tennessee.

PDF version (identical to the print version)

Online version (formatted for the web) – Please Like/Tweet the article so they will consider doing more game development articles in the future!