Lets make a Commodore 64 Text Adventure Game!A simple tutorial by John Christian LonningdalPart 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 |