From Completely in the Dark to Complete in Box: Making an NES game in 2020

In November 2019 I had a vague dream and no idea how to achieve it: to release a game for my favorite system of all time, the Nintendo Entertainment System.

In November 2020, I released From Below, and new game for the NES, complete in box, on a physical cart. It sold out in 20 minutes, and although it is a fairly simple game, it has garnered much praise for its fluid and modern feeling gameplay.

Maybe you are like I was: you have some programming experience, and want to make an NES game, but the whole thing seems daunting. This post is for you!

I am going to detail my journey from knowing nothing about NES Development, to releasing From Below, and some learnings from along the way.

This is not a programming guide for making NES games, although I will point you to some great resources that are that. This is instead just a 50,000ft view of the steps I went through.

About Me

A bit of background about me first: I am a professional game programmer, and have also worked on a number of small indie game projects. So I came into all this with a really solid understanding of how to build games; just not for the NES specifically. I had not, however, built a game for anything remotely as old or as constrained as the NES (the closest thing would be Pico-8, or maybe the PS2).

I came to learn that NES games, although originally all written in 6502 assembly language, today could be written almost entirely in C. The trade off between the two is speed and memory efficiency (assembly) with readability (C).

6502 Assembly Example:

L2007:                   
  LDA _pad_all_new         
  BEQ L200A                
  LDY _cur_konami_index    
  LDA _konami_code,Y       
  AND _pad_all_new         
  PHA                      
  PLA                      
  BEQ L2009                
  INC _cur_konami_index    
  JMP L200A                
L2009:                   
  STA _cur_konami_index    

The C Code that Generated the Assembly:

// The original code written in C.
// For me, this is much easier to read.
if (pad_all_new != 0)
{
	if (pad_all_new & konami_code[cur_konami_index])
	{
		++cur_konami_index;
	}
	else
	{
		cur_konami_index = 0;
	}
}

I decided that learning to work with NES hardware was going to be a big enough challenge on its own without trying to learn assembly at the same time. So I opted to write my first game in C.

First Steps

About 6 months before starting From Below, I found a great book: “Making Games for the NES” by Steven Hugg.

This is a fantastic book for people like me. It assumes you know how to program in C, but takes you step by step through the process of programming an NES game in C. I would highly recommend it!

You can actually view all of the projects covered by the book in its “8bit workshop IDE”. This custom development environment runs in a web browser and lets you code your NES projects and see them update live in the integrated NES emulator. Really impressive stuff!

I tried to dedicate a bit of time everyday to work through the book, and after a few months had more or less finished it (there are a few “extra” chapters at the end that I didn’t do at this point).

I think this is really important: if you are struggling, try to dedicate a bit of time to your goals every day. Even if it’s just a few minutes. It makes a huge difference for me.

Although I thought the book was great, and really helped me understand how the NES worked, and what programming for it was all about, I came away feeling a little lost.

I could program little snippets of games in the web IDE, but I didn’t really understand how it all got put together. I didn’t even understand how to make graphics for my games, for instance. Or what compiler it was using.

Luckily I came across a great set of NES tutorials at nesdoug.com. While “Making Games for the NES” was great at giving very detailed descriptions of how to program for the NES and how the hardware works, nesdoug.com was like a rapid fire version of that. With the knowledge I had gained from the book over months, I was able to breeze through 20ish chapters of nesdoug.com in a few nights!

The Scrolling Tutorial on nesdoug.com

In the case of nesdoug, it also explained how to set up your own build environment (I use VSCode), build art (I use yy-chr) and how all the behind the scenes pluming worked (I use CC65 for compiling). I came out of that tutorial series extremely energized and eager to make something!

Tools of the Trade

NES Screen Tool – Used for building nametable layouts.
yy-chr – Used for editing graphics.
Visual Studio Code – Used for writing code, building, and running the game.
Mesen NES Emulator – Highly recommended for it’s accuracy and debugging capabilities.

The Start of From Below

This was around May 2020 at this point, and this was when I started From Below. I decided that I was going to remake Tetris for my first game.

Tetris is often used as a “first game project” because it is fairly simple, has well understood gameplay, but it also has most of the pieces that make a game a game (sound, music, graphics, real-time gameplay, input, etc). A kind of “hello world” for game dev.

On top of that I would add a twist: a “Kraken” monster would be crawling up from the bottom of the board, dropping garbage pieces which the player would need to clear.

After 2 weeks, surprisingly, I had most of the basic gameplay done!

From Below Week 2

I started posting weekly updates on forums.nesdev.com and seemed to be getting a decent amount of engagement despite it being not the most exciting concept.

By week 5 the Kraken gameplay was taking shape, and I had some original graphics.

From Below Week 5

By week 7 I was calling the game “Feature Complete” and opening it to a public Beta.

From Below Week 7 – Beta 1

At this point I created a Discord channel for the game, to help make interacting with players a bit easier, and this was a huge boon to the game.

A number of “classic Tetris” players got wind of From Below, and started giving me tons of feedback around high level play of the game. Stuff I had no idea about: kill screen, lock delay, spawn delay, and more. They also found a ton of bugs including a really bad RNG issue which resulted in blocks repeating in longer games.

