Inspiration

We're huge fans of retro Nintendo games, and we wanted a different kind of programming challenge. Pong is one of the greatest achievements in gaming, and it's a pretty simple game, so we decided to remake it as our first full game for the NES.

What it does

It's a remake of Pong, with ASCII characters and chiptune music.

How we built it

We programmed it the same way Nintendo programmers would've in the '80s. Good old-fashioned 6502 assembly language. Of course, we had to use emulators and tools adapted for windows, but the struggle was ultimately no different from that of times past. Additionally, we used YY-Chr for drawing pixelated graphics and NESst for arranging our graphics into a background screen. Famitracker was used to write the music.

Challenges we ran into

EVERYTHING. The NES uses a modified 6502 processor, so there wasn't too much documentation to begin with. It's fundamentally different from every practical programming language. The majority of code consists of storing and loading different values into hexadecimal addresses. And because it's so low-level, we had to keep track of every little hardware detail, such as Vertical-Blank refreshing and transferring individual binary digits to different registers to read input from controllers. Even displaying a pixel on the screen can be an ordeal, because the correct tile has to be placed in the correct place, right in the time when the screen is refreshing. Even if statements require several opcodes and branches.

We had to use an outside library (GGsound) to implement the sound engine and then to write the music for the game, which took up more data in the memory than expected. Importing the music into our game caused the game engine and graphics data to get tangled with the sound data, so we had to sift through the code and make sure that everything was in the right place, expand the memory, and use several different sound files.

Accomplishments that we're proud of

Displaying the background. Displaying the sprites. Displaying anything at all. Reading controller input. Drawing the entire ASCII character set for the graphics, with each character contained within an 8x8 pixel tile. Making a song. Importing the music into the code (definitely the hardest part). Making the ball collide with that paddle. Making the player 2 controller work (for some reason that only worked when we loaded it's values into the player 1 controller's register).

What we learned

We learned that, no matter what the odds are, we can still do at least slightly better than what we thought possible. We learned to deeply appreciate high-level programming languages, because of how they take care of all the little hardware details, from screen refreshing to garbage collection to loading and storing register variables. We learned to appreciate the simplicity of the modern if-else statement and for loop. Above all, however, we have gained a fundamental understanding of machine code, and the underlying processes of all computers.

Built With

  • 6502-assembly
  • famitracker
  • nesst
  • yy-chr
Share this project:

Updates