Lets make a Commodore 64 Text Adventure Game!

A simple tutorial by John Christian Lonningdal

Part 2 - Main loop and code structure

While the C64 basic isnt particularly any good for building a good and structured piece of code there are still things you should consider from the start to make it easier to extend later. One of these is to avoid having tight line numbering. There is a reason why the infinitely looped hello world sample code sample often starts with line 10 and the next is line 20. While I will definitely break this at times, I still prefer to divide the whole code into major blocks of 100 lines to keep it somewhat structured. Here is a quick summary:

  0- 99 Intro text and initialization
100-199 Main loop
200-299 Commands (LOOK, INVENTORY, QUIT)
300-399 Room descriptions
400-499 Object descriptions
500-599 Direction descriptions
600-699 Room specific commands (directions and other interaction)
700-799 Game ending descriptions

So depending on what part of the game you are working on you can choose to only list that number range. Note that since the size of this sample game is small the amount of lines set aside for each block is fairly small. For those interested in optimizing code, remember that code using low line numbers takes less space than the large ones simply because they are stored as ascii chars on e.g. GOTO statements. GOTO 10 is two bytes shorter than GOTO 1000. While it does not account for much in our small example, you can do all kinds of interesting optimizations to shave off bytes from your basic code to fit that extra room or puzzle in. :)

Ok, lets add some initialisation and the main loop:

First we have initialisation of some variables:

  • R = room number you are in
  • GL = if you are carrying the gold coin
  • SW = if you are carrying the sword
  • BL = if you are a believer (0=not prayed yet,1=no,2=yes)
  • BO = if you have pushed the boulder out of the way
These are often referred to game state variables and will affect what options are available to you at any particular time in the game and is typically what you need to save if your game provides a save and load option (the best ones offering temporary memory saves). Generally you should try to keep a tidy list of state variables so that it becomes easier to save the game state without having to hunt around in your code at a later stage to find these. This sample code is using a very brute force implementation for states and really only good for small adventures of this type so we will definitely rewrite this during the course of this tutorial to something far more reusable. Imagine how your code is to manage when you have 50 or 100 objects you can pick up and do things with. :) Finally, after this initialisation we call a subroutine at line 200 which is the same as doing a LOOK command so that we get the description of the room we start in.

The next part of the code shows our MAIN loop. It asks you for a command and jumps to a subroutine at 600 which will contain room specific command tests. After this we have a number of global commands that work from all rooms, QUIT, INV and LOOK which will jump to the appropriate code to execute that command. Then we have a number of state tests based on the result of the variable OK. Since basic doesnt offer functions with return values we have to initialise a variable which can then be set in each function in order to execute something based on the result. The OK variable has three meanings:

  • 0 = Command was not recognized
  • 1 = Command was recognized and appropriate output presented
  • 2 = Command was recognized and resulted in a relocation of the player (do a LOOK)
  • 3 = Command was recognized with no output (show an "OK" message)
I am quite sure there are other ways to do this and you could of course do the appropriate jump from within each command. Its just that its easier to treat them as subroutines with a RETURN in case you relocate some of the code and in that case its easier to work with return states. When to use GOSUBs or just GOTOs is a matter of evaluation. If you keep a good overview of all your GOTOs then you shouldnt have any problem.

Finally if the MAIN loop runs to the bottom it will output a message saying it does not understand the command and loop back up again. Again, this is a very simplistic approach to how one goes about parsing commands. I have used simple string compare in this first example which has serious drawbacks which we will discuss later as we improve it. Most notably it requires you to write the commands just as they are tested for and my code even has a mix of shortened commands as well as full length ones (e.g you have to write LOOK fully, while INVENTORY can only be written as INV). It is fairly simple to accept several command lengths and variations by testing on more strings, but we will explore a better way later when we look at command parsing and tokenizing. It will also output the same error message even if the verb is a known one but not in that particular context. This can be fairly annoying and confusing for a player so that will have to be fixed later as well. For our first adventure implementation this simple solution will do.

Part 3 - Some command implementations
Back to index
 
 
All images and text are Copyrighted by John Christian Lønningdal 2007-2015 unless indicated.
Until Microsoft bothers to implement the standards this site will look best on Firefox, Opera or Chrome.