What I originally had thought would be a few days, maybe a week, of beta testing, turned into 2 months! But the game is a million times better for it. I personally feel like it is the best playing “falling block” game on the platform!

A short clip of high level play by 801pel.

Limited Edition

During this time, I made the decision to release a physical version of the game once the game was finished. Originally I didn’t plan to because I didn’t think there was enough to it to warrant a $60+ purchase. However, as I continued to post on NESDev, Reddit and Twitter, I had a lot of people telling me they wanted to buy a copy.

I decided to do a very limited run of the game: 50 copies now, with a stipulation that I might do 50 more in the future (to make sure I don’t piss of the collectors).

I contacted all the big NES publishers to see if they could help me out, and a lot did in different ways, but ultimately I decided to self-publish this game. I was a little concerned about getting a take-down notice from the Tetris Company, and didn’t want to have anyone else to worry about if I did need to pull the plug. I also figured there was no better time to learn what goes into putting together something like this, than with a limited run of my own game.

Given that I had no idea what I was doing, I also decided that I would have everything built and ready to ship prior to selling any copies. No pre-orders etc. I didn’t want to be on the line for something I wasn’t even sure I knew how to build.

In the end I ended up sourcing my boxes, manuals and stickers from a local company on Etsy that makes “bootleg” boxes for commercial games (and other stuff too).

The game NROM PCBs are by Broke Studio. Having bought a bunch of games off them (Nebs n Debs, Micro Mages, etc) I knew they could deliver. They also helped me out with “warning” stickers for the back of the carts, Styrofoam for inside the box, and little plastic bags for the games.

The yellow plastic shells and black sleeves are from a Chinese company via AliExpress. They seemed to be the best price, and were able to get them to me in just a couple weeks, despite needing to travel so far.

All the shipping materials (boxes, envelopes, bubble wrap, etc) were from random places on Amazon.

All the content in the game (art, music, and sound) was done for free (although I did send them a free copy of the game).

I plan to do a breakdown of all the costs, and how I landed at the final sale price, in the coming weeks.

There are a million little pieces that go into a physical release…

Marketing

Around this time Haradius Zero, a really fantastic NES Homebrew shmup came to North America with a similar sized release (100 games, in 2 batches of 50). I was very surprised to see it struggle to sell those 100 copies, and it really worried me, given that Haradius Zero seemed much more appealing of a game, and had more “wow factor” right out of the gate.

Originally I had picked 50 games because I thought it would sell out with no problem, but now I was starting to doubt. I decided not to take things for granted, and more actively marketed the release.

I posted lots of teaser images on twitter, where I have a modest 1.6k following, as well as the NES discords, reddit, etc.

I created a free mailchimp mailing list, which would be used as a launch day notification to everyone who was interested. I made a conscious decision to not send any mail to the mailing list until launch day, to avoid people unsubscribing due to spam. By launch day I had 151 people signed up.

I ended up sending 2 emails: 1 a few days prior to launch to allow people to plan, and set reminders etc, and another 10 minutes before the sale went live. Of the 151 people that the email went to, 105 opened the email, and 78 clicked the “buy now” button, which I think would be considered a small but highly engaged audience.

Launch Day

The sale itself was on eBay. The day before the sale was scheduled to start, I attempted to schedule the sale, and was greeted with an error saying I am only allowed to sell 10 items a month, up to $1000! I was really freaking out, contacted eBay, and after a long chat was able to get my limit increased to the exact amount I needed for From Below. Could have been a total disaster!

I chose to launch at 9AM EST to ensure the widest range of available market (9AM EST, 12AM PST, 5PM GMT).

It seemed to all pay off, as I got to watch the first 10 copies sell in seconds! Then another 10. And within less than 20 minutes, all 50 copies had sold. Quite a relief and a huge pay off for many months of hard work.

Final Thoughts

Speaking of work, I often get asked how to get something like this done while having a full-time job, and kids/family, etc. Here is what I do, and it works very well for me:

Every night I put my kids to bed around 8pm. From that point until 10pm I do something productive. Could be programming, marketing, writing this blog, etc. But it needs to be productive, not just consuming something. At 10pm, I am free to stop and go veg-out on the couch if I want, guilt free. I know I have done something worthwhile with my night. Funny thing is though, once I get working, even on nights I didn’t want to, 10pm comes and goes and I often don’t stop working.

For me, there is something very satisfying about creating, and something very empty about consuming (I think I get that from my wife who has like 3 side jobs at any given time).

Making NES games isn’t particularly hard these days, and yet it’s very common that people aren’t able to push through to finish them. I think it really just takes perseverance. Make a little progress everyday, and before you know it you’ll have gone from knowing nothing about making NES games, to selling your first release on eBay!

2 thoughts on “From Completely in the Dark to Complete in Box: Making an NES game in 2020

    1. Not pure assembly, but I am finding that as I do more complex things I am needing to do more and more in assembly, just because the c-wrapper libs I use don’t handle everything. I suspect performance will become a thing at some point too.

Comments are closed.