
Today was packed with client work, so instead of delving into the more intricate aspects of my game, I focused on customizing the character set for the C64 version.
Like many vintage computers, the C64 allows you to modify its default character set (akin to a font) to showcase special tile graphics in your game.
You accomplish this by creating a character data array chars[], populated with hexadecimal or binary values that represent the pixel patterns for each character definition loaded into memory.
For crafting custom characters, I often utilize two excellent tools: the PETSCII, Sprite and Character Editor and CBM PRG Studio. While the latter isn’t very mac-friendly, the former can be accessed from any browser, making it more convenient.
I remember spending countless enjoyable hours sketching on graph paper and calculating pixel values manually, but those days are long gone!
cl65 -t c64 -v -o chars.prg charset-c64.c && x64sc chars.prg
#include#include #include #include // Custom character set data - 8x8 pixel patterns for each character unsigned char chars[] = { // ... character patterns ... }; unsigned int key, i; // Initialize the PETSCII character set in screen memory void petscii() { bgcolor(0); // Set background color bordercolor(0); textcolor(5); // Set text color clrscr(); // Clear the screen // Output each character to screen memory for(i = 51200; i < 51200 + 256; i++) { POKE(i,i - 51200); } } void main() { // Load our custom character set into memory at $C000 memcpy(49152, &chars, sizeof(chars)); // Configure C64's memory for the custom character set POKE(56576, PEEK(57576) & 252); // Set RAM bank for character ROM POKE(53272, 32); // Use custom character set POKE(648, 200); // Set the cursor character petscii(); // Display PETSCII characters key = cgetc(); // Wait for a key press }
As illustrated above, most characters are implemented in the game, though a few still require drawing or tweaking.
Keep in mind that these details may shift during testing and playtesting as user feedback comes in!
Initially, I added characters to RAM for C64 compilation but later considered how to map these characters to the updated tiles.
The map utilizes ASCII characters—like 'g' for goblins and 'r' for rats. I wanted to retain the alphanumeric characters while swapping them out for their graphic representations during display.
This led to my initial solution: whenever the game places a character at specific coordinates, it calls cputxy, a function from conio.h. While CC65 uses this library, I opted for an intermediary function to translate characters without replacing the entire library.
For translation, I considered a lookup table for efficiency, but opted for a simple switch statement for ease of writing and readability. I can always revisit creating a lookup table later. A similar approach is needed for Atari since it has its own PETSCII variant.
I can refactor as I move onto other platforms, but this setup suffices for now.
One small mistake I discovered: the question mark symbol is currently used for the door graphic. Whoops!
A bit more tweaking and then I’ll shift my focus to designing additional enemies.
Diverse enemies will enhance the fun and longevity of the game. Right now, I have one that behaves randomly and another that actively attacks the player.
One concept I'm considering is a “Cultist” character who would try to defend the idols we need to collect, positioning itself between the player and the nearest idol. I’m unsure if this logic is too ambitious for 8-bit systems, but I’m giving it some thought.
Original article by retrogamecoders.com


