Hacker News new | past | comments | ask | show | jobs | submit login
Making a Game Boy Game. Part 1: Getting Started (invisibleup.neocities.org)
275 points by broahmed on Jan 10, 2019 | hide | past | favorite | 33 comments

Game Boy development was interesting in that you were always coding with battery in mind. You couldn't simply "NOP" your way through something, you had to "HALT". So your game loop was always "halt and wait for interrupt, do action, halt again".

Allegedly, if you didn't do this, Nintendo would reject your game outright.

I'm not too familiar with game development, is that unusual? It's pretty natural in other forms of software development. In user space, you mostly wait on system calls (e.g. select, blocking read/write, thread synchronization primitives), and in the kernel that usually translates to another process being scheduled. If there's nothing to be scheduled, you hit the idle loop, which, roughly spoken, halts the core until the next interrupt. Sometimes you need to poll a device that does not signal completion with an interrupt, or some locks may actually spin (for a while at least) before sleeping, but, conceptually at least, I'd almost call those exceptions to a rule.

This isn't necessarily different for game development, but it's different for Game Boy scale hardware, where there is no scheduler/kernel/OS/anything. You manually have to halt the hardware if you don't want the CPU to spin, and busy-loops were common on home computers & mains-powered consoles of the same era.

I got that, I was just wondering if there was more to it between e.g. Game Boy and NES than having the extra HALT in your main/idle loop, and maybe less unconditional polling. Apparently not, thanks!

I think you may have misunderstood. I think OP meant that you have to explicitly "freeze" or "halt" the program to save on battery. In other forms of software development, it's not common to explicitly state in your code that you're waiting for the kernel to interrupt you. The kernel's scheduler decides when to interrupt and pre-empts the running process. There are definitely systems out there where the running process gives processor control back to the kernel scheduler but I don't think it's common.

No, almost all invocations of system calls are implicitly telling the kernel that you now wish to sleep, and want to be waken up once the system call completes. It's abstracted away from you by mostly looking like a regular function call, but it's there. It's more explicitly apparent if you e.g. wait on a semaphore, but the principle is the same.

Just type "ps ax" into your shell, most processes will be in state "S", sleeping because of a system call.

My point is, you kind of have to go out of your way to spin CPU without actually having any work in front of you.

It's the opposite on 8-bit stuff, because there's nothing else running, and CPUs on such systems typically never stop working anyway - so if your game has nothing to do, it still has to do something.

So it's normal to just enter a little loop in your code, often one that waits for a flag that's set by an interrupt routine that runs in response to vertical blank or a timer or something. So your loop is literally just waiting for time to pass. Load flag, is flag zero, repeat loop if zero, that sort of thing, over and over again.

But with the gameboy's halt functionality, you can add a halt in there, I guess: halt, load flag, is flag zero, repeat loop if zero. Then the CPU can go dormant until the next interrupt, rather than spending its time running that loop. (It might wake up needlessly, if some other interrupt occurs, but it'll still be no more expensive than the loop.)

So the only difference really is whether you have a HALT at the end of your main loop or not, I guess. (Well, and that you sometimes had to poll, because there isn't an interrupt for everything you're waiting for.)

Run something like the original starcraft on modern hardware. It'll use 100% of a cpu.

Assuming the hardware is then fast enough to run at the full frame rate, what's it doing once it's done with everything that needed being done? Just burning cycles in a busy loop with no progress?

Typically, yes. It didn't matter back in the day when the CPU had no way to enter an idle state to begin with. Wikipedia says that Intel CPUs didn't actually enter a low-power state on HLT until 1994 [1].

[1]: https://en.wikipedia.org/wiki/HLT_(x86_instruction)#History_...

Compared to contemporary non-battery powered video game consoles it is a bit of an unusual consideration. When you have no scheduler, no battery and the CPU stays comfortably cool no matter what it's up to, there are no reasons to write programs like this.

I think the main difference is really that in user space there is an os always doing something in the background. On a gameboy though when you say halt it truly halts the hardware unlike an idle loop which just spins. So an actual hardware interrupt is needed to restart things.

For embedded software without an os it is not uncommon when not explicitly doing something to enter a spin table.

The idle loop of an OS usually halts the core and waits for an actual hardware interrupt, too. And if your user space program is e.g. waiting on a disk read, there is a pretty good chance that the OS has nothing else to do and hits that loop, halting the core, until the disk delivers, or maybe a timer interrupt kicks in.

So there's not much difference between a Game Boy and a modern computer in that particular regard, other than the many thick abstraction layers between the system call invocation and the halt instruction.

