Hi, people! Time for another progress update for my C64 RPG!

Since changing the game over to cartridge, I’ve refactored some of the code to utilise the cartridge to reduce the code size. As this is starting to feel like a massive game (in C64 terms), my main concern was running out of code RAM; I was down to 7K, still quite a bit, but that was starting to dwindle as I added more code…

Oh, I Love My Cutscene System!

Yes, yes, I do!

My old cutscenes had a limit of 2K for resident cutscenes (e.g. potion mixing), 3K for one offs. But the new system can use up to 4K! And with the speed of the cartridge (almost instant bar a bit of decompressing), I can push the memory usage to the max. You see, it also means I can off-load some code into cutscene files, and load on-demand. One example is the Status screen.

The Status screen has functionality for using items (such as health potions), dropping items, equipping characters, plus displaying the stats for all the characters. Altogether it’s just under 2K of code (okay, just over $700 to be precise). Since I can embed code into my cutscene files, I simply created a new cutscene overlay file consisting of nothing but Status Screen code. And with my assembler system, any cutscene file can access any function or variable in the main code, and the main code can access any function in a cutscene file (once it’s “loaded”). I’ve done the same for the combat system, this time freeing up just under 4K of code RAM. As a result, I still have 7K of code space left, despite adding new code.

I’ve also added a chaining functionality to the cutscene system. What this means is in one call to my C64 engine code, I can specify what ROM file to load, plus a start address. So when I have a large cutscene spread across several parts, each part can chain into the next, freeing up more precious RAM from the main game code.

The beauty of all these changes is I can off-load as much game code to cutscenes as possible. The cutscene system is extremely good for one-off pieces of code, and I plan to make full use of the system for all the bespoke sections of the game.

Changes To The Object System

My map editor has the ability to place points on the map, points I call “Interaction Points” (or IPs for short). IPs have data associated with them, namely type, position, and an additional parameter. Some points can be enabled/disabled by the code, and to do this I use a 128 byte table of what I call “Enables”. Each IP can have an enable ID, so that objects/interactions can be switched on/off.

Originally I wanted to keep the system simple, so I had one type to draw a sprite, one to draw characters, one for interactions, one for talking to characters, one for portals, and another for doorways. Upon loading the map, the game code would parse the IP list and store specific IPs into different lists for fast access. So I had lists for Objects, Portals, Doorway, and Characters. Problem was I had to tie Interaction points with Object points by using an Enable, and it was all starting to get messy/scary. Plus, I needed trigger areas, and that would mean adding a whole new sub-system…

Instead, I’ve created a new list of types, and each type has a set of flags associated with it. Currently, I have flags for Draw, Interact, Trigger, plus a few others. So, for example, I can add a Treasure Chest that can be drawn, as well as interacted with. The code has various tables for each type:

Pre-draw – used to decide whether to draw a sprite or not.

Draw Sprite – used to fetch the sprite number to draw; also allows animation.

Interact – only called when the player hits the interact button.

Trigger – only triggered when the player steps into a trigger zone.

For triggers, I store an extra byte per IP, holding the x/y size (packed using a 4:4 format). The largest trigger size can be 15×15, but since the trigger is centred around its origin, the actual maximum size is 31×31 map blocks, way more than I need!

If I wanted, I could add an IP that is both drawn and triggered… I have full flexibility, and it’s all data-driven!

Each IP also has a direction: N, S, E, W or Any. With interactions, I can specify whether to allow just one direction, or allow any direction. The direction parameter can also be used to specify what direction a placed character is looking.

Every IP has a size parameter, even if they don’t need it. I do use the size for the portals, so now I don’t have to funnel the player down a narrow passage to trigger a map change.

Moving Forward…

So, the result of all this re-working is right now I’m not too worried about code space, and have every faith that everything can/will fit. Also, I keep finding little bits of code to put into cutscene files; really doesn’t matter how small, as long as it isn’t speed critical, it’ll go quite nicely into a cutscene file.

Speaking of which, I’ve been adding more cutscenes, or more specifically, the code to control the delivery system. You see, in my books, Briley has to work hard as a delivery girl for the Baxter family to earn her keep. Clarissa Baxter gives her a list of daily bread deliveries to make, and Briley carries them out, meeting all sorts of characters in the village of Maepole (as well as getting into trouble). Oh, I should perhaps mention that the Baxters are a family of bakers, with Leofard Baxter baking the bread, and Clarissa organising the deliveries for all her girls.

Since this controls the story flow of the novels (at least initially), I thought I’d incorporate it into the game, and so far it’s working rather well…