Last time, we learned how to write, build and play games with ScottKit. But the game we made was absolutely trivial: two rooms, connected. The only thing you could do in the game was to move back and forth between the two rooms — and even that only worked because GO (and the six directions acting as verbs) are built-in commands. This time, we’ll expand the game: here’s a map of the expanded version.
Compared with last time, we’ve added one more room (the cell) and our first two items. One of the items is a treasure, as indicated by its name starting with an asterisk.
In Scott Adams games, there are only two kinds of object: rooms and items. And those two concepts are quite separate — unlike in more sophisticated games such as those in Infocom’s Z-Code, where the same underlying data-structure is used for rooms, items, vehicles, abstract concepts like directions, and even the player.
Each room has a name (which is used only within the ScottKit file, to refer to it), a string that functions as its description, and zero or more exits that lead to other rooms. Those are the only intrinsic properties of a room: if you want any others, such as darkness/light, or a help-text to be emitted when in a particular room, then you will need to code it up yourself — we’ll see how to do that next time.
We saw in the previous post how to define a room: a new room is introduced by the keyword room followed by the room-name and then the description string. For example:
room chamber "square chamber"
The name (in this case “chamber”) will be used in various contexts that we’ll discuss later to refer to the room from other parts of the ScottKit program. When the description is rendered, for historical reasons it is always prefixed with the string “I’m in a” — omitting this nearly unvarying prefix saved a few bytes on the microcomputers that ran the early games in this format. If you want to override this default behaviour, you do it by beginning the description string with an asterisk: this is skipped, and the rest is emitted verbatim. So for example:
room ante "*I'm in an antechamber" # We need "an", not "a" room dump "*This is a rubbish dump" # No "I" involved at all
Following a room declaration like this, you can provide one or more exits. Each of them is of the form exit direction roomName. For example:
exit west chamber exit south cell
Needless to say, this pair of exits indicates that going west from the last declared room takes you to the room called “chamber”, and going south takes you to “cell”. The room names may have been declared earlier in the file, or they may be declared subsequently: forward references are fine, but all rooms named in exits must be defined somewhere in the file.
It’s fine for multiple exits of a single room to lead to the same destination, or for an exit to lead back to the same room it exited from. (Both these tricks used to be staples of the mazes that adventure-game designers felt obliged to include in their games.)
By the way, newlines (outside of strings) are not significant in ScottKit. I find it convenient to put each exit on its own line separate from the room, but you don’t need to do that. The following three-line program, for example, defines the whole geography of the map above (rooms only, no items):
room chamber "square chamber" exit east dungeon room dungeon "gloomy dungeon" exit west chamber exit south cell room cell "dungeon cell" exit north dungeon
That’s all there is to say about rooms. They are simple things. Items have a little bit more going on.
Like a room, an item has a name that is used only during compilation to refer to it, and a textual description. It can have other properties as well. A new item is introduced by the keyword item followed by the item-name and then the description string. For example:
item coin "*Gold coin*"
Some items (such as the coin or a lamp) can be picked up and carried around; others (such as a tree or a castle) cannot. Rather than laboriously code actions for picking up and dropping the portable items, you can simply nominate the name by which the user refers to the object when GETting or DROPping it, using the keyword called followed by a string:
item coin "*Gold coin*" called "coin"
The user will then be able to GET COIN and DROP COIN, and so to move it around the map. An item with no called clause cannot be picked up or dropped (unless you code special actions to achieve this).
A key part of the state of the game is the record of the rooms that each item is in. By default, an item begins the game in the room that was defined before it, so that simply listing a room and then three items will cause the game to begin with those three items all in that room. (Items listed before the first room begin the game nowhere).
But you can override that default. If an item definition is followed by at roomName, then it will begin the game in the nominated room; and if instead it is followed by nowhere, then it begins the game nowhere, and will only come into play if actions bring it into one of the accessible rooms or the player’s inventory.
(You can define any game without using at or nowhere at all, if you like: just start by listing the objects that begin the game nowhere, then after each room, list the items that begin the game in that room. But sometimes it’s nice to have the flexibility not to do that: we’ll see an example next time.)
Putting it together
Here, then, is the complete source code for the map above:
room chamber "square chamber" exit east dungeon item sign "Sign says: leave treasure here, then say SCORE" room dungeon "gloomy dungeon" exit west chamber exit south cell room cell "dungeon cell" exit north dungeon item coin "*Gold coin*" called "coin"
And here’s how it looks when you compile and play that game:
ringo:tutorial mike$ scottkit -c t2.sck > t2.sao ringo:tutorial mike$ scottkit t2.sao ScottKit, a Scott Adams game toolkit in Ruby. Release 1.0, (C) 2010 Mike Taylor <firstname.lastname@example.org> Distributed under the GNU software license I'm in a square chamber Obvious exits: East. I can also see: Sign says: leave treasure here, then say SCORE Tell me what to do ? e I'm in a gloomy dungeon Obvious exits: South, West. Tell me what to do ? s I'm in a dungeon cell Obvious exits: North. I can also see: *Gold coin* Tell me what to do ? get coin O.K. Tell me what to do ? n I'm in a gloomy dungeon Obvious exits: South, West. Tell me what to do ? w I'm in a square chamber Obvious exits: East. I can also see: Sign says: leave treasure here, then say SCORE Tell me what to do ? drop coin O.K.
Next time: actions, treasures, and winning a game!