In 1990, a computer magazine published a game I wrote. It was a big deal for teenage me.
There is now a thriving “retrocomputing” scene, with people making new software and hardware for computers like the Commodore 64 and Apple II. I decided to update my old game, and experience what developing for these classic machines is like now.
The Game
In August 1987, Compute!’s Gazette published Bounty Hunter, an educational game in which you chase a bad guy around the U.S. It was played on a map that flipped between east and west halves. I thought it would be fun to do a similar game with countries, played on a scrolling world map. Compute!’s Gazette published that game, International Bounty Hunter, in March 1990.


The Challenge
My goals for the 2025 edition:
- An updated map, of course. The original had 2 Germanies and a Soviet Union!
- A bigger map.
- Make it run on the Commodore 64. The original was written for the C128, using BASIC 7’s new graphics commands. But I want this to run on the real hardware of the best-selling personal computer ever.
Can I do it with my rusty 8-bit programming skills?
Just for context: when I developed this in 1989, there was no World Wide Web (the first web page went online in late 1990). There were bulletin-board systems (BBSes) but participating in one would have meant a modem call to Winnipeg. Computer class in school was just typing, so learning programming was a solo exercise, using magazines and books.

The Data
How I made the map in 1989: I photocopied a map onto graph paper and colored the squares with markers. Which got the aspect ratio wrong, incidentally, because the characters on the C64 aren’t square. 🙄
How I made the map in 2025:
- I downloaded a shapefile from Natural Earth.
- The original map looks like a Robinson projection, so I projected the new map the same way:
ogr2ogr -f "ESRI Shapefile" -lco ENCODING=UTF-8 -t_srs "ESRI:54030" projected_map.shp.zip /vsizip/ne_110m_admin_0_map_units.zip - I used Python libraries Fiona and Pillow to draw the shapes into a GIF.
I mostly re-used the country colors from the original game. For the countries in the Balkan Peninsula and the post-Soviet states, I used a greedy graph coloring algorithm to assign new colors.
How I got the routes between countries in 1989: I looked at a map and listed the connections by hand.
How I got the routes in 2025: I used the The World Factbook’s list of land boundaries. There’s some commentary mixed in with the data, but with a small amount of cleanup the list can be parsed with Beautiful Soup.
I asked ChatGPT what the main hub for international travel is on each continent. It told me: Atlanta, São Paulo, London, Dubai, Johannesburg, Sydney, and Tokyo. I allowed shortcuts between those hubs wherever you could draw a line over just ocean.
In the original game, your starting point—the country you’re “working for”—was random. I’m a tad uncomfortable even “pretend-working” for some unpleasant regimes out there, so in this update, you work only for countries rated “Free” in the Freedom in the World report.

The Code
This time around, I am developing on a Mac with the VICE emulator.
What language to use? I considered compiled BASIC, but opted for the cc65 C compiler. My C skills are rusty, but not as rusty as my BASIC!
I mentioned that I want a bigger map. Will I run into memory limits? The original map was 192×101, but for the correct aspect ratio it should have been 266×101. That already multiplies to 26,000, and we only have 38K for the program and data combined. Storing 2 color values per byte (Commodore computers have only 16 colors) is a quick way to cut the map’s bulk in half.
I began with the map drawing code, which would be the hardest part because it needs to be fast. Specifically, it must run in less than 1/60 of a second.
Why? The C64 used a cathode-ray tube monitor, where an electron beam races from the top to the bottom of the screen, lighting up pixels as it goes. If you’re modifying the whole screen—for example, to redraw a map—then you really don’t want to be drawing where the electron beam currently is, because that produces nasty flickering effects. Ideally, you want to follow along behind the beam, making your screen updates, ready for when the beam returns to the top of the screen.
The screen is redrawn 60 times per second. On a 1 MHz computer, that means I get about 16,666 clock cycles to retrieve the color data, unpack the 2 colors from each byte, write them to the screen, and handle loop counters.
As a baseline, drawing the map using C with nested loops (rows & columns) and *dst++=*src++ style copying takes around 210,500 cycles.
My final version, written in assembly language, comes in around 14,900 cycles. The speed was achieved with 3 techniques:
- Loop unrolling: I do just 2 loops, one for the top half of the map and one for the bottom half.
- Self-modifying code: Typically, to retrieve data from dynamically-allocated memory, you would use indirect-indexed addressing:
LDA ($addr),Y. Indexed absolute addressing is faster, but to use it you have to know the memory addresses ahead of time and hardcode them. Or, calculate the addresses and insert them into your code on the fly. Self-modifying code sounds dangerous, but cc65 has macros to help make the code readable and the operations safer. - Counting down: I loop right-to-left across the screen. If you make your loop variable X go from 0 to 40, then after each INX (increment X) you have to compare to 40 to know if you’ve hit the end of your loop. But if you go from 40 to 0, then after each DEX (decrement X) you don’t have to compare to 0: DEX has a built-in check of whether it has hit zero. That saves one compare operation for every step of the loop.
You can measure speed using the stopwatch and breakpoints in the VICE monitor, but there’s a more fun way to do it. There’s a trick where you change the screen border color as your code runs, and the width of the color stripes shows you how long your code takes:

Scrolling the map is potentially a faster operation than drawing it from scratch. Scrolling is mostly just shifting data that’s already on the screen, and you only have to retrieve & unpack new data for the edges. Maybe that can be an exercise for 2026 🙂.
The other speed concern is the C64’s legendarily slow disk drive. I want to minimize the map size and the number of disk operations to read it. As in the original game, I compressed the map data, using run-length encoding for its simplicity. I tried a few variations of RLE. The one that worked best on this data: any byte with the high bit set to 0 is a color, any byte with the high bit set to 1 is a count between 3–130. I use only 2 disk reads: read 4 bytes to get the map dimensions, then read the remainder of the file in one go, using the same memory allocated for the map as the read buffer.

With map scrolling and disk I/O done, the rest of the program logic is simple:

And here’s the game: ibh2025.d64. Not much explanation is needed for playing it. You can generally jump along island chains and from islands to the nearest large landmass. Some tiny countries are missing. Some countries are abbreviated to save your poor typing fingers (like USA and DRC). You can type HELP or HINT or simply press Return to get a suggestion on where you can go next.
So how was the experience of coding for the C64 now? It was fantastic being able to write in C, build with Makefiles, debug with the VICE monitor, and browse advice on Lemon64. I was shocked how many details about the C64 sprang readily from my memory like 1989 was just yesterday.


The C64 is a classic for a reason: a powerful but affordable and friendly computer that savvy programmers pushed to do amazing things. I feel privileged to have grown up in the era of those machines and I am delighted that a community of enthusiasts is keeping them alive.
I’ll close by saying I’m still kinda proud of how teenage me captured those cartoon characters as sprites!



















This is the cover of the March 1990 issue of Compute!’s Gazette, a magazine dedicated to the 



