• Skip to main content
  • Skip to header right navigation
  • Skip to site footer
Retro Game Coders

Retro Game Coders

Retro computer/console game + dev community

  • About
    • Retro Computer Collection
    • Contact
  • Blog
  • Retro Resources
    • Retro Gaming Timeline
    • Online Retro IDE
    • Retro Pixel Art Editor
    • Dungeon Loom Map Editor
    • 6502 Programmer’s Reference
    • Emulators
      • Acorn Electron
      • Amstrad CPC Emulator
      • Online BBC Micro Emulator
      • Commodore PET Emulator
      • Browser C64 Emulator
      • DOSBox/DOS PC emulator
      • Tandy CoCo/Dragon
    • Best Retro YouTube Channels
    • New Retro Books
    • Raspberry Pi Amiga Emulation
    • MiSTer FPGA Tutorial
    • BMC64 C64 Pi
  • Community

Home » Retro Game Coders Blog » Programming

Replacing Parts of Strings in C64 BASIC

C64 Strings

More investigation of C64 BASIC string manipulation and data structures

In an earlier part of my C64 Text Adventure series, I mentioned later versions of Commodore BASIC had a MID$= command that allowed you to replace part of a string with a new value, but C64 BASIC does not have this ability.

A few people wanted more information about this, so here it is.

Join Retro Game Coders Community
Join the Retro Game Coders Community

C64 String Commands Recap

If you recall, the C64 has actually a nice set of string (text) related features. Read about C64 BASIC string commands over on that article but for now the most important for extracting parts of a string are:

  • LEFT$ – Get the characters at the start of the string
  • RIGHT$ – Get the characters at the end of the string
  • MID$ – Get characters from the middle of a string

and also LEN (gets the length of the string)

You can now follow the tutorials and edit the code right in your web browser with the Online Retro IDE

– No downloads, configuration, etc necessary, and it is free!

Replacing Fixed-Length Strings

Part of the confusion is from my example using MID$ rather than RIGHT$ in my string-sandwich:

My original thinking was this made it flexible for working with variable-length strings, but on reflection we still have fixed positions for which character we are replacing (we swap the character at position 4 with the letter ‘X’).

That’s the problem with the C64 not having a REPLACE or even an INSTR function like many other dialects of BASIC. INSTR (or functions like it) will search for a string within another string, and return the character position. This would allow you to look for the character ‘D’ and use that number to figure out where to start and end the replacement.

For situations as in our text adventure where our strings reference room connections (with two digits each for North, East, South, West, Up and Down), we would have duplication in the strings. We couldn’t replace ’00’ with ’04’ as in many cases that would make multiple exits change to point to that room.

Fixed-Length Data Makes Everything Easier?

There's a good reason why fixed-length data fields were used for years in early critical systems
There’s a good reason why fixed-length data fields were used for years in early critical systems

If the string is fixed length with fixed width strings within it, the math becomes easier and the code is quicker to run. There’s a good reason why for a long time fixed width data fields were the norm in critical systems.

Thinking more about this, a more reusable subroutine might be something like the following, you just need to know the total width of your record (12 characters), the field width (2 characters in this case), and where in the record the field starts (4):

Replacing part of a fixed-length string
Replacing part of a fixed-length string
10 DIM R$: FS=4: FE=12-(FS+2)
20 R$="ABCDEFGHIJKL"
30 PRINT CHR$(147)
40 PRINT R$
50 ST$=LEFT$(R$,FS)
60 SE$=RIGHT$(R$,FE)
70 NU$=ST$+"**"+SE$
80 PRINT NU$
90 PRINT LEN(R$),LEN(NU$)

💬 Questions or comments? Head over to the community to discuss!

Alternatives to String Manipulation

Rather than using strings and messing around with characters within those strings, for my exits data I could use a multi-dimension array instead:

PRINT CHR$(147)
REM ROOM COUNT 20 
RC=20: DIM R(RC,6)
R(1,0)=0
R(1,1)=0
R(1,2)=2
R(1,3)=3
R(1,4)=4
R(1,5)=0

CR=1: REM CURRENT ROOM
PRINT "AVAILABLE EXITS:"
IF R(CR,O) > 0 THEN PRINT ". NORTH"
IF R(CR,1) > 0 THEN PRINT ". EAST"
IF R(CR,2) > 0 THEN PRINT ". SOUTH"
IF R(CR,3) > 0 THEN PRINT ". WEST"
IF R(CR,4) > 0 THEN PRINT ". UP"
IF R(CR,5) > 0 THEN PRINT ". DOWN"

Why don’t I? Let’s look at the pros and cons, based on my assumptions:

Pros

  • Much faster for lookups and comparisons.
  • Easier for logic and changes.
  • No string garbage collection or manipulation overhead.
  • Cleaner to display exits or move the player between rooms programmatically.

Cons

  • Slightly more memory per entry (each number is stored as 5 bytes internally).
  • Less compact and more complicated to save/load from file in plain text form.
  • More complex if the room connections end up stored in DATA statements.

Conclusion (Not Concluded)

Maybe I should refactor the code to use a multi-dimensioned array, or at least test it, but right now I have a working game engine plus I am now working on a map editor and exporting the rooms from that tool. If I change now, even if the approach is better, that sets me back and down a rabbit hole I might never escape from!

Category: ProgrammingTag: basic programming, Commodore 64 (C64)
Previous Post:code a chip8 interpreter emulatorCHIP8 and How Emulators Work
Next Post:Introducing Dungeon Loom (Text Adventure/Dungeon Map Editor)Dungeon Loom Text Adventure Map Editor

Retro Game Coders

Retro computer/console game + dev programming community by Chris Garrett

  • Bluesky
  • Threads
  • Facebook
  • Instagram
  • YouTube
  • Mastodon

Maker Hacks ・ D6Combat・chrisg.com

© Copyright 2026 Chris Garrett

Privacy ﹒ Terms of Service

Return to top