Area536 :: Rebooted

Sep 2, 2023 - 4 minute read - C64 gamedev

Larry 64 game design overview

In the last post I explored why porting the AGI engine would be a fruitless endeavour. So now what? Hand-code the whole thing 6502 Assembler! Yes! Well, sure, but how to go about that? This blog describes some of the design choices I made while weighing my options on the Commodore 64.

Stock C64 or expanded?

At the time of writing it’s the summer of 2023 and most Commodore 64 compatible machines “in the wild” are either not actual Commodore 64 machines at all (meaning that they’re some form of emulation) or heavily modded/expanded original hardware with a lot of extra RAM and other modern bits added to them. So the questions looms: should Larry work on a bog-standard 1982 vintage Commodore 64? And the answer is a resounding yes. Where else would the challenge be if I could move the goal posts at every inconvenient turn?

Game architecture

After converting the first background graphic from the original, I quickly found out that running Larry would take an inordinate amount of memory for the background graphics alone. I’m not entirely sure on how many of the original scenes I’ll end up porting over, there are roughly 30 of them where a bitmap graphic is simply required. The original graphics are simply too intricate (and I’m too crummy an artist) to recreate them in one of the C64’s character modes. So multicolor bitmaps it is, but those take a lot of RAM: 4KB for the bitmap itself, 1KB for screen RAM and 1KB for color RAM. That, times 30-ish, would fill a 1541 floppy to the brim already leaving zero room for game logic, sprites, music or anything else. Making the game a single-load disk game, the lowest realistic common denominator for Commodore 64 hardware, is completely off the table.

So we’re going to do multi-loading in some form, across multiple disk sides at the very least. The game probably fits on a 3.5" disk, but hardly anyone has those lying around and the D81 emulator format isn’t always as well-supported as the ubiquitous D64. So I started out desiging to run from the 1541.

The game would ideally load a core program that’d be as small as possible, which would then take over and load the rest of the game as conservatively as possible and on-demand.

This quickly put me in the swamp of fastloaders, the 21st century emulation scene, and the fact that not all fastloaders of the day play nice with the jungle of emulated 1541-ish devices out there. So fastloading, for all intents and purposes, is indeed off the table.

You want a C64 experience? You deal with crappy load times. It’s part of the vintage retro game vibe. Don’t like it? Run the DOS version of this game from a hard drive. Not the friendliest way to treat my “customers” but heck, this is a hobby project. The loading times weren’t really all that bad anyway. And if your speedloader of choice lives in ROM, overwriting KERNAL in a sane way, the game will use it regardless and it’ll still work. My initial experiments with a Final Cartridge III showed 20 secs. of load time from the bootstrapper to Larry walking up to Lefty’s front door.

Minigames with shared state

The way this design is going, is towards a series of 30-ish mini games with only a minium of shared state between them as the player progresses. This shared state would consist of important flags like the score tally, the amount of cash in your wallet, your inventory items, and miscellaneous in-game flags that would keep track of your progress. Things like having non-player characters remember having talked to you before etc. All very light-weight, to be stored in as few bytes as possible. Together with the on-screen position of the player sprite, those flags would form the main meat of what constitutes a savegame eventually.

Creating minigames should be relatively straightforward, but there’d also be a lot of shared code and graphical assets. This nudges me towards first coding a shared “core” before bolting any number of “scenes” on top of that later on.

So the target is set: I’m creating a lean and mean core engine in 100% 6502 Assembler that will support an as yet uncertain amount of shared state and the addition of “scenes” later on. The first item on the agenda: the iconic street outside Lefty’s front door.