
The NES Homebrew Scene - shortformblog
https://tedium.co/2018/04/10/nes-homebrew-scene-history/
======
jimmaswell
A while ago I wanted to try some NES ROM hacking but I couldn't find any tools
for it that were really convenient - I ended up typing 6502 into some online
assembler to copy the output into HxD and other processes like that. So, I
wrote something more to my liking that was more like an IDE.

I couldn't think of a good name, but I was modding Kid Icarus at the time, and
it's in .NET, so I just called it IcarusNet. It was primarily for ROM hacking,
but as far as I know, it should be suitable for writing something from scratch
in conjunction with tile editing programs and maybe other things you'd need.

Not nearly as advanced as NESMaker (very impressive from the looks of it)
seems to be, but maybe a middle ground for someone who wants to write a game
more to the metal but also wants something more graphical with the same "one
click assemble/run" mindset.

Comes with instructions for a sample project to make an edit to a freely
available ROM in less than 5 minutes.

[https://github.com/ldyeax/IcarusNet](https://github.com/ldyeax/IcarusNet)

Since then I've heard that license might have some problems for software, so
I'll change it if the need arises.

~~~
phs
As someone who simply wanted a NES assembler, I've found cc65 [0] to be great,
for example wrapped as a docker image in [1].

[0]: [https://github.com/cc65/cc65](https://github.com/cc65/cc65) [1]:
[https://hub.docker.com/r/philhsmith/cc65/](https://hub.docker.com/r/philhsmith/cc65/)

------
pubby
Nowdays, it's impossible to do modern programming without relying on millions
of lines of other people's code. It's frameworks and libraries all the way
down.

On the NES however, every line of code is yours. There's no such thing as
libraries, operating systems, or frameworks. They don't exist. It's
refreshing.

One of the big problems of modern programming is how easy it is to add
complexity. As Charles Moore once said:

>"Simplify the problem you've got or rather don't complexify it. I've done it
myself, it's fun to do. You have a boring problem and hiding behind it is a
much more interesting problem. So you code the more interesting problem and
the one you've got is a subset of it and it falls out trivial. But of course
you wrote ten times as much code as you needed to solve the problem that you
actually had."

It's easy to add complexity on modern systems, but it's hard on the NES. The
programming too clunky; it's too much work to anything but simple things. For
that reason, it's far more common to simplify the problem and reduce features
rather than add them. It's a wonderful thing.

~~~
drewying
I agree with you in general, but I think it's worth pointing out that
programming the NES's PPU is actually very similar to programming with a 2D
graphics library today.

NES games never wrote their own scrolling logic, or there own graphics logic.
They wrote tile values into a background table and then told the NES how much
to scroll the playing field, and the NES rendered and scrolled everything
automagically.

NES games never drew their own sprites. They just said "Hey NES, write the
sprite at this x and y location" and the NES did it.

Audio worked the same way.

Honestly, coding for the NES would be similar to working with a simple 2D
graphics library. So I don't know if it would be accurate to say "every line
of code is yours" on the NES. It's more just that the "libraries" used were
implemented in hardware instead of software.

~~~
marshray
> NES games never drew their own sprites. They just said "Hey NES, write the
> sprite at this x and y location"

Yeah, but the hardware is so limited with weird corner cases that writing a
bitblt might be easier. For example, some games have to reconfigure their
sprites at the beginning of every horizontal scan line to overcome the
hardware limitation on simultaneously displayed sprites (8).

~~~
klodolph
Which games? To my knowledge this is at best _exceptionally rare_ because
there are only ~114 CPU cycles in a scan line. The reports I've heard are that
if you do any OAM changes mid-frame, you get something like four lines of
glitches. More common is to just do a full OAM DMA during vertical blank, at
least from the ROMs I've seen.

~~~
marshray
I can't find the original link where I read about this, it may have been more
theory than about specific games. These links seem to be relevant:
[http://wiki.nesdev.com/w/index.php/Sprite_overflow_games](http://wiki.nesdev.com/w/index.php/Sprite_overflow_games)
[http://forums.nesdev.com/viewtopic.php?t=16299](http://forums.nesdev.com/viewtopic.php?t=16299)

------
wgerard
Somewhat related:

I'm always thoroughly impressed with how complicated and knowledgeable the
people who work on these topics are.

I don't even use the product, but I love reading the Dolphin blog [0] because
they write about fairly complicated topics in a way that's pretty
approachable, and it always makes me appreciate how much I don't know about
these topics.

While I feel like it would be difficult-but-not-impossible to be a contributor
to say, the linux kernel (this is probably me grossly oversimplifying the
process), I think I could spend the next year diving into graphics programming
and basic hardware topics and still not contribute in any meaningful way to a
project like Dolphin.

Articles like this and the Dolphin blog definitely make me realize how much I
don't know.

0: [https://dolphin-emu.org/blog/](https://dolphin-emu.org/blog/)

~~~
xfer
The difference is domain knowledge, it takes time. You might feel that way
about kernel because the high level concept of resource management is
pervasive in programming. So you might feel you can easily dive into it, but
it will take you equally long to say port the kernel to a new
architecture/write drivers for a new platform.

------
dietrichepp
I recently started work on an NES project, and wrote the first part of it up:
[https://www.moria.us/blog/2018/03/nes-
development](https://www.moria.us/blog/2018/03/nes-development)

It's a lot of work. I've managed to get data from Tiled into my ROM image, and
I'm working on figuring out an architecture for scrolling and displaying a
status bar.

Implementing scrolling and a status bar sounds simple but is actually a total
pain. You only have two screens of tiles to work with, which can be arranged
horizontally or vertically, and anything more complicated than scrolling in a
single direction (including status bars) requires adjusting the scrolling
registers between scanlines, and making sure that your status bar is in a
different part of the tilemap (called "name tables") than your world.

A common way to accomplish this is to lay out your graphics memory so a
certain address line turns on and off once every scanline, and then putting a
chip (called a "mapper") on the game cartridge which wires that address line
to a counter, which drives a CPU interrupt line. Simpler games like Super
Mario Bros. don't need this extra chip, but you only get a single status bar +
scrolling in one direction only. Games with scrolling in both directions often
display graphical glitches on the edge of the screen, like Super Mario Bros. 3
(look at the right edge of the screen).

This is unnecessary on newer consoles, and less painful even on the Sega
Master System.

~~~
jacquesm
But programming with restrictions like that will make you a better programmer.
Nothing brings out creativity better than a limiting environment.

~~~
airforce1
> Nothing brings out creativity better than a limiting environment.

This is so true as a life principle!

I once read a book about the development of laser guided bombs [1], and in it
it talked about how Texas Instruments made the first viable prototype [2] on a
shoe-string budget even though they were competing against a large government
contractor with a huge budget.

Because of the budgetary constraints, TI couldn't afford multi-million dollar
wind tunnels for testing, so they built scale models of the bomb and dropped
them into swimming pools, performing mathematics transforms on the results
using the drag coefficients of water vs air. They came up with a bunch of
other innovations as well, such as the shuttlecock seeker head and made a
superior product that vastly outperformed the high-budget contractor.

[1] [https://www.amazon.com/Weapons-Choice-Development-
Precision-...](https://www.amazon.com/Weapons-Choice-Development-Precision-
Munitions/dp/0817315322) [2]
[https://en.wikipedia.org/wiki/Paveway](https://en.wikipedia.org/wiki/Paveway)

~~~
makapuf
I'd find completely awesome if it weren't for tools aimed at killing people.
I'm not sure I enjoy advances in that area.

~~~
AdamJacobMuller
It's just as easy to say it is a tool designed to save lives. Ultimately it's
a tool, it's how you use it that's important.

~~~
ffxtian
Just as easy maybe, but fundamentally incorrect. Its mechanism of action is
killing people -- choosing to believe the claim that killing those people will
save lives alters neither the purpose nor MO of the tool.

~~~
thomastjeffery
The goal of the mechanism is to kill fewer people than other available
methods.

Tools are, simply put, devices that increase a user's leverage.

We live in a world full of tools capable of leveraging against life. We also
live in a world with individuals and groups who - for whatever reasons -
choose to use that leverage.

We can't get rid of tools like this. They are very straightforward inventions,
especially as technical knowledge increases. The simplest nuclear fission
reactor is a bomb. That does not make nuclear fission fundamentally worthless,
and whether you agree that knowledge about it is a "good" or not, that
knowledge is not going to simply disappear.

> choosing to believe the claim that killing those people will save lives
> alters neither the purpose nor MO of the tool.

How a tool is used does not change what it is or what it does. It does,
however, define the purpose. If the purpose of killing someone is to prevent
that individual from taking another life - or several other lives - then the
purpose of the tool used is to save lives. The goal for perfecting a tool that
is to be used for that purpose is to minimize the amount of lives taken, and
damage done. That means a "better" bomb takes fewer lives, saving more.

If you choose to believe that an individual taking action against the life of
another has not forfeit his/her own right to live, then you might consider
this tool to have no legitimate purpose. Frankly, I disagree, and hope you
will reconsider.

------
octorian
My own personal story with the NES didn't last that long, because I was a kid
without money, terrible at platformers, and my parents wouldn't buy me a lot
of games. You can only play Super Mario Bros so many times before you're tired
of not making it past the 2nd level. So I eventually switched to computers
(Apple II vintage), and never looked back to consoles.

This past year, however, I decided to take up a little retro project based on
the NES. Its best described as a "video game music player alarm clock", using
some authentic hardware. It uses the CPU from an actual NES to faithfully
synthesize music from actual NES games, while building the surrounding system
out of modern components.

First prototype in action:
[https://www.youtube.com/watch?v=izMFPKmD5ZU](https://www.youtube.com/watch?v=izMFPKmD5ZU)

Blog posts detailing the project:
[http://hecgeek.blogspot.com/2018/02/nestronic-1.html](http://hecgeek.blogspot.com/2018/02/nestronic-1.html)
[http://hecgeek.blogspot.com/2018/03/nestronic-2.html](http://hecgeek.blogspot.com/2018/03/nestronic-2.html)

------
rbanffy
I was a bit turned off by the way assembly is described as "tricky" and
"tedious"... All programming languages can be tricky and tedious. Assembly
(specially on the 6502) is conceptually _very_ simple and, while it may not be
trivial to translate higher-level concepts to its simplicity, as long as what
you want can be readily expressed in it, it's trivially easy.

You will, of course, need to know what bits to set at what addresses to make
the NES auxiliary chips work and do what you expect them to do and that may
represent some work but that complexity is from the platform, not the
language. You can have a library (or a set of macros) that deals with it
written in any language you can compile for the platform.

~~~
simias
>Assembly (specially on the 6502) is conceptually very simple and, while it
may not be trivial to translate higher-level concepts to its simplicity, as
long as what you want can be readily expressed in it, it's trivially easy.

That's precisely why I would qualify ASM as "tricky" and "tedious". You're
bogged down in the tiny details that nowadays a compiler would probably solve
as well (or even better) than you do. If you want to express "I want to make a
function that adds two integers" then yeah it's trivial. If instead it's "I
want to iterate through the leaves of a binary tree and compute its standard
deviation" then have fun; good luck.

"This is a multiplication by 5, it's pretty expensive, probably better off
shifting by two and adding once. Oh but then I need an intermediary register,
do I have one available?"

"I guess I could inline this bit of assembly here instead of making a function
call. Oh but wait now I need to re-do my register allocation to match."

"I need to reserve a bit more stack space to bank this register, let's modify
my function's prelude and prologue to match."

Ain't got no time for that.

I think writing assembly is a skill any coder should have, especially if you
usually deal with close-to-the-metal languages like C, C++ or Rust for
instance. I think having a good grasp of assembly will make you a better
coder, if only because it'll let you read the assembly output of your compiler
to figure out what gets optimized and how (and also maybe what you could
change to speed things up). There are also a few situations where writing
assembly is the right solution.

That being said you'd have to pay me a lot to write a full application in
assembly, regardless of how many layers of macros and pre-processing steps I'm
allowed to use (unless gcc is allowable as a pre-processing step...)

~~~
jackhack
You've captured exactly what it feels like -- this is the constant tension
among asm developers. I love really high performance code, but I also like
accomplishing more than one trivial thing per hour. It's hard to even remember
the time before I knew C, when coding in assembly was all there was. When it
was "normal." But I do remember the first time I wrote for the M68000 chipset
and finding a multiply and divide instruction. "What? I don't have to write my
own divide routine?" Tears of joy!

I will typically build something out in a high level language, profile to see
where the time is going, and take a closer look at the algorithm first to see
if it's sensible or some different approach should be taken. If it's an
appropriate algo, then it's time to look at the implementation to see where we
can shave cycles.

For the most part, even if you're talking to hardware that requires
exceedingly precise timing (interface/bus protocols, certain chips), C will
probably do the job. (It's no coincidence it was referred to as "universal
assembly language".) Only where one is absolutely starved for resources (as
the NES, and many 8-bit systems were/are) is ASM necessary.

"high level when you can, assembly when you must"

~~~
pjmlp
> "high level when you can, assembly when you must"

I was already following that on MS-DOS with its 640 KB, with all Basic,
Pascal, C and C++ compilers from Borland and Clipper.

Although I did spent one year still focused on using TASM for everything and
playing how much I could cram into a COM file.

------
ashleyn
The appeal of retro console/computer dev is essentially an exercise in
constrained programming. Systems of these era had extremely constrained
specifications, and making the most of them is an art in itself.

~~~
ythn
Sometimes I wish we had more constraints because I fear we've all forgotten
how to write fast and lean code in favor of semi-fast but very bloated code.

I remember back when I first used Windows 95, opening programs was very snappy
and I was impressed. I imagined Windows of the future being even snappier, but
somehow the opposite has happened. Now every application takes a long time to
boot up, check for updates, etc just because they use orders of magnitude more
resources. I long for apps with instantaneous startup times, no loading
screens, and small footprints

~~~
lmm
We haven't forgotten, we choose to put our time and energy into features
rather than performance because that's what end users care more about (at
least, it's what they vote with their feet for).

~~~
chongli
Some things have been lost, though, and I'm not even referring to the usual
claim about constraints facilitating creativity. Games of the 8- and 16-bit
console generations, as well as all arcade games up until that point, were
written with CRT monitors in mind and often used 'racing the beam' techniques.
This resulted in games with extremely low latency, something you never find in
a game of any sort today.

The difference can be felt when comparing a game like Super Mario Bros running
on an emulator with a typical LCD screen to running on original hardware with
a CRT monitor. The emulated version is so sluggish it feels like you're
playing underwater!

~~~
lmm
> Games of the 8- and 16-bit console generations, as well as all arcade games
> up until that point, were written with CRT monitors in mind and often used
> 'racing the beam' techniques. This resulted in games with extremely low
> latency, something you never find in a game of any sort today.

The techniques haven't been lost - if anything there are probably more people
who know how to do those things today than there were in the past.

Typical LCD monitors are undeniably worse in many ways than the CRTs they
replaced, but again, most customers turned out to prefer the convenience of
the LCD on the whole. Nowadays with the rise of 144Hz monitors those rare
users who care a lot about gaming latency do have an option.

~~~
chongli
This article [1] has been posted on HN before but not everybody has read it so
I thought I'd mention it here. If you scroll down there's a paragraph where
Dan talks about 144 Hz gaming monitors. Shocker of Shockers (not surprising to
me, actually) the Apple ][ has far lower latency than a modern PC, even with
one of these monitors. When actually measured with a high speed camera, a CRT
refreshing at 60 Hz still has lower average latency than a 144 Hz gaming LCD.

I would expect the NES to perform similarly to the Apple, since it has the
same CPU (6502) and also uses a CRT display.

[1] [https://danluu.com/input-lag/](https://danluu.com/input-lag/)

------
agentultra
I literally just wrote my first ROM that displays a green box on a black
background working on my retropie machine last night.

The NES homebrew scene is pretty cool and the tools and languages have come a
long way. One interesting avenue that might be work exploring is to use code
generation and CSPs to generate and shrink code.

It's a lot of fun. It's why I like the PICO8. Constraints are interesting.

I just wish I still had my old BASIC code for games I made on my Amiga back in
the day...

~~~
ansible
> _Constraints are interesting._

Constraints are also helpful when working towards a sense of mastery.

Look at a modern operating system (or console) for that matter. So much
capability, so much complexity. You'll never learn it all, never be able to
master it.

Heck, just truly understanding the machine code of a modern processor, and
knowing everything it does and can do is quite a daunting task.

These older 8-bit systems (NES, C64, etc.) in contrast are much easier to
completely understand. If you are willing to live within the limitations, you
can create something really awesome, and be able to leverage the full extent
of the system's capabilities.

That provides enormous satisfaction to some.

~~~
agentultra
Just understanding the intel instruction set is basicallly impossible for a
mere mortal. How thick is that reference manual now?

------
chrismaltby
Slightly related, but for GameBoy Homebrew, I've been working on a Javascript
implementation of GBDK, a C library for GameBoy dev, and am using Emscripten
to build a React debug tool allowing you to check out the state of the
different graphics buffers and registers and print to the browser console. Bit
early days but it's really helping speed up a game I'm working on.

[https://www.gbdkjs.com/](https://www.gbdkjs.com/)

Got an example project at

[https://www.gbdkjs.com/examples/shooter/web/](https://www.gbdkjs.com/examples/shooter/web/)

------
CM30
It's also a matter of seeing what you can achieve on aging hardware. Can you
do better than a team of professionals could in the 80s? Could you make
something that pushes the console to its limits? Those types of questions are
very inviting for both homebrew and ROM hack developers alike. Or perhaps
before them, for those in the demoscene.

------
trentnix
Love the NES and love retro gaming, but the article completely contradicts
itself. It's not just driven by nostalgia, but...

 _It says something about the legacy of the NES that most homebrewers continue
to make games for the system for reasons other than nostalgia. It’s mostly
because they love the NES.

“I’ve always wanted to create NES games, ever since I was a kid. I remember
sitting around drawing maps on paper, daydreaming of what my designs would be
like to play,” explained Nathan Tolbert, a relatively new figure to the NES
homebrew scene who’s already built a couple of titles for the annual NESDEV
competition._

So...nostalgia.

 _One creator, Antione Fantys, wants to bring back some of the elements from
retro games that don’t seem to exist in the modern generation. Because the NES
is the most iconic of these systems, he enjoys programming with it, citing the
limitations of the system as a means to creating the most accurate
representation of a retro game as possible._

More nostalgia.

The article pretty much proves these homebrews are the product of nostalgia.
Not that there is anything wrong with that.

~~~
mieseratte
I used to do a lot of dev against the NES. 6502 for the NES was my first
language, wrote my own assembler, built games, cartridges, etc. etc. Hell, I
even have a PCB, minus the PRG and CHR ROMs, from an old Ice Hockey cartridge
on my desk in front of me as I write this.

Never had an NES growing up, never played one until I got into NES dev. I was
turned onto it by a classmate. We're both too young to have had the NES
growing up, so we simply couldn't be a nostalgia play. There's a lot of folks
who get into because it's surprisingly approachable, and scratches the itch of
"make a game." TFA just had a bad quote...

~~~
trentnix
Nostalgia doesn't have to be purely about one's childhood interests, although
it frequently is. In your case, your interest still seems a product of
nostalgia.

I don't really understand why people view interests based on nostalgia as a
weakness. Being nostalgic doesn't have to mean that life isn't good or that
things were better once upon a time.

Like what you like, do what you do, and enjoy what you enjoy without apology!

~~~
2Xheadpalm
If we want to get pedantic; "Nostalgia: a wistful or excessively sentimental
yearning for return to or of some past period or irrecoverable condition",
where there seems to be an emphasis on 'wistful', 'excessive' and
'irrecoverable' parts of the definition, which in turn can infer a negative
connotation about it all.

However, I agree with you, trying to capture past enjoyments and in cases like
this, continue to make new memories and fun times, go for it I say!

------
nickysielicki
[https://twitter.com/clearvus](https://twitter.com/clearvus) streams at 9pm
EST on Mondays and Thursdays on Twitch, he has been working through making an
NES game from scratch. He is off this week, but people who are interested in
seeing this type of work should definitely check out his series, he deserves
way more viewers! I've learned a lot from it.

[https://www.twitch.tv/clearvus](https://www.twitch.tv/clearvus)

recordings are posted on youtube:
[https://www.youtube.com/watch?v=XwGj1ciSAtw](https://www.youtube.com/watch?v=XwGj1ciSAtw)

------
euske
Maan, I envy the homebrew scenes in the US so much. In Japan there are a few
people who're doing homebrew, but because of the constant intimidation by
Nintendo and marginalization by the society ("they're technically criminals.")
they're not as open or organized as the US. I think we're killing our own
talents.

------
felipebueno
I haven't read the article yet but, judging by the title, I thinks this is
relevant:

[https://www.kickstarter.com/projects/1316851183/nesmaker-
mak...](https://www.kickstarter.com/projects/1316851183/nesmaker-make-nes-
games-no-coding-required)

------
FeteCommuniste
The existence of phenomena like this and the demoscene made me realize that
there are levels of programming skill that I will never be able to reach. Kind
of disheartening, but still neat to watch other people do it.

~~~
zellyn
I felt like that for a long time, and eventually it prompted me to build an
Apple II emulator, and implement the compiler from the Coursera Compilers
course.

Simple versions of these things are not as insurmountable as you think: just
put your foot on the first step :-)

------
typetypetype
Very nice! One thing I always loved about Nintendo games is that you can
usually just pop them in and start playing. No dragged out tutorials, setups,
etc.

------
VyseofArcadia
The article namedrops Shovel Knight. I highly recommend the game. It's one of
the best games I've ever played, even putting nostalgia aside.

------
TruthSHIFT
I've had a lot of fun trying homebrew games on my modded NES Classic. If
you're a fan of the original Metroid, you should definitely try Rogue Dawn. It
plays like a true sequel to NES metroid and it adds features from later
Metroid games.

------
lanius
Are there any uniquely impressive homebrew NES games worth playing?

------
germinalphrase
Can anyone recommend any particular enjoyable home brew games? I can see a few
already listed in comments, but it would be nice to gather up a short list.

~~~
eltoozero
Blade Buster, fast paced modern time attack shmup; very pretty, don’t forget
to hit select to increase speed.

My top score in 2min is 500,000+.

~~~
germinalphrase
That's great! (and difficult).... 100,000 is initial best.

Having recently discovered OpenEmu, I'm trying to track down good
homebrew/freeware games.

------
phjesusthatguy3
I got to the "and these are the reasons why" section before I really had to
give up. The reasons why you remember the NES over every other video game
system of the era was that Nintendo were monopolizing bastards at that time,
and if you (as a developer) made games for the NES to be released in the USA,
you were essentially forfeiting the right to release those games for other
systems in the USA.

Honestly, I'm glad Nintendo got knocked down a peg on their last few systems.
I'm just not happy about what they taught their competitors.

------
nkozyra
The best games age well. People still play pac man. People still play Mario.
That said, the aesthetic is absolutely nostalgic.

~~~
foobarrio
The aesthetic serves a purpose though. Hi-fi 3D game assets take orders of
magnitude more work to create than low-fi 2D ones. I agree that nostalgia and
familiarity are what allows gamers to accept NES-style graphics as a valid
form of low-fi 2D art. The creator of Stardew Valley mentioned he wouldn't
have been able to finish the game had he had to create 3D assets that looked
as good to people as the current 2D art.

Having people accept NES-style pixel art is a boon to indie devs. Games like
Super Meat Boy have higher res 2D graphics but is still a similar aesthetic.
Low-fi poly is also a retro art style. However I've noticed that low-fi poly
games are still rendered in high resolution and using more advanced lighting
techniques so still requires more work than low-fi 2D.

------
jdlyga
My favorite genre of games are still platformers. 20xx (A Megaman X roguelike)
is my favorite game I've played this year.

------
ricksnyke
Fascinating that these scenes are still thriving, just recently saw "8-Bit
Guy"'s postmortem video on writing and shipping a game for C64.

------
OrganicMSG
Of course it isn't just driven by nostalgia. It also requires a constant
supply of coffee, for one thing.

------
kraig911
Ah nostalgia. Everyone here should look up the original meaning of nostalgia
though to really understand this. It's so apt yet so crippling.

