The C64 port I waited for at thirteen, finally being written, by me
Area six, sometimes seven. One credit. My best friend at my shoulder. That is as far as we ever got.
SEGA put Wonder Boy into the arcades in 1986, and by 1987 it had found its way into our local pizzeria. I was thirteen, and that cabinet quickly became the centre of my universe.
My best friend and I spent hours in there, feeding way, way too many coins into that machine. The pizza was optional. Wonder Boy was not ;) We learned where every bee came from, which egg hid the skateboard and which one hid the eggplant that drains your vitality. We could have drawn the maps from memory.
And we got good. Properly good. In the end we could almost play through the whole game on one credit. Almost. The arcade has eight areas of four rounds each, and those last few areas beat us every single time. It still bugs me a little.
We loved it so much that we waited, patiently, for the version for our home computer, our beloved C64. We counted the days.
When it finally arrived, it felt nothing like the real thing. The look was wrong, the feel was wrong, and the magic from the pizzeria simply was not in it. A huge, huge disappointment for two boys who had already spent their pocket money twice over on the original.
To be fair, the teams doing these conversions often had only weeks to get a game out of the door, and the tooling back then was limited. So they pulled out their old routines and did what they could to make it work, and quality paid the price for the deadline. I know that now. It did not make it hurt any less at thirteen.
Area 1, Round 1. Here we go again
Fast forward nearly forty years. I am back writing cool stuff on the C64, and that old disappointment was still sitting there, waiting. So I decided to make the port it deserved: one that plays as close to the arcade as is humanly possible on a machine as restricted as the C64.
Not an easy feat. The arcade has a Z80 and video hardware built for exactly this kind of game. The C64 has a 1 MHz 6510, a VIC-II chip, eight sprites and a lot of attitude.
Round 1-1 on the skateboard, the bit we all lived for
The game logic and the level maps come from the arcade itself. I ripped and disassembled the arcade's Z80 code and spent a lot of evenings in MAME's debugger, stepping through it and analysing how everything really behaves. From that I built a reference for how the game should play, and I keep holding the C64 version up against it to spot where the two drift apart.
The graphics come from the SEGA Master System version, because its tiles and sprites are much closer to what a C64 multicolour screen can actually show. So it is a mash-up, with one ground rule set on day one: where the two disagree, the arcade wins.
And they disagree a lot. I keep a drift log of every difference, and it is past 120 entries, each one marked arcade, SMS or C64 compromise.
Some are big. The SMS boy walks 35% faster than the arcade boy, and on the SMS running is barely faster than walking. The port uses the arcade's numbers: walk 1.5 pixels per frame, run 2.25, skateboard 2.5. Jump height, gravity, vitality, fruit values and what pops out of the eggs are all arcade values too.
Some are small and sneaky. On round 1-1 the arcade has 82 objects and the SMS a thinned-out 70: fewer fruit, no bees, no frog. Arcade snails stop at a pit edge, SMS snails never do. The SMS even painted two static platforms over the wide pit where the arcade has four floating leaves. Out went the platforms, back came the leaves.
The payoff: the boy runs, jumps, skates and lands the way he does in the arcade, and I can play the same moves on both machines and compare them side by side. One honest difference: a PAL C64 runs at 50 Hz against the arcade's 60, so everything takes a fifth longer. Your vitality lasts about 64 seconds instead of 53. Call it the relaxed edition.
A word on the pictures on this page: the graphics you see are early drafts. Many of the level tiles still need work to sit properly on a C64, and the bosses are not polished up yet either. All of that gets a proper polish before release, so expect it to look a lot better than this.
A port like this lives or dies on its tools, so I built my own. Five of them: a gameplay map editor that lines up the arcade, SMS and C64 maps on one axis, a level graphics editor, a boss editor, a pose editor for the boy, and an object editor for every enemy, item and platform. Each one shows the arcade right next to the C64, so I can see straight away where we drift.
The level editor: round 1-1 on the cell grid, with the palette and the round's object list
The level graphics editor paints a map's tiles, and the objects baked into it, exactly as the C64 will display them. It also enforces the rule every C64 graphician knows by heart: a background colour plus three colours per cell, and not one more.
From area 4 on, the SMS orders its levels differently, so each arcade map was matched to the right SMS artwork by comparing ground profiles and pits. Where the terrain still did not line up, whole columns of SMS graphics were shifted up or down onto the arcade's ground heights.
The pose editor: pose 20, skating right, next to the arcade frame
Two sprites, five colours and a mid-body colour change: if he looks wrong, the whole game looks wrong.
The pose editor puts each of his 32 poses next to the original arcade frame as an onion-skin reference, so walking, throwing, skating and getting burnt all keep the arcade's character.
The boss editor: the body, the arcade reference and the live 1-4 arena
All the boss art lives here: the body, a different head for each area, the fireballs, the rewards and Tina. Everything is edited live in the real arena, with a colour-clash check, so I know straight away when something won't survive on a C64.
The boss himself is still work in progress: I still need to weave the blue from the bitmap into his clothes, and he will get a proper polish after that. Tina is in too, waiting at the very end, although her new look is still to come.
So where does a port like this come from? Mostly from the demo scene. Since coming back to the C64 in 2020 I have put out 70-odd releases with Atlantis and Pretzel Logic, and a few of them did all right: Mojo came second in the C64 demo compo at X'2023, and a handful of others won their compos. The C64 Scene page has the full list, so I will let that do the talking.
The real point is what the scene teaches you. Demo coders have spent four decades asking the C64 for things it was never built to do: counting every CPU cycle, timing a register write to the exact spot on the exact raster line, cheating the video chip into behaving differently. Almost every trick on this page has a demo-scene ancestor. The catch, as I learned on Kong-Fu Masters, is that a demo only has to work once, the way you scripted it. A game has to work every single frame, whatever the player throws at it.
Here is what that looks like in practice. No code, I promise. Just the problems, why they hurt, and how I got round them.
Round 4-2: snails, pots, fruit, a bee, a hatchet. Count the moving bits
A sprite is a little picture the C64's video chip can lay over the background and move around for free. The catch: there are eight of them, each 24 x 21 pixels. That is it. Eight.
The boy takes two of them. The other six are shared by the score bar at the top, and then by every enemy, every hatchet and every moving platform in the game. On round 1-1, if everything were a sprite, up to eight would need the same line of the screen at once, and 199 frames would go over the limit.
The way out is one simple rule: if it never moves, it gets painted into the background picture instead. Rocks, bonfires, signs, fruit and still platforms are all drawn straight into the bitmap. I call those software sprites, as opposed to the hardware ones. A painted object costs no sprite, no CPU time per frame, and it can never flicker. Think of a theatre: the furniture is painted on the stage set, and only the actors get spotlights.
That rule alone is huge. Round 1-1 peaks at five sprites on a line and never goes over six. Every piece of fruit in the bitmap saves about 1,000 CPU cycles a frame, and lining the fruit up on the 8 x 8 grid cut their graphics from 104 tiles down to 71.
The busier rounds get a twist I call “bitmap until it moves”. A bee, snail, frog or spider waiting for you is painted into the background. On the very first frame it moves, it is wiped from the picture and becomes a real sprite for good. If I have done my job, you never notice the switch.
Round 2-2: six bats, two bananas and a hatchet. The multiplexer earns its keep
Painting the furniture is not enough. Some rounds have bats and bees by the dozen, and they all move. So the six enemy sprites have to be used more than once per screen. That is called multiplexing.
The video chip draws the screen top to bottom, line by line. Once a sprite has been drawn, nothing stops you grabbing that same sprite and moving it further down the screen, before the beam gets there, to show something else. One sprite, several objects.
The hard part is the timing. The switch has to happen after the old object is done and before the new one starts, and the screen does not wait for you. In this engine a sprite can be reused once the next object starts 24 or more lines lower, and the switch happens 22 lines into the old one. That gives at most six objects in any 24-line band, and twelve on screen in total.
To hit those moments I use one of the C64's timer chips as a line clock, ticking every 63 cycles, which is exactly one raster line. It interrupts the CPU at the right moment, about three times a frame, costing around 220 cycles each. A wide moving platform, 61 pixels across, is simply three sprites side by side.
And when a band is simply too full? Then, and only then, something has to give. The fair way is to take turns: the object that was shown last frame sits this one out, so a crowded object flickers for a moment instead of vanishing.
It is a trick I keep for very special occasions, and the numbers say exactly how special. I simulated runs through all 32 rounds: flicker kicks in on about 1 frame in 150, 13 of the 32 rounds never need it at all, and no object is ever away for more than a single frame, one fiftieth of a second. I have honestly never spotted it while playing.
There was exactly one spot in the whole game that broke the rule: three shuttle platforms and a bobbing one on top of each other in round 7-1, where a platform part could go missing for four frames. One banana was quietly retired from that spot, and now nothing is ever lost anywhere in the game.
Some of the SEGA Master System art is just a little too big for a 24 x 21 sprite. The cobra is 23 lines tall, the boulder 24, and the swordfish is 32 pixels long. Those get a few rows or columns dropped evenly, so they still look like themselves and still fit in one sprite.
Round 4-3, the ice castle: five colours of boy, in front of everything
On the C64 the order of sprites is fixed in hardware: the lower number always wins. The boy is sprites 0 and 1, so he is always in front of every enemy. Free, and exactly right.
He is also two sprites stacked on top of each other. Sprite 0 is hires, sharp but one colour, and carries his light red skin and the outline detail. Behind it, sprite 1 is multicolour: black, white and one colour of its own.
Black, white, light red and one more is four colours. The arcade boy has blond hair and a green grass skirt. So halfway down his body, while the screen is being drawn, I change sprite 1's own colour: yellow for the hair above, light green for the skirt below. One figure, five colours.
That colour change has to land 18 lines below his top edge and be done within three lines, wherever he is, every frame, while everything else is going on. Measured over 982 frames, it was never more than two lines late. That is the kind of thing nobody will ever notice when it works, and everybody notices when it does not.
The bosses have a priority trick of their own. Each new head grows out of the boss's body, using the sprite bit that puts a sprite behind the background. That only works if the body's light blue and white sit in the colour slots that cover such a sprite, and the wall's black and blue sit in the slots that don't. So I re-ordered 31 wall tiles once, same picture, different slot order, and my build now refuses any arena tile that breaks the rule.
Round 1-2: off the island and down toward the sea, with an octopus for company
Wonder Boy is one long run to the right, and it scrolls on a full multicolour bitmap. That is 8,000 bytes of picture plus 2,000 bytes of colour. Moving all of that with the CPU costs about 77,000 cycles: nearly four whole frames, for every single frame.
That is why almost every C64 game of the era scrolled a character screen, a grid of reusable tiles, instead. A bitmap scroller at full speed simply was not on the table.
Unless you cheat. There is a famous demo-scene trick called VSP: write one value into the video chip on one particular raster line, timed to the exact CPU cycle, and the chip starts drawing the screen up to 40 characters “late”. The whole picture shifts sideways and the CPU moves nothing. Instead of repainting the scenery, you slide the window frame.
On top of that there are two screens. You watch one sliding while the other, hidden, is rebuilt in small slices, and they swap every 12 columns (96 pixels) on flat ground, every 8 on slopes. The colour memory exists only once, so it cannot be swapped. On those frames all 1,000 bytes are copied in one go, about 9,200 cycles, starting on line 248 and racing the beam back to the top of the screen.
It scrolls up and down too. The arcade ties the camera's height to how far along the level you are, a 1-in-4 slope rule, so I do the same: the screen switches frame by frame between a flat mode and a climbing mode. While climbing, the view gives up one row (184 lines instead of 192), and a second trick, the line crunch, makes the video chip skip up to two whole rows of characters in a single raster line, so the picture can jump vertically without the CPU moving a byte. The view is 304 x 192 pixels, wider than the arcade's 224, so you see a bit more of what is coming.
And it is pixel-exact: 568 out of 568 test frames at speeds from a quarter of a pixel to four pixels a frame, and 908 out of 908 in the gameplay demo.
Round 3-2: bees, a boulder, a hatchet and a slope, all in one fiftieth of a second
A PAL C64 gives you 19,656 CPU cycles per frame, fifty frames a second. A few thousand of those are gone before you start, eaten by the interrupts and by the video chip stealing the bus to fetch the picture.
The rest is a shopping list. On a busy frame: copying the hidden screen, 1,400 to 1,800 cycles. Working out where every object sits on screen, about 1,600. Their behaviour, 1,500. Music, about 1,000. Drawing the new column of scenery, 1,100.
So there is one rule above all others: the scroll and the boy always run at the full 50 frames a second, and the objects get what is left. Enemies far away from the boy can coast for a frame, still moving but skipping their thinking. Anything within 256 units of him always runs in full, because that is where you are looking.
Then it is the old demo-coder grind, shaving cycles wherever they hide. The screen copy runs at 9 cycles a byte, as fast as a copy loop can go on a 6510. The score bar used to be redrawn in one go for 10,000 to 15,000 cycles. Now it updates one changed item per frame for about 400.
Bit by bit it adds up. The game went from showing 108.3 frames per 100 game frames down to 102.0, practically a solid 50 Hz. Fruit in the bitmap alone took it from 105.7 to 103.8. The boss rooms went from as bad as 195 down to about 100.
None of this would fit on a floppy, and back in 1987 a lot of conversions had to drop levels and simplify enemies just to squeeze into memory. This one lives on a 1 MB EasyFlash cartridge: 64 banks of 16 KB, with the level maps, the graphics, the game logic, the boy's 32 poses, the enemy sprites, the bosses, the screens and the music each in banks of their own. A lot of the code runs straight from the cartridge.
I dropped save games, which freed up 16 half-banks and leaves 62 whole banks for the game. What that buys: all 32 rounds, every arcade tune, the attract and end screens, and not one second of loading. Plug in, switch on, play. Just like the pizzeria.
Hatchet versus the first boss in round 1-4. The boss graphics are still an early draft
Round four of every area ends in the same castle arena, with a boss that is 48 x 46 pixels in a lot of colours. Way too big for C64 sprites.
So once the arena scrolls in, the screen locks and the boss body is drawn into the bitmap as a software sprite, 42 lines tall and 7 characters wide. Two double-width overlay sprites add the pink and purple the background cells can't hold, and the heads, fireballs and the boy stay hardware sprites.
Each boss pose is stored pre-shifted to two positions, so a four-pixel step is a straight redraw with no shifting at all. The drawing is done by speed code, the demo coder's best friend: thousands of instructions written out one after another by a tool, with no loops and no decisions, at about 11 cycles a byte, roughly 4,500 cycles a step. The body goes into the hidden screen and then the two screens flip, so you never see it half drawn.
My favourite detail: the arcade decides what the boss does next using the Z80's R register, an internal counter that ticks along by itself and makes a lovely cheap dice. The 6510 has nothing like it. So the C64 fakes it with a counter that adds 37 every boss frame.
And no recorded playthrough I had ever reached a boss, so every boss fight was rebuilt purely from reading the arcade's code.
Every engine has its war stories. A few favourites:
The jittering boy. On screen he wobbled between X positions 115 and 118. In about one frame in six, his sprite position was handed over just after the interrupt that reads it, so it got paired with the wrong camera. Now both are handed over together, and he sits at 115 in every frame.
The memory-eating scroller. On some C64s the VSP trick corrupts one byte in every eight of a page of memory, depending on how the machine powered up. In the emulator, with the bug switched on and an unlucky power-up, an early build simply crashed. The fix was pure scene logic: park the timing code in a page padded with NOP instructions, the 6510's “do nothing”, so the corruption writes a NOP over a NOP. Real hardware still gets the final word on that one.
The black frame. The multiplexer once ran before the next raster interrupt was set up. The interrupt never came, and the whole frame went black.
Frozen after victory. Beat a boss and the game hung. Code in one cartridge bank was calling the sound routine in another bank that was not switched in. My build now refuses any call across banks.
The lying speedometer. My boss-room test said the fight dropped 9% of its frames. Not great, not terrible. Then I spotted that the debug counter was only 8 bits: it counts to 255 and quietly starts again at zero. Counted properly, the last castle fight was running at about half speed. Ouch. That one sent me straight back to shaving cycles, and it is the reason the boss rooms went from 195 to about 100.
Game development is trade-offs, and the C64 has opinions. The SMS cave walls are orange, and the nearest C64 colour was yellow, the brightest it has. Walls everywhere turned yellow, so now they are a darker brown and orange. The blue caveman was exactly the same blue as the sky behind him, so all you saw was his outline. He is yellow now, everywhere.
The score bar picks its colours for every 64 pixels of scenery, so it stays readable over sky, grass and cave, and it only changes where it has to. Lifts wrap at the edges of the C64's smaller view: one that rides off the top comes back in at the bottom, so the boy can never ride one out of sight. The SMS has 36 or more maps, but the arcade builds all 32 rounds from just 11, reusing them with new enemy and object lists. Sticking to the arcade's 11 is what lets everything fit on the cart. And with one fire button, fire runs and throws, up jumps, and the coin texts became PUSH START.
Put it all together and you get something no C64 could show you in 1987: a full-colour bitmap world scrolling smoothly in both directions, the arcade's own rules and object lists, every round, every tune, bosses rebuilt from the original code, and no loading. And I have something the 1987 teams never had: a megabyte cartridge, the arcade's code laid bare, an emulator with a debugger to see what the arcade really does, and nearly forty years of tricks the scene invented in the meantime. It would be a shame not to use them.
Kong-Fu Masters, my other game, is pretty much done, done. Wonder Boy is not there yet, but it is fully playable, and that is when the fun part starts.
What is there: all 32 rounds on all 11 maps are on the cartridge and playable, running on a C64 engine built from scratch for this game. Every arcade enemy and object type has C64 code, and the boss fights run in every area's castle, Tina included. The title, attract, high-score, name entry, bonus tally and continue screens are built from the arcade's own code and data. All of the arcade's music is converted to the SID and wired in.
What is next: graphics and music still have a lot of improvement to come. The bosses and many of the level tiles need their proper polish, the sign lettering got lost in conversion, Tina's new look is on its way, and the first-pass music conversions will make way for proper ones, plus a round-clear jingle.
The code will get a few more turns too. It already runs at practically a solid 50 frames a second, but I am sure there are a couple more cycles to squeeze out to make it run even better. Then a lean release build, and testing on real hardware.
Back in that pizzeria we never saw the end of the game. This time I fully intend to, even if I have to write it myself. To be continued.