Flappy Bird? Where did that come from?
Hello! It’s been way too long again. For some reason I’ve gotten a bit out of the habit of blogging my progress with things. That’s basically because I was saying the same things over and over again. And also, I was incresingly worried I wasn’t making the right choices! I’d fallen back into the habit of not completing projects, and that was probably as frustrating to read about as to do.
THE ARGUMENT
And then came an argument on Reddit. On a game programming subreddit, a perfectly normal question of whether it’s possible to make games if you don’t have much maths skills. I responded with the standard, non-controversial talking point.
Of course, I got a reponse from a third person. Let’s call him Angry Reddit Guy:

It goes on until I tell him he doesn’t know what he’s talking about, and he laughs at me for being a child. Good times :)
And lo, suddenly I was angry. A *bit* at ARG, but mostly because hell! This was good advice. And I’m still very sure this guy has never developed a game to completion - his Reddit profile doesn’t show any dev at all.
So why can’t I finish a game?
WHAT IS FLAPPY BIRD?
You’ll get a lot of answers to this, but to someone who grew up in the 80s, the real answer is ‘a re-skin’. Since I can remember, there have been Spectrum demos where you drive a line through a cavern, left to right, and don’t crash into the floor or ceiling. Flappy Bird is the same, just with gravity in it. It also sacrifices increasing difficulty and any variety of obstacles. Looks pretty, though!
From my side I know how to make this game as a jerky mess, so the challenge wasn’t really how to do it, but how to keep the feature list short while keeping the update speed high. I think I did it. But what did I learn?
THE MATHS IS INDEED SIMPLE, BUT THE FIDDLING IS NOT
Yep, turns out I was right, the actual maths for movement is so simple I can screenshot it in one page for you. And it includes other bits too! Like triggering the sound effects for flapping. And making sure we’re not in Get Ready mode. And clamping the bird to the top of screen.

Shall I do a full explanation? The secret is, the momentum is stored as an 8:8 fixed-point number. This way, I can easily change speeds accurately without doing lots of fiddling with the floating-point calculator. There’s always 3 times as much work in a game as you expect, so why add some if you don’t need to? Here’s the first version:
Previously I’d got a little stuck with my plans on the sprite manager. The idea was to run the 'game’ on the interrupts at a steady 50hz, and the display catches up whenever it can. But to make sure things are updated safely, you would attach a routine to the sprite data, and the manager would run the code when it was safe. So far so good.
But I really needed another version of the variables used, because I can’t guarantee the sprites will run at a certain rate. And it’s a little weird when people turn off gravity in a game for a bit.
So here’s the sprite updater. You can see now it’s mostly copying values from one place to another, and that’s intentional - at that point I was still thinking about the concept of volatility. Remember that word, it enables me to change the main hero values without worrying, and the sprite updater only makes a copy when it needs to.

The bottom bit is taking a sine wave as the input, so you don’t plummet to your death immediately on starting. So far, so simple. Next up let’s add in a few obstacles:
OBSTACLES AND COLLISION DETECTION
Yep, that’s the obstacles added in. Pretty easy to get a random height within a range, but in the end I made a few more tweaks to this: with my pseudo-random number generator I could use a modulus to get a range of a certain size. Then eventually I also made it a little too big, and clamped the answer to within a smaller range. This would slightly favour pipes being extremely high or low, because seeing 12 pipes in a row at basically the same height was pretty boring.
I’d chosen a narrower screen width for the game for a couple of reasons:
- It was an iPhone game, which was bafflingly played in portrait mode. Part of the benefit is, you can only see a single upcoming pipe, so there’s no question of planning a strategy.
- It would make a scrolling game a little easier to run :) Let’s be realistic about the horsepower available here.
But there’s one other benefit - I didn’t need to worry about pipe clipping immediately. Good - I just want to concentrate on game mechanics first, and add in display techniques later.
With the obstacles in place, now adding in colliders makes sense.

The plan was simple in the end, but it took me a while to get there because, as always, I’m trying to generalise too quickly. It’s not a good personality trait if you can’t make any simple decisions because you’re thinking about turning them into complicated decisions.
In the end keeping a single collider for each pair of pipes was enough. When you breach the collider with the bird’s hitbox, you test whether it is entirely between the middle area, and score points if so. Otherwise, bye bye birdie (sorry). I also made sure there was a flag to set to make sure you only scored one point for each collider, useful.
In this case, I really gave up on generalising, and just wrote bespoke code for this game. There’s only one type of collision that can take place, which is far simpler than, say, R-Type. So I don’t need to categorise the collision type (eg do bullets touch other bullets? Can the hero get hit by his own bullets? etc), I just test the bird against everything else.
The benefits to modified code is, I can make the hitbox for the bird nice and small, which makes the game generous. After this tweak, I never got the feeling the game was unfair, a BIG no-no to most gameplayers. The generalised collider will have to wait!
MODIFIED SPRITE PRINTERS
I’ve spent a lot of time over the last few years making fast sprite printing and clearing routines, can’t stress enough how useful it is being comfortable with this process in general. I plugged in some existing routines from R-Type, which are good at clipping sprites on the side of the screen. Worked fine for standard sprites - let’s call them pipe heads - but I hadn’t bargained for the stretchiness of the pipe *necks*:


Took a little time to work out but I got there. The game saves some extra time by having a static background, which means I don’t have to copy bits of background to each sprite’s buffer when printing. I did run out of space beneath the screens at this point, but worked a way round it. The code takes more memory than you’d think, especially when unrolling loops for speed.
Essentially, these printers are painting up-and-down rather than left-and-right. This makes it easy to do a few things, like print the same pixel byte in multiple places. You can also find an easy break in the code to stop printing, and get a clip effect on one side. I needed loads of different versions though! A pair for each of the pipes printing on even x-coords and odd, times two for clipping to the left or right of the screen, times two for printing top pipes and bottom pipes.
Sometimes it’s all about the grind.
THE MUSIC WENT DOWN REALLY WELL
As this was a quick project I didn’t want to spend several nights relearning how to use a tracker, and I had this one track lying around from years ago that I was proud of. It helps that I’m a huge Maxo fan, and the track is now ten years old.
I used plenty of little tricks to get this tune written, I might need to make another post about that. I’ve been searching for chiptune tutorials for more tricks, and you’d be surprised how little useful information is out there, unless you’re struggling to make your first tune.
So I was really happy to see Stefan (with one eff, Stefan) Drissen made an oscilloscope view of the music, it’s mesmerising.

One thing I’ve realised is that the best tunes seem to be very flexible with their arrangement - different voicings and things. This tune pretty much forced me to find new voicings every few bars, and it reminded me I needed to get my tracker working.
…AND THE BUGFIXING
There were a few things I couldn’t get working exactly right, and had to ditch:
- Icons for music and sound effects toggles
- A nice transition from the credits screen back to main attract screen
Again, a big learning experience for me. Where I can sit on a project for weeks because I can’t perfect it, this time I needed to release something quick. So I deemed these things not essential, and binned them!
Another big win was working out more of how the SimCoupe disassembler/monitor worked. I had put the interrupt jump table at &6000, which is exactly one byte after the screen. Smell the danger. In more cases than I expected, I would put a monitor on the jump table and find sprite printers and their nasty, nasty off-by-one errors:

I consider Interrupt-based bugs one of the hardest types to debug, so this was invaluable.
I felt I had fixed enough issues to publish, and the community gathered around to circle the mistakes. Thankfully, not too many! But they definitely found a few extra things:
- Missing 256K check
Yep, this was an oversight! I should have a quick check that works out if you have the 512K expanded memory. I need it for this game. An easy fix:

I hooked it into a nice message, should there be only 256K. I’ll be putting this in every project from now on - it’s just courtesy isn’t it.
- Volatility was back, baby!
Okay, remember how smart I thought I was about 3 pages ago? Well, there were many little niggles that were still unfixed, and they seem to all have the same source - volatile data that cannot be trusted. So pop-quiz: which of these routines do you prefer?:

Top one, right? Easy to read, purely functional. Wrong, you need the bottom version. This is because if you get an interrupt when only half of the address has been written in, you’ll end up jumping to who-knows-where! The instruction LD (nnnn),HL will do that in one go, and that needs all the other hassle surrounding it.
I’ll admit, this really isn’t a great solution, but it will do for now. In future, I’ll need to go through my sprite manager and find all other instances of this. But I learnt that if you are doing bug-fixes, sometimes a little ugliness and a few bytes lost is tolerable.
So some small pauses people were noticing were down to this! It meant for one frame I was successfully jumping to random addresses, and the game still wasn’t crashing. It’s a miracle, right?
END OF THE ARGUMENT
So, after all this, did I get back to Angry Reddit Guy? Of course not :) I’m pretty sure I did this for myself, and I don’t care to shame some bored doomscrolling stranger. Haha, sweet invisible revenge.
Is it over? Yeah, thanks for sticking it out this far! Back soon with more games!

![Honestly I’m still here! Sorry I’ve been quiet over the last year. I’m um… [insert excuse]
Okay - so I’ve discovered Tumblr doesn’t like being looked directly in the eyes. You know what this iconic end-of-level boss is from, and I know what it’s...](https://64.media.tumblr.com/71f57a2ee137b24615a95c7955411392/88806a624fc0b924-51/s500x750/c505363412b5fe76eebe2d0f44408ef5ab7c5222.png)



