Home / Commodore 64 / Phase 0 / Lesson 11
Lesson 11 of 64

Text Tricks

What you'll learn:

  • Slice strings with `LEFT$`, `MID$`, `RIGHT$`, and measure them with `LEN`.
  • Convert between numbers and strings using `VAL()` and `STR$()`.
  • Normalize player input (uppercase, trimmed) for reliable parsing.
  • Build a tiny command parser that splits verb/object and drives responses.
17% Complete

Lesson 11 – Text Tricks

Menus, HUDs, and parsers live on strings. With a handful of text functions you can format prompts, trim input, and let players talk to your world. Today we’ll carve strings up, tidy them, and wire a lightweight adventure prompt.

[📷 suggested: screenshot of a text prompt responding to commands like “GET LAMP”]


The One-Minute Tour

  • LEN counts characters.
  • LEFT$, MID$, RIGHT$ slice from the start, middle, or end.
  • CHR$(19) homes the cursor so you can overwrite HUD elements.
  • Simple loops find spaces and split a phrase into verb/object pairs.

Warm-Up: Measuring and Slicing

NEW
10 A$="COMMODORE 64"
20 PRINT LEN(A$)
30 PRINT LEFT$(A$,9)
40 PRINT RIGHT$(A$,2)
50 PRINT MID$(A$,11,2)

Outputs: 13, COMMODORE, 64, 64. Remember: string positions start at 1, not 0. MID$(A$,11,2) plucks two characters starting at the 11th.

Tip: LEN("") returns zero. Handy when you want to ignore blank input.


Cleaning Player Input

The keyboard happily accepts lowercase, extra spaces, and accidental punctuation. Normalize before parsing:

NEW
10 INPUT "WHAT NOW";CM$
20 CM$=CM$+" "
30 FOR I=1 TO LEN(CM$)
40 CH$=MID$(CM$,I,1)
50 IF CH$>="a" AND CH$<="z" THEN CH$=CHR$(ASC(CH$)-32)
60 MID$(CM$,I,1)=CH$
70 NEXT I
80 PRINT "NORMALISED:";CM$

Line 20 appends a space to simplify parsing later; lines 30–70 convert lowercase letters to uppercase. ASC grabs a character code; subtracting 32 transforms lowercase to uppercase in PETSCII.

[📷 suggested: prompt showing “get lamp” → “GET LAMP ”]


Splitting Verb and Object

Once input is tidy, find the first space and slice:

NEW
10 INPUT "COMMAND";CM$
20 CM$=CM$+" "
30 SPACEPOS=LEN(CM$)
40 FOR I=1 TO LEN(CM$)
50 IF MID$(CM$,I,1)=" " THEN SPACEPOS=I:I=LEN(CM$)
60 NEXT I
70 VB$=LEFT$(CM$,SPACEPOS-1)
80 OB$=MID$(CM$,SPACEPOS+1,LEN(CM$)-SPACEPOS)
90 PRINT "VERB:";VB$
100 PRINT "OBJECT:";OB$

Try GO NORTH, TAKE LAMP, LOOK. The verb and object fall neatly into two variables.

[📷 suggested: output showing VERB/OBJECT lines]


Converting Between Numbers and Strings

Sometimes you need to turn a number into a string (for formatting) or parse a string as a number (for input). BASIC V2 provides STR$() and VAL():

NEW
10 SCORE=1250
20 S$=STR$(SCORE)
30 PRINT "STRING:";S$;"<"
40 PADDED$=RIGHT$("0000"+S$,4)
50 PRINT "PADDED:";PADDED$
60 INPUT "ENTER A NUMBER";N$
70 VALUE=VAL(N$)
80 PRINT "YOU ENTERED:";VALUE
90 PRINT "DOUBLED:";VALUE*2

Line 20 converts SCORE to a string. Warning: STR$() adds a leading space for positive numbers (" 1250"), so trim it if needed. Line 40 pads the score to 4 digits by prepending zeros and taking the rightmost characters—perfect for HUDs. Line 70 converts the input string N$ to a number. If N$ isn’t valid (like "ABC"), VAL() returns 0.

Tip: Use VAL(MID$(S$,2)) to skip the leading space from STR$(), or just use RIGHT$(STR$(N),LEN(STR$(N))-1).

Common uses:

  • Score padding: RIGHT$("0000"+STR$(SCORE),4) displays 0042 instead of 42.
  • Parsing numeric input: GUESS=VAL(IN$) for guessing games.
  • Custom number formats: Build strings like "LEVEL "+STR$(LVL)+" COMPLETE".

Mini Parser in Action

Let’s turn those slices into behaviour.

