Rooms and items in ScottKit

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.

Rooms

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.

Items

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 <mike@miketaylor.org.uk>
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!

Advertisements

11 responses to “Rooms and items in ScottKit

  1. (didn’t read the above yet, will do in a bit..)

    Do you have ‘lint’ functions in the compiler? Might be slick, if not.

    I’m thinking stuff like..
    – ensure rooms all have two ways in/out (ie: dead ends not allowed?)
    – or better yet .. a graph check, that ensures all rooms are reachable (this is distinct to the above in that you could have rooms AB and CD that satisfy exit/enter above, but never reach each other, so that you essentially are wasting rooms.)
    – …. I leave others as an exercise for the student :)

  2. Great articles, Mike!

  3. Interesting idea, to offer linting options. I think the way I’d want to do this is with a command-line option --lint (or -L for short) that takes as its argument a sequence of characters indicating specific conditions to check for. I'll add it to to the TODO list at the bottom of the change-log. (Or: you could file this as an issue in the bug-tracker: it would be nice to get that off the ground!)

  4. Trivial quibble: After you explain about the meaning of a * at the start of a room description, you give two examples, but one of them (the dump) doesn’t have the * at the start and it looks as if it needs one. (Unless there’s some magic involving capital letters?)

  5. Thanks for spotting that mistake, g — now fixed!

  6. Pingback: Actions in ScottKit | The Reinvigorated Programmer

  7. Pingback: Scottkit is born! Only seven and a half years late! | The Reinvigorated Programmer

  8. Pingback: Building adventure games with ScottKit | The Reinvigorated Programmer

  9. Jeff, thanks for filing issue #1 I fixed it in release 1.3.0, which includes the first two forms of linting you mentioned. (See my comment on the issue for why I didn’t do the third.)

  10. Pingback: Occurrences (or daemons) in ScottKit | The Reinvigorated Programmer

  11. Pingback: Boilerplate for ScottKit games: standard actions | The Reinvigorated Programmer

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s