My Briley witch C64 RPG is based upon a number of “Game Days”, each Day containing quests and tasks. And with 9 Days out of 21 complete, things are still progressing.
But to complete the game, I have to ensure there’s adequate resources left, including cartridge ROM space, code RAM, sprite VRAM etc.
Well, I’ve already taken measures to help me, namely using a scripting system to alleviate the pressure on the precious code RAM, and that’s helping a lot!
File System Concerns
By using a 512k cartridge, there’s plenty of storage remaining, and I’m confident I have enough space left to add everything I’m planning; my current plan is to fill the cartridge, adding any sub-games I feel appropriate.
Every new script added pushes the game progress further along (adding hardly anything to the RAM usage), but every new script also consumes another ROM file slot, and I have just 256 of those for everything.
With Game Day 9 complete, I’d already used 132 files (some for the graphics, engine/game code, most for the scripts), so I was growing a little nervous about file usage. I mean, I was fairly sure there was enough left, but I just wanted to make sure.
Okay, so my sprite system was (and still is) a bit of a mess. I have a 2K chunk of VRAM set aside for (32) combat sprites, and each map was loading its own set of sprites, limiting what creatures could appear on that map. Didn’t think it would be a problem at first, my maps all being a modest size.
For combat, I use 6 sprites per creature, so I could have a maximum of 5 different creatures in each map. These were embedded in each map file to avoid using up a file slot.
Some cutscenes also need sprites, so some of that combat sprite VRAM was being used for them. Cutscenes would use sprite data embedded in the script file, and copy the sprites into VRAM using a sc_copy_sprites script command. This both helped keep the number of files down, and allowed scripts to use whatever additional sprites they needed.
But what I really wanted was a way to load on-demand the creature sprites I needed for combat; this would make organising the data so much simpler and easier (as well as make the system future proof). I did think about packing multiple creatures into multiple files and loading/copying only what was needed. Not an ideal solution, so I needed another.
Extending File Numbers
My ROM file directory consisted of 5 bytes per entry: the ROM bank number, location within the ROM bank, plus the file length. As it turned out, I didn’t need the file length as it’s already encoded within the compressed files, and I don’t use uncompressed files (other than the initial bootstrap code used to load and run the engine code).
So the solution to my file problem was to extend the number of files to 512. This would complicate matters as I’d been using an 8-bit index for loading files.
But There was a simple way around the problem: I could split the file directory into two banks and give each bank a specific purpose. That way I could still use an 8-bit index, but use two different ROM file load routines. I had to extend the ROM file directory, but not by much. I really only need 3 bytes per entry (ROM bank, plus addr L/H), so 2 banks equates to 6 bytes per entry.
To facilitate the changes, I’ve changed my build system so I can tag which bank files belong. BTW, the whole process of building the two ROM file directories is automated. This includes the romf_equ.asm file which has a list of all the defines needed to access ROM files. The first bank is prefixed “ROMF_“, while the 2nd bank is “ROMF2_“.
My current plan is to use the 2nd file bank for all the sprite files, plus any specific items (such as music, sub-games etc.). Instead of embedding sprite data into script files, I’m separating those out into files and loading them via the script by using a couple of new script commands:
- sc_load_sprites – this loads a sprite file from the 2nd file bank into VRAM.
- sc_load_sprites_adr – this loads a sprite file from the 2nd file bank to the specified address.
Another good reason for loading the sprites by script commands is to speed up the script load. There can be a delay on script files as they are decompressed, so reducing the script file size speeds up the load; sprites can instead be loaded once the script is running, the process unnoticeable with a bit of care.
And Back To Combat
With more ROM file numbers to play with, I could reorganise the combat sprites. Each creature now has its own ROM file. So the new process for combat is: trigger combat to start, then roll the screen out to black while loading the combat script. Once the screen is blank, load only the creature sprites that are needed, patching the creature data tables as needed so the combat system knows what creature uses what sprites.
Since I use compressed files and each file holds its destination address, I added functionality to the file decompressor whereby I can override the file’s destination address and load it at an alternate, a function needed by the combat sprite loader, as well as some cutscenes.
And That’s It!
So, moving forward, file numbers won’t be a problem. If I manage to use up all 512 file slots, I’ll be surprised! If this was to arise, I could always add a 3rd ROM file bank, so no worries really. At the moment, the ROM file directory only consumes 1.5K of cartridge space.
The current state of the game is I still have just under 0.5K of engine code RAM left, and just under 5K of game code RAM left, with another 4K RAM block waiting for use if I need it.
Using scripts is pretty awesome, and I keep finding better ways to do things by using them.
Now I have more ROM files to play with, the next step is to add a better sprite management system. I have some ideas, so will be implementing a new system soon…