NEW
10 PRINT CHR$(147)
20 PRINT "YOU ARE IN A CAVERNOUS HALL." : PRINT "EXITS: NORTH, EAST" : PRINT "ITEMS: TORCH"
30 PRINT : INPUT "COMMAND";IN$
40 IN$=IN$+" "
50 GOSUB 1000
60 GOSUB 2000
70 GOTO 30

1000 REM --- PARSE ---
1010 VERB$="" : OBJ$=""
1020 FOR I=1 TO LEN(IN$)
1030 CH$=MID$(IN$,I,1)
1040 IF CH$>="a" AND CH$<="z" THEN CH$=CHR$(ASC(CH$)-32)
1050 MID$(IN$,I,1)=CH$
1060 NEXT I
1070 SPACEPOS=LEN(IN$)
1080 FOR I=1 TO LEN(IN$)
1090 IF MID$(IN$,I,1)=" " THEN SPACEPOS=I:I=LEN(IN$)
1100 NEXT I
1110 VERB$=LEFT$(IN$,SPACEPOS-1)
1120 OBJ$=MID$(IN$,SPACEPOS+1,LEN(IN$)-SPACEPOS)
1130 RETURN

2000 REM --- RESPOND ---
2010 IF VERB$="LOOK" THEN PRINT "THE HALL ECHOES." : RETURN
2020 IF VERB$="GO" THEN GOSUB 3000 : RETURN
2030 IF VERB$="TAKE" THEN GOSUB 4000 : RETURN
2040 PRINT "I DON'T FOLLOW." : RETURN

3000 REM --- GO ---
3010 IF OBJ$="NORTH" OR OBJ$="N" THEN PRINT "YOU HEAD NORTH." : RETURN
3020 IF OBJ$="EAST" OR OBJ$="E" THEN PRINT "YOU HEAD EAST." : RETURN
3030 PRINT "YOU BUMP INTO WALLS." : RETURN

4000 REM --- TAKE ---
4010 IF OBJ$="TORCH" THEN PRINT "YOU TAKE THE TORCH." : RETURN
4020 PRINT "THERE IS NO ";OBJ$;" HERE." : RETURN

Type a few commands; the parser obeys simple verbs and objects. We’re still storing state in your head, but the framework is ready for inventories, rooms, and puzzle logic.


Experiment Section

  • Trim leading/trailing spaces: loop from the front and back until the first/last non-space character.
  • Synonyms: before the verb IF VB$="GET" THEN VB$="TAKE", etc.
  • Multi-word objects: look for the second space and preserve the rest.
  • Status HUD: use PRINT CHR$(19) to home the cursor and rewrite a top-line status after each command.
  • Combine with Week 1 sound cues—GOSUB successSound when the player scores.

[🎥 suggested: clip showing synonyms being accepted]


Concept Expansion

Text tricks help far beyond adventures: scoreboard labels, input prompts, even file names rely on clean string handling. Later we’ll log player actions to arrays or DATA tables and push these techniques into Assembly for fast screen formatting.


Game Integration

  • Command buffers: feed parser output directly into room logic.
  • Menus: highlight options by slicing strings and reprinting dynamic text.
  • HUD updates: pad scores with RIGHT$("0000"+STR$(SCORE),4) to keep digits aligned.
  • Dialogue systems: store phrases in DATA and insert player names with LEFT$ / MID$ combos.

From the Vault

  • Your Sinclair — check out magazine tips on BASIC parsers.
  • Paradroid — even action games rely on clean status text and slicing.

Quick Reference

LEN(S$)               : REM length of string
LEFT$(S$,N)           : REM first N characters
RIGHT$(S$,N)          : REM last N characters
MID$(S$,P,L)          : REM L chars starting at position P
CHR$(ASC(CH$)-32)     : REM uppercase conversion for letters
STR$(N)               : REM number to string (with leading space!)
VAL(S$)               : REM string to number (returns 0 if invalid)
  • Always add a trailing space before parsing to simplify loops.
  • Normalise case so comparisons succeed regardless of how the player types.
  • STR$() adds a leading space to positive numbers—trim with MID$(STR$(N),2).
  • VAL() returns 0 for non-numeric strings; validate input before using.
  • Guard against blank input before slicing to avoid LEN errors.

What You’ve Learnt

  • Measured and sliced strings with the core BASIC text functions.
  • Converted between numbers and strings using VAL() and STR$() for formatting and parsing.
  • Normalised and parsed user commands into verb/object pairs.
  • Built a reusable command handler that mirrors classic adventure frameworks.
  • Positioned yourself for menus, HUDs, and story-driven gameplay.

Next lesson: Memory Games — load map layouts and vocab lists from DATA so your worlds stop hardcoding everything.