Hacking Flappy Bird

"Sos" created a port of the iOS game Flappy Bird for the C64. It is too difficult for me, so I hacked it and implemented a computer player for it (my highscore without the hack was 9).

First I needed to unpack the game. I loaded it in the VICE emulator, set a breakpoint in the monitor at the program start and after some single stepping and more breakpoints finally the game started with a jump to $3000. I saved the game with "bsave" (from $0801 to $7fff) in the monitor. There was another basic header after unpacking, which jumps to $3000.

Then my idea was to emulate the joystick fire presses. I set a breakpoint on joystick input read ("break load dc00") and there are multiple positions in the program where it is read: waiting for fire when the game starts, acknowledge of the help graphics and then in the game. The position in the game is at $5da8. I replaced it with a "jsr $c000", filled the PRG file until $bfff and wrote some assembler to concat at the end of the PRG. First test was a "lda $dc00; rts" and it worked.

Then I analyzed how the game detects a hit with the tubes. This was easy, because when I disabled "sprite-background collisions" in the VIC settings in VICE, it didn't detect hits with the tubes anymore. So the tubes are characters with a modified character set and of course the bird is a sprite. A quick fill test for $0400 showed that the standard character screen position was still used. I set a breakpoint on store on $0427 (last character in the first row, "break store $0427") and found the scroll function and function for creating new tubes. It uses the voice 3 oscillator register for the y position, with the noise generator as a random number generator. There is a counter at $1e1e for the distance between the tubes and when it is 0, I can read the y character position in $1e20.

The rest was easy: Calculate the y raster position from the character position, delay it with a ringbuffer and compare it with the bird y sprite position. If too low, flap. As a bonus, the hack can be enabled with joystick left, and disabled with right. The source code: flappy.asm. For faster turnaround time while adjusting the offsets and ringbuffer delay, I used a script to compile my assembler program, concat it to the original program and start it in VICE:

java -jar "C:\Program Files (x86)\kickassembler\KickAss.jar" -binfile flappy.asm
copy /b flappy-unpacked.prg + flappy.bin flappy.prg
"C:\Program Files\WinVICE-2.4-x64\x64.exe" flappy.prg

Finally I packed the result with exomizer: flappy-bird.prg


26. Februar 2014, Frank Buß