This is part one, but the author has also written 4 other parts. They are also pretty interesting, and some more focused on the visuals. The author also made the in-development game called Aqua and Ashes open-source on GitHub (https://github.com/InvisibleUp/AquaAndAshes)

* Part 1 - https://invisibleup.neocities.org/articles/18/

* Part 2 - https://invisibleup.neocities.org/articles/19/

* Part 3 - https://invisibleup.neocities.org/articles/20/

* Part 4 - https://invisibleup.neocities.org/articles/21/

* Part 5 - https://invisibleup.neocities.org/articles/23/

The intro to low level computing class at Georgia Tech used Game Boy Advanced as the platform that the projects were built on.

It was cool at first, but I ended up too deep in the weeds with platform idiosyncrasies to really get much actual C knowledge.

The original Game Boy is very different in that regard, to the point where it's relatively simple to get an emulator implemented that can decently play some games.

Of course, there are more intricacies the deeper you dig below the surface, but for the original Game Boy, that is more of a concern for emulators that aim at going towards 100% compatibility. As a game developer, you can probably stay at the surprisingly small apparent surface for quite some time (and at least the earlier Game Boy games often did).

I'm curious what you felt was idiosyncratic about the gba.

Things like converting a png to a bitmap array for storage were always fun, but tooling mostly handled that for you.

The apis like dma and io? Or something else?

Wow I think this is the first time I've been mentioned on hacker news! That was a super fun project and I use the header utility very often!

You should submit some of your articles - they're super interesting.

Just a note that she has four other articles in this series at the moment! You can easily find them by clicking the Articles link at the top of her site.

Off-topic: this is the first I've heard of neocities.org but I went there with high expectations and I'm positively impressed. I guess having been online for 20+ years makes me relatively "old" (many of those much older than my generation were not so keen to get online way back when) and by God do I miss the "old internet".

Neocities' description truly resonates with me:

    > Neocities is a social network of 216,300 web sites that are
    > bringing back the lost individual creativity of the web. We
    > offer free static web hosting and tools that allow you to
    > create your own web site. Join us!

My site is hosted by Neocities (who I support with a measily $5/mo) because I also miss Geocities and the "old internet". It's not that I couldn't have just picked any old host to serve static assets for me - but that it wanted to be a community of artsy/non-corporatized websites ran by hobbyists.

I was about to make a snarky comment, because it took me awhile to realize that you weren't talking about Geocities. I guess there's probably a connection:


Yeah its pretty cool. Its not just another free static web hosting but a place to find quirky bits of art and creativity unlike Git* pages which is just blogs and project pages.

There's nothing stopping you from putting "quirky bits of art and creativity" on a Git-host+static-site-generator site. Given that most of the Git-host web-apps have editing interfaces, there's not even a barrier to entry.

IMHO, it's mostly just that "you can freely host a static website on the same services programmers use to freely host source code" isn't a well-known thing outside of the programming community. GitHub/GitLab/etc. should do some outreach at the digital-art/interactive-media departments of universities.

The big big difference is discovery. Neocites has an explore page that shows you all of these mostly pointless personal pages and js games which often link internally to other neocities pages so you end up with a bubble resembling the old web rather than other static hosts that have websites that are just another blog in the modern commercialized internet.

That is really cool. One of the featured sites is an NES RPG fan page complete with a hand-drawn interpretation of the world map. It feels funny to describe a web page as "quaint", but that's the only word I can think of.


The first time I stumbled onto Neocities I also pined for the web as it was 2 decades ago and wondered if I shouldn’t encourage everyone I knew to put a site up there in hopes of spurring on a movement to change people’s tastes away from repetitively-polished-for-commercial-exploitation websites. Think it could work?

For me I do it this way: 1. Get a sprite system, audio, sfx, save state, game loop solution going for the platform (GBC). Usually something is available like Cocos.

2. Create the game! Sprites, animations, sounds, game code for all parts.

Then I test play, and iterate until it’s ready to share.

Starting from scratch like this website is like starting from step zero, not step one.

Yeah, nooooo. Cocos2d is a relatively heavyweight game engine aimed at platforms with bitmapped graphics and lots of CPU and memory. It's completely unsuitable for an embedded system like the original Game Boy, which uses hardware tile/sprite graphics and has very limited compute resources (4.19 MHz Z80-like CPU, 8 kB SRAM).

Cocos on the original Game Boy? There are some C libraries like GBDK, but nothing as high level as Cocos, we're talking about a very limited hardware.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact