1. Tutorial B - Excalibur

Note
Tutorial B will take approximately 3 hours of minutes of time (feel free to skip the 'keyboard' sections if you are familiar with keyboard shortcuts).

1.1. About Excalibur

In this tutorial, we will learn how to code a text adventure with graphics.

The adventure game we will use as the focus of the coding portion of the lessons is "Excalibur: Sword of Kings".

Excalibur: Sword of Kings, was written in 1987, by Ian Smith & Shaun McClure.

excalzx lady
Figure 1. Excalibur (1987)

Excalibur, Sword of Kings is copyright of Adventuron Software Limited, all rights reserved.

1.2. Tutorial Structure

birwood 1

The plan for this course is as follows:

  1. Learn How To Play A Text Adventure Game. (approximately 30 minutes).

  2. How To Use The Keyboard. (approximately 30-45 minutes, skippable).

  3. How To Code A Game. (approximately 3 - 4 hours, progress is saved).

  4. Make Your Own Game. (after the course is finished).

2. Design

2.1. The Game Design

demon knight

There are five things to think about when creating a simple text adventure game.

2.1.1. 1 - Story

Most adventure games revolve around a goal, and some reason for trying to achieve the goal.

The story may be very complicated, almost like a book, or it could be very simple, such as in Excalibur.

2.1.2. 2 - Locations

Locations are places that the player can be inside the game.

Each location has its own sentences to describe itself, and in Excalibur, every location has a picture (graphic).

2.1.3. 3 - Map

The map of a game that describes how the locations are connected together.

2.1.4. 4 - Objects

A game usually has a series of things in it (or objects). A thing can be an object like an apple, or a thing might even be a person. Adventuron calls all these things "objects".

The player can take objects, drop object, and use objects. The game remembers what the player has, and where every object is, even if the player doesn’t have it yet.

2.1.5. 5 - Puzzles

The puzzles of a game describe things that must be solved to make progress in a game.

Usually a part of the game is blocked until a puzzle is solved, then after the player is allowed in the new part of the game, new puzzles are revealed.

2.2. Story

castle smaller

The story of Excalibur: Sword of Kings, is that Arthur has been taken prisoner by the evil sorceress Crania and it’s up to you, a knight of the round table, to find Excalibur, defeat the sorceress, and rescue King Arthur.

2.3. Locations

winch room

There are 4 different areas in Excalibur.

  1. The Road Area.

  2. The Forest of Birwood.

  3. Camelot Castle.

  4. The Salt Mines.

Each area has several locations.

Locations can be indoors (like a room), or outdoors, like in a forest.

Excalibur also shows the player a simple picture (like the one at the top of this section) when describing the location to the player.

We will learn how to add graphics in this course, but not how to draw them.

You can double click in the documentation panel to make the documentation full screen, you can double click again to minimise back to just showing in the left hand column.

Here is a list of all the locations (and the graphics we will add to the game later):

(Locations with two images are places where the contents of the location can change due to solving a puzzle)

Location Graphic Description

hut

hut

You are in a ramshackled hut. Golden sunlight filters through an open doorway to the north.

road 1

road 1

You are standing on a grass bordered track. A hut lies to the south.

road 2

road 2

You are where the road twists eastwards. Small hills around the road are crowned with vibrant red Hawthornes.

road 3

road 3

You are on a rutted gritty track that is flanked by lush pasture. A small clump of trees can be seen on a hill in the distance.

road 4

road 4

You are on a dusty path skirting the edge of Birwood. The faint whisper of foliage can be heard from afar.

lamp seller on road

lamp seller on road after buy lamp

You are where the path branches to the east and continues south towards a chasm.

chasm

chasm

You are stood on the edge of a huge chasm. A tightrope spans the gap, but it looks dangerous.

edge of birwood

birwood

You are on the edge of Birwood. A rope spans a chasm northwards.

deep inside birwood

birwood

You are deep inside Birwood. The trees are alive with the buzzing of tiny insects.

birwood bush

birwood bush

You are stood on the mossy floor below the canopy of leaves which lets a wan light filter through.

demon knight road

demon knight road demon knight cleared road

You are in a dip in the road by dark Birwood. Ravens stark cries can be heard from above.

foot of tree

foot of tree foot of tree with ladder

You are at the foot of a large stone tree that is bare of any branches. The road ends here.

top of tree

top of tree

You are in a stone room set in a large petrified tree. Thick dust carpets the floor.

castle approach_1

castle approach 1

You are now a fair distance from Birwood. The denizens of the countryside make the only sound here. You can see castle Camelot on the eastern horizon.

castle approach 2

castle approach 2 castle door open

You are outside a now foreboding looking Camelot. Its once proud standards now whipped and torn by the winds. A great stone door is the only way in.

castle porch

castle porch

You are in the porch of Camelot. Long dark shadows are cast here, playing tricks with your eyes.

banquet hall

banquet hall

You are in an abandoned banquet hall. Furniture lays broken on the floor.

drafty room

drafty trapdoor close smashed trapdoor

You are in a drafty room. Wind blows through gaps in the mortar creating howling noises.

ornate antechamber

ornate antechamber

You are in an ornate antechamber that is mantled in thin ice, that even covers the paintings.

portcullis

portcullis downportcullis up

You are in a small dingy room which has an iron portcullis set into the northern wall.

salt mine 1

salt mine

You are in an old salt mine. Stygian tunnels lead off to the west and south.

salt mine 2

salt mine

You are in the west part of the mine/ It looks like it’s been over worked and abandoned.

salt mine 3

salt mine

You are at the end of the mine. You can hear the drip of water.

worm room

worm roomsalt mine

You are in the south part of the mine. There been recent movement in the rocks near your feet.

cold room

cold room cold room clear

You are in a bitterly cold room. Everything is coated in a thick layer of ice. Dense icicles show a weird tapestry of frost on the ceiling.

winch room

winch room

You are in the winch room. A huge turning mechanism stands in the corner.

armoury

armoury

You are in the armoury. Cobwebs hang like drapes. Empty weapon racks line the walls.

most splendid room

most splendid room most splendid room clear

You are in the most splendid room in the castle. Rugs and paintings adorn the floor and walls.

arthur

arthur

You are in a sparse and lonely room. A chill wind enters through the high window.

game over screen

game over

NOTE :: This is not a room, just a graphic.

ending screen

ending screen

NOTE :: This is not a room, just a graphic.

2.4. Map

portcullis

A map is a drawing that shows locations in the game, and how they are connected together.

There are four main directions (called compass directions):

compass 1

A map can be drawn as one big drawing, or may be split up into different pieces.

The map of Excalibur is in two parts:

2.5. Part 1 (Outside The Castle)

map 1

2.6. Part 2 (Inside The Castle)

map 2

2.7. Reading The Maps

A map is a visual way of seeing connections, but we can also turn these connections into words.

Here is how to read the map, using the compass directions as our guide:

  • We can say that road 1 is NORTH of the hut.

  • We can say the the hut is SOUTH of road 1.

  • We can say that demon knight is EAST of lamp seller.

  • We can say that lamp seller is WEST of the demon knight.

2.8. Up and Down

Up and down on maps tend to be treated the same way as north or south, but up and down always needs to be labelled.

2.9. Puzzles

castle approach 2

2.9.1. Puzzles

Excalibur is a short game with just 13 puzzles, most easy to solve. The fun of the adventure is exploring, seeing new graphics, and working out how to solve puzzles.

Not all the answers are obvious. Each object will give a clue if the player types "examine xxxxx" where xxxxx is the name of something.

This adventure is simple for the purpose of the tutorial, and usually (puzzle type) text adventure games have many more puzzles than this one.

It is strongly recommended that you play the game before you read onwards, as spoilers for all the puzzles will follow. The link below has a built in tutorial to help you understand how to play the game.

Click Here to play Excalibur (will open in new window).

Puzzle Description

Climbing The Tree

The player will encounter a tree that has no branches and cannot be climbed.

The player needs to collect the ladder from the start location, and type lean ladder or stand ladder at the base of the tree, and then the player can navigate "up" to reach the stone room inside the top of the tree.

At the top of the tree, is the short sword.

Crossing The Chasm

The player encounters a gorge. The gorge has a tightrope, but it looks dangerous. If the player types "cross gorge" then they will fall and the game will end.


To solve the puzzle the player must break ladder to make a pole, and then once the player is holding the pole, type cross chasm, and the game will inform the player that they use the pole to balance, and they can make their way across the gorge and into the forest.

If the player breaks the ladder before climbing the tree, then the game is not winnable.

Treasure In The Forest

In the forest, the player must examine (or search) two items in the forest. e xamine logs will find an axe, and examine bush will find the stone key.

Crossing The Chasm Again

Making sure they are still holding the pole (from the broken ladder), the player must type cross chasm again to return to the road network.

Getting Past the Demon Knight

The player must type attack knight (or similar), when holding the short sword in order to defeat the knight in battle.


The knight was blocking the road to camelot, so if the player didn’t solve the tree puzzle, and the knight puzzle, then the player cannot reach the entrance of Camelot.

Opening The Gate

At the front gate of camelot, whilst holding the stone key, the player must type unlock door, then open door. This will allow the player to enter camelot.

Buying The Lamp

Inside the castle there is a coin, and the coin must be picked up, and the player must go back outside the castle to buy lamp from the old woman that is selling lamps.

The Trapdoor

Inside the castle, there is an old trapdoor.

Whilst holding the axe, the player should type smash trapdoor or break trapdoor and the trapdoor will be replaced with a broken trapdoor message, and the player should be able to type "down" to enter the salt mines (beneath the castle).

The Rockworm

Inside the salt mines, there is a creature called a rockworm, which is blocking the way further into the mines. If the player tries to go past the room, the player will be attacked and the game will end.


To remove the rockworm, light lamp. Once past the rockworm, go further into the mines and take the salt. Some string is also in the mines, but it serves no purpose.

Getting Past The Ice Creature

In another part of the castle, there is an ice creature, blocking a doorway. throw salt at ice creature to melt it.

Once past the rock creature, get oil, and get excalibur (the legendary sword) from the armoury room.

Opening The Portcullis

There is one part of the castle that is blocked now, it is a room with a closed portcullis (gate). We should now be holding the oil and excalibur. Inside the winch room, there is a winch but it is rusty.


Type oil winch, then type turn winch, doing so will raise the portcullis (open the gate).

The Sorceress

In the room on the other side of the portcullis we see the sorceress Crania, and she has cast a spell at the player.


If the player is holding excalibur, they should type reflect spell or deflect spell and it will bounce the spell using excalibur and make the sorceress vanish.

King Arthur

Now we have access to one more room of the castle, and in this room, King Arthur is prisoner, and is asleep. Type wake arthur, and the game is won.

2.10. Objects

drafty room

2.11. Objects & Scenery

The game features a variety of objects and scenery, some of which have a use, some of which do not. The player must figure out how to interact with objects in the game.

Any items of interest in the game is referred to as an "object", even people. Usually, players can pick up objects, but some "objects" are marked as immovable, and cannot be collected.

2.11.1. Objects (Things we can pick up or use)

Identifier Description Found At Notes

ladder

a ladder

hut

Used to climb tree (by leaning it), then must be broken to create a pole with which to cross the chasm.

red_fish

a red fish

road_3

Not Useful

short_sword

a short sword

top_of_tree

Used to defeat the Demon Knight.

coin

a coin

ornate_antechamber

Used to purchase lamp from old lady.

string

some string

salt_mine_2

Not Useful

salt

some salt

salt_mine_3

Used to melt ice creature.

oil

can of oil

cold_room

Used to oil the winch, so it can be turned to open the portcullis.

excalibur

Excalibur!

armoury

Used to reflect incoming spell from Crania.

long_pole

a long pole

-

Created by breaking ladder. Required to cross chasm.

rungs

some rungs

-

Created by breaking ladder. Not Useful.

stone_key

a stone key

-

Created by examining bush. Used to open door of camelot castle.

axe

a wood cutters' axe

-

Created by examining logs. Used to smash trapdoor, so we can enter the salt mines.

lamp

a lamp

-

Created by buying lamp (with coin) from old lady. Used to frighten away the rockworm (by lighting lamp).

Scenery (Things we can’t pick up)
Object Name Description Initial Location Notes

old_woman

an old woman selling lamps

lamp_seller_on_road

Disappears after buying lamp with coin.

logs

a pile of logs

deep_inside_birwood

Must be examined to find the woodcutters' axe.

bush

a bush

birwood_bush

Must be examined to find the stone key.

demon_knight

a Demon Knight guarding the east road

demon_knight_road

Blocks the road to camelot. Must be attacked once holding the short sword. Disappears after attacked.

trapdoor

an old trapdoor

drafty_room

Blocks the entrace to the salt mines. Smashed with axe. After smashing, trapdoor is removed and replaced with smashed trapdoor.

smashed_trapdoor

a smashed trapdoor

-

Smashed trapdoor is created when the non-smashed trapdoor is smashed when carrying the woodcutters' axe.

rockworm

a Rockworm, guarding the south tunnel

worm_room

Blocks the path further into the salt mines. Must be scared away by lighting lamp.

ice_creature

an Ice Creature, guarding the north exit

cold_room

Blocks the entrance to the winch room and armoury, must be melted by throwing ice at it. When melted, ice creature is removed from the game.

winch

a winch

winch_room

Must be oiled, then turned to open the portcullis in the portcullis room.

spell

a spell flying at you from Crania

most_splendid_room

Must be deflected or reflected using excalibur. Once spell is reflected or deflected, then Crania (and spell) are removed from the game.

asleep_arthur

King Arthur (asleep)

arthur (arthur is the room identifier)

Arthur must be woken to win the game.

3. The Keyboard

3.1. Coding And The Keyboard

Feel free to skip this chapter for now if you are familiar with the keyboard, or just wish to start the coding section.

You can skip the chapter by clicking the up arrow above this text, and then just scroll down to the next chapter in the lesson list.

keyboard

Adventuron is a code based system and requires that game-makers are able to use a keyboard and mouse / touchpad.

If it’s your first time to type a large document on a keyboard, don’t worry - practise makes perfect

3.2. Moving The Cursor

We will now practise using the keyboard.

Step 1 - Select "Keyboard Practise" from the menu at the bottom right of the middle panel (the editor window). Make sure there is a tick next to the "Keyboard Practise" menu option.

Step 2 - Click inside the text editor window you the left mouse button.

006b

Step 3 - After selected the keyboard practise mode, type in the following text:

006c

If you have never used a keyboard before this might be hard at first, so ask an adult for help in finding the right buttons to press if you get lost.

3.3. Selecting text with the cursor keys, holding the SHIFT key

Holding the SHIFT button whist tapping a cursor will "select" text (light it up).

The SHIFT key is the key to the left of the "Z" key on the keyboard.

cursor select

3.4. Selecting text, by holding left mouse button then moving mouse

We can also select text by moving the mouse to the start of an area, holding the left mouse button, moving it until the text is selected then letting go.

mouse select

3.5. Deleting Text

backspace

The backspace button is usually above the ENTER button and next to the + and - buttons. The image above shows the key on a typical keyboard.

This may not match your keyboard layout exactly.

If we press the BACKSPACE button when text is selected, all the text we selected will disappear.

select and backspace

3.6. Select All, Cut,Copy & Paste

3.7. The Control / Command Button

The Control button is usually the bottom left key on Linux, Windows and Chromebook keyboards. Some keyboards may have this button in a slightly different place, so please look at your own keyboard to find where it is.

keyboard

3.8. Information For Apple Computer Users

This course will refer to the special button as the Control button, but on Apple branded home computers, the COMMAND button should be used instead of the CONTROL button for all shortcuts that use the CONTROL button.

3.9. Select All

Hold the CONTROL button and then tap the A button to select all text in the editor.

select all

3.10. Copy Paste

Select some text (using cursor keys + shift or mouse drag), then hold the CONTROL button and then tap the C button to make an in-memory copy of the selected text (copy). Then press CONTROL and V to place the copy of the text that was copied where the cursor is.

copy paste

3.11. Cut Paste

Select some text (using cursor keys + shift or mouse drag), then hold the CONTROL button and then tap the X button to make an in-memory copy of the selected text, and also to delete the selection from the document (cut).

Then press CONTROL and V to place the copy of the deleted text that was copied where the cursor is. Cut and paste is extremely useful for moving text around quickly.

cut paste

3.12. Undo

Hold the CONTROL button and then tap the Z button to undo the last action you performed, this can work more than once. This is very handy if you press something wrong, or type something wrong. Remember, it’s very normal to get things wrong, in fact, that’s the reason that undo is there.

undo

3.13. Saving

There are two ways to save in Adventuron.

  1. You can press CONTROL + S on the keyboard together.

  2. Or you can click the play icon (picture) on the top bar. It looks like a triangle pointing right.

play icon
Figure 2. Save game then start game.

If you can’t remember all of these it’s OK. You will reminded when and how you can save.

3.14. Privacy Modes & Save Files

Adventuron stores your files in the browser. If you close the browser tab, it will remember the file you were working on.

If you use Adventuron Classroom in 'incognito' or private browsing mode, then your work will be lost when you close the Window as nothing is currently stored on the Adventuron website server.

Feel free to skip this section if you wish, but more useful keyboard commands are included here.

3.15. Page Up & Page Down

We can use the PAGE UP and PAGE DOWN buttons to move the cursor up and down the screen, very quickly. The mouse wheel can also be used to page up and page down.

3.15.1. (Page Up/Down on Chromebooks )

On some Chromebooks, page up and page down buttons do not exist. You can press CONTROL + SHIFT + CURSOR UP / DOWN buttons to move through the text one page at a time.

3.16. Redo (Control + Y)

Hold the CONTROL button and the Y button to redo something you already undid. There is no image for this description, as it’s difficult to demonstrate visually. Try it out thout straight after an undo.

3.17. Finding Text (Control + F)

Sometimes you might want to find some text in Adventuron. To do this, press CONTROL + F together, and then type the letters of the word you are looking for.

3.18. Underscore (_)

A very important key is the underscore character:

_

The underscore character is used a lot in Adventuron. To type it, you need to press the button to the right of the '0' key on the keyboard, whilst pressing SHIFT.

3.19. Colon (:)

Another very important key is the colon character:

:

The colon character is used a lot in adventuron. To type it, you need to press the button to the right of the 'L' key on the keyboard, whilst pressing SHIFT.

3.20. Double Quote (")

Another very important key is the double quote character:

"

The double quote character is used a lot in adventuron. To type it, you need look at your keyboard for where it is, and press it whilst pressing SHIFT. (this key in a different place depening on your keyboard type).

There are more advanced things you can do with the keyboard, and they are all very fun, but that’s enough for now.

3.21. Typing special characters (British Keyboard)

Keyboards are different in different parts of the world, so this guide is only for people with British keyboards.

Here are the characters that require the shift button on a British keyboard.

Special character How to type

!

Hold Shift & Press 1

"

Hold Shift & Press 2

£

Hold Shift & Press 3

$

Hold Shift & Press 4

%

Hold Shift & Press 5

^

Hold Shift & Press 6

&

Hold Shift & Press 7

*

Hold Shift & Press 8

(

Hold Shift & Press 9

)

Hold Shift & Press 0

_ (underscore)

Hold Shift & Press -

+

Hold Shift & Press =

~

Hold Shift & Press #

:

Hold Shift & Press ;

{

Hold Shift & Press [

}

Hold Shift & Press ]

<

Hold Shift & Press ,

>

Hold Shift & Press .

?

Hold Shift & Press /

4. First Code

4.1. Getting Started With Autocompletion

Before we can start to code, we need to clear the editor window of all text and switch off keyboard practise mode (if it is enabled).

To do this, click the "Menu" button, and select "Start Coding (Clear All Text)" option.

See the animation below:

new 004b

4.2. Creating The First Location

Now let’s type-in the first location in Excalibur.

Each location requires an ID part and a DESCRIPTION part.

In Adventuron the ID is the part of a line of code BEFORE the : letter. The DESCRIPTION is surrounded by the double-quote " characters.

this_is_the_id : location "This is the description" ;

IDs cannot contain spaces but can contain underscores.

We will change the first location to have an ID of hut, type in the description of the first location, and set the start location of the game to the id of the hut location.

002

4.3. Testing The Game

To test the game, either press CONTROL + S, or click the "save" button at the top of the window.

play icon

It doesn’t do much yet, but Adventuron is at least describing our first location.

003

Code so far …​

########################################
#  Adventuron                          #
########################################

start_at      = hut

########################################
#  Locations                           #
########################################

locations {

   hut    : location "You are in an old hut. Sunlight shines in from a doorway to the north." ;

}

########################################
#  Connections                         #
########################################

connections {

   from, direction, to = [

   ]

}

########################################
#  Objects                             #
########################################

objects {

}

4.4. Connecting Locations Together

4.5. Compass Directions

new compass

4.6. Connection Our 3 Locations Together

In the tutorial game, the hut has an exit north to road_1, and road_1 has an exit north to road_2. We can put this in a table to make it nice and clear.

map a
  1. A box that is above another box is NORTH of that box.

  2. A box that is below another box is SOUTH of that box.

  3. A box that is left of another box is WEST of that box.

  4. A box that is right of another box is EAST of that box.

We connect locations together using the connections table.

From Location Direction To Location

Hut

North

Road 1

Road 1

North

Road 2

Adventuron automatically knows that if road 1 is north of the hut, that the hut is south of road 1, so you don’t need to create connections in each direction.

4050 1

Placing your cursor on a blank line in the middle the connections block, and press CONTROL + SPACE.

The first item to be suggested will be a location identifier. This is the from location.

4050 2

Select "hut" as the from location, by using the cursor (arrow) keys on the keyboard, then press the ENTER button. You can move up or down the selected options with the CURSOR KEYS, or you can use the mouse to click the option you want.

After you select hut, Adventuron will write "hut," (hut followed by comma).

The middle section header colour will be red and read "Attention required on line xx" (xx is a number), because connections require 3 items per line.

Until we add all three items on a line, Adventuron will not be very happy. It likes everything to be very tidy.

Next, press CONTROL + SPACE again. This is now the direction column, again use the cursor (arrow) keys to select NORTH, then press the ENTER button.

4050 3

The line should now read "hut, north, " and your cursor (the flashy part) should be at the end of the line.

4050 4

The window should be reporting there is a validation problem. This is because it is waiting for the 3rd entry on the line. The third entry should be the "road_1".

Press "r" then press CONTROL + SPACE, and we will be presented with an option for road_1 and road_2.

4050 5

Select road_1, then press enter.

4050 6

Typing the first few letters of something you are looking for before pressing CONTROL + SPACE will only show options containing the letters you typed. Typing the first few letters of things you know about can really speed up AUTOCOMPLETION.

4.7. And Again

Now we go to a new line, and repeat the process but for "road_1, north, road_2".

006

Now …​ Click the PLAY button …​.

play icon

Now use the right hand side of the screen to explore these three locations. Adventuron will display the connections between our locations.

007

South is the opposite direction as north, so we can type "n" (short for north) to move up the map, and "s" (short for south) to move down the map.

If we try to go in a direction without a connection, Adventuron will tell inform us that we cannot go that way.

We can also click on the directions with a mouse click to go in that direction.

Here is the code so far

########################################
#  Adventuron                          #
########################################

start_at      = hut

########################################
#  Locations                           #
########################################

locations {

   hut    : location "You are in an old hut. Sunlight shines in from a doorway to the north." ;
   road_1 : location "You are standing on a track. The hut is south." ;
   road_2 : location "You are where the road turns eastwards. You see small hills in the distance." ;

}

########################################
#  Connections                         #
########################################

connections {

   from, direction, to = [
      hut,    north, road_1,
      road_1, north, road_2,
   ]

}

########################################
#  Objects                              #
########################################

objects {

}

4.8. Adding an object

lamp

In Adventuron, objects are a type of things that exists in the game world.

The first object in the game, in the first location (the hut) in fact, is the ladder.

Adventuron supports different types of objects, but the ladder is just a normal type of object (can be picked up and put down), so we create it as an object.

To create the ladder object, we move the cursor (using the mouse or the cursor keys) to an empty line inside the objects {} code block.

4100 1

We then press CONTROL + SPACE, and just like creating a new location, we type the name of the object id (or nickname), then we press the TAB button (usually left of the letter Q) to move to the area between the " letters, then type the description of the object.

008

Articles

The part between the '"' characters, is usually prefixed by the "article" which is a word like "the" or "some" or "a" or "an".

If you don’t know what an article is, or which one to use, ask a teacher or a trusted grown up.

If you don’t know what to do, just write the name of the object by itself.

Placing The Ladder In The Hut

Now we have defined what a ladder is, but we need to place the ladder in the hut.

We want to put the ladder in the hut, so we need to find a bit of space in the objects line. The place where you find space is usually before the ";" character.

Move your cursor just before the ";" character, and press CONTROL + SPACE:

4100 2

Once there, now type "sta", this will narrow down the set of options to options that contain "sta".

After selecting "start_at" from the list, now we have to choose the start location for the ladder.

4100 3

When your cursor is between the "" characters, press CONTROL + SPACE again !

4100 4

Now we can choose which location in which we wish to create the ladder.

4100 5

Select "hut" (using the cursor keys then pressing ENTER, or clicking with your mouse pointer). Adventuron will type hut automatically.

Here is an animation showing this process:

009

Now let’s press the PLAY ICON and play the game for a little while …​.

play icon
010

4.8.1. Great Job!

If you have got this far, congratulations.

If you feel tired, or get stuck, then take a break, or ask a trusted grown up for help.

4.8.2. Code So Far

########################################
#  Adventuron                          #
########################################

start_at      = hut

########################################
#  Locations                           #
########################################

locations {

   hut    : location "You are in an old hut. Sunlight shines in from a doorway to the north." ;
   road_1 : location "You are standing on a track. The hut is south." ;
   road_2 : location "You are where the road turns eastwards. You see small hills in the distance." ;

}

########################################
#  Connections                         #
########################################

connections {

   from, direction, to = [
      hut,    north, road_1,
      road_1, north, road_2,
   ]

}

########################################
#  Objects                             #
########################################

objects {
   ladder : object "a ladder" start_at = "hut" ;
}

4.9. Adding all the locations

castle smaller

We will now type in all the remaining locations of Excalibur into the game.

It’s much easier if you do this in a pair, with one person reading the ids and descriptions, and the other person typing.

Remember, you always need to start on an EMPTY LINE then press CONTROL + SPACE and Adventuron will give you a new location template. After that, type the name of the identifier, then press the TAB button (left of the Q button), then type the description of the location.

The underscore '_' looks like a minus symbol, but lower. To type it you have to hold the SHIFT button and press the minus '-' button.

You can copy and paste this text if you wish, but this is good typing practise if you have the time to type all these locations yourself.

(If the following text is too cramped, remember you can double click the documentation to go into full screen mode, then double click to go back)

locations {

   hut                    : location "You are in an old hut. Sunlight shines in from a doorway to the north.";
   road_1                 : location "You are standing on a track. The hut is south.";
   road_2                 : location "You are where the road turns eastwards. You see small hills in the distance.";
   road_3                 : location "You are on a road surrounded by grass. Trees can be seen on a hill in the distance.";
   road_4                 : location "You are on a dusty path on the edge of Birwood.";
   lamp_seller_on_road    : location "You are at a crossroads.";
   chasm                  : location "You are stood on the edge of a huge chasm (a cliff). A tightrope spans the gap, but it looks dangerous.";
   edge_of_birwood        : location "You are on the edge of Birwood. A rope spans the chasm northwards." ;
   deep_inside_birwood    : location "You are deep inside Birwood. The trees are alive with the buzzing of tiny insects.";
   birwood_bush           : location "You are standing in Birwood. A gap in the trees lets a warm light filter through.";
   demon_knight_road      : location "You are in a dip in the road by dark Birwood. Birds can be heard above.";
   foot_of_tree           : location "You are at the bottom of a large stone tree that is bare of any branches. The road ends here.";
   top_of_tree            : location "You are in a stone room set in a large stone tree.";
   castle_approach_1      : location "You are now a fair distance from Birwood. You can see castle Camelot to the east.";
   castle_approach_2      : location "You are outside Camelot Castle. A great stone door is the only way in.";
   castle_porch           : location "You are in the porch of Camelot.";
   banquet_hall           : location "You are in an abandoned banquet hall (eating area). Furniture lays broken on the floor.";
   drafty_room            : location "You are in a drafty room. Wind blows through gaps in the walls creating howling noises.";
   ornate_antechamber     : location "You are in an antechamber covered in thin ice that even covers the paintings.";
   portcullis             : location "You are in a room which has an iron portcullis set into the northern wall.";
   salt_mine_1            : location "You are in an old salt mine. Tunnels lead to the west and south.";
   salt_mine_2            : location "You are in the west part of the mine. It looks like it's been abandoned.";
   salt_mine_3            : location "You are at the end of the mine. You can hear the drip of water.";
   worm_room              : location "You are in the south part of the mine. There been recent movement in the rocks near your feet.";
   cold_room              : location "You are in a bitterly cold room. Everything is coated in a thick layer of ice.";
   winch_room             : location "You are in the winch room.";
   armoury                : location "You are in the armoury. Empty weapon racks line the walls.";
   most_splendid_room     : location "You are in the most splendid room in the castle. Rugs and paintings adorn the floor and walls.";
   arthur                 : location "You are in a sparse and lonely room. A cold wind enters through a high window.";

}

4.10. Code So Far

########################################
#  Adventuron                          #
########################################

start_at      = hut

########################################
#  Locations                           #
########################################

locations {

   hut                    : location "You are in an old hut. Sunlight shines in from a doorway to the north.";
   road_1                 : location "You are standing on a track. The hut is south.";
   road_2                 : location "You are where the road turns eastwards. You see small hills in the distance.";
   road_3                 : location "You are on a road surrounded by grass. Trees can be seen on a hill in the distance.";
   road_4                 : location "You are on a dusty path on the edge of Birwood.";
   lamp_seller_on_road    : location "You are at a crossroads.";
   chasm                  : location "You are stood on the edge of a huge chasm (a cliff). A tightrope spans the gap, but it looks dangerous.";
   edge_of_birwood        : location "You are on the edge of Birwood. A rope spans the chasm northwards." ;
   deep_inside_birwood    : location "You are deep inside Birwood. The trees are alive with the buzzing of tiny insects.";
   birwood_bush           : location "You are standing in Birwood. A gap in the trees lets a warm light filter through.";
   demon_knight_road      : location "You are in a dip in the road by dark Birwood. Birds can be heard above.";
   foot_of_tree           : location "You are at the bottom of a large stone tree that is bare of any branches. The road ends here.";
   top_of_tree            : location "You are in a stone room set in a large stone tree.";
   castle_approach_1      : location "You are now a fair distance from Birwood. You can see castle Camelot to the east.";
   castle_approach_2      : location "You are outside Camelot Castle. A great stone door is the only way in.";
   castle_porch           : location "You are in the porch of Camelot.";
   banquet_hall           : location "You are in an abandoned banquet hall (eating area). Furniture lays broken on the floor.";
   drafty_room            : location "You are in a drafty room. Wind blows through gaps in the walls creating howling noises.";
   ornate_antechamber     : location "You are in an antechamber covered in thin ice that even covers the paintings.";
   portcullis             : location "You are in a room which has an iron portcullis set into the northern wall.";
   salt_mine_1            : location "You are in an old salt mine. Tunnels lead to the west and south.";
   salt_mine_2            : location "You are in the west part of the mine. It looks like it's been abandoned.";
   salt_mine_3            : location "You are at the end of the mine. You can hear the drip of water.";
   worm_room              : location "You are in the south part of the mine. There been recent movement in the rocks near your feet.";
   cold_room              : location "You are in a bitterly cold room. Everything is coated in a thick layer of ice.";
   winch_room             : location "You are in the winch room.";
   armoury                : location "You are in the armoury. Empty weapon racks line the walls.";
   most_splendid_room     : location "You are in the most splendid room in the castle. Rugs and paintings adorn the floor and walls.";
   arthur                 : location "You are in a sparse and lonely room. A cold wind enters through a high window.";

}

########################################
#  Connections                         #
########################################

connections {

   from, direction, to = [
      hut,    north, road_1,
      road_1, north, road_2,
   ]

}

########################################
#  Objects                             #
########################################

objects {
   ladder : object "a ladder" start_at = "hut" ;
}

4.11. Adding all the navigation options

It is now time to add all the navigation options, and for now, we will ignore the areas of the map that are blocked (the parts with the dotted line).

Map - Part 1

map 1
Figure 3. Click to see larger image

Map - Part 2

map 2
Figure 4. Click to see larger image

This table (which was prepared from the map earlier in the tutorial) shows how all the locations are connected.

from direction to

hut

leads north to

road_1

road_1

leads north to

road_2

road_2

leads east to

road_3

road_3

leads east to

road_4

road_4

leads north to

foot_of_tree

road_4

leads south to

lamp_seller_on_road

lamp_seller_on_road

leads east to

demon_knight_road

lamp_seller_on_road

leads south to

chasm

foot_of_tree

leads up to

top_of_tree

chasm leads

leads south to

edge_of_birwood

edge_of_birwood

leads south to

deep_inside_birwood

deep_inside_birwood

leads west to

birwood_bush

demon_knight_road

leads east to

castle_approach_1

castle_approach_1

leads east to

castle_approach_2

castle_approach_2

leads east to

castle_porch

castle_porch

leads east to

banquet_hall

banquet_hall

leads north to

portcullis

banquet_hall

leads south to

drafty_room

portcullis

leads north to

most_splendid_room

most_splendid_room

leads west to

arthur

drafty_room

leads east to

ornate_antechamber

drafty_room

leads down to

salt_mine_1

ornate_antechamber

leads east to

cold_room

cold_room

leads north to

winch_room

winch_room

leads east to

armoury

salt_mine_1

leads west to

salt_mine_2

salt_mine_1

leads south to

worm_room

worm_room

leads south to

salt_mine_3

Now, we have to enter this information into the connections block of code.

Now, you must repeat the lesson from earlier for each entry in this table. See the animation at the bottom of this section to show how this works, but you have to use CONTROL + SPACE - a lot.

It might help if you do this in a pair, and one person reads out each line, as the other person creates a new line in the navigation table. After you type each line, check it to make sure you have not made any mistakes.

The video below is sped up, but the it shows how you should be able to edit the connections easily, using CONTROL + SPACE.

011 new

After entering this information into Adventuron, you now have a map you can completely explore.

Here is the source-code you should have entered so far …​.

########################################
#  Adventuron                          #
########################################

start_at      = hut

########################################
#  Locations                           #
########################################

locations {

   hut                    : location "You are in an old hut. Sunlight shines in from a doorway to the north.";
   road_1                 : location "You are standing on a track. The hut is south.";
   road_2                 : location "You are where the road turns eastwards. You see small hills in the distance.";
   road_3                 : location "You are on a road surrounded by grass. Trees can be seen on a hill in the distance.";
   road_4                 : location "You are on a dusty path on the edge of Birwood.";
   lamp_seller_on_road    : location "You are at a crossroads.";
   chasm                  : location "You are stood on the edge of a huge chasm (a cliff). A tightrope spans the gap, but it looks dangerous.";
   edge_of_birwood        : location "You are on the edge of Birwood. A rope spans the chasm northwards." ;
   deep_inside_birwood    : location "You are deep inside Birwood. The trees are alive with the buzzing of tiny insects.";
   birwood_bush           : location "You are standing in Birwood. A gap in the trees lets a warm light filter through.";
   demon_knight_road      : location "You are in a dip in the road by dark Birwood. Birds can be heard above.";
   foot_of_tree           : location "You are at the bottom of a large stone tree that is bare of any branches. The road ends here.";
   top_of_tree            : location "You are in a stone room set in a large stone tree.";
   castle_approach_1      : location "You are now a fair distance from Birwood. You can see castle Camelot to the east.";
   castle_approach_2      : location "You are outside Camelot Castle. A great stone door is the only way in.";
   castle_porch           : location "You are in the porch of Camelot.";
   banquet_hall           : location "You are in an abandoned banquet hall (eating area). Furniture lays broken on the floor.";
   drafty_room            : location "You are in a drafty room. Wind blows through gaps in the walls creating howling noises.";
   ornate_antechamber     : location "You are in an antechamber covered in thin ice that even covers the paintings.";
   portcullis             : location "You are in a room which has an iron portcullis set into the northern wall.";
   salt_mine_1            : location "You are in an old salt mine. Tunnels lead to the west and south.";
   salt_mine_2            : location "You are in the west part of the mine. It looks like it's been abandoned.";
   salt_mine_3            : location "You are at the end of the mine. You can hear the drip of water.";
   worm_room              : location "You are in the south part of the mine. There been recent movement in the rocks near your feet.";
   cold_room              : location "You are in a bitterly cold room. Everything is coated in a thick layer of ice.";
   winch_room             : location "You are in the winch room.";
   armoury                : location "You are in the armoury. Empty weapon racks line the walls.";
   most_splendid_room     : location "You are in the most splendid room in the castle. Rugs and paintings adorn the floor and walls.";
   arthur                 : location "You are in a sparse and lonely room. A cold wind enters through a high window.";

}

########################################
#  Connections                         #
########################################

connections {

   from, direction, to = [
      hut,                  north,  road_1,
      road_1,               north,  road_2,
      road_2,               east,   road_3,
      road_3,               east,   road_4,
      road_4,               north,  foot_of_tree,
      road_4,               south,  lamp_seller_on_road,
      lamp_seller_on_road,  east,   demon_knight_road,
      lamp_seller_on_road,  south,  chasm,
      foot_of_tree,         up,     top_of_tree,
      chasm,                south,  edge_of_birwood,
      edge_of_birwood,      south,  deep_inside_birwood,
      deep_inside_birwood,  west,   birwood_bush,
      demon_knight_road,    east,   castle_approach_1,
      castle_approach_1,    east,   castle_approach_2,
      castle_approach_2,    east,   castle_porch,
      castle_porch,         east,   banquet_hall,
      banquet_hall,         north,  portcullis,
      banquet_hall,         south,  drafty_room,
      portcullis,           north,  most_splendid_room,
      most_splendid_room,   west,   arthur,
      drafty_room,          east,   ornate_antechamber,
      drafty_room,          down,   salt_mine_1,
      ornate_antechamber,   east,   cold_room,
      cold_room,            north,  winch_room,
      winch_room,           east,   armoury,
      salt_mine_1,          west,   salt_mine_2,
      salt_mine_1,          south,  worm_room,
      worm_room,            south,  salt_mine_3,
   ]

}

########################################
#  Objects                             #
########################################

objects {
   ladder : object "a ladder" start_at = "hut" ;
}

4.12. Adding all the objects

We will now create all the remaining objects and scenery, and set the start location of each item using start_at.

As a reminder, this is how we describe an object at a location.

ladder : object "a ladder" start_at="hut" ;

The full list of objects is repeated here, for convenience:

4.12.1. Objects (Things we can pick up or use)

Identifier Description Found At

ladder

a ladder

hut

red_fish

a red fish

road_3

short_sword

a short sword

top_of_tree

coin

a coin

ornate_antechamber

string

some string

salt_mine_2

salt

some salt

salt_mine_3

oil

can of oil

cold_room

excalibur

Excalibur!

armoury

long_pole

a long pole

-

rungs

some rungs

-

stone_key

a stone key

-

axe

a wood cutters' axe

-

lamp

a lamp

-

Scenery (Objects or People we can’t pick up)
Object Name Description Initial Location

old_woman

an old woman selling lamps

lamp_seller_on_road

logs

a pile of logs

deep_inside_birwood

bush

a bush

birwood_bush

demon_knight

a Demon Knight guarding the east road

demon_knight_road

trapdoor

an old trapdoor

drafty_room

smashed_trapdoor

a smashed trapdoor

-

rockworm

a Rockworm, guarding the south tunnel

worm_room

ice_creature

an Ice Creature, guarding the north exit

cold_room

winch

a winch

winch_room

spell

a spell flying at you from Crania

most_splendid_room

Remember that we create an object by pressing CONTROL + SPACE on an empty line in the objects {} code block, select 'object', then type in the identifier, then press the TAB button to type in the description.

To create a new line, press ENTER at the end of the line (after the ';').

Non moveable things are known as 'scenery' and scenery is something that is shown by the game, but cannot be put in your pocket.

It’s important that you tell the computer if something is an object (you can take it), or scenery (you can not take it).

The completed code block should look like this:

objects {

   # Items we can pick-up (Objects)

   ladder           : object  "a ladder"       start_at="hut" ;
   red_fish         : object  "a red fish"     start_at="road_3" ;
   short_sword      : object  "a short sword"  start_at="top_of_tree" ;
   coin             : object  "a coin"         start_at="ornate_antechamber" ;
   string           : object  "some string"    start_at="salt_mine_2" ;
   salt             : object  "some salt"      start_at="salt_mine_3" ;
   oil              : object  "can of oil"     start_at="cold_room" ;
   excalibur        : object  "Excalibur!"     start_at="armoury" ;
   long_pole        : object  "a long pole" ;
   rungs            : object  "some rungs" ;
   stone_key        : object  "a stone key" ;
   axe              : object  "a wood cutters' axe" ;
   lamp             : object  "a lamp" ;

   # Things or people that we cannot pick up (Scenery)

   old_woman        : scenery "an old woman selling lamps"               start_at="lamp_seller_on_road" ;
   logs             : scenery "a pile of logs"                           start_at="deep_inside_birwood" ;
   bush             : scenery "a bush"                                   start_at="birwood_bush" ;
   demon_knight     : scenery "a Demon Knight guarding the east road"    start_at="demon_knight_road" ;
   trapdoor         : scenery "an old trapdoor"                          start_at="drafty_room" ;
   smashed_trapdoor : scenery "a smashed trapdoor" ;
   rockworm         : scenery "a Rockworm, guarding the south tunnel"    start_at="worm_room" ;
   ice_creature     : scenery "an Ice creature, guarding the north exit" start_at="cold_room" ;
   winch            : scenery "a winch"                                  start_at="winch_room" ;
   spell            : scenery "a spell flying at you from Crania"        start_at="most_splendid_room" ;
   asleep_arthur    : scenery "King Arthur (asleep)"                     start_at="arthur" ;

}

4.12.2. If you make a mistake

If you make a mistake, you can copy and paste from this document into your own code. If you have somehow done something wrong, and want to catch-up, you can copy and paste from the code at the bottom of this section.

4.12.3. Locations, Connections & Objects

We now have the basic structure of the game defined.

We have the location descriptions, connections between locations, and objects that the game contains.

Even though we have not yet created the puzzles, we should now be able to explore the world, and all the objects / scenery in the world, without the game stopping us from going anywhere.

012

4.13. Code So Far

########################################
#  Adventuron                          #
########################################

start_at      = hut

########################################
#  Locations                           #
########################################

locations {

   hut                    : location "You are in an old hut. Sunlight shines in from a doorway to the north.";
   road_1                 : location "You are standing on a track. The hut is south.";
   road_2                 : location "You are where the road turns eastwards. You see small hills in the distance.";
   road_3                 : location "You are on a road surrounded by grass. Trees can be seen on a hill in the distance.";
   road_4                 : location "You are on a dusty path on the edge of Birwood.";
   lamp_seller_on_road    : location "You are at a crossroads.";
   chasm                  : location "You are stood on the edge of a huge chasm (a cliff). A tightrope spans the gap, but it looks dangerous.";
   edge_of_birwood        : location "You are on the edge of Birwood. A rope spans the chasm northwards." ;
   deep_inside_birwood    : location "You are deep inside Birwood. The trees are alive with the buzzing of tiny insects.";
   birwood_bush           : location "You are standing in Birwood. A gap in the trees lets a warm light filter through.";
   demon_knight_road      : location "You are in a dip in the road by dark Birwood. Birds can be heard above.";
   foot_of_tree           : location "You are at the bottom of a large stone tree that is bare of any branches. The road ends here.";
   top_of_tree            : location "You are in a stone room set in a large stone tree.";
   castle_approach_1      : location "You are now a fair distance from Birwood. You can see castle Camelot to the east.";
   castle_approach_2      : location "You are outside Camelot Castle. A great stone door is the only way in.";
   castle_porch           : location "You are in the porch of Camelot.";
   banquet_hall           : location "You are in an abandoned banquet hall (eating area). Furniture lays broken on the floor.";
   drafty_room            : location "You are in a drafty room. Wind blows through gaps in the walls creating howling noises.";
   ornate_antechamber     : location "You are in an antechamber covered in thin ice that even covers the paintings.";
   portcullis             : location "You are in a room which has an iron portcullis set into the northern wall.";
   salt_mine_1            : location "You are in an old salt mine. Tunnels lead to the west and south.";
   salt_mine_2            : location "You are in the west part of the mine. It looks like it's been abandoned.";
   salt_mine_3            : location "You are at the end of the mine. You can hear the drip of water.";
   worm_room              : location "You are in the south part of the mine. There been recent movement in the rocks near your feet.";
   cold_room              : location "You are in a bitterly cold room. Everything is coated in a thick layer of ice.";
   winch_room             : location "You are in the winch room.";
   armoury                : location "You are in the armoury. Empty weapon racks line the walls.";
   most_splendid_room     : location "You are in the most splendid room in the castle. Rugs and paintings adorn the floor and walls.";
   arthur                 : location "You are in a sparse and lonely room. A cold wind enters through a high window.";

}

########################################
#  Connections                         #
########################################

connections {

   from, direction, to = [
      hut,                  north,  road_1,
      road_1,               north,  road_2,
      road_2,               east,   road_3,
      road_3,               east,   road_4,
      road_4,               north,  foot_of_tree,
      road_4,               south,  lamp_seller_on_road,
      lamp_seller_on_road,  east,   demon_knight_road,
      lamp_seller_on_road,  south,  chasm,
      foot_of_tree,         up,     top_of_tree,
      chasm,                south,  edge_of_birwood,
      edge_of_birwood,      south,  deep_inside_birwood,
      deep_inside_birwood,  west,   birwood_bush,
      demon_knight_road,    east,   castle_approach_1,
      castle_approach_1,    east,   castle_approach_2,
      castle_approach_2,    east,   castle_porch,
      castle_porch,         east,   banquet_hall,
      banquet_hall,         north,  portcullis,
      banquet_hall,         south,  drafty_room,
      portcullis,           north,  most_splendid_room,
      most_splendid_room,   west,   arthur,
      drafty_room,          east,   ornate_antechamber,
      drafty_room,          down,   salt_mine_1,
      ornate_antechamber,   east,   cold_room,
      cold_room,            north,  winch_room,
      winch_room,           east,   armoury,
      salt_mine_1,          west,   salt_mine_2,
      salt_mine_1,          south,  worm_room,
      worm_room,            south,  salt_mine_3,
   ]

}

########################################
#  Objects                             #
########################################

objects {

   # Items we can pick-up (Objects)

   ladder           : object  "a ladder"                                    start_at="hut" ;
   red_fish         : object  "a red fish"                              start_at="road_3" ;
   short_sword      : object  "a short sword"                               start_at="top_of_tree" ;
   coin             : object  "a coin"                                      start_at="ornate_antechamber" ;
   string           : object  "some string"                                 start_at="salt_mine_2" ;
   salt             : object  "some salt"                                   start_at="salt_mine_3" ;
   oil              : object  "can of oil"                                  start_at="cold_room" ;
   excalibur        : object  "Excalibur!"                                  start_at="armoury" ;
   long_pole        : object  "a long pole" ;
   rungs            : object  "some rungs" ;
   stone_key        : object  "a stone key" ;
   axe              : object  "a wood cutters' axe" ;
   lamp             : object  "a lamp" ;

   # Things or people that we cannot pick up (Scenery)

   old_woman        : scenery "an old woman selling lamps"                  start_at="lamp_seller_on_road" ;
   logs             : scenery "a pile of logs"                              start_at="deep_inside_birwood" ;
   bush             : scenery "a bush"                                      start_at="birwood_bush" ;
   demon_knight     : scenery "a Demon Knight guarding the east road"  start_at="demon_knight_road" ;
   trapdoor         : scenery "an old trapdoor"                             start_at="drafty_room" ;
   smashed_trapdoor : scenery "a smashed trapdoor" ;
   rockworm         : scenery "a Rockworm, guarding the south tunnel"       start_at="worm_room" ;
   ice_creature     : scenery "an Ice creature, guarding the north exit"    start_at="cold_room" ;
   winch            : scenery "a winch"                                     start_at="winch_room" ;
   spell            : scenery "a spell flying at you from Crania"           start_at="most_splendid_room" ;
   asleep_arthur    : scenery "King Arthur (asleep)"                        start_at="arthur" ;

}

5. Adding Logic

5.1. Responding to commands

5.2. What Are Commands?

Text adventure games respond to some kind of command (usually text), then usually show some text, or do something in response to the text..

If the player types something the game doesn’t know about, the game try its best to give the player some feedback.

If a reply is not programmed, then Adventuron will use one of its standard replies.

do not understand

There are different ways of writing command handlers, but the way we will use in the tutorial is the "manual" method.

This method involves, manually looking at the verb (the doing word) and the noun (the thing, person, object, or scenery).

The text we wish to respond to is "EXAMINE LADDER".

So, what happens if we type examine ladder.

If we are not in the same location as the ladder …​

ladder not here

If we are in the same location as the ladder …​

ladder nothing special

The response we want when examine the ladder (when it is held or in the same location) is "A LONG POLE WITH RUNGS ATTACHED."

5.3. Why examine messages are important

Why do we want this response?

Well, the response is there to give the player a clue about how the ladder might be used. Later on, there is a tightrope across a chasm.

Normally a pole is used by people balancing on a tightrope, so this message gives a clue to the player that the ladder could be converted into a pole, somehow.

5.4. Creating the on_command {} block

To write our handler, we need a new section creating in the document. We need a blank line of text, OUTSIDE of "connections", "locations" and "objects" blocks.

The location can be anywhere you like (outside of the other code blocks), but we will place it UNDERNEATH the objects block.

To create the "on_command {}" block, press CONTROL + SPACE, next start typing the first few letters of on_command (such as "on"), when you see the "on_command" item, select it using the "enter" button on the keyboard.

013

The "on_command {}" block is used to process commands that the player submitted (could be via keyboard or joypad or hyperlink or voice) …​ and respond to those user entered command with a reaction.

If nothing is matched, the Adventuron will either do something with the command itself (if it knows what to do), or tell the player that it doesn’t something about what they typed.

5.5. Creating a ": match" command

Now we need to match "examine ladder", so lets go to an empty line inside on_command {} and press …​ CONTROL + SPACE. There are a couple of options here, so let’s select "match", and then press enter.

After pressing enter, we should see the following block of code appear. The "get lamp" text is already highlighted by the editor, this means if we start typing, it will automatically wipe over the text.

The "get lamp" text is just there to demonstrate how to use match items, and will appear as a default every time you create a new match using this technique. You don’t need to delete it, you just start typing and it will disappear.

014

Now lets save our text by pressing CONTROL + S, and press the PLAY icon to try out the adventure.

Still, when typing "EXAMINE LADDER", nothing seems to happen.

That’s because we didn’t tell Adventuron what to do if ladder is matched, so Adventuron didn’t do anything, and therefore just gave its normal response.

5.6. Creating a ": print" command

Now, inside the ": match {}" command, on a blank line, press CONTROL + SPACE. A big list of commands are available here, but we won’t look at these right now.

Start typing the letters "pri" (the first 3 letters of print), and now we will be able to pick the command we are interested in, which is "print".

The text we want to display is "A LONG POLE WITH RUNGS ATTACHED.", so after selecting the "print" command, type "A LONG POLE WITH RUNGS ATTACHED." in the area between the quotes (").

015

In the original Excalibur: Sword of Kings game, all messages are in capital letters, but this is optional, and if you prefer not to use capital letters, that is fine.

Now, lets save the document with CONTROL + S, and run the game with the play icon. Actually, it’s not necessary to press the PLAY icon, as CONTROL + S will reset the game every time.

Now when we type "EXAMINE LADDER" we see the response "A LONG POLE WITH RUNGS ATTACHED." appear. Success !

016

But, there is a problem ! Can you guess what it is?

The problem is that if you type "EXAMINE LADDER" anywhere, even if you are in a different location, you still get the same response.

The response to the command should only be made when the ladder is present - and to do that we need to make the ": print {}" command CONDITIONAL.

The code so far …​.

########################################
#  Adventuron                          #
########################################

start_at      = hut

########################################
#  Locations                           #
########################################

locations {

   hut                    : location "You are in an old hut. Sunlight shines in from a doorway to the north.";
   road_1                 : location "You are standing on a track. The hut is south.";
   road_2                 : location "You are where the road turns eastwards. You see small hills in the distance.";
   road_3                 : location "You are on a road surrounded by grass. Trees can be seen on a hill in the distance.";
   road_4                 : location "You are on a dusty path on the edge of Birwood.";
   lamp_seller_on_road    : location "You are at a crossroads.";
   chasm                  : location "You are stood on the edge of a huge chasm (a cliff). A tightrope spans the gap, but it looks dangerous.";
   edge_of_birwood        : location "You are on the edge of Birwood. A rope spans the chasm northwards." ;
   deep_inside_birwood    : location "You are deep inside Birwood. The trees are alive with the buzzing of tiny insects.";
   birwood_bush           : location "You are standing in Birwood. A gap in the trees lets a warm light filter through.";
   demon_knight_road      : location "You are in a dip in the road by dark Birwood. Birds can be heard above.";
   foot_of_tree           : location "You are at the bottom of a large stone tree that is bare of any branches. The road ends here.";
   top_of_tree            : location "You are in a stone room set in a large stone tree.";
   castle_approach_1      : location "You are now a fair distance from Birwood. You can see castle Camelot to the east.";
   castle_approach_2      : location "You are outside Camelot Castle. A great stone door is the only way in.";
   castle_porch           : location "You are in the porch of Camelot.";
   banquet_hall           : location "You are in an abandoned banquet hall (eating area). Furniture lays broken on the floor.";
   drafty_room            : location "You are in a drafty room. Wind blows through gaps in the walls creating howling noises.";
   ornate_antechamber     : location "You are in an antechamber covered in thin ice that even covers the paintings.";
   portcullis             : location "You are in a room which has an iron portcullis set into the northern wall.";
   salt_mine_1            : location "You are in an old salt mine. Tunnels lead to the west and south.";
   salt_mine_2            : location "You are in the west part of the mine. It looks like it's been abandoned.";
   salt_mine_3            : location "You are at the end of the mine. You can hear the drip of water.";
   worm_room              : location "You are in the south part of the mine. There been recent movement in the rocks near your feet.";
   cold_room              : location "You are in a bitterly cold room. Everything is coated in a thick layer of ice.";
   winch_room             : location "You are in the winch room.";
   armoury                : location "You are in the armoury. Empty weapon racks line the walls.";
   most_splendid_room     : location "You are in the most splendid room in the castle. Rugs and paintings adorn the floor and walls.";
   arthur                 : location "You are in a sparse and lonely room. A cold wind enters through a high window.";

}

########################################
#  Connections                         #
########################################

connections {

   from, direction, to = [
      hut,                  north,  road_1,
      road_1,               north,  road_2,
      road_2,               east,   road_3,
      road_3,               east,   road_4,
      road_4,               north,  foot_of_tree,
      road_4,               south,  lamp_seller_on_road,
      lamp_seller_on_road,  east,   demon_knight_road,
      lamp_seller_on_road,  south,  chasm,
      foot_of_tree,         up,     top_of_tree,
      chasm,                south,  edge_of_birwood,
      edge_of_birwood,      south,  deep_inside_birwood,
      deep_inside_birwood,  west,   birwood_bush,
      demon_knight_road,    east,   castle_approach_1,
      castle_approach_1,    east,   castle_approach_2,
      castle_approach_2,    east,   castle_porch,
      castle_porch,         east,   banquet_hall,
      banquet_hall,         north,  portcullis,
      banquet_hall,         south,  drafty_room,
      portcullis,           north,  most_splendid_room,
      most_splendid_room,   west,   arthur,
      drafty_room,          east,   ornate_antechamber,
      drafty_room,          down,   salt_mine_1,
      ornate_antechamber,   east,   cold_room,
      cold_room,            north,  winch_room,
      winch_room,           east,   armoury,
      salt_mine_1,          west,   salt_mine_2,
      salt_mine_1,          south,  worm_room,
      worm_room,            south,  salt_mine_3,
   ]

}

########################################
#  Objects                             #
########################################

objects {

   # Items we can pick-up (Objects)

   ladder           : object  "a ladder"                                    start_at="hut" ;
   red_fish         : object  "a red fish"                                  start_at="road_3" ;
   short_sword      : object  "a short sword"                               start_at="top_of_tree" ;
   coin             : object  "a coin"                                      start_at="ornate_antechamber" ;
   string           : object  "some string"                                 start_at="salt_mine_2" ;
   salt             : object  "some salt"                                   start_at="salt_mine_3" ;
   oil              : object  "can of oil"                                  start_at="cold_room" ;
   excalibur        : object  "Excalibur!"                                  start_at="armoury" ;
   long_pole        : object  "a long pole" ;
   rungs            : object  "some rungs" ;
   stone_key        : object  "a stone key" ;
   axe              : object  "a wood cutters' axe" ;
   lamp             : object  "a lamp" ;

   # Things or people that we cannot pick up (Scenery)

   old_woman        : scenery "an old woman selling lamps"                  start_at="lamp_seller_on_road" ;
   logs             : scenery "a pile of logs"                              start_at="deep_inside_birwood" ;
   bush             : scenery "a bush"                                      start_at="birwood_bush" ;
   demon_knight     : scenery "a Demon Knight guarding the east road"  start_at="demon_knight_road" ;
   trapdoor         : scenery "an old trapdoor"                             start_at="drafty_room" ;
   smashed_trapdoor : scenery "a smashed trapdoor" ;
   rockworm         : scenery "a Rockworm, guarding the south tunnel"       start_at="worm_room" ;
   ice_creature     : scenery "an Ice creature, guarding the north exit"    start_at="cold_room" ;
   winch            : scenery "a winch"                                     start_at="winch_room" ;
   spell            : scenery "a spell flying at you from Crania"           start_at="most_splendid_room" ;
   asleep_arthur    : scenery "King Arthur (asleep)"                        start_at="arthur" ;

}

########################################
#  On Command                          #
########################################

on_command {

   : match "examine ladder"  {

      : print "A LONG POLE WITH RUNGS ATTACHED." ;

   }

}

5.7. The ": if" command

The ": if" command lets us do something but only if it’s the right time to do it.

Checking to see if something is the right time is called a conditional logic.

We use conditions every day when we speak to each other. We might say something like, "if the weather is good, let’s go to the park". The right time to go to the park is when the weather is good.

On Saturday, I go to the cinema, is also kind of a condition too. It can be rephrased "if it’s saturday, I go to the cinema."

We tell computers the right time to do something using the word "if".

We wish to only display "A LONG POLE WITH RUNGS ATTACHED." when we examine the ladder if we are in the same location or if we are holding the ladder.

The if command is in 3 parts:

  • : if → This is an if command

  • () → Is it a good time to do this?

  • {} → This is what we should do, only if it’s the right time to do it.

To make our "if" command, we make a line ABOVE the print command, then press CONTROL + SPACE, then type "if" then select the if with the CURSOR KEYS, then press ENTER.

017

We can see in the video above how to make an if statement using the autocomplete (CONTROL + SPACE) method.

if statement 1

5.8. Cutting And Pasting The Print Statement

This is also a good time to show how to cut and paste.

Go to the end of the match code block (using a mouse or the cursor keys), and then once at the end of the line, hold the SHIFT button on the keyboard (ask a grown up or friend if you can’t find the button), and then keep tapping the cursor key left and up until the whole of the match code block is selected (starting from the ":" character next to match).

If you select too much, use the right and down cursor keys to go back.

Once you select the print line, let go of the shift key, and the cursor keys, then press CONTROL + X, on the keyboard. This will cut the text. Cutting text is like deleting text temporarily, but the computer remembers the deleted text so it can move it somewhere else.

Now move the cursor to the empty line inside main part of the if statement and press CONTROL + V. This will paste the cut text into the new space.

018

You can see from the video about that we add new spaces to the start of the "match" block when it is inside of the "if" block. This makes the code easier to see the start and end of blocks.

Cutting and pasting is extremely useful, and it really benefits you to practise cutting and pasting a lot of text. If you have a mouse, you can also select the text by dragging the mouse across the text you want to cut.

If you want to copy text, rather than move text, use CONTROL + C, instead of CONTROL + X at the beginning…​.

If you have cut and paste correctly, the header bar should not be red, and we should save the document (CONTROL + S), and move forward.

We now have an if statement with the thing to do if it’s a good time part (the print command), but we still don’t know when it is the right time to perform the print command…​

5.9. How to check if it is the right time to do something!

Usually when we want to do something, we need to ask permission first. Asking permission usually has two answers, "yes", and "no". Computers understand "yes" and "no" very well.

So, when is the right time to be able to examine the ladder? Well, you can’t examine (look) at a ladder if it’s not in the same location can you? So, it either has to be in the same location, or if you are holding it. That’s the right time that you can examine (look) at a ladder.

Adventuron has lots of different recipes for getting a yes or a no answer. One of these recipes is called the "is_present" recipe.

"present" has two meanings. The first meaning is the type of thing you might get on your birthday.

The second mean is if something is with you. You could say, "my friend is here', or "my friend is present", and they both mean the same thing.

We can use "is_present" to check to see if the ladder is in the same location or if the person playing the game is holding the ladder.

The best way to understand it is to show how we type this in …​

019

Adventuron will only perform the middle part (the part between the {} bracey brackets) only if the ladder is in the same location, or we are holding the ladder.

Now we can see that we can only look at the ladder if it is in the same location as us. If we go north from the hut, and try to examine the ladder, we see the usual message that is shown when adventuron doesn’t know what to do.

Press CONTROL + S to save your progress, and try out examining the ladder when you are in the hut, and when you are not in the hut.

Remember that navigating requires you to know the directions of the compass. North is up on the map, south is down.

020

5.9.1. The code so far …​.

It’s useful at this point to show where we are at. This is the listing that we should have at this point in time, if we have followed all the instructions. Please check you are up to date.

########################################
#  Adventuron                          #
########################################

start_at      = hut

########################################
#  Locations                           #
########################################

locations {

   hut                    : location "You are in an old hut. Sunlight shines in from a doorway to the north.";
   road_1                 : location "You are standing on a track. The hut is south.";
   road_2                 : location "You are where the road turns eastwards. You see small hills in the distance.";
   road_3                 : location "You are on a road surrounded by grass. Trees can be seen on a hill in the distance.";
   road_4                 : location "You are on a dusty path on the edge of Birwood.";
   lamp_seller_on_road    : location "You are at a crossroads.";
   chasm                  : location "You are stood on the edge of a huge chasm (a cliff). A tightrope spans the gap, but it looks dangerous.";
   edge_of_birwood        : location "You are on the edge of Birwood. A rope spans the chasm northwards." ;
   deep_inside_birwood    : location "You are deep inside Birwood. The trees are alive with the buzzing of tiny insects.";
   birwood_bush           : location "You are standing in Birwood. A gap in the trees lets a warm light filter through.";
   demon_knight_road      : location "You are in a dip in the road by dark Birwood. Birds can be heard above.";
   foot_of_tree           : location "You are at the bottom of a large stone tree that is bare of any branches. The road ends here.";
   top_of_tree            : location "You are in a stone room set in a large stone tree.";
   castle_approach_1      : location "You are now a fair distance from Birwood. You can see castle Camelot to the east.";
   castle_approach_2      : location "You are outside Camelot Castle. A great stone door is the only way in.";
   castle_porch           : location "You are in the porch of Camelot.";
   banquet_hall           : location "You are in an abandoned banquet hall (eating area). Furniture lays broken on the floor.";
   drafty_room            : location "You are in a drafty room. Wind blows through gaps in the walls creating howling noises.";
   ornate_antechamber     : location "You are in an antechamber covered in thin ice that even covers the paintings.";
   portcullis             : location "You are in a room which has an iron portcullis set into the northern wall.";
   salt_mine_1            : location "You are in an old salt mine. Tunnels lead to the west and south.";
   salt_mine_2            : location "You are in the west part of the mine. It looks like it's been abandoned.";
   salt_mine_3            : location "You are at the end of the mine. You can hear the drip of water.";
   worm_room              : location "You are in the south part of the mine. There been recent movement in the rocks near your feet.";
   cold_room              : location "You are in a bitterly cold room. Everything is coated in a thick layer of ice.";
   winch_room             : location "You are in the winch room.";
   armoury                : location "You are in the armoury. Empty weapon racks line the walls.";
   most_splendid_room     : location "You are in the most splendid room in the castle. Rugs and paintings adorn the floor and walls.";
   arthur                 : location "You are in a sparse and lonely room. A cold wind enters through a high window.";

}

########################################
#  Connections                         #
########################################

connections {

   from, direction, to = [
      hut,                  north,  road_1,
      road_1,               north,  road_2,
      road_2,               east,   road_3,
      road_3,               east,   road_4,
      road_4,               north,  foot_of_tree,
      road_4,               south,  lamp_seller_on_road,
      lamp_seller_on_road,  east,   demon_knight_road,
      lamp_seller_on_road,  south,  chasm,
      foot_of_tree,         up,     top_of_tree,
      chasm,                south,  edge_of_birwood,
      edge_of_birwood,      south,  deep_inside_birwood,
      deep_inside_birwood,  west,   birwood_bush,
      demon_knight_road,    east,   castle_approach_1,
      castle_approach_1,    east,   castle_approach_2,
      castle_approach_2,    east,   castle_porch,
      castle_porch,         east,   banquet_hall,
      banquet_hall,         north,  portcullis,
      banquet_hall,         south,  drafty_room,
      portcullis,           north,  most_splendid_room,
      most_splendid_room,   west,   arthur,
      drafty_room,          east,   ornate_antechamber,
      drafty_room,          down,   salt_mine_1,
      ornate_antechamber,   east,   cold_room,
      cold_room,            north,  winch_room,
      winch_room,           east,   armoury,
      salt_mine_1,          west,   salt_mine_2,
      salt_mine_1,          south,  worm_room,
      worm_room,            south,  salt_mine_3,
   ]

}

########################################
#  Things                              #
########################################

objects {

   # Items we can pick-up (Objects)

   ladder           : object  "a ladder"                                    start_at="hut" ;
   red_fish         : object  "a red fish"                                  start_at="road_3" ;
   short_sword      : object  "a short sword"                               start_at="top_of_tree" ;
   coin             : object  "a coin"                                      start_at="ornate_antechamber" ;
   string           : object  "some string"                                 start_at="salt_mine_2" ;
   salt             : object  "some salt"                                   start_at="salt_mine_3" ;
   oil              : object  "can of oil"                                  start_at="cold_room" ;
   excalibur        : object  "Excalibur!"                                  start_at="armoury" ;
   long_pole        : object  "a long pole" ;
   rungs            : object  "some rungs" ;
   stone_key        : object  "a stone key" ;
   axe              : object  "a wood cutters' axe" ;
   lamp             : object  "a lamp" ;

   # Things or people that we cannot pick up (Scenery)

   old_woman        : scenery "an old woman selling lamps"                  start_at="lamp_seller_on_road" ;
   logs             : scenery "a pile of logs"                              start_at="deep_inside_birwood" ;
   bush             : scenery "a bush"                                      start_at="birwood_bush" ;
   demon_knight     : scenery "a Demon Knight guarding the east road"  start_at="demon_knight_road" ;
   trapdoor         : scenery "an old trapdoor"                             start_at="drafty_room" ;
   smashed_trapdoor : scenery "a smashed trapdoor" ;
   rockworm         : scenery "a Rockworm, guarding the south tunnel"       start_at="worm_room" ;
   ice_creature     : scenery "an Ice creature, guarding the north exit"    start_at="cold_room" ;
   winch            : scenery "a winch"                                     start_at="winch_room" ;
   spell            : scenery "a spell flying at you from Crania"           start_at="most_splendid_room" ;
   asleep_arthur    : scenery "King Arthur (asleep)"                        start_at="arthur" ;

}

########################################
#  On Command                          #
########################################

on_command {

   : if ( is_present "ladder" ) {
      : match "examine ladder"  {
         : print "A LONG POLE WITH RUNGS ATTACHED." ;
      }
   }

}

5.10. Adding all the other EXAMINE actions

5.11. Examine

In text adventure games, objects are able to be examined.

To examine a sword we would type:

examine sword

It’s a way of delivering clues to the player, and sometimes to discover something hidden.

Here are the some messages that we wish to display when examining certain objects.

Table 1. Examine Handlers (Part 1 of 2)
match condition message

examine ladder

is_present "ladder"

A LONG POLE WITH RUNGS ATTACHED.

examine woman

is_present "old_woman"

SHE LOOKS AT YOU WITH AN INTENSE GLARE.

examine lamp

is_present "lamp"

IT’S OLD AND TARNISHED.

examine fish

is_present "red_fish"

IT STINKS!

examine sword

is_present "short_sword"

INSCRIBED UPON IT ARE THE WORDS 'GOOD LUCK!' ~~ MERLIN.

So, let’s now enter these new items.

The following code should be added to the bottom of the on_command{} section:

: match "examine woman"  {
  : if (is_present "old_woman") {
     : print "SHE LOOKS AT YOU WITH AN INTENSE GLARE." ;
  }
}
: match "examine lamp"  {
  : if (is_present "lamp") {
     : print "IT'S OLD AND TARNISHED." ;
  }
}
: match "examine fish"  {
  : if (is_present "red_fish") {
     : print "IT STINKS!" ;
  }
}
: match "examine sword"  {
  : if (is_present "short_sword") {
     : print "INSCRIBED UPON IT ARE THE WORDS 'GOOD LUCK' ~~ MERLIN." ;
  }
}

We will also modify the existing ladder handler to place the command matcher on the outside.

021

So far the only thing that we have done in response to a player entering some text (such as examine ladder or examine lamp), is to display some text to the player.

Sometimes we want to do something else.

Table 2. Examine Handlers (Part 2 of 2)
match condition message other actions

examine bush

is_present "bush"

YOU FIND SOMETHING!

Create the stone_key , wait for the user to press something, then redescribe the scene. * NOTE: This is slightly different behaviour to the original game.

examine logs

is_present "logs"

YOU FIND AN AXE!

Create the axe in the current location, wait for the user to press something, then redescribe the scene. * NOTE: This is slightly different behaviour to the original game.

Both the logs and the bush create a new object in the scene that the player is in when they are examined.

They also redescribe (refresh) the description of the scene so that the player can see the created objects. Hiding objects within a scene is quite normal in this type of adventure.

To be able to program this, we require 3 new commands, in addition to the ': print' command, which we have already used.

We also require 1 new condition.

Table 3. Commands So Far
Command Description

: print

Displays some text to the player

: create

Creates an object in the current scene (NEW)

: press_any_key

Tells the game to wait until the player either presses a key on the keyboard, or clicks the mouse, or touches the touchscreen. (NEW)

: redescribe

Tells the game to clear the screen, then to redescribe the current scene, including the contents of the scene. (NEW)

Table 4. Conditions So Far
Command Description

: is_present

Is an object carried or in the same scene as the player?

: has_not_created

Has the object not yet been created? (NEW)

5.11.1. AND statements (&&)

To create the logic for the last two examine messages, we also require an and statement.

An AND statement what we use to put together statements that must ALL BE TRUE in order to execute the part between the { } statements.

We use AND statements in English all the time to describe some requirements. Things like "if the weather is good and I have time this weekend, I will go to the park."

"We will go to the park only if the weather is good, AND we have time."

In Adventuron, an and is written using the && letters. Let’s see how this is used below by building our logic for "examine logs" and "examine bushes".

022

In the animation shown above, the bush code block is created, and after checking the "is_present" condition, the && operator is used to connect the two expressions that must be true.

The next condition that is added is has_not_created "stone_key".

   : match "examine bush"  {
      : if (is_present "bush" && has_not_created "stone_key") {
         : print "YOU FIND SOMETHING!" ;
         : create "stone_key" ;
         : press_any_key ;
         : redescribe ;
      }
   }

The purpose behind this condition is to make sure that we won’t KEEP generating keys every time the bush is examined.

Without this, every time we examine the bush, the message is displayed, and the key is regenerated.

Next in the animation, we create the message to display when the bush is examined (for the first time), then we add the "create" command to create the key (in the scene that the player is in), then we add the "press_any_key" command, and finally, the "redescribe" command.

We copy this block of code using copy and paste (as described earlier), and then modify the differences we need the logs.

We swap the stone_key for the axe, and the logs for the bush, and we have a different message to print, but the structure of the block is the same, so that’s why we copied and pasted.

It’s important not to type more than you need to type, so learning to copy and paste is a time saver.

There is actually a more elegant (easier) way to give objects examine messages and to check for existence of something, but we are sticking to the basic method in this tutorial.

Let’s Play

So, let’s play the game again to see what happens when we examine the bush and the logs.

023

The code so far …​.

########################################
#  Adventuron                          #
########################################

start_at      = hut

########################################
#  Locations                           #
########################################

locations {

   hut                    : location "You are in an old hut. Sunlight shines in from a doorway to the north.";
   road_1                 : location "You are standing on a track. The hut is south.";
   road_2                 : location "You are where the road turns eastwards. You see small hills in the distance.";
   road_3                 : location "You are on a road surrounded by grass. Trees can be seen on a hill in the distance.";
   road_4                 : location "You are on a dusty path on the edge of Birwood.";
   lamp_seller_on_road    : location "You are at a crossroads.";
   chasm                  : location "You are stood on the edge of a huge chasm (a cliff). A tightrope spans the gap, but it looks dangerous.";
   edge_of_birwood        : location "You are on the edge of Birwood. A rope spans the chasm northwards." ;
   deep_inside_birwood    : location "You are deep inside Birwood. The trees are alive with the buzzing of tiny insects.";
   birwood_bush           : location "You are standing in Birwood. A gap in the trees lets a warm light filter through.";
   demon_knight_road      : location "You are in a dip in the road by dark Birwood. Birds can be heard above.";
   foot_of_tree           : location "You are at the bottom of a large stone tree that is bare of any branches. The road ends here.";
   top_of_tree            : location "You are in a stone room set in a large stone tree.";
   castle_approach_1      : location "You are now a fair distance from Birwood. You can see castle Camelot to the east.";
   castle_approach_2      : location "You are outside Camelot Castle. A great stone door is the only way in.";
   castle_porch           : location "You are in the porch of Camelot.";
   banquet_hall           : location "You are in an abandoned banquet hall (eating area). Furniture lays broken on the floor.";
   drafty_room            : location "You are in a drafty room. Wind blows through gaps in the walls creating howling noises.";
   ornate_antechamber     : location "You are in an antechamber covered in thin ice that even covers the paintings.";
   portcullis             : location "You are in a room which has an iron portcullis set into the northern wall.";
   salt_mine_1            : location "You are in an old salt mine. Tunnels lead to the west and south.";
   salt_mine_2            : location "You are in the west part of the mine. It looks like it's been abandoned.";
   salt_mine_3            : location "You are at the end of the mine. You can hear the drip of water.";
   worm_room              : location "You are in the south part of the mine. There been recent movement in the rocks near your feet.";
   cold_room              : location "You are in a bitterly cold room. Everything is coated in a thick layer of ice.";
   winch_room             : location "You are in the winch room.";
   armoury                : location "You are in the armoury. Empty weapon racks line the walls.";
   most_splendid_room     : location "You are in the most splendid room in the castle. Rugs and paintings adorn the floor and walls.";
   arthur                 : location "You are in a sparse and lonely room. A cold wind enters through a high window.";

}

########################################
#  Connections                         #
########################################

connections {

   from, direction, to = [
      hut,                  north,  road_1,
      road_1,               north,  road_2,
      road_2,               east,   road_3,
      road_3,               east,   road_4,
      road_4,               north,  foot_of_tree,
      road_4,               south,  lamp_seller_on_road,
      lamp_seller_on_road,  east,   demon_knight_road,
      lamp_seller_on_road,  south,  chasm,
      foot_of_tree,         up,     top_of_tree,
      chasm,                south,  edge_of_birwood,
      edge_of_birwood,      south,  deep_inside_birwood,
      deep_inside_birwood,  west,   birwood_bush,
      demon_knight_road,    east,   castle_approach_1,
      castle_approach_1,    east,   castle_approach_2,
      castle_approach_2,    east,   castle_porch,
      castle_porch,         east,   banquet_hall,
      banquet_hall,         north,  portcullis,
      banquet_hall,         south,  drafty_room,
      portcullis,           north,  most_splendid_room,
      most_splendid_room,   west,   arthur,
      drafty_room,          east,   ornate_antechamber,
      drafty_room,          down,   salt_mine_1,
      ornate_antechamber,   east,   cold_room,
      cold_room,            north,  winch_room,
      winch_room,           east,   armoury,
      salt_mine_1,          west,   salt_mine_2,
      salt_mine_1,          south,  worm_room,
      worm_room,            south,  salt_mine_3,
   ]

}

########################################
#  Things                              #
########################################

objects {

   # Items we can pick-up (Objects)

   ladder           : object  "a ladder"                                    start_at="hut" ;
   red_fish         : object  "a red fish"                                  start_at="road_3" ;
   short_sword      : object  "a short sword"                               start_at="top_of_tree" ;
   coin             : object  "a coin"                                      start_at="ornate_antechamber" ;
   string           : object  "some string"                                 start_at="salt_mine_2" ;
   salt             : object  "some salt"                                   start_at="salt_mine_3" ;
   oil              : object  "can of oil"                                  start_at="cold_room" ;
   excalibur        : object  "Excalibur!"                                  start_at="armoury" ;
   long_pole        : object  "a long pole" ;
   rungs            : object  "some rungs" ;
   stone_key        : object  "a stone key" ;
   axe              : object  "a wood cutters' axe" ;
   lamp             : object  "a lamp" ;

   # Things or people that we cannot pick up (Scenery)

   old_woman        : scenery "an old woman selling lamps"                  start_at="lamp_seller_on_road" ;
   logs             : scenery "a pile of logs"                              start_at="deep_inside_birwood" ;
   bush             : scenery "a bush"                                      start_at="birwood_bush" ;
   demon_knight     : scenery "a Demon Knight guarding the east road"  start_at="demon_knight_road" ;
   trapdoor         : scenery "an old trapdoor"                             start_at="drafty_room" ;
   smashed_trapdoor : scenery "a smashed trapdoor" ;
   rockworm         : scenery "a Rockworm, guarding the south tunnel"       start_at="worm_room" ;
   ice_creature     : scenery "an Ice creature, guarding the north exit"    start_at="cold_room" ;
   winch            : scenery "a winch"                                     start_at="winch_room" ;
   spell            : scenery "a spell flying at you from Crania"           start_at="most_splendid_room" ;
   asleep_arthur    : scenery "King Arthur (asleep)"                        start_at="arthur" ;

}

########################################
#  On Command                          #
########################################

on_command {
   : match "examine ladder"  {
      : if ( is_present "ladder" ) {
         : print "A LONG POLE WITH RUNGS ATTACHED." ;
      }
   }
   : match "examine woman"  {
      : if (is_present "old_woman") {
         : print "SHE LOOKS AT YOU WITH AN INTENSE GLARE." ;
      }
   }
   : match "examine lamp"  {
      : if (is_present "lamp") {
         : print "IT'S OLD AND TARNISHED." ;
      }
   }
   : match "examine fish"  {
      : if (is_present "red_fish") {
         : print "IT STINKS!" ;
      }
   }
   : match "examine sword"  {
      : if (is_present "short_sword") {
         : print "INSCRIBED UPON IT ARE THE WORDS 'GOOD LUCK' ~~ MERLIN." ;
      }
   }
   : match "examine bush"  {
      : if (is_present "bush" && has_not_created "stone_key") {
         : print "YOU FIND SOMETHING!" ;
         : create "stone_key" ;
         : press_any_key ;
         : redescribe ;
      }
   }
   : match "examine logs"  {
      : if (is_present "logs" && has_not_created "axe") {
         : print "YOU FIND AN AXE!" ;
         : create "axe" ;
         : press_any_key ;
         : redescribe ;
      }
   }
}

6. Graphics

6.1. Adding Pictures (graphics)

6.1.1. Introducing Files

Do you remember at the beginning of this guide, that we saw pictures of the original version of Excalibur?

It had lots of bright colourful pictures.

excalzx hut
Figure 5. Excalibur (1987)
excalzx lady
Figure 6. Excalibur (1987)

These pictures are called graphics, and you can use graphics to make your adventure more fun and colourful.

Adventuron lets you add (also known as import) fun blocky graphics from files.

A file is a named thing on your computer, that you can access inside a folder. Files can contain all sorts of things, like words, or web pages, or music, or videos, or …​ graphics.

There are lots of different types of graphic files, but the type that Adventuron likes best is PNG.

A PNG file is a type of file that can hold old-style blocky graphics very nicely, but it can also store other types of picture too.

The most common type of graphic file type is JPEG, but this type of file can sometimes make blocky graphics blurry, so let’s use PNG instead.

6.1.2. How do you make a PNG file?

An upcoming version of Adventuron will also feature a basic graphics editor.

But, for the time being, on Windows, you might use Microsoft Paint, and when you save the file, make sure to select PNG.

paint

On OSX, there are many applications that will produce PNG files. Ask a parent or teacher to recommend one.

6.1.3. Zip Import

Adventuron can also import (add) many files at the same time, if they are inside another type of file called a ZIP file.

A zip file is available containing all the Excalibur graphics.

This file is made available for the purpose of following this tutorial only, and must not be redistributed.

These graphics should ONLY be used for following this tutorial and MUST NOT be used in any personal adventures you make yourself. Better to make your own graphics.

6.1.4. So, how do we import graphics?

Well, see the little button at the bottom of the editor window with "Menu", click that, and then select the "Import" option.

After clicking that, find the zip file you downloaded (it should be in the downloads folder on your computer), and then click "Open".

024

Getting the graphics from the zip "file" into the Adventuron is called importing. It can also be sometimes referred to as loading.

The graphics we just imported (or loaded) share the same identifiers as the scenes we have already entered.

Adventuron will automatically associate the graphics with the scenes, if they share the same identifiers, so now all the initial scene graphics are set up already.

When the import takes place, Adventuron converts the graphics into text. It’s not readable to human beings but the computer knows how to read this strange text.

assets base64

If it looks impossible to read, then don’t worry, it’s impossible to read for everyone.

This type of text is called base64 text, and it’s not important for humans to be able to read it - just understand that it makes sense to the computer.

All that’s important is the identifier part, and that the computer knows how to read it.

Later versions of Adventuron will hide this information.

Now that we importing the graphics, we should be able to take a walk around the game world, but this time, with graphics.

025

The code so far

########################################
#  Adventuron                          #
########################################

start_at      = hut

########################################
#  Locations                           #
########################################

locations {

   hut                    : location "You are in an old hut. Sunlight shines in from a doorway to the north.";
   road_1                 : location "You are standing on a track. The hut is south.";
   road_2                 : location "You are where the road turns eastwards. You see small hills in the distance.";
   road_3                 : location "You are on a road surrounded by grass. Trees can be seen on a hill in the distance.";
   road_4                 : location "You are on a dusty path on the edge of Birwood.";
   lamp_seller_on_road    : location "You are at a crossroads.";
   chasm                  : location "You are stood on the edge of a huge chasm (a cliff). A tightrope spans the gap, but it looks dangerous.";
   edge_of_birwood        : location "You are on the edge of Birwood. A rope spans the chasm northwards." ;
   deep_inside_birwood    : location "You are deep inside Birwood. The trees are alive with the buzzing of tiny insects.";
   birwood_bush           : location "You are standing in Birwood. A gap in the trees lets a warm light filter through.";
   demon_knight_road      : location "You are in a dip in the road by dark Birwood. Birds can be heard above.";
   foot_of_tree           : location "You are at the bottom of a large stone tree that is bare of any branches. The road ends here.";
   top_of_tree            : location "You are in a stone room set in a large stone tree.";
   castle_approach_1      : location "You are now a fair distance from Birwood. You can see castle Camelot to the east.";
   castle_approach_2      : location "You are outside Camelot Castle. A great stone door is the only way in.";
   castle_porch           : location "You are in the porch of Camelot.";
   banquet_hall           : location "You are in an abandoned banquet hall (eating area). Furniture lays broken on the floor.";
   drafty_room            : location "You are in a drafty room. Wind blows through gaps in the walls creating howling noises.";
   ornate_antechamber     : location "You are in an antechamber covered in thin ice that even covers the paintings.";
   portcullis             : location "You are in a room which has an iron portcullis set into the northern wall.";
   salt_mine_1            : location "You are in an old salt mine. Tunnels lead to the west and south.";
   salt_mine_2            : location "You are in the west part of the mine. It looks like it's been abandoned.";
   salt_mine_3            : location "You are at the end of the mine. You can hear the drip of water.";
   worm_room              : location "You are in the south part of the mine. There been recent movement in the rocks near your feet.";
   cold_room              : location "You are in a bitterly cold room. Everything is coated in a thick layer of ice.";
   winch_room             : location "You are in the winch room.";
   armoury                : location "You are in the armoury. Empty weapon racks line the walls.";
   most_splendid_room     : location "You are in the most splendid room in the castle. Rugs and paintings adorn the floor and walls.";
   arthur                 : location "You are in a sparse and lonely room. A cold wind enters through a high window.";

}

########################################
#  Connections                         #
########################################

connections {

   from, direction, to = [
      hut,                  north,  road_1,
      road_1,               north,  road_2,
      road_2,               east,   road_3,
      road_3,               east,   road_4,
      road_4,               north,  foot_of_tree,
      road_4,               south,  lamp_seller_on_road,
      lamp_seller_on_road,  east,   demon_knight_road,
      lamp_seller_on_road,  south,  chasm,
      foot_of_tree,         up,     top_of_tree,
      chasm,                south,  edge_of_birwood,
      edge_of_birwood,      south,  deep_inside_birwood,
      deep_inside_birwood,  west,   birwood_bush,
      demon_knight_road,    east,   castle_approach_1,
      castle_approach_1,    east,   castle_approach_2,
      castle_approach_2,    east,   castle_porch,
      castle_porch,         east,   banquet_hall,
      banquet_hall,         north,  portcullis,
      banquet_hall,         south,  drafty_room,
      portcullis,           north,  most_splendid_room,
      most_splendid_room,   west,   arthur,
      drafty_room,          east,   ornate_antechamber,
      drafty_room,          down,   salt_mine_1,
      ornate_antechamber,   east,   cold_room,
      cold_room,            north,  winch_room,
      winch_room,           east,   armoury,
      salt_mine_1,          west,   salt_mine_2,
      salt_mine_1,          south,  worm_room,
      worm_room,            south,  salt_mine_3,
   ]

}

########################################
#  Objects                             #
########################################

objects {

   # Items we can pick-up (Objects)

   ladder           : object  "a ladder"                                    start_at="hut" ;
   red_fish         : object  "a red fish"                                  start_at="road_3" ;
   short_sword      : object  "a short sword"                               start_at="top_of_tree" ;
   coin             : object  "a coin"                                      start_at="ornate_antechamber" ;
   string           : object  "some string"                                 start_at="salt_mine_2" ;
   salt             : object  "some salt"                                   start_at="salt_mine_3" ;
   oil              : object  "can of oil"                                  start_at="cold_room" ;
   excalibur        : object  "Excalibur!"                                  start_at="armoury" ;
   long_pole        : object  "a long pole" ;
   rungs            : object  "some rungs" ;
   stone_key        : object  "a stone key" ;
   axe              : object  "a wood cutters' axe" ;
   lamp             : object  "a lamp" ;

   # Things or people that we cannot pick up (Scenery)

   old_woman        : scenery "an old woman selling lamps"                  start_at="lamp_seller_on_road" ;
   logs             : scenery "a pile of logs"                              start_at="deep_inside_birwood" ;
   bush             : scenery "a bush"                                      start_at="birwood_bush" ;
   demon_knight     : scenery "a Demon Knight guarding the east road"  start_at="demon_knight_road" ;
   trapdoor         : scenery "an old trapdoor"                             start_at="drafty_room" ;
   smashed_trapdoor : scenery "a smashed trapdoor" ;
   rockworm         : scenery "a Rockworm, guarding the south tunnel"       start_at="worm_room" ;
   ice_creature     : scenery "an Ice creature, guarding the north exit"    start_at="cold_room" ;
   winch            : scenery "a winch"                                     start_at="winch_room" ;
   spell            : scenery "a spell flying at you from Crania"           start_at="most_splendid_room" ;
   asleep_arthur    : scenery "King Arthur (asleep)"                        start_at="arthur" ;

}

########################################
#  On Command                          #
########################################

on_command {
   : match "examine ladder"  {
      : if ( is_present "ladder" ) {
         : print "A LONG POLE WITH RUNGS ATTACHED." ;
      }
   }
   : match "examine woman"  {
      : if (is_present "old_woman") {
         : print "SHE LOOKS AT YOU WITH AN INTENSE GLARE." ;
      }
   }
   : match "examine lamp"  {
      : if (is_present "lamp") {
         : print "IT'S OLD AND TARNISHED." ;
      }
   }
   : match "examine fish"  {
      : if (is_present "red_fish") {
         : print "IT STINKS!" ;
      }
   }
   : match "examine sword"  {
      : if (is_present "short_sword") {
         : print "INSCRIBED UPON IT ARE THE WORDS 'GOOD LUCK' ~~ MERLIN." ;
      }
   }
   : match "examine bush"  {
      : if (is_present "bush" && has_not_created "stone_key") {
         : print "YOU FIND SOMETHING!" ;
         : create "stone_key" ;
         : press_any_key ;
         : redescribe ;
      }
   }
   : match "examine logs"  {
      : if (is_present "logs" && has_not_created "axe") {
         : print "YOU FIND AN AXE!" ;
         : create "axe" ;
         : press_any_key ;
         : redescribe ;
      }
   }
}

// Placeholders used for documentation purposes only as graphic data is too large to place in document.
assets {
   graphics {
      armoury               : placeholder ;
      arthur                : placeholder ;
      banquet_hall          : placeholder ;
      birwood_bush          : placeholder ;
      castle_approach_1     : placeholder ;
      castle_approach_2     : placeholder ;
      castle_approach_2a    : placeholder ;
      castle_porch          : placeholder ;
      chasm                 : placeholder ;
      cold_room             : placeholder ;
      cold_room_2           : placeholder ;
      deep_inside_birwood   : placeholder ;
      demon_knight_road     : placeholder ;
      demon_knight_road_2   : placeholder ;
      drafty_room           : placeholder ;
      drafty_room_2         : placeholder ;
      edge_of_birwood       : placeholder ;
      ending_screen         : placeholder ;
      excalibur_loading     : placeholder ;
      foot_of_tree          : placeholder ;
      foot_of_tree_2        : placeholder ;
      game_over             : placeholder ;
      hut                   : placeholder ;
      lamp_seller_on_road   : placeholder ;
      lamp_seller_on_road_2 : placeholder ;
      most_splendid_room    : placeholder ;
      most_splendid_room_2  : placeholder ;
      ornate_antechamber    : placeholder ;
      portcullis            : placeholder ;
      portcullis_2          : placeholder ;
      road_1                : placeholder ;
      road_2                : placeholder ;
      road_3                : placeholder ;
      road_4                : placeholder ;
      salt_mine_1           : placeholder ;
      salt_mine_2           : placeholder ;
      salt_mine_3           : placeholder ;
      top_of_tree           : placeholder ;
      winch_room            : placeholder ;
      worm_room             : placeholder ;
      worm_room_2           : placeholder ;
   }
}

7. Implementing Puzzles

7.1. Blocking The Top Of The Tree

foot of tree

At this point in the tutorial, the player has complete freedom to go everywhere, and there are no puzzles.

It is common in this type of game, for areas of the map to be blocked.

Blocking means restricting access to a location or an area of the map (until a puzzle is solved or action is performed).

The first block we will create is blocking access to the top of the tree.

Currently, there is no barrier to going from the bottom of the tree to the top of the tree.

The first puzzle in the game is climbing the stone tree. There are no branches on the tree, so it cannot be climbed.

Even though we have created an entry in the connections section, describing that the bottom of the tree leads up to the top of the tree, after creating the BLOCK, typing up should not allow the player to go UP to the location "top of tree" unless the ladder is rested against the tree.

7.2. Boolean Variables

But before we get to blocks, we need to create a boolean variable.

A boolean variable is a container for a yes or no answer.

Imagine it like an envelope, and inside the envelope there can only be written "yes" or "no".

In most computer languages, YES is the same as TRUE, and NO is the same as FALSE.

  • YES = TRUE

  • NO = FALSE

So, now, we will create an envelope that contains the answer to the question:

is the ladder standing against the tree?

  • yes or no (true or false)

The ladder starts in the hut, so the answer to the question at the start of the game is no (or false).

We will store this fact inside the boolean variable 'is_ladder_standing'. We could call the variable 'is_the_ladder_standing_against_the_tree' but keeping variable names as short as possible makes it faster to code.

Variables are convenient because it lets the game author keep track of when the player has done things in the game.

Never be tempted to make variable names TOO SHORT, because you need to understand what they mean.

We can create the boolean variable like this by pressing CONTROL + SPACE, on a blank line when not in another section (just above on_command {} is good), then typing the name

new 001

Type it yourself, or copy and paste it from here:

booleans {
   is_ladder_standing : boolean "false";
}

7.3. Standing the ladder against the tree

Next we want to be able to change the VALUE of the boolean variable.

Remember, 'is_ladder_standing', now contains a false (no) answer, but if the player goes to the tree, holding the ladder, and type LEAN LADDER or STAND LADDER or REST LADDER or DROP LADDER then we should put a true (or yes) value in this variable (or envelope).

on_command {}
: match "stand ladder;lean ladder;rest ladder;drop ladder"  {
  : if (is_carried "ladder" && is_at "foot_of_tree") {
     : drop ;
     : set_true "is_ladder_standing" ;
     : set_graphic graphic = "foot_of_tree_2"  target = "foot_of_tree" ;
     : redescribe;
  }
}

The code show above does the following.

  1. It checks that the player typed stand ladder or lean ladder or rest ladder or drop ladder. If the player didn’t type one of these things, then we don’t execute any further step.

  2. Next it checks that the player is carrying the ladder, and that the player is currently at the foot of the tree location. If the players isn’t carrying the ladder or isn’t at the foot of the tree, then we don’t execute any further step.

  3. It drops the object currently being reference (in this case ladder).

  4. It puts a true (or yes) value into the is_ladder_standing variable.

  5. It changes the graphic for the current scene to the 2nd version (a version showing the ladder).

  6. It redescribes the current location (forcing the graphic and text to be refreshed).

7.4. Taking the ladder from the tree

on_command {}
: match "get ladder"  {
  : if (is_at "foot_of_tree" && is_beside "ladder") {
     : get ;
     : set_false "is_ladder_standing" ;
     : set_graphic graphic = "foot_of_tree" target  = "foot_of_tree" ;
     : redescribe ;
  }
}

The code show above does the following.

  1. It checks that the player typed "get ladder". If the player didn’t type it, then we don’t execute any further step.

  2. Next it checks that the player is beside (but not carrying) the ladder, and that the player is currently at the foot of the tree location. If the players isn’t beside the ladder or isn’t at the foot of the tree, then we don’t execute any further step.

  3. It gets the object currently being reference (in this case ladder).

  4. It puts a false (or yes) value into the is_ladder_standing variable.

  5. It changes the graphic for the current scene to the 1st version (a version not showing the stood ladder).

  6. It redescribes the current location (forcing the graphic and text to be refreshed).

7.5. Progress Report

Now we have code that will change the location graphic and change the VALUE of the 'is_ladder_standing' boolean variable when the ladder is stood against the tree, and when it is taken from the tree location.

new 002

Although we have code now to record if the ladder is standing or not, it doesn’t prevent us from going UP the tree when the ladder is not stood against the tree. Also, the UP direction is still listed even when the ladder is not standing against the tree.

For real immersion, we want to remove the UP direction from the exit lists if the ladder is not standing against the tree.

We can achieve both of these goals (remove up exit, and block access up) by using a barrier.

7.6. Introducing Barriers

A barrier (in Adventuron) is something that stops you from going somewhere and is contained in a section called barriers {}.

There are many types of barrier, but the one we will use for the tree puzzle is a block.

A block prevents acess to a location via regular direction commands (north, south, east, west, up, down, …​).

As standard, if the block is active then the block will also remove the direction from list of available directions. This lets the player know that the direction is not available. Sometimes we do want to list the location of a blocked exit anyway, and we will explore this option later.

A regular block requires the following:

  • A location identifier to block

  • A message to display (or a subroutine to execute).

  • An activation condition.

The activation condition which tells the block when it should be active, or inactive.

In this case, we will look at the is_ladder_standing variable.

barriers{}
tree : block {
  location          = top_of_tree
  message           = YOU CAN'T FIND YOUR GRIP
  block_when_not    = is_ladder_standing
  show_blocked_exit = false
}

The code shown above tells Adventuron to block the top_of_tree location, but only when is_ladder_standing contains a false (no) value/answer.

Adventuron takes care of removing the listing of an exit when a block is encountered, so if the ladder is not stood at the bottom of the tree, the "UP" exit will not be shown.

If the player types UP by themselves, they see the message "YOU CAN’T FIND YOUR GRIP" but they do not travel to the top of the tree.

7.6.1. Testing the block

If we click the PLAY icon at the top of the screen, and play the game now. We can navigate to the bottom of the tree (N, N, E, E, N), and we can now see that UP is not listed as an exit.

If we type UP, we are show the message "YOU CAN’T FIND YOUR GRIP".

We have successfully BLOCKED access to the top of the tree.

029

7.7. The code so far …​..

########################################
#  Adventuron                          #
########################################

start_at       = hut

########################################
#  Locations                           #
########################################

locations {

   hut                    : location "You are in an old hut. Sunlight shines in from a doorway to the north.";
   road_1                 : location "You are standing on a track. The hut is south.";
   road_2                 : location "You are where the road turns eastwards. You see small hills in the distance.";
   road_3                 : location "You are on a road surrounded by grass. Trees can be seen on a hill in the distance.";
   road_4                 : location "You are on a dusty path on the edge of Birwood.";
   lamp_seller_on_road    : location "You are at a crossroads.";
   chasm                  : location "You are stood on the edge of a huge chasm (a cliff). A tightrope spans the gap, but it looks dangerous.";
   edge_of_birwood        : location "You are on the edge of Birwood. A rope spans the chasm northwards." ;
   deep_inside_birwood    : location "You are deep inside Birwood. The trees are alive with the buzzing of tiny insects.";
   birwood_bush           : location "You are standing in Birwood. A gap in the trees lets a warm light filter through.";
   demon_knight_road      : location "You are in a dip in the road by dark Birwood. Birds can be heard above.";
   foot_of_tree           : location "You are at the bottom of a large stone tree that is bare of any branches. The road ends here.";
   top_of_tree            : location "You are in a stone room set in a large stone tree.";
   castle_approach_1      : location "You are now a fair distance from Birwood. You can see castle Camelot to the east.";
   castle_approach_2      : location "You are outside Camelot Castle. A great stone door is the only way in.";
   castle_porch           : location "You are in the porch of Camelot.";
   banquet_hall           : location "You are in an abandoned banquet hall (eating area). Furniture lays broken on the floor.";
   drafty_room            : location "You are in a drafty room. Wind blows through gaps in the walls creating howling noises.";
   ornate_antechamber     : location "You are in an antechamber covered in thin ice that even covers the paintings.";
   portcullis             : location "You are in a room which has an iron portcullis set into the northern wall.";
   salt_mine_1            : location "You are in an old salt mine. Tunnels lead to the west and south.";
   salt_mine_2            : location "You are in the west part of the mine. It looks like it's been abandoned.";
   salt_mine_3            : location "You are at the end of the mine. You can hear the drip of water.";
   worm_room              : location "You are in the south part of the mine. There been recent movement in the rocks near your feet.";
   cold_room              : location "You are in a bitterly cold room. Everything is coated in a thick layer of ice.";
   winch_room             : location "You are in the winch room.";
   armoury                : location "You are in the armoury. Empty weapon racks line the walls.";
   most_splendid_room     : location "You are in the most splendid room in the castle. Rugs and paintings adorn the floor and walls.";
   arthur                 : location "You are in a sparse and lonely room. A cold wind enters through a high window.";

}

########################################
#  Connections                         #
########################################

connections {

   from, direction, to = [
      hut,                  north,  road_1,
      road_1,               north,  road_2,
      road_2,               east,   road_3,
      road_3,               east,   road_4,
      road_4,               north,  foot_of_tree,
      road_4,               south,  lamp_seller_on_road,
      lamp_seller_on_road,  east,   demon_knight_road,
      lamp_seller_on_road,  south,  chasm,
      foot_of_tree,         up,     top_of_tree,
      chasm,                south,  edge_of_birwood,
      edge_of_birwood,      south,  deep_inside_birwood,
      deep_inside_birwood,  west,   birwood_bush,
      demon_knight_road,    east,   castle_approach_1,
      castle_approach_1,    east,   castle_approach_2,
      castle_approach_2,    east,   castle_porch,
      castle_porch,         east,   banquet_hall,
      banquet_hall,         north,  portcullis,
      banquet_hall,         south,  drafty_room,
      portcullis,           north,  most_splendid_room,
      most_splendid_room,   west,   arthur,
      drafty_room,          east,   ornate_antechamber,
      drafty_room,          down,   salt_mine_1,
      ornate_antechamber,   east,   cold_room,
      cold_room,            north,  winch_room,
      winch_room,           east,   armoury,
      salt_mine_1,          west,   salt_mine_2,
      salt_mine_1,          south,  worm_room,
      worm_room,            south,  salt_mine_3,
   ]

}

########################################
#  Objects                             #
########################################

objects {

   # Items we can pick-up (Objects)

   ladder           : object  "a ladder"                                    start_at="hut" ;
   red_fish         : object  "a red fish"                                  start_at="road_3" ;
   short_sword      : object  "a short sword"                               start_at="top_of_tree" ;
   coin             : object  "a coin"                                      start_at="ornate_antechamber" ;
   string           : object  "some string"                                 start_at="salt_mine_2" ;
   salt             : object  "some salt"                                   start_at="salt_mine_3" ;
   oil              : object  "can of oil"                                  start_at="cold_room" ;
   excalibur        : object  "Excalibur!"                                  start_at="armoury" ;
   long_pole        : object  "a long pole" ;
   rungs            : object  "some rungs" ;
   stone_key        : object  "a stone key" ;
   axe              : object  "a wood cutters' axe" ;
   lamp             : object  "a lamp" ;

   # Things or people that we cannot pick up (Scenery)

   old_woman        : scenery "an old woman selling lamps"                  start_at="lamp_seller_on_road" ;
   logs             : scenery "a pile of logs"                              start_at="deep_inside_birwood" ;
   bush             : scenery "a bush"                                      start_at="birwood_bush" ;
   demon_knight     : scenery "a Demon Knight guarding the east road"  start_at="demon_knight_road" ;
   trapdoor         : scenery "an old trapdoor"                             start_at="drafty_room" ;
   smashed_trapdoor : scenery "a smashed trapdoor" ;
   rockworm         : scenery "a Rockworm, guarding the south tunnel"       start_at="worm_room" ;
   ice_creature     : scenery "an Ice creature, guarding the north exit"    start_at="cold_room" ;
   winch            : scenery "a winch"                                     start_at="winch_room" ;
   spell            : scenery "a spell flying at you from Crania"           start_at="most_splendid_room" ;
   asleep_arthur    : scenery "King Arthur (asleep)"                        start_at="arthur" ;

}

########################################
#  Booleans                            #
########################################

booleans {
   is_ladder_standing : boolean "false";
}

########################################
#  Blocks                              #
########################################

barriers {
   tree : block {
      location          = top_of_tree
      message           = YOU CAN'T FIND YOUR GRIP
      block_when_not    = is_ladder_standing
      show_blocked_exit = false
   }
}

########################################
#  On Command                          #
########################################

on_command {
   : match "examine ladder"  {
      : if ( is_present "ladder" ) {
         : print "A LONG POLE WITH RUNGS ATTACHED." ;
      }
   }
   : match "examine woman"  {
      : if (is_present "old_woman") {
         : print "SHE LOOKS AT YOU WITH AN INTENSE GLARE." ;
      }
   }
   : match "examine lamp"  {
      : if (is_present "lamp") {
         : print "IT'S OLD AND TARNISHED." ;
      }
   }
   : match "examine fish"  {
      : if (is_present "red_fish") {
         : print "IT STINKS!" ;
      }
   }
   : match "examine sword"  {
      : if (is_present "short_sword") {
         : print "INSCRIBED UPON IT ARE THE WORDS 'GOOD LUCK' ~~ MERLIN." ;
      }
   }
   : match "examine bush"  {
      : if (is_present "bush" && has_not_created "stone_key") {
         : print "YOU FIND SOMETHING!" ;
         : create "stone_key" ;
         : press_any_key ;
         : redescribe ;
      }
   }
   : match "examine logs"  {
      : if (is_present "logs" && has_not_created "axe") {
         : print "YOU FIND AN AXE!" ;
         : create "axe" ;
         : press_any_key ;
         : redescribe ;
      }
   }

   : match "get ladder"  {
      : if (is_at "foot_of_tree" && is_beside "ladder") {
         : get ;
         : set_false "is_ladder_standing" ;
         : set_graphic target = "foot_of_tree" graphic = "foot_of_tree"  ;
         : redescribe ;
      }
   }

   : match "stand ladder;lean ladder;rest ladder"  {
      : if (is_carried "ladder" && is_at "foot_of_tree") {
         : drop ;
         : set_true "is_ladder_standing" ;
         : set_graphic target = "foot_of_tree" graphic = "foot_of_tree_2"  ;
         : redescribe;
      }
   }

}

// Placeholders used for documentation purposes only as graphic data is too large to place in document.
assets {
   graphics {
      armoury               : placeholder ;
      arthur                : placeholder ;
      banquet_hall          : placeholder ;
      birwood_bush          : placeholder ;
      castle_approach_1     : placeholder ;
      castle_approach_2     : placeholder ;
      castle_approach_2a    : placeholder ;
      castle_porch          : placeholder ;
      chasm                 : placeholder ;
      cold_room             : placeholder ;
      cold_room_2           : placeholder ;
      deep_inside_birwood   : placeholder ;
      demon_knight_road     : placeholder ;
      demon_knight_road_2   : placeholder ;
      drafty_room           : placeholder ;
      drafty_room_2         : placeholder ;
      edge_of_birwood       : placeholder ;
      ending_screen         : placeholder ;
      excalibur_loading     : placeholder ;
      foot_of_tree          : placeholder ;
      foot_of_tree_2        : placeholder ;
      game_over             : placeholder ;
      hut                   : placeholder ;
      lamp_seller_on_road   : placeholder ;
      lamp_seller_on_road_2 : placeholder ;
      most_splendid_room    : placeholder ;
      most_splendid_room_2  : placeholder ;
      ornate_antechamber    : placeholder ;
      portcullis            : placeholder ;
      portcullis_2          : placeholder ;
      road_1                : placeholder ;
      road_2                : placeholder ;
      road_3                : placeholder ;
      road_4                : placeholder ;
      salt_mine_1           : placeholder ;
      salt_mine_2           : placeholder ;
      salt_mine_3           : placeholder ;
      top_of_tree           : placeholder ;
      winch_room            : placeholder ;
      worm_room             : placeholder ;
      worm_room_2           : placeholder ;
   }
}

7.8. Fighting the Knight

demon knight road

We are going to now code the first danger of the game.

The Demon Knight stands in the path on the way to Camelot. Currently, we can just walk past the knight, because we haven’t added any logic.

If we try to attack the knight without a weapon, then the knight will defeat us in battle, and the game will end.

If we try to walk past the knight, then the knight will strike us, and the game will end.

The way to defeat the knight is to attack the knight whilst carrying the short sword (which was obtained from the room at the top of the tree, which itself required the ladder puzzle to be solved).

So our logic is:

  1. If in same location as knight, and issuing the 'east' command, then describe defeat, and end game.

  2. If in the same location as the knight, and typing 'attack knight', or 'fight knight', and not holding short sword, then describe defeat, and end game.

  3. If in the same location as the knight, and typing 'attack knight', or 'fight knight', and holding short sword, then describe victory, and remove the knight from the game.

This puzzle will use a different kind of block.

A subroutine block is a block that executes a subroutine instead of moving to the blocked location.

Our First Subroutine Block (Added in barriers{} section)
knight : block {
  location          = castle_approach_1
  gosub             = lose_fight
  block_when_exists = demon_knight
  show_blocked_exit = true
}

The 'show_blocked_exit' option is something that can be added to a block to tell adventuron to show the blocked exit in the exits list.

In this puzzle, we want to show the exit 'east' even though moving in that direction will end the game.

As standard, if there is an active block, then the exit will not be listed until the block is removed or made inactive.

7.8.1. Subroutines

A subroutine is section of code that can be referenced from some other part of the code.

The advantage of using subroutines is that sometimes the same functionality needs to be used multiple times, and it makes it easy to write code that does one thing, in one place, rather than copying and pasting it in multiple places.

The code inside a subroutine can be referenced in various parts of Adventuron, and once the code is finished executing, it returns to the place in the code from where it was referenced (unless the subroutine ends the game).

We will place the battle logic in three subroutines.

Subroutine Id Description When Referenced

lose_fight

The subroutine will print the message "THE KNIGHT WIELDS HIS SWORD DEFTLY AND ATTACKS YOU…​." then it will execute the "end_game" subroutine.

If we try to move into the blocked location beyond the knight or if we attempt to attack the knight without the short sword, then the lose_fight subroutine is executed.

win_fight

This subroutine prints the message "A GREAT BATTLE ENSUES IN WHICH YOU ARE VICTORIOUS. BEFORE YOUR EYES THE KNIGHT TURNS TO DUST ALONG WITH YOUR SWORD!", then the short sword is removed from the game, the knight is removed from the game, the graphic for the location with the knight is changed to remove the knight, and the block of the castle_approach_1 location is removed.

This subroutine is executed if we fight the knight whilst holding the short sword.

end_game

Waits for the user to press a button, then clears the current screen, then shows the "game_over" graphic, then prints the message, "Your quest is over …​…​…​.", then prints the number of turns, and signals to Adventuron to end the game (game over).

The subroutine is executed when the game is lost. It is referenced from the "lose_fight" subroutine, but it will also be referenced by other parts of the game later on.

Subroutines
########################################
#  Subroutines                         #
########################################

subroutines {

   // This subroutine is executed if we lose a fight with the knight
   lose_fight : subroutine {
      // Have to explicitly attack the knight, even if you have the sword.
      : print "THE KNIGHT WIELDS HIS SWORD DEFTLY AND ATTACKS YOU...." ;
      : gosub "end_game" ;
   }

   // This subroutine is executed if we win a fight with the knight.
   win_fight : subroutine {
      : print "A GREAT BATTLE ENSUES IN WHICH YOU ARE VICTORIOUS. THE KNIGHT TURNS TO DUST BEFORE YOUR EYES ALONG WITH YOUR SWORD!" ;
      : press_any_key ;
      : destroy "demon_knight" ;
      : destroy "short_sword" ;
      : set_graphic graphic = "demon_knight_road_2" target = "demon_knight_road" ;
      : redescribe ;
   }

   end_game : subroutine {
      : press_any_key ;
      : clear_screen;
      : print_graphic "game_over" ;
      : print "Your quest is over .........." ;
      : turns ;
      : end_game ;
   }
}

To initiate fighting the knight, then the command "fight knight" or "attack knight" or "challenge knight" should be typed.

on_command {} code
: match "fight knight;attack knight;challenge knight"  {
  : if (is_present "demon_knight") {
     : if (is_carried "short_sword") {
        : gosub "win_fight" ;
     }
     : else {
        : gosub "lose_fight" ;
     }
  }
}

7.8.2. Else Statements

In the previous block, we see the used of an 'else' statement. An else statement is a block or code that will only be executed if and 'if' statement that appears above it, has a condition that is not 'true'.

An else statement can only be used after an 'if' statement or an 'else_if' statement (described later).

7.8.3. The code so far

########################################
#  Adventuron                          #
########################################

start_at       = hut

########################################
#  Locations                           #
########################################

locations {

   hut                    : location "You are in an old hut. Sunlight shines in from a doorway to the north.";
   road_1                 : location "You are standing on a track. The hut is south.";
   road_2                 : location "You are where the road turns eastwards. You see small hills in the distance.";
   road_3                 : location "You are on a road surrounded by grass. Trees can be seen on a hill in the distance.";
   road_4                 : location "You are on a dusty path on the edge of Birwood.";
   lamp_seller_on_road    : location "You are at a crossroads.";
   chasm                  : location "You are stood on the edge of a huge chasm (a cliff). A tightrope spans the gap, but it looks dangerous.";
   edge_of_birwood        : location "You are on the edge of Birwood. A rope spans the chasm northwards." ;
   deep_inside_birwood    : location "You are deep inside Birwood. The trees are alive with the buzzing of tiny insects.";
   birwood_bush           : location "You are standing in Birwood. A gap in the trees lets a warm light filter through.";
   demon_knight_road      : location "You are in a dip in the road by dark Birwood. Birds can be heard above.";
   foot_of_tree           : location "You are at the bottom of a large stone tree that is bare of any branches. The road ends here.";
   top_of_tree            : location "You are in a stone room set in a large stone tree.";
   castle_approach_1      : location "You are now a fair distance from Birwood. You can see castle Camelot to the east.";
   castle_approach_2      : location "You are outside Camelot Castle. A great stone door is the only way in.";
   castle_porch           : location "You are in the porch of Camelot.";
   banquet_hall           : location "You are in an abandoned banquet hall (eating area). Furniture lays broken on the floor.";
   drafty_room            : location "You are in a drafty room. Wind blows through gaps in the walls creating howling noises.";
   ornate_antechamber     : location "You are in an antechamber covered in thin ice that even covers the paintings.";
   portcullis             : location "You are in a room which has an iron portcullis set into the northern wall.";
   salt_mine_1            : location "You are in an old salt mine. Tunnels lead to the west and south.";
   salt_mine_2            : location "You are in the west part of the mine. It looks like it's been abandoned.";
   salt_mine_3            : location "You are at the end of the mine. You can hear the drip of water.";
   worm_room              : location "You are in the south part of the mine. There been recent movement in the rocks near your feet.";
   cold_room              : location "You are in a bitterly cold room. Everything is coated in a thick layer of ice.";
   winch_room             : location "You are in the winch room.";
   armoury                : location "You are in the armoury. Empty weapon racks line the walls.";
   most_splendid_room     : location "You are in the most splendid room in the castle. Rugs and paintings adorn the floor and walls.";
   arthur                 : location "You are in a sparse and lonely room. A cold wind enters through a high window.";

}

########################################
#  Connections                         #
########################################

connections {

   from, direction, to = [
      hut,                  north,  road_1,
      road_1,               north,  road_2,
      road_2,               east,   road_3,
      road_3,               east,   road_4,
      road_4,               north,  foot_of_tree,
      road_4,               south,  lamp_seller_on_road,
      lamp_seller_on_road,  east,   demon_knight_road,
      lamp_seller_on_road,  south,  chasm,
      foot_of_tree,         up,     top_of_tree,
      chasm,                south,  edge_of_birwood,
      edge_of_birwood,      south,  deep_inside_birwood,
      deep_inside_birwood,  west,   birwood_bush,
      demon_knight_road,    east,   castle_approach_1,
      castle_approach_1,    east,   castle_approach_2,
      castle_approach_2,    east,   castle_porch,
      castle_porch,         east,   banquet_hall,
      banquet_hall,         north,  portcullis,
      banquet_hall,         south,  drafty_room,
      portcullis,           north,  most_splendid_room,
      most_splendid_room,   west,   arthur,
      drafty_room,          east,   ornate_antechamber,
      drafty_room,          down,   salt_mine_1,
      ornate_antechamber,   east,   cold_room,
      cold_room,            north,  winch_room,
      winch_room,           east,   armoury,
      salt_mine_1,          west,   salt_mine_2,
      salt_mine_1,          south,  worm_room,
      worm_room,            south,  salt_mine_3,
   ]

}

########################################
#  Objects                             #
########################################

objects {

   # Items we can pick-up (Objects)

   ladder           : object  "a ladder"                                    start_at="hut" ;
   red_fish         : object  "a red fish"                                  start_at="road_3" ;
   short_sword      : object  "a short sword"                               start_at="top_of_tree" ;
   coin             : object  "a coin"                                      start_at="ornate_antechamber" ;
   string           : object  "some string"                                 start_at="salt_mine_2" ;
   salt             : object  "some salt"                                   start_at="salt_mine_3" ;
   oil              : object  "can of oil"                                  start_at="cold_room" ;
   excalibur        : object  "Excalibur!"                                  start_at="armoury" ;
   long_pole        : object  "a long pole" ;
   rungs            : object  "some rungs" ;
   stone_key        : object  "a stone key" ;
   axe              : object  "a wood cutters' axe" ;
   lamp             : object  "a lamp" ;

   # Things or people that we cannot pick up (Scenery)

   old_woman        : scenery "an old woman selling lamps"                  start_at="lamp_seller_on_road" ;
   logs             : scenery "a pile of logs"                              start_at="deep_inside_birwood" ;
   bush             : scenery "a bush"                                      start_at="birwood_bush" ;
   demon_knight     : scenery "a Demon Knight guarding the east road"  start_at="demon_knight_road" ;
   trapdoor         : scenery "an old trapdoor"                             start_at="drafty_room" ;
   smashed_trapdoor : scenery "a smashed trapdoor" ;
   rockworm         : scenery "a Rockworm, guarding the south tunnel"       start_at="worm_room" ;
   ice_creature     : scenery "an Ice creature, guarding the north exit"    start_at="cold_room" ;
   winch            : scenery "a winch"                                     start_at="winch_room" ;
   spell            : scenery "a spell flying at you from Crania"           start_at="most_splendid_room" ;
   asleep_arthur    : scenery "King Arthur (asleep)"                        start_at="arthur" ;

}

########################################
#  Booleans                            #
########################################

booleans {
   is_ladder_standing : boolean "false";
}

########################################
#  Blocks                              #
########################################

barriers {
   tree : block {
      location          = top_of_tree
      message           = YOU CAN'T FIND YOUR GRIP
      block_when_not    = is_ladder_standing
      show_blocked_exit = false
   }

   knight : block {
      location          = castle_approach_1
      gosub             = lose_fight
      block_when_exists = demon_knight
      show_blocked_exit = true
   }
}

########################################
#  On Command                          #
########################################

on_command {
   : match "examine ladder"  {
      : if ( is_present "ladder" ) {
         : print "A LONG POLE WITH RUNGS ATTACHED." ;
      }
   }
   : match "examine woman"  {
      : if (is_present "old_woman") {
         : print "SHE LOOKS AT YOU WITH AN INTENSE GLARE." ;
      }
   }
   : match "examine lamp"  {
      : if (is_present "lamp") {
         : print "IT'S OLD AND TARNISHED." ;
      }
   }
   : match "examine fish"  {
      : if (is_present "red_fish") {
         : print "IT STINKS!" ;
      }
   }
   : match "examine sword"  {
      : if (is_present "short_sword") {
         : print "INSCRIBED UPON IT ARE THE WORDS 'GOOD LUCK' ~~ MERLIN." ;
      }
   }
   : match "examine bush"  {
      : if (is_present "bush" && has_not_created "stone_key") {
         : print "YOU FIND SOMETHING!" ;
         : create "stone_key" ;
         : press_any_key ;
         : redescribe ;
      }
   }
   : match "examine logs"  {
      : if (is_present "logs" && has_not_created "axe") {
         : print "YOU FIND AN AXE!" ;
         : create "axe" ;
         : press_any_key ;
         : redescribe ;
      }
   }

   : match "get ladder"  {
      : if (is_at "foot_of_tree" && is_beside "ladder") {
         : get ;
         : set_false "is_ladder_standing" ;
         : set_graphic target = "foot_of_tree" graphic = "foot_of_tree"  ;
         : redescribe ;
      }
   }

   : match "stand ladder;lean ladder;rest ladder"  {
      : if (is_carried "ladder" && is_at "foot_of_tree") {
         : drop ;
         : set_true "is_ladder_standing" ;
         : set_graphic target = "foot_of_tree" graphic = "foot_of_tree_2"  ;
         : redescribe;
      }
   }

    : match "fight knight;attack knight;challenge knight"  {
      : if (is_present "demon_knight") {
         : if (is_carried "short_sword") {
            : gosub "win_fight" ;
         }
         : else {
            : gosub "lose_fight" ;
         }
      }
    }


}


########################################
#  Subroutines                         #
########################################

subroutines {

   // This subroutine is executed if we lose a fight with the knight
   lose_fight : subroutine {
      // Have to explicitly attack the knight, even if you have the sword.
      : print "THE KNIGHT WIELDS HIS SWORD DEFTLY AND ATTACKS YOU...." ;
      : gosub "end_game" ;
   }

   // This subroutine is executed if we win a fight with the knight.
   win_fight : subroutine {
      : print "A GREAT BATTLE ENSUES IN WHICH YOU ARE VICTORIOUS. THE KNIGHT TURNS TO DUST BEFORE YOUR EYES ALONG WITH YOUR SWORD!" ;
      : press_any_key ;
      : destroy "demon_knight" ;
      : destroy "short_sword" ;
      : set_graphic graphic = "demon_knight_road_2"  target = "demon_knight_road" ;
      : redescribe ;
   }

   end_game : subroutine {
      : press_any_key ;
      : clear_screen;
      : print_graphic "game_over" ;
      : print "Your quest is over .........." ;
      : turns ;
      : end_game ;
   }

}

// Placeholders used for documentation purposes only as graphic data is too large to place in document.
assets {
   graphics {
      armoury               : placeholder ;
      arthur                : placeholder ;
      banquet_hall          : placeholder ;
      birwood_bush          : placeholder ;
      castle_approach_1     : placeholder ;
      castle_approach_2     : placeholder ;
      castle_approach_2a    : placeholder ;
      castle_porch          : placeholder ;
      chasm                 : placeholder ;
      cold_room             : placeholder ;
      cold_room_2           : placeholder ;
      deep_inside_birwood   : placeholder ;
      demon_knight_road     : placeholder ;
      demon_knight_road_2   : placeholder ;
      drafty_room           : placeholder ;
      drafty_room_2         : placeholder ;
      edge_of_birwood       : placeholder ;
      ending_screen         : placeholder ;
      excalibur_loading     : placeholder ;
      foot_of_tree          : placeholder ;
      foot_of_tree_2        : placeholder ;
      game_over             : placeholder ;
      hut                   : placeholder ;
      lamp_seller_on_road   : placeholder ;
      lamp_seller_on_road_2 : placeholder ;
      most_splendid_room    : placeholder ;
      most_splendid_room_2  : placeholder ;
      ornate_antechamber    : placeholder ;
      portcullis            : placeholder ;
      portcullis_2          : placeholder ;
      road_1                : placeholder ;
      road_2                : placeholder ;
      road_3                : placeholder ;
      road_4                : placeholder ;
      salt_mine_1           : placeholder ;
      salt_mine_2           : placeholder ;
      salt_mine_3           : placeholder ;
      top_of_tree           : placeholder ;
      winch_room            : placeholder ;
      worm_room             : placeholder ;
      worm_room_2           : placeholder ;
   }
}

7.9. Crossing the chasm

chasm

The ladder has a second use.

To cross the chasm you need to be holding a pole to help you balance, then type CROSS CHASM whilst holding the pole.

Both sides of the chasm require typing CROSS CHASM to take you to the opposite side, and the holding of the pole that assists your balance.

The pole is an object that is created if the player types BREAK LADDER, SMASH LADDER or DISASSEMBLE LADDER whilst holding the ladder.

The clue to solve this puzzle is the use of the word "tightrope" in the "edge of a huge chasm" location.

Tightrope walkers usually hold a pole to help their balance.

Examining the ladder describes the ladder as "A LONG POLE WITH RUNGS ATTACHED.". Interesting !

Breaking, smashing or dismantling the ladder will create the objects "some rungs" and "a long pole". It will also remove the ladder from the game.

The ladder can be broken at any time, including BEFORE climbing the tree. Breaking the ladder this way puts the game into an unwinnable state, as the ladder cannot be reconstructed.

The player will probably become aware of this if they solve the chasm puzzle before the tree puzzle, but if they don’t it may be frustrating.

QUIZ - Can you think of a way to fix the unwinnability problem here ?

7.9.1. Breaking The Ladder

The logic for breaking the ladder is fairly straightforward.

The following code should be added to the bottom of the on_command{} section:

: match "break ladder;smash ladder;disassemble ladder"  {
   : if (is_carried "ladder") {
      : print   "OK."       ;
      : destroy "ladder"    ;
      : create  "long_pole" ;
      : create  "rungs"     ;
      : press_any_key       ;
      : redescribe          ;
   }
}

Here is an animation on how it should look to create this block:

new 003

We will be using less animations going forward as you should be getting used to how to use CONTROL + SPACE, TAB, the CURSOR KEYS, and other keyboard shortcuts.

7.9.2. Commenting Out Code

Moving on, we need to code in the chasm crossing logic. Currently the navigation table allows free movements from the chasm location to the edge_of_birwood.

We will use yet another form of blocking now which is simply removing the navigation item entirely.

To do this, we can "comment out" the line in the navigation table which connects the chasm location to the edge_of_birwood location.

To comment something out, we can type the // character at the start of the line (or lines) we wish to ignore. We could also delete the line, but in this case, we will comment out the line.

Commented out code is completely ignored by Adventuron.

It can be useful to temporarily disable and enable blocks of code.

035

7.9.3. The GOTO Command

We now wish to write the code that will allow the player to travel between the chasm location and the edge_of_birwood location when CROSS CHASM is typed and entered in either of those locations (whilst holding the pole).

Some logic can be added for falling if the player types "CROSS CHASM" without holding the pole.

: match "cross chasm; balance _; walk _"  {
  : if (is_at "chasm" && is_carried "long_pole") {
     : print "THE POLE HELPS YOU BALANCE...." ;
     : press_any_key ;
     : goto "edge_of_birwood" ;
     : redescribe ;
  }
  : if (is_at "chasm" && !is_carried "long_pole") {
     : print "YOU LOSE YOUR BALANCE....." ;
     : gosub "end_game" ;
  }
  : if (is_at "edge_of_birwood" && is_carried "long_pole") {
     : print "THE POLE HELPS YOU BALANCE...." ;
     : press_any_key ;
     : goto "chasm" ;
     : redescribe ;
  }
  : if (is_at "edge_of_birwood" && !is_carried "long_pole") {
     : print "YOU LOSE YOUR BALANCE....." ;
     : gosub "end_game" ;
  }
}

The "!" character in from of is_carried "long_pole" means NOT, and of course the && characters read as AND.

7.9.4. Code so far …​..

########################################
#  Adventuron                          #
########################################

start_at       = hut

########################################
#  Locations                           #
########################################

locations {

   hut                    : location "You are in an old hut. Sunlight shines in from a doorway to the north.";
   road_1                 : location "You are standing on a track. The hut is south.";
   road_2                 : location "You are where the road turns eastwards. You see small hills in the distance.";
   road_3                 : location "You are on a road surrounded by grass. Trees can be seen on a hill in the distance.";
   road_4                 : location "You are on a dusty path on the edge of Birwood.";
   lamp_seller_on_road    : location "You are at a crossroads.";
   chasm                  : location "You are stood on the edge of a huge chasm (a cliff). A tightrope spans the gap, but it looks dangerous.";
   edge_of_birwood        : location "You are on the edge of Birwood. A rope spans the chasm northwards." ;
   deep_inside_birwood    : location "You are deep inside Birwood. The trees are alive with the buzzing of tiny insects.";
   birwood_bush           : location "You are standing in Birwood. A gap in the trees lets a warm light filter through.";
   demon_knight_road      : location "You are in a dip in the road by dark Birwood. Birds can be heard above.";
   foot_of_tree           : location "You are at the bottom of a large stone tree that is bare of any branches. The road ends here.";
   top_of_tree            : location "You are in a stone room set in a large stone tree.";
   castle_approach_1      : location "You are now a fair distance from Birwood. You can see castle Camelot to the east.";
   castle_approach_2      : location "You are outside Camelot Castle. A great stone door is the only way in.";
   castle_porch           : location "You are in the porch of Camelot.";
   banquet_hall           : location "You are in an abandoned banquet hall (eating area). Furniture lays broken on the floor.";
   drafty_room            : location "You are in a drafty room. Wind blows through gaps in the walls creating howling noises.";
   ornate_antechamber     : location "You are in an antechamber covered in thin ice that even covers the paintings.";
   portcullis             : location "You are in a room which has an iron portcullis set into the northern wall.";
   salt_mine_1            : location "You are in an old salt mine. Tunnels lead to the west and south.";
   salt_mine_2            : location "You are in the west part of the mine. It looks like it's been abandoned.";
   salt_mine_3            : location "You are at the end of the mine. You can hear the drip of water.";
   worm_room              : location "You are in the south part of the mine. There been recent movement in the rocks near your feet.";
   cold_room              : location "You are in a bitterly cold room. Everything is coated in a thick layer of ice.";
   winch_room             : location "You are in the winch room.";
   armoury                : location "You are in the armoury. Empty weapon racks line the walls.";
   most_splendid_room     : location "You are in the most splendid room in the castle. Rugs and paintings adorn the floor and walls.";
   arthur                 : location "You are in a sparse and lonely room. A cold wind enters through a high window.";

}

########################################
#  Connections                         #
########################################

connections {

   from, direction, to = [
      hut,                  north,  road_1,
      road_1,               north,  road_2,
      road_2,               east,   road_3,
      road_3,               east,   road_4,
      road_4,               north,  foot_of_tree,
      road_4,               south,  lamp_seller_on_road,
      lamp_seller_on_road,  east,   demon_knight_road,
      lamp_seller_on_road,  south,  chasm,
      foot_of_tree,         up,     top_of_tree,
      //chasm,                south,  edge_of_birwood,
      edge_of_birwood,      south,  deep_inside_birwood,
      deep_inside_birwood,  west,   birwood_bush,
      demon_knight_road,    east,   castle_approach_1,
      castle_approach_1,    east,   castle_approach_2,
      castle_approach_2,    east,   castle_porch,
      castle_porch,         east,   banquet_hall,
      banquet_hall,         north,  portcullis,
      banquet_hall,         south,  drafty_room,
      portcullis,           north,  most_splendid_room,
      most_splendid_room,   west,   arthur,
      drafty_room,          east,   ornate_antechamber,
      drafty_room,          down,   salt_mine_1,
      ornate_antechamber,   east,   cold_room,
      cold_room,            north,  winch_room,
      winch_room,           east,   armoury,
      salt_mine_1,          west,   salt_mine_2,
      salt_mine_1,          south,  worm_room,
      worm_room,            south,  salt_mine_3,
   ]

}

########################################
#  Objects                             #
########################################

objects {

   # Items we can pick-up (Objects)

   ladder           : object  "a ladder"                                    start_at="hut" ;
   red_fish         : object  "a red fish"                                  start_at="road_3" ;
   short_sword      : object  "a short sword"                               start_at="top_of_tree" ;
   coin             : object  "a coin"                                      start_at="ornate_antechamber" ;
   string           : object  "some string"                                 start_at="salt_mine_2" ;
   salt             : object  "some salt"                                   start_at="salt_mine_3" ;
   oil              : object  "can of oil"                                  start_at="cold_room" ;
   excalibur        : object  "Excalibur!"                                  start_at="armoury" ;
   long_pole        : object  "a long pole" ;
   rungs            : object  "some rungs" ;
   stone_key        : object  "a stone key" ;
   axe              : object  "a wood cutters' axe" ;
   lamp             : object  "a lamp" ;

   # Things or people that we cannot pick up (Scenery)

   old_woman        : scenery "an old woman selling lamps"                  start_at="lamp_seller_on_road" ;
   logs             : scenery "a pile of logs"                              start_at="deep_inside_birwood" ;
   bush             : scenery "a bush"                                      start_at="birwood_bush" ;
   demon_knight     : scenery "a Demon Knight guarding the east road"  start_at="demon_knight_road" ;
   trapdoor         : scenery "an old trapdoor"                             start_at="drafty_room" ;
   smashed_trapdoor : scenery "a smashed trapdoor" ;
   rockworm         : scenery "a Rockworm, guarding the south tunnel"       start_at="worm_room" ;
   ice_creature     : scenery "an Ice creature, guarding the north exit"    start_at="cold_room" ;
   winch            : scenery "a winch"                                     start_at="winch_room" ;
   spell            : scenery "a spell flying at you from Crania"           start_at="most_splendid_room" ;
   asleep_arthur    : scenery "King Arthur (asleep)"                        start_at="arthur" ;

}

########################################
#  Booleans                            #
########################################

booleans {
   is_ladder_standing : boolean "false";
}

########################################
#  Blocks                              #
########################################

barriers {
   tree : block {
      location          = top_of_tree
      message           = YOU CAN'T FIND YOUR GRIP
      block_when_not    = is_ladder_standing
      show_blocked_exit = false
   }

   knight : block {
      location          = castle_approach_1
      gosub             = lose_fight
      block_when_exists = demon_knight
      show_blocked_exit = true
   }
}

########################################
#  On Command                          #
########################################

on_command {
   : match "examine ladder"  {
      : if ( is_present "ladder" ) {
         : print "A LONG POLE WITH RUNGS ATTACHED." ;
      }
   }
   : match "examine woman"  {
      : if (is_present "old_woman") {
         : print "SHE LOOKS AT YOU WITH AN INTENSE GLARE." ;
      }
   }
   : match "examine lamp"  {
      : if (is_present "lamp") {
         : print "IT'S OLD AND TARNISHED." ;
      }
   }
   : match "examine fish"  {
      : if (is_present "red_fish") {
         : print "IT STINKS!" ;
      }
   }
   : match "examine sword"  {
      : if (is_present "short_sword") {
         : print "INSCRIBED UPON IT ARE THE WORDS 'GOOD LUCK' ~~ MERLIN." ;
      }
   }
   : match "examine bush"  {
      : if (is_present "bush" && has_not_created "stone_key") {
         : print "YOU FIND SOMETHING!" ;
         : create "stone_key" ;
         : press_any_key ;
         : redescribe ;
      }
   }
   : match "examine logs"  {
      : if (is_present "logs" && has_not_created "axe") {
         : print "YOU FIND AN AXE!" ;
         : create "axe" ;
         : press_any_key ;
         : redescribe ;
      }
   }

   : match "get ladder"  {
      : if (is_at "foot_of_tree" && is_beside "ladder") {
         : get ;
         : set_false "is_ladder_standing" ;
         : set_graphic target = "foot_of_tree" graphic = "foot_of_tree"  ;
         : redescribe ;
      }
   }

   : match "stand ladder;lean ladder;rest ladder"  {
      : if (is_carried "ladder" && is_at "foot_of_tree") {
         : drop ;
         : set_true "is_ladder_standing" ;
         : set_graphic target = "foot_of_tree" graphic = "foot_of_tree_2"  ;
         : redescribe;
      }
   }

    : match "fight knight;attack knight;challenge knight"  {
      : if (is_present "demon_knight") {
         : if (is_carried "short_sword") {
            : gosub "win_fight" ;
         }
         : else {
            : gosub "lose_fight" ;
         }
      }
    }

    : match "break ladder;smash ladder;disassemble ladder"  {
       : if (is_carried "ladder") {
          : print   "OK."       ;
          : destroy "ladder"    ;
          : create  "long_pole" ;
          : create  "rungs"     ;
          : press_any_key       ;
          : redescribe          ;
       }
    }

    : match "cross chasm; balance _; walk _"  {
      : if (is_at "chasm" && is_carried "long_pole") {
         : print "THE POLE HELPS YOU BALANCE...." ;
         : press_any_key ;
         : goto "edge_of_birwood" ;
         : redescribe ;
      }
      : if (is_at "chasm" && !is_carried "long_pole") {
         : print "YOU LOSE YOUR BALANCE....." ;
         : gosub "end_game" ;
      }
      : if (is_at "edge_of_birwood" && is_carried "long_pole") {
         : print "THE POLE HELPS YOU BALANCE...." ;
         : press_any_key ;
         : goto "chasm" ;
         : redescribe ;
      }
      : if (is_at "edge_of_birwood" && !is_carried "long_pole") {
         : print "YOU LOSE YOUR BALANCE....." ;
         : gosub "end_game" ;
      }
    }
}


########################################
#  Subroutines                         #
########################################

subroutines {

   // This subroutine is executed if we lose a fight with the knight
   lose_fight : subroutine {
      // Have to explicitly attack the knight, even if you have the sword.
      : print "THE KNIGHT WIELDS HIS SWORD DEFTLY AND ATTACKS YOU...." ;
      : gosub "end_game" ;
   }

   // This subroutine is executed if we win a fight with the knight.
   win_fight : subroutine {
      : print "A GREAT BATTLE ENSUES IN WHICH YOU ARE VICTORIOUS. THE KNIGHT TURNS TO DUST BEFORE YOUR EYES ALONG WITH YOUR SWORD!" ;
      : press_any_key ;
      : destroy "demon_knight" ;
      : destroy "short_sword" ;
      : set_graphic graphic = "demon_knight_road_2"  target = "demon_knight_road" ;
      : redescribe ;
   }

   end_game : subroutine {
      : press_any_key ;
      : clear_screen;
      : print_graphic "game_over";
      : print "Your quest is over .........." ;
      : turns ;
      : end_game ;
   }

}

// Placeholders used for documentation purposes only as graphic data is too large to place in document.
assets {
   graphics {
      armoury               : placeholder ;
      arthur                : placeholder ;
      banquet_hall          : placeholder ;
      birwood_bush          : placeholder ;
      castle_approach_1     : placeholder ;
      castle_approach_2     : placeholder ;
      castle_approach_2a    : placeholder ;
      castle_porch          : placeholder ;
      chasm                 : placeholder ;
      cold_room             : placeholder ;
      cold_room_2           : placeholder ;
      deep_inside_birwood   : placeholder ;
      demon_knight_road     : placeholder ;
      demon_knight_road_2   : placeholder ;
      drafty_room           : placeholder ;
      drafty_room_2         : placeholder ;
      edge_of_birwood       : placeholder ;
      ending_screen         : placeholder ;
      excalibur_loading     : placeholder ;
      foot_of_tree          : placeholder ;
      foot_of_tree_2        : placeholder ;
      game_over             : placeholder ;
      hut                   : placeholder ;
      lamp_seller_on_road   : placeholder ;
      lamp_seller_on_road_2 : placeholder ;
      most_splendid_room    : placeholder ;
      most_splendid_room_2  : placeholder ;
      ornate_antechamber    : placeholder ;
      portcullis            : placeholder ;
      portcullis_2          : placeholder ;
      road_1                : placeholder ;
      road_2                : placeholder ;
      road_3                : placeholder ;
      road_4                : placeholder ;
      salt_mine_1           : placeholder ;
      salt_mine_2           : placeholder ;
      salt_mine_3           : placeholder ;
      top_of_tree           : placeholder ;
      winch_room            : placeholder ;
      worm_room             : placeholder ;
      worm_room_2           : placeholder ;
   }
}

7.10. Opening The Castle Door

castle approach 2

The next puzzle is opening the castle stone door. The door is either open or closed, locked or unlocked.

The door requires the stone key to unlock the door. The stone key was found in the bush in Birwood forest.

A door is a kind of barrier, and can be created in the barriers section (at the top of the document).

We create a door this way, and it will take care of all the opening / closing / and blocking logic for us.

barriers{}
castle_door : door {
  key   = stone_key
  from  = castle_approach_2
  to    = castle_porch
  on_unlock {
     : print "YOU UNLOCK IT WITH THE KEY, WHICH JAMS IN THE LOCK." ;
     : destroy "stone_key" ;
  }
  on_open {
     : set_graphic graphic = "castle_approach_2a" target = "castle_approach_2" ;
     : redescribe ;
  }
  on_close {
     : set_graphic graphic = "castle_approach_2"  target = "castle_approach_2" ;
     : redescribe ;
  }
}

The on_unlock {} section is executed when the door is unlocked. In our section, we wish to destroy the key (remove it from being carried by the player) after the door is locked.

The on_open {} section is executed when the door is opened. In our case, we wish to change the graphic to a version of the graphic with an open door, then redescribe (repaint) the current location.

The on_close {} section is executed when the door is closed. In our case, we wish to change the graphic to a version of the graphic with a closed door, then redescribe (repaint) the current location.

An animation of creating this block is shown here:

new 005

7.10.1. Code so far

########################################
#  Adventuron                          #
########################################

start_at       = hut

########################################
#  Locations                           #
########################################

locations {

   hut                    : location "You are in an old hut. Sunlight shines in from a doorway to the north.";
   road_1                 : location "You are standing on a track. The hut is south.";
   road_2                 : location "You are where the road turns eastwards. You see small hills in the distance.";
   road_3                 : location "You are on a road surrounded by grass. Trees can be seen on a hill in the distance.";
   road_4                 : location "You are on a dusty path on the edge of Birwood.";
   lamp_seller_on_road    : location "You are at a crossroads.";
   chasm                  : location "You are stood on the edge of a huge chasm (a cliff). A tightrope spans the gap, but it looks dangerous.";
   edge_of_birwood        : location "You are on the edge of Birwood. A rope spans the chasm northwards." ;
   deep_inside_birwood    : location "You are deep inside Birwood. The trees are alive with the buzzing of tiny insects.";
   birwood_bush           : location "You are standing in Birwood. A gap in the trees lets a warm light filter through.";
   demon_knight_road      : location "You are in a dip in the road by dark Birwood. Birds can be heard above.";
   foot_of_tree           : location "You are at the bottom of a large stone tree that is bare of any branches. The road ends here.";
   top_of_tree            : location "You are in a stone room set in a large stone tree.";
   castle_approach_1      : location "You are now a fair distance from Birwood. You can see castle Camelot to the east.";
   castle_approach_2      : location "You are outside Camelot Castle. A great stone door is the only way in.";
   castle_porch           : location "You are in the porch of Camelot.";
   banquet_hall           : location "You are in an abandoned banquet hall (eating area). Furniture lays broken on the floor.";
   drafty_room            : location "You are in a drafty room. Wind blows through gaps in the walls creating howling noises.";
   ornate_antechamber     : location "You are in an antechamber covered in thin ice that even covers the paintings.";
   portcullis             : location "You are in a room which has an iron portcullis set into the northern wall.";
   salt_mine_1            : location "You are in an old salt mine. Tunnels lead to the west and south.";
   salt_mine_2            : location "You are in the west part of the mine. It looks like it's been abandoned.";
   salt_mine_3            : location "You are at the end of the mine. You can hear the drip of water.";
   worm_room              : location "You are in the south part of the mine. There been recent movement in the rocks near your feet.";
   cold_room              : location "You are in a bitterly cold room. Everything is coated in a thick layer of ice.";
   winch_room             : location "You are in the winch room.";
   armoury                : location "You are in the armoury. Empty weapon racks line the walls.";
   most_splendid_room     : location "You are in the most splendid room in the castle. Rugs and paintings adorn the floor and walls.";
   arthur                 : location "You are in a sparse and lonely room. A cold wind enters through a high window.";

}

########################################
#  Connections                         #
########################################

connections {

   from, direction, to = [
      hut,                  north,  road_1,
      road_1,               north,  road_2,
      road_2,               east,   road_3,
      road_3,               east,   road_4,
      road_4,               north,  foot_of_tree,
      road_4,               south,  lamp_seller_on_road,
      lamp_seller_on_road,  east,   demon_knight_road,
      lamp_seller_on_road,  south,  chasm,
      foot_of_tree,         up,     top_of_tree,
      //chasm,                south,  edge_of_birwood,
      edge_of_birwood,      south,  deep_inside_birwood,
      deep_inside_birwood,  west,   birwood_bush,
      demon_knight_road,    east,   castle_approach_1,
      castle_approach_1,    east,   castle_approach_2,
      castle_approach_2,    east,   castle_porch,
      castle_porch,         east,   banquet_hall,
      banquet_hall,         north,  portcullis,
      banquet_hall,         south,  drafty_room,
      portcullis,           north,  most_splendid_room,
      most_splendid_room,   west,   arthur,
      drafty_room,          east,   ornate_antechamber,
      drafty_room,          down,   salt_mine_1,
      ornate_antechamber,   east,   cold_room,
      cold_room,            north,  winch_room,
      winch_room,           east,   armoury,
      salt_mine_1,          west,   salt_mine_2,
      salt_mine_1,          south,  worm_room,
      worm_room,            south,  salt_mine_3,
   ]

}

########################################
#  Objects                             #
########################################

objects {

   # Items we can pick-up (Objects)

   ladder           : object  "a ladder"                                    start_at="hut" ;
   red_fish         : object  "a red fish"                                  start_at="road_3" ;
   short_sword      : object  "a short sword"                               start_at="top_of_tree" ;
   coin             : object  "a coin"                                      start_at="ornate_antechamber" ;
   string           : object  "some string"                                 start_at="salt_mine_2" ;
   salt             : object  "some salt"                                   start_at="salt_mine_3" ;
   oil              : object  "can of oil"                                  start_at="cold_room" ;
   excalibur        : object  "Excalibur!"                                  start_at="armoury" ;
   long_pole        : object  "a long pole" ;
   rungs            : object  "some rungs" ;
   stone_key        : object  "a stone key" ;
   axe              : object  "a wood cutters' axe" ;
   lamp             : object  "a lamp" ;

   # Things or people that we cannot pick up (Scenery)

   old_woman        : scenery "an old woman selling lamps"                  start_at="lamp_seller_on_road" ;
   logs             : scenery "a pile of logs"                              start_at="deep_inside_birwood" ;
   bush             : scenery "a bush"                                      start_at="birwood_bush" ;
   demon_knight     : scenery "a Demon Knight guarding the east road"  start_at="demon_knight_road" ;
   trapdoor         : scenery "an old trapdoor"                             start_at="drafty_room" ;
   smashed_trapdoor : scenery "a smashed trapdoor" ;
   rockworm         : scenery "a Rockworm, guarding the south tunnel"       start_at="worm_room" ;
   ice_creature     : scenery "an Ice creature, guarding the north exit"    start_at="cold_room" ;
   winch            : scenery "a winch"                                     start_at="winch_room" ;
   spell            : scenery "a spell flying at you from Crania"           start_at="most_splendid_room" ;
   asleep_arthur    : scenery "King Arthur (asleep)"                        start_at="arthur" ;

}

########################################
#  Booleans                            #
########################################

booleans {
   is_ladder_standing : boolean "false";
}

########################################
#  Blocks                              #
########################################

barriers {

   castle_door : door {
     key   = stone_key
     from  = castle_approach_2
     to    = castle_porch
     on_unlock {
        : print "YOU UNLOCK IT WITH THE KEY, WHICH JAMS IN THE LOCK." ;
        : destroy "stone_key" ;
     }
     on_open {
        : set_graphic graphic = "castle_approach_2a" target = "castle_approach_2" ;
        : redescribe ;
     }
     on_close {
        : set_graphic graphic = "castle_approach_2"  target = "castle_approach_2" ;
        : redescribe ;
     }
   }

   tree : block {
      location          = top_of_tree
      message           = YOU CAN'T FIND YOUR GRIP
      block_when_not    = is_ladder_standing
      show_blocked_exit = false
   }

   knight : block {
      location          = castle_approach_1
      gosub             = lose_fight
      block_when_exists = demon_knight
      show_blocked_exit = true
   }

}

########################################
#  On Command                          #
########################################

on_command {
   : match "examine ladder"  {
      : if ( is_present "ladder" ) {
         : print "A LONG POLE WITH RUNGS ATTACHED." ;
      }
   }
   : match "examine woman"  {
      : if (is_present "old_woman") {
         : print "SHE LOOKS AT YOU WITH AN INTENSE GLARE." ;
      }
   }
   : match "examine lamp"  {
      : if (is_present "lamp") {
         : print "IT'S OLD AND TARNISHED." ;
      }
   }
   : match "examine fish"  {
      : if (is_present "red_fish") {
         : print "IT STINKS!" ;
      }
   }
   : match "examine sword"  {
      : if (is_present "short_sword") {
         : print "INSCRIBED UPON IT ARE THE WORDS 'GOOD LUCK' ~~ MERLIN." ;
      }
   }
   : match "examine bush"  {
      : if (is_present "bush" && has_not_created "stone_key") {
         : print "YOU FIND SOMETHING!" ;
         : create "stone_key" ;
         : press_any_key ;
         : redescribe ;
      }
   }
   : match "examine logs"  {
      : if (is_present "logs" && has_not_created "axe") {
         : print "YOU FIND AN AXE!" ;
         : create "axe" ;
         : press_any_key ;
         : redescribe ;
      }
   }

   : match "get ladder"  {
      : if (is_at "foot_of_tree" && is_beside "ladder") {
         : get ;
         : set_false "is_ladder_standing" ;
         : set_graphic target = "foot_of_tree" graphic = "foot_of_tree"  ;
         : redescribe ;
      }
   }

   : match "stand ladder;lean ladder;rest ladder"  {
      : if (is_carried "ladder" && is_at "foot_of_tree") {
         : drop ;
         : set_true "is_ladder_standing" ;
         : set_graphic target = "foot_of_tree" graphic = "foot_of_tree_2"  ;
         : redescribe;
      }
   }

    : match "fight knight;attack knight;challenge knight"  {
      : if (is_present "demon_knight") {
         : if (is_carried "short_sword") {
            : gosub "win_fight" ;
         }
         : else {
            : gosub "lose_fight" ;
         }
      }
    }

    : match "break ladder;smash ladder;disassemble ladder"  {
       : if (is_carried "ladder") {
          : print   "OK."       ;
          : destroy "ladder"    ;
          : create  "long_pole" ;
          : create  "rungs"     ;
          : press_any_key       ;
          : redescribe          ;
       }
    }

    : match "cross chasm; balance _; walk _"  {
      : if (is_at "chasm" && is_carried "long_pole") {
         : print "THE POLE HELPS YOU BALANCE...." ;
         : press_any_key ;
         : goto "edge_of_birwood" ;
         : redescribe ;
      }
      : if (is_at "chasm" && !is_carried "long_pole") {
         : print "YOU LOSE YOUR BALANCE....." ;
         : gosub "end_game" ;
      }
      : if (is_at "edge_of_birwood" && is_carried "long_pole") {
         : print "THE POLE HELPS YOU BALANCE...." ;
         : press_any_key ;
         : goto "chasm" ;
         : redescribe ;
      }
      : if (is_at "edge_of_birwood" && !is_carried "long_pole") {
         : print "YOU LOSE YOUR BALANCE....." ;
         : gosub "end_game" ;
      }
    }
}


########################################
#  Subroutines                         #
########################################

subroutines {

   // This subroutine is executed if we lose a fight with the knight
   lose_fight : subroutine {
      // Have to explicitly attack the knight, even if you have the sword.
      : print "THE KNIGHT WIELDS HIS SWORD DEFTLY AND ATTACKS YOU...." ;
      : gosub "end_game" ;
   }

   // This subroutine is executed if we win a fight with the knight.
   win_fight : subroutine {
      : print "A GREAT BATTLE ENSUES IN WHICH YOU ARE VICTORIOUS. THE KNIGHT TURNS TO DUST BEFORE YOUR EYES ALONG WITH YOUR SWORD!" ;
      : press_any_key ;
      : destroy "demon_knight" ;
      : destroy "short_sword" ;
      : set_graphic graphic = "demon_knight_road_2"  target = "demon_knight_road" ;
      : redescribe ;
   }

   end_game : subroutine {
      : press_any_key ;
      : clear_screen;
      : print_graphic "game_over" ;
      : print "Your quest is over .........." ;
      : turns ;
      : end_game ;
   }

}

// Placeholders used for documentation purposes only as graphic data is too large to place in document.
assets {
   graphics {
      armoury               : placeholder ;
      arthur                : placeholder ;
      banquet_hall          : placeholder ;
      birwood_bush          : placeholder ;
      castle_approach_1     : placeholder ;
      castle_approach_2     : placeholder ;
      castle_approach_2a    : placeholder ;
      castle_porch          : placeholder ;
      chasm                 : placeholder ;
      cold_room             : placeholder ;
      cold_room_2           : placeholder ;
      deep_inside_birwood   : placeholder ;
      demon_knight_road     : placeholder ;
      demon_knight_road_2   : placeholder ;
      drafty_room           : placeholder ;
      drafty_room_2         : placeholder ;
      edge_of_birwood       : placeholder ;
      ending_screen         : placeholder ;
      excalibur_loading     : placeholder ;
      foot_of_tree          : placeholder ;
      foot_of_tree_2        : placeholder ;
      game_over             : placeholder ;
      hut                   : placeholder ;
      lamp_seller_on_road   : placeholder ;
      lamp_seller_on_road_2 : placeholder ;
      most_splendid_room    : placeholder ;
      most_splendid_room_2  : placeholder ;
      ornate_antechamber    : placeholder ;
      portcullis            : placeholder ;
      portcullis_2          : placeholder ;
      road_1                : placeholder ;
      road_2                : placeholder ;
      road_3                : placeholder ;
      road_4                : placeholder ;
      salt_mine_1           : placeholder ;
      salt_mine_2           : placeholder ;
      salt_mine_3           : placeholder ;
      top_of_tree           : placeholder ;
      winch_room            : placeholder ;
      worm_room             : placeholder ;
      worm_room_2           : placeholder ;
   }
}

7.11. Buying the Lamp

lamp seller on road

Buying the lamp is a very simple piece of logic, and is an 'item swap' puzzle. You take an item to a place, type something, and it is replaced with something else.

In this case, the "old woman selling lamps" has a lamp to "sell". When the player gains access to the castle, they will find a coin.

If the player takes the coin, then goes to the same location as the woman, and types BUY LAMP or GIVE COIN, then the game will print "THE OLD LADY TAKES YOUR COIN, GIVES YOU A BRASS LAMP, THEN DISAPPEARS INTO THIN AIR.".

The following code should be added at the end (but inside) the on_command {} section of code.

on_command {}
: match "give coin; buy lamp"  {
  : if (is_present "old_woman") {
     : if (is_carried "coin") {
        : print "THE OLD LADY TAKES YOUR COIN, GIVES YOU A BRASS LAMP, THEN DISAPPEARS INTO THIN AIR." ;
        : destroy "coin" ;
        : destroy "old_woman" ;
        : create "lamp" target="inventory" ;
        : set_graphic graphic = "lamp_seller_on_road_2"  target = "lamp_seller_on_road" ;
        : press_any_key ;
        : redescribe ;
     }
     : else {
        : match "buy lamp"  {
           : print "'CROSS MY PALM WITH SILVER!'" ;
        }
     }
  }
}

7.11.1. Code so far:

########################################
#  Adventuron                          #
########################################

start_at       = hut

########################################
#  Locations                           #
########################################

locations {

   hut                    : location "You are in an old hut. Sunlight shines in from a doorway to the north.";
   road_1                 : location "You are standing on a track. The hut is south.";
   road_2                 : location "You are where the road turns eastwards. You see small hills in the distance.";
   road_3                 : location "You are on a road surrounded by grass. Trees can be seen on a hill in the distance.";
   road_4                 : location "You are on a dusty path on the edge of Birwood.";
   lamp_seller_on_road    : location "You are at a crossroads.";
   chasm                  : location "You are stood on the edge of a huge chasm (a cliff). A tightrope spans the gap, but it looks dangerous.";
   edge_of_birwood        : location "You are on the edge of Birwood. A rope spans the chasm northwards." ;
   deep_inside_birwood    : location "You are deep inside Birwood. The trees are alive with the buzzing of tiny insects.";
   birwood_bush           : location "You are standing in Birwood. A gap in the trees lets a warm light filter through.";
   demon_knight_road      : location "You are in a dip in the road by dark Birwood. Birds can be heard above.";
   foot_of_tree           : location "You are at the bottom of a large stone tree that is bare of any branches. The road ends here.";
   top_of_tree            : location "You are in a stone room set in a large stone tree.";
   castle_approach_1      : location "You are now a fair distance from Birwood. You can see castle Camelot to the east.";
   castle_approach_2      : location "You are outside Camelot Castle. A great stone door is the only way in.";
   castle_porch           : location "You are in the porch of Camelot.";
   banquet_hall           : location "You are in an abandoned banquet hall (eating area). Furniture lays broken on the floor.";
   drafty_room            : location "You are in a drafty room. Wind blows through gaps in the walls creating howling noises.";
   ornate_antechamber     : location "You are in an antechamber covered in thin ice that even covers the paintings.";
   portcullis             : location "You are in a room which has an iron portcullis set into the northern wall.";
   salt_mine_1            : location "You are in an old salt mine. Tunnels lead to the west and south.";
   salt_mine_2            : location "You are in the west part of the mine. It looks like it's been abandoned.";
   salt_mine_3            : location "You are at the end of the mine. You can hear the drip of water.";
   worm_room              : location "You are in the south part of the mine. There been recent movement in the rocks near your feet.";
   cold_room              : location "You are in a bitterly cold room. Everything is coated in a thick layer of ice.";
   winch_room             : location "You are in the winch room.";
   armoury                : location "You are in the armoury. Empty weapon racks line the walls.";
   most_splendid_room     : location "You are in the most splendid room in the castle. Rugs and paintings adorn the floor and walls.";
   arthur                 : location "You are in a sparse and lonely room. A cold wind enters through a high window.";

}

########################################
#  Connections                         #
########################################

connections {

   from, direction, to = [
      hut,                  north,  road_1,
      road_1,               north,  road_2,
      road_2,               east,   road_3,
      road_3,               east,   road_4,
      road_4,               north,  foot_of_tree,
      road_4,               south,  lamp_seller_on_road,
      lamp_seller_on_road,  east,   demon_knight_road,
      lamp_seller_on_road,  south,  chasm,
      foot_of_tree,         up,     top_of_tree,
      //chasm,                south,  edge_of_birwood,
      edge_of_birwood,      south,  deep_inside_birwood,
      deep_inside_birwood,  west,   birwood_bush,
      demon_knight_road,    east,   castle_approach_1,
      castle_approach_1,    east,   castle_approach_2,
      castle_approach_2,    east,   castle_porch,
      castle_porch,         east,   banquet_hall,
      banquet_hall,         north,  portcullis,
      banquet_hall,         south,  drafty_room,
      portcullis,           north,  most_splendid_room,
      most_splendid_room,   west,   arthur,
      drafty_room,          east,   ornate_antechamber,
      drafty_room,          down,   salt_mine_1,
      ornate_antechamber,   east,   cold_room,
      cold_room,            north,  winch_room,
      winch_room,           east,   armoury,
      salt_mine_1,          west,   salt_mine_2,
      salt_mine_1,          south,  worm_room,
      worm_room,            south,  salt_mine_3,
   ]

}

########################################
#  Objects                             #
########################################

objects {

   # Items we can pick-up (Objects)

   ladder           : object  "a ladder"                                    start_at="hut" ;
   red_fish         : object  "a red fish"                                  start_at="road_3" ;
   short_sword      : object  "a short sword"                               start_at="top_of_tree" ;
   coin             : object  "a coin"                                      start_at="ornate_antechamber" ;
   string           : object  "some string"                                 start_at="salt_mine_2" ;
   salt             : object  "some salt"                                   start_at="salt_mine_3" ;
   oil              : object  "can of oil"                                  start_at="cold_room" ;
   excalibur        : object  "Excalibur!"                                  start_at="armoury" ;
   long_pole        : object  "a long pole" ;
   rungs            : object  "some rungs" ;
   stone_key        : object  "a stone key" ;
   axe              : object  "a wood cutters' axe" ;
   lamp             : object  "a lamp" ;

   # Things or people that we cannot pick up (Scenery)

   old_woman        : scenery "an old woman selling lamps"                  start_at="lamp_seller_on_road" ;
   logs             : scenery "a pile of logs"                              start_at="deep_inside_birwood" ;
   bush             : scenery "a bush"                                      start_at="birwood_bush" ;
   demon_knight     : scenery "a Demon Knight guarding the east road"  start_at="demon_knight_road" ;
   trapdoor         : scenery "an old trapdoor"                             start_at="drafty_room" ;
   smashed_trapdoor : scenery "a smashed trapdoor" ;
   rockworm         : scenery "a Rockworm, guarding the south tunnel"       start_at="worm_room" ;
   ice_creature     : scenery "an Ice creature, guarding the north exit"    start_at="cold_room" ;
   winch            : scenery "a winch"                                     start_at="winch_room" ;
   spell            : scenery "a spell flying at you from Crania"           start_at="most_splendid_room" ;
   asleep_arthur    : scenery "King Arthur (asleep)"                        start_at="arthur" ;

}


########################################
#  Booleans                            #
########################################

booleans {
   is_ladder_standing : boolean "false";
}

########################################
#  Barriers                            #
########################################

barriers {

   castle_door : door {
     key   = stone_key
     from  = castle_approach_2
     to    = castle_porch
     on_unlock {
        : print "YOU UNLOCK IT WITH THE KEY, WHICH JAMS IN THE LOCK." ;
        : destroy "stone_key" ;
     }
     on_open {
        : set_graphic graphic = "castle_approach_2a" target = "castle_approach_2" ;
        : redescribe ;
     }
     on_close {
        : set_graphic graphic = "castle_approach_2"  target = "castle_approach_2" ;
        : redescribe ;
     }
   }

   tree : block {
      location          = top_of_tree
      message           = YOU CAN'T FIND YOUR GRIP
      block_when_not    = is_ladder_standing
      show_blocked_exit = false
   }

   knight : block {
      location             = castle_approach_1
      gosub             = lose_fight
      block_when_exists = demon_knight
      show_blocked_exit = true
   }

}

########################################
#  On Command                          #
########################################

on_command {
   : match "examine ladder"  {
      : if ( is_present "ladder" ) {
         : print "A LONG POLE WITH RUNGS ATTACHED." ;
      }
   }
   : match "examine woman"  {
      : if (is_present "old_woman") {
         : print "SHE LOOKS AT YOU WITH AN INTENSE GLARE." ;
      }
   }
   : match "examine lamp"  {
      : if (is_present "lamp") {
         : print "IT'S OLD AND TARNISHED." ;
      }
   }
   : match "examine fish"  {
      : if (is_present "red_fish") {
         : print "IT STINKS!" ;
      }
   }
   : match "examine sword"  {
      : if (is_present "short_sword") {
         : print "INSCRIBED UPON IT ARE THE WORDS 'GOOD LUCK' ~~ MERLIN." ;
      }
   }
   : match "examine bush"  {
      : if (is_present "bush" && has_not_created "stone_key") {
         : print "YOU FIND SOMETHING!" ;
         : create "stone_key" ;
         : press_any_key ;
         : redescribe ;
      }
   }
   : match "examine logs"  {
      : if (is_present "logs" && has_not_created "axe") {
         : print "YOU FIND AN AXE!" ;
         : create "axe" ;
         : press_any_key ;
         : redescribe ;
      }
   }

   : match "get ladder"  {
      : if (is_at "foot_of_tree" && is_beside "ladder") {
         : get ;
         : set_false "is_ladder_standing" ;
         : set_graphic target = "foot_of_tree" graphic = "foot_of_tree"  ;
         : redescribe ;
      }
   }

   : match "stand ladder;lean ladder;rest ladder"  {
      : if (is_carried "ladder" && is_at "foot_of_tree") {
         : drop ;
         : set_true "is_ladder_standing" ;
         : set_graphic target = "foot_of_tree" graphic = "foot_of_tree_2"  ;
         : redescribe;
      }
   }

    : match "fight knight;attack knight;challenge knight"  {
      : if (is_present "demon_knight") {
         : if (is_carried "short_sword") {
            : gosub "win_fight" ;
         }
         : else {
            : gosub "lose_fight" ;
         }
      }
    }

    : match "break ladder;smash ladder;disassemble ladder"  {
       : if (is_carried "ladder") {
          : print   "OK."       ;
          : destroy "ladder"    ;
          : create  "long_pole" ;
          : create  "rungs"     ;
          : press_any_key       ;
          : redescribe          ;
       }
    }

    : match "cross chasm; balance _; walk _"  {
      : if (is_at "chasm" && is_carried "long_pole") {
         : print "THE POLE HELPS YOU BALANCE...." ;
         : press_any_key ;
         : goto "edge_of_birwood" ;
         : redescribe ;
      }
      : if (is_at "chasm" && !is_carried "long_pole") {
         : print "YOU LOSE YOUR BALANCE....." ;
         : gosub "end_game" ;
      }
      : if (is_at "edge_of_birwood" && is_carried "long_pole") {
         : print "THE POLE HELPS YOU BALANCE...." ;
         : press_any_key ;
         : goto "chasm" ;
         : redescribe ;
      }
      : if (is_at "edge_of_birwood" && !is_carried "long_pole") {
         : print "YOU LOSE YOUR BALANCE....." ;
         : gosub "end_game" ;
      }
    }

   : match "give coin; buy lamp"  {
     : if (is_present "old_woman") {
        : if (is_carried "coin") {
           : print "THE OLD LADY TAKES YOUR COIN, GIVES YOU A BRASS LAMP, THEN DISAPPEARS INTO THIN AIR." ;
           : destroy "coin" ;
           : destroy "old_woman" ;
           : create "lamp" target="inventory" ;
           : set_graphic graphic = "lamp_seller_on_road_2"  target = "lamp_seller_on_road" ;
           : press_any_key ;
           : redescribe ;
        }
        : else {
           : match "buy lamp"  {
              : print "'CROSS MY PALM WITH SILVER!'" ;
           }
        }
     }
   }
}


########################################
#  Subroutines                         #
########################################

subroutines {

   // This subroutine is executed if we lose a fight with the knight
   lose_fight : subroutine {
      // Have to explicitly attack the knight, even if you have the sword.
      : print "THE KNIGHT WIELDS HIS SWORD DEFTLY AND ATTACKS YOU...." ;
      : gosub "end_game" ;
   }

   // This subroutine is executed if we win a fight with the knight.
   win_fight : subroutine {
      : print "A GREAT BATTLE ENSUES IN WHICH YOU ARE VICTORIOUS. THE KNIGHT TURNS TO DUST BEFORE YOUR EYES ALONG WITH YOUR SWORD!" ;
      : press_any_key ;
      : destroy "demon_knight" ;
      : destroy "short_sword" ;
      : set_graphic graphic = "demon_knight_road_2"  target = "demon_knight_road" ;
      : redescribe ;
   }

   end_game : subroutine {
      : press_any_key ;
      : clear_screen;
      : print_graphic "game_over" ;
      : print "Your quest is over .........." ;
      : turns ;
      : end_game ;
   }

}

// Placeholders used for documentation purposes only as graphic data is too large to place in document.
assets {
   graphics {
      armoury               : placeholder ;
      arthur                : placeholder ;
      banquet_hall          : placeholder ;
      birwood_bush          : placeholder ;
      castle_approach_1     : placeholder ;
      castle_approach_2     : placeholder ;
      castle_approach_2a    : placeholder ;
      castle_porch          : placeholder ;
      chasm                 : placeholder ;
      cold_room             : placeholder ;
      cold_room_2           : placeholder ;
      deep_inside_birwood   : placeholder ;
      demon_knight_road     : placeholder ;
      demon_knight_road_2   : placeholder ;
      drafty_room           : placeholder ;
      drafty_room_2         : placeholder ;
      edge_of_birwood       : placeholder ;
      ending_screen         : placeholder ;
      excalibur_loading     : placeholder ;
      foot_of_tree          : placeholder ;
      foot_of_tree_2        : placeholder ;
      game_over             : placeholder ;
      hut                   : placeholder ;
      lamp_seller_on_road   : placeholder ;
      lamp_seller_on_road_2 : placeholder ;
      most_splendid_room    : placeholder ;
      most_splendid_room_2  : placeholder ;
      ornate_antechamber    : placeholder ;
      portcullis            : placeholder ;
      portcullis_2          : placeholder ;
      road_1                : placeholder ;
      road_2                : placeholder ;
      road_3                : placeholder ;
      road_4                : placeholder ;
      salt_mine_1           : placeholder ;
      salt_mine_2           : placeholder ;
      salt_mine_3           : placeholder ;
      top_of_tree           : placeholder ;
      winch_room            : placeholder ;
      worm_room             : placeholder ;
      worm_room_2           : placeholder ;
   }
}

7.12. Breaking The Trapdoor

drafty trapdoor close

Inside the castle is a trapdoor, which is locked, and cannot be opened or unlocked.

The solution is to smash the trapdoor.

The axe is required to smash the trapdoor, and this can be found by examining the logs inside Birwood Forest.

When the player types SMASH TRAPDOOR or CHOP TRAPDOOR or BREAK TRAPDOOR we also need to swap the scenery object of "trapdoor" with the new object "smashed trapdoor" and update the graphic in the 'drafty_room' to show the smashed trapdoor.

We add a block for the 'salt_mine_1' location (the location underneath the room with the trapdoor).

The block is only active when the original (non swapped) 'trapdoor' object exists, so when we swap the trapdoor objects for the smashed trapdoor object, the block is switched off, and the DOWN exit is shown.

barriers {}
trapdoor : block {
   location            = salt_mine_1
   message             = THE TRAPDOOR IS JAMMED SHUT!
   block_when_exists   = trapdoor
}
on_command{}
: match "smash trapdoor;chop trapdoor;break trapdoor"  {
  : if (is_present "trapdoor") {
     : if (is_carried "axe") {
        : print "USING THE AXE, YOU SMASH THE TRAPDOOR!" ;
        : destroy "trapdoor" ;
        : create "smashed_trapdoor" ;
        : destroy "axe" ;
        : set_graphic target = "drafty_room" graphic = "drafty_room_2" ;
        : pause "1600" ;
        : redescribe ;
     }
     : else {
        : print "A FRUITLESS EXERCISE!" ;
        : done ;
     }
  }
}

7.12.1. Block identifiers

You might be asking what is the purpose of the part of the block definition before the ':' character.

my_block_id : block {/* .... */}
this_can_be_anything : block {/* .... */}

Well, it’s just an identifier for the block, and used internally.

The identified should be unique, but it doesn’t correspond to anything else. It is 'arbitrary'.

Arbitrary is a word that means that 'it could be anything'. All adventuron requires is an id here, but it helps if you name it something useful, so you can remember what the block is doing.

7.12.2. The Pause Command

This section introduces the ': pause' command.

The ': pause' command is used to introduce a delay (or pause) in executing your code.

Usage
   : pause "1600" ;

The number in the quotes represents milliseconds of time to wait. One second is the same as 1,000 milliseconds of time, so the line shown above commands Adventuron to wait for 1.6 seconds.

The reason for this might be to give the player a change to read something before moving on, or for dramatic effect.

Make sure that if using a pause before a clear screen or redescribe command, that you give the player a second chance to understand what just happened.

In this case, we give two visual indicators that the trapdoor is smashed. We change the on screen graphic, and we change the on screen text (to show a smashed trapdoor).

It is a good idea NOT to place any critical story information behind a pause followed by an instant clearing of the screen (or redescribe). It will be frustrating for the player.

7.12.3. Code so far

########################################
#  Adventuron                          #
########################################

start_at       = hut

########################################
#  Locations                           #
########################################

locations {

   hut                    : location "You are in an old hut. Sunlight shines in from a doorway to the north.";
   road_1                 : location "You are standing on a track. The hut is south.";
   road_2                 : location "You are where the road turns eastwards. You see small hills in the distance.";
   road_3                 : location "You are on a road surrounded by grass. Trees can be seen on a hill in the distance.";
   road_4                 : location "You are on a dusty path on the edge of Birwood.";
   lamp_seller_on_road    : location "You are at a crossroads.";
   chasm                  : location "You are stood on the edge of a huge chasm (a cliff). A tightrope spans the gap, but it looks dangerous.";
   edge_of_birwood        : location "You are on the edge of Birwood. A rope spans the chasm northwards." ;
   deep_inside_birwood    : location "You are deep inside Birwood. The trees are alive with the buzzing of tiny insects.";
   birwood_bush           : location "You are standing in Birwood. A gap in the trees lets a warm light filter through.";
   demon_knight_road      : location "You are in a dip in the road by dark Birwood. Birds can be heard above.";
   foot_of_tree           : location "You are at the bottom of a large stone tree that is bare of any branches. The road ends here.";
   top_of_tree            : location "You are in a stone room set in a large stone tree.";
   castle_approach_1      : location "You are now a fair distance from Birwood. You can see castle Camelot to the east.";
   castle_approach_2      : location "You are outside Camelot Castle. A great stone door is the only way in.";
   castle_porch           : location "You are in the porch of Camelot.";
   banquet_hall           : location "You are in an abandoned banquet hall (eating area). Furniture lays broken on the floor.";
   drafty_room            : location "You are in a drafty room. Wind blows through gaps in the walls creating howling noises.";
   ornate_antechamber     : location "You are in an antechamber covered in thin ice that even covers the paintings.";
   portcullis             : location "You are in a room which has an iron portcullis set into the northern wall.";
   salt_mine_1            : location "You are in an old salt mine. Tunnels lead to the west and south.";
   salt_mine_2            : location "You are in the west part of the mine. It looks like it's been abandoned.";
   salt_mine_3            : location "You are at the end of the mine. You can hear the drip of water.";
   worm_room              : location "You are in the south part of the mine. There been recent movement in the rocks near your feet.";
   cold_room              : location "You are in a bitterly cold room. Everything is coated in a thick layer of ice.";
   winch_room             : location "You are in the winch room.";
   armoury                : location "You are in the armoury. Empty weapon racks line the walls.";
   most_splendid_room     : location "You are in the most splendid room in the castle. Rugs and paintings adorn the floor and walls.";
   arthur                 : location "You are in a sparse and lonely room. A cold wind enters through a high window.";

}

########################################
#  Connections                         #
########################################

connections {

   from, direction, to = [
      hut,                  north,  road_1,
      road_1,               north,  road_2,
      road_2,               east,   road_3,
      road_3,               east,   road_4,
      road_4,               north,  foot_of_tree,
      road_4,               south,  lamp_seller_on_road,
      lamp_seller_on_road,  east,   demon_knight_road,
      lamp_seller_on_road,  south,  chasm,
      foot_of_tree,         up,     top_of_tree,
      //chasm,                south,  edge_of_birwood,
      edge_of_birwood,      south,  deep_inside_birwood,
      deep_inside_birwood,  west,   birwood_bush,
      demon_knight_road,    east,   castle_approach_1,
      castle_approach_1,    east,   castle_approach_2,
      castle_approach_2,    east,   castle_porch,
      castle_porch,         east,   banquet_hall,
      banquet_hall,         north,  portcullis,
      banquet_hall,         south,  drafty_room,
      portcullis,           north,  most_splendid_room,
      most_splendid_room,   west,   arthur,
      drafty_room,          east,   ornate_antechamber,
      drafty_room,          down,   salt_mine_1,
      ornate_antechamber,   east,   cold_room,
      cold_room,            north,  winch_room,
      winch_room,           east,   armoury,
      salt_mine_1,          west,   salt_mine_2,
      salt_mine_1,          south,  worm_room,
      worm_room,            south,  salt_mine_3,
   ]

}

########################################
#  Objects                             #
########################################

objects {

   # Items we can pick-up (Objects)

   ladder           : object  "a ladder"                                    start_at="hut" ;
   red_fish         : object  "a red fish"                                  start_at="road_3" ;
   short_sword      : object  "a short sword"                               start_at="top_of_tree" ;
   coin             : object  "a coin"                                      start_at="ornate_antechamber" ;
   string           : object  "some string"                                 start_at="salt_mine_2" ;
   salt             : object  "some salt"                                   start_at="salt_mine_3" ;
   oil              : object  "can of oil"                                  start_at="cold_room" ;
   excalibur        : object  "Excalibur!"                                  start_at="armoury" ;
   long_pole        : object  "a long pole" ;
   rungs            : object  "some rungs" ;
   stone_key        : object  "a stone key" ;
   axe              : object  "a wood cutters' axe" ;
   lamp             : object  "a lamp" ;

   # Things or people that we cannot pick up (Scenery)

   old_woman        : scenery "an old woman selling lamps"                  start_at="lamp_seller_on_road" ;
   logs             : scenery "a pile of logs"                              start_at="deep_inside_birwood" ;
   bush             : scenery "a bush"                                      start_at="birwood_bush" ;
   demon_knight     : scenery "a Demon Knight guarding the east road"  start_at="demon_knight_road" ;
   trapdoor         : scenery "an old trapdoor"                             start_at="drafty_room" ;
   smashed_trapdoor : scenery "a smashed trapdoor" ;
   rockworm         : scenery "a Rockworm, guarding the south tunnel"       start_at="worm_room" ;
   ice_creature     : scenery "an Ice creature, guarding the north exit"    start_at="cold_room" ;
   winch            : scenery "a winch"                                     start_at="winch_room" ;
   spell            : scenery "a spell flying at you from Crania"           start_at="most_splendid_room" ;
   asleep_arthur    : scenery "King Arthur (asleep)"                        start_at="arthur" ;

}

########################################
#  Booleans                            #
########################################

booleans {
   is_ladder_standing : boolean "false";
}

########################################
#  Barriers                            #
########################################

barriers {

   castle_door : door {
     key   = stone_key
     from  = castle_approach_2
     to    = castle_porch
     on_unlock {
        : print "YOU UNLOCK IT WITH THE KEY, WHICH JAMS IN THE LOCK." ;
        : destroy "stone_key" ;
     }
     on_open {
        : set_graphic graphic = "castle_approach_2a" target = "castle_approach_2" ;
        : redescribe ;
     }
     on_close {
        : set_graphic graphic = "castle_approach_2"  target = "castle_approach_2" ;
        : redescribe ;
     }
   }

   tree : block {
      location          = top_of_tree
      message           = YOU CAN'T FIND YOUR GRIP
      block_when_not    = is_ladder_standing
      show_blocked_exit = false
   }

   knight : block {
      location            = castle_approach_1
      gosub               = lose_fight
      block_when_exists   = demon_knight
      show_blocked_exit   = true
   }

   trapdoor : block {
      location            = salt_mine_1
      message             = THE TRAPDOOR IS JAMMED SHUT!
      block_when_exists   = trapdoor
   }

}

########################################
#  On Command                          #
########################################

on_command {
   : match "examine ladder"  {
      : if ( is_present "ladder" ) {
         : print "A LONG POLE WITH RUNGS ATTACHED." ;
      }
   }
   : match "examine woman"  {
      : if (is_present "old_woman") {
         : print "SHE LOOKS AT YOU WITH AN INTENSE GLARE." ;
      }
   }
   : match "examine lamp"  {
      : if (is_present "lamp") {
         : print "IT'S OLD AND TARNISHED." ;
      }
   }
   : match "examine fish"  {
      : if (is_present "red_fish") {
         : print "IT STINKS!" ;
      }
   }
   : match "examine sword"  {
      : if (is_present "short_sword") {
         : print "INSCRIBED UPON IT ARE THE WORDS 'GOOD LUCK' ~~ MERLIN." ;
      }
   }
   : match "examine bush"  {
      : if (is_present "bush" && has_not_created "stone_key") {
         : print "YOU FIND SOMETHING!" ;
         : create "stone_key" ;
         : press_any_key ;
         : redescribe ;
      }
   }
   : match "examine logs"  {
      : if (is_present "logs" && has_not_created "axe") {
         : print "YOU FIND AN AXE!" ;
         : create "axe" ;
         : press_any_key ;
         : redescribe ;
      }
   }

   : match "get ladder"  {
      : if (is_at "foot_of_tree" && is_beside "ladder") {
         : get ;
         : set_false "is_ladder_standing" ;
         : set_graphic target = "foot_of_tree" graphic = "foot_of_tree"  ;
         : redescribe ;
      }
   }

   : match "stand ladder;lean ladder;rest ladder"  {
      : if (is_carried "ladder" && is_at "foot_of_tree") {
         : drop ;
         : set_true "is_ladder_standing" ;
         : set_graphic target = "foot_of_tree" graphic = "foot_of_tree_2"  ;
         : redescribe;
      }
   }

    : match "fight knight;attack knight;challenge knight"  {
      : if (is_present "demon_knight") {
         : if (is_carried "short_sword") {
            : gosub "win_fight" ;
         }
         : else {
            : gosub "lose_fight" ;
         }
      }
    }

    : match "break ladder;smash ladder;disassemble ladder"  {
       : if (is_carried "ladder") {
          : print   "OK."       ;
          : destroy "ladder"    ;
          : create  "long_pole" ;
          : create  "rungs"     ;
          : press_any_key       ;
          : redescribe          ;
       }
    }

    : match "cross chasm; balance _; walk _"  {
      : if (is_at "chasm" && is_carried "long_pole") {
         : print "THE POLE HELPS YOU BALANCE...." ;
         : press_any_key ;
         : goto "edge_of_birwood" ;
         : redescribe ;
      }
      : if (is_at "chasm" && !is_carried "long_pole") {
         : print "YOU LOSE YOUR BALANCE....." ;
         : gosub "end_game" ;
      }
      : if (is_at "edge_of_birwood" && is_carried "long_pole") {
         : print "THE POLE HELPS YOU BALANCE...." ;
         : press_any_key ;
         : goto "chasm" ;
         : redescribe ;
      }
      : if (is_at "edge_of_birwood" && !is_carried "long_pole") {
         : print "YOU LOSE YOUR BALANCE....." ;
         : gosub "end_game" ;
      }
    }

   : match "give coin; buy lamp"  {
     : if (is_present "old_woman") {
        : if (is_carried "coin") {
           : print "THE OLD LADY TAKES YOUR COIN, GIVES YOU A BRASS LAMP, THEN DISAPPEARS INTO THIN AIR." ;
           : destroy "coin" ;
           : destroy "old_woman" ;
           : create "lamp" target="inventory" ;
           : set_graphic graphic = "lamp_seller_on_road_2"  target = "lamp_seller_on_road" ;
           : press_any_key ;
           : redescribe ;
        }
        : else {
           : match "buy lamp"  {
              : print "'CROSS MY PALM WITH SILVER!'" ;
           }
        }
     }
   }


   : match "smash trapdoor;chop trapdoor;break trapdoor"  {
     : if (is_present "trapdoor") {
        : if (is_carried "axe") {
           : print "USING THE AXE, YOU SMASH THE TRAPDOOR!" ;
           : destroy "trapdoor" ;
           : create "smashed_trapdoor" ;
              : destroy "axe" ;
           : set_graphic target = "drafty_room" graphic = "drafty_room_2" ;
           : pause "1600" ;
           : redescribe ;
        }
        : else {
           : print "A FRUITLESS EXERCISE!" ;
           : done ;
        }
     }
   }

}


########################################
#  Subroutines                         #
########################################

subroutines {

   // This subroutine is executed if we lose a fight with the knight
   lose_fight : subroutine {
      // Have to explicitly attack the knight, even if you have the sword.
      : print "THE KNIGHT WIELDS HIS SWORD DEFTLY AND ATTACKS YOU...." ;
      : gosub "end_game" ;
   }

   // This subroutine is executed if we win a fight with the knight.
   win_fight : subroutine {
      : print "A GREAT BATTLE ENSUES IN WHICH YOU ARE VICTORIOUS. THE KNIGHT TURNS TO DUST BEFORE YOUR EYES ALONG WITH YOUR SWORD!" ;
      : press_any_key ;
      : destroy "demon_knight" ;
      : destroy "short_sword" ;
      : set_graphic graphic = "demon_knight_road_2"  target = "demon_knight_road" ;
      : redescribe ;
   }

   end_game : subroutine {
      : press_any_key ;
      : clear_screen;
      : print_graphic "game_over" ;
      : print "Your quest is over .........." ;
      : turns ;
      : end_game ;
   }

}

// Placeholders used for documentation purposes only as graphic data is too large to place in document.
assets {
   graphics {
      armoury               : placeholder ;
      arthur                : placeholder ;
      banquet_hall          : placeholder ;
      birwood_bush          : placeholder ;
      castle_approach_1     : placeholder ;
      castle_approach_2     : placeholder ;
      castle_approach_2a    : placeholder ;
      castle_porch          : placeholder ;
      chasm                 : placeholder ;
      cold_room             : placeholder ;
      cold_room_2           : placeholder ;
      deep_inside_birwood   : placeholder ;
      demon_knight_road     : placeholder ;
      demon_knight_road_2   : placeholder ;
      drafty_room           : placeholder ;
      drafty_room_2         : placeholder ;
      edge_of_birwood       : placeholder ;
      ending_screen         : placeholder ;
      excalibur_loading     : placeholder ;
      foot_of_tree          : placeholder ;
      foot_of_tree_2        : placeholder ;
      game_over             : placeholder ;
      hut                   : placeholder ;
      lamp_seller_on_road   : placeholder ;
      lamp_seller_on_road_2 : placeholder ;
      most_splendid_room    : placeholder ;
      most_splendid_room_2  : placeholder ;
      ornate_antechamber    : placeholder ;
      portcullis            : placeholder ;
      portcullis_2          : placeholder ;
      road_1                : placeholder ;
      road_2                : placeholder ;
      road_3                : placeholder ;
      road_4                : placeholder ;
      salt_mine_1           : placeholder ;
      salt_mine_2           : placeholder ;
      salt_mine_3           : placeholder ;
      top_of_tree           : placeholder ;
      winch_room            : placeholder ;
      worm_room             : placeholder ;
      worm_room_2           : placeholder ;
   }
}

7.13. Defeating The RockWorm

worm room

The Rockworm puzzle is the most complex puzzle to code, so please take your time to read and study this section.

The Rockworm lives in the salt mine under the castle and is blocking the way forward.

The solution to this puzzle is simply to persuade it to leave.

Rockworms are sensitive to light, so lighting the lamp is all that is required to scare the worm away.

The worm is blocking further access to the salt mines, and salt is required to tackle the Ice Creature problem.

7.13.1. Design Problems

We should discuss some design problems with this puzzle. In the 1980s, 'sudden death' puzzles were very common, and 'learn-by-death' puzzles were also common. This is one of those puzzles.

Rather than change the original logic, we will implement the mechanics here, as the game is short, and a death will only cost the player a few minutes of time.

The game also has save slots, so if the player feels like something is dangerous they can save the game.

7.13.2. Outcomes

There are 3 different outcomes to this puzzle.

1. Solution

The solution to getting past the rockworm is the light the lamp (which was purchased from the old woman) in the same room as the worm. The worm will make a noise, and get out of the way (the worm doesn’t like light).

2. Sudden Death 1

The first way is to linger in the worm’s location for too long. The game will warn the player before the worm will make its fatal move, then on the next move, if the player has not moved away, the player will 'die'.

3. Sudden Death 2

The second is to try to move beyond the worm. This is a variant of the knight logic (where moving past the demon knight would end the game).

Note
The original logic of the game had a restriction that it was only possible to light the lamp once, and if you did it at the wrong time, the game was unwinnable. This version of the game removes that unwinnable state.
The Worm Attacks !

First, we can put the worm attack code into a subroutine, so we can reference it from multiple places in our code. This is because the worm can attack in multiple ways (if we stay too long, or if we try to move past the worm).

subroutines {}
worm_attack : subroutine {
  : print "THE ROCKWORM RISES UP AND TAKES YOU IN ITS GLEAMING MANDIBLES." ;
  : gosub "end_game" ;
}

Now we create the block (a subroutine block) in the barriers{} section.

This will make sure that if the player attempts to move past the worm, they will see the message "THE ROCKWORM RISES UP AND TAKES YOU IN ITS GLEAMING MANDIBLES.", and then the game will end.

barriers {}
worm : block {
    location            = salt_mine_3
    gosub               = worm_attack
    block_when_exists   = rockworm
    show_blocked_exit   = true
}
Timed Events

Adventuron supports timed events. A timed even is something that will happen after a certain amount of turns of the game (entering commands).

To perform a timed event, we need to put some if statements in the on_tick {} block of code. The on_tick{} section of code is executed after the player has submitted a command.

This can be after the screen is redrawn (such as changing location), or it could be after any command is executed (such as GET LAMP or EXAMINE BUSH).

In Excalibur, we want the worm to attack if the player stays in the same location as the worm for 4 turns. We also want to issue a warning to the player after 3 turns that the worm is getting ready to attack.

The code to achieve this is as follows.

on_tick {
   : if (is_present "rockworm" ) {
      : if (linger() == 3) {
         : print "THE ROCKWORM STARTS MOVING TOWARDS YOU" ;
      }
      : if (linger() == 4) {
         : gosub "worm_attack" ;
      }
   }
}

The on_tick {} block is executed after the player enters a command.

The next part is an if () {} statement that checks to see if the rockworm is present in the same scene / location of the game. The inner if statements will only be executed if we are sharing a scene with the rockworm.

The first INNER IF STATEMENT tests to see if we have been 3 turns in the current location. If we have then it prints "THE ROCKWORM STARTS MOVING TOWARDS YOU".

The second INNER IF STATEMENT tests to see if we have been 4 turns in the current location. If we have, then it prints "THE ROCKWORM RISES UP AND TAKES YOU IN ITS GLEAMING MANDIBLES.", and it executs the end_game subroutine. (Game over).

The linger() function

You may be wondering what is linger(), and how it works. linger is an expression item that resolves to a number. It returns the number of turns since we arrived in a location (or scene). Just after we change location, it will RETURN a ZERO value. ZERO is the number 0.

Numbers can be turned into a yes or no answer by comparing them against other numbers.

Integer Operator Sample Description

==

linger() == 3

Return TRUE 3 turns after arriving in the current scene, return FALSE otherwise.

==

linger() == 4

Return TRUE 4 turns after arriving in the current scene, return FALSE otherwise.

Boolean Variables

A boolean variable is a way of storing if something is a yes answer (true) or a no answer (false).

In Excalibur, we create the 'is_light_lit' boolean variable, which is initially set to have a 'false' value. A 'false' value is the same as a 'no' value. So, this section of code tells the game, that at the start of the game, we should remember that we light is not lit.

We can change the VALUE of a VARIABLE during the game, and we can ask questions about the current content of a variable from anywhere inside our game code. So, later on in the code, we can store a TRUE value inside 'is_light_lit'…​. But that comes later.

booleans {
   is_light_lit : boolean "false" ;
}

The boolean variable is created at root level (not inside any other block of code).

Lighting The Lamp

While the player is holding the unlit lamp (the game checks the value of the 'is_light_lit' variable), if the player types LIGHT LAMP the following actions are performed:

  • We set the 'is_light_lit' boolean variable to a value of TRUE (we use this to inform the player that the light has gone out if they change location).

If the player lights the lamp in the presence of the Rockworm, the following happens:

  • We print the message "THE ROCKWORM’S SENSITIVE EYES ARE SURPRISED BY THE STRONG LIGHT AND IT RETREATS DOWN ITS BURROW …​."

  • We remove the Rockworm from the game.

  • We remove the block from 'salt_mine_3' location.

  • We change the graphic of 'worm_room' location to the replacement picture 'worm_room_2' (room without the worm).

  • We wait for the user to press any key.

  • Redescribe the current location (redraw the graphic and clear previous commands from the screen).

If the light is lit without the worm present, then:

  • Print the message "IT EMITS A BRIGHT LIGHT."

on_command{}
: match "light lamp; switch lamp; turn lamp"  {
  : if (is_present "lamp" && is_light_lit == false) {
    : set_true "is_light_lit" ;
    : if (is_present "rockworm") {
       : print "THE ROCKWORM'S SENSITIVE EYES ARE SURPRISED BY THE STRONG LIGHT AND IT RETREATS DOWN ITS BURROW ...." ;
       : destroy "rockworm" ;
       : set_graphic target = "worm_room" graphic = "worm_room_2" ;
       : press_any_key ;
       : redescribe ;
    }
    : else {
       : print "IT EMITS A BRIGHT LIGHT." ;
       : done ;
    }
  }
}
on_describe{}

The on_describe{} code block is executed when a scene is described, either by moving to a new location, or by typing (or clicking/touching/saying) "look".

It is usually used to add additional information to a scene or to trigger some event (triggering an event means performing some code that tells the player new information or changes the game).

We will use this block to make sure that we report that the light (from the lamp) goes out when we change location. The purpose of this is so that the player must always type LIGHT LAMP to solve the Rockworm puzzle.

If the player could just light the lamp and carry it around indefinately, then they may solve the Rockworm puzzle accidentally.

Putting this in the on_describe {} means that whatever location is travelled to after lighting the lamp, the light is described as going out, so the player knows that lighting the lamp will still do something if they do it again.

on_describe {
  : if (is_light_lit) {
     : print "THE LIGHT'S GONE OUT." ;
     : set_false "is_light_lit" ;
  }
}

7.13.3. Code so far …​.

########################################
#  Adventuron                          #
########################################

start_at       = hut

########################################
#  Locations                           #
########################################

locations {

   hut                    : location "You are in an old hut. Sunlight shines in from a doorway to the north.";
   road_1                 : location "You are standing on a track. The hut is south.";
   road_2                 : location "You are where the road turns eastwards. You see small hills in the distance.";
   road_3                 : location "You are on a road surrounded by grass. Trees can be seen on a hill in the distance.";
   road_4                 : location "You are on a dusty path on the edge of Birwood.";
   lamp_seller_on_road    : location "You are at a crossroads.";
   chasm                  : location "You are stood on the edge of a huge chasm (a cliff). A tightrope spans the gap, but it looks dangerous.";
   edge_of_birwood        : location "You are on the edge of Birwood. A rope spans the chasm northwards." ;
   deep_inside_birwood    : location "You are deep inside Birwood. The trees are alive with the buzzing of tiny insects.";
   birwood_bush           : location "You are standing in Birwood. A gap in the trees lets a warm light filter through.";
   demon_knight_road      : location "You are in a dip in the road by dark Birwood. Birds can be heard above.";
   foot_of_tree           : location "You are at the bottom of a large stone tree that is bare of any branches. The road ends here.";
   top_of_tree            : location "You are in a stone room set in a large stone tree.";
   castle_approach_1      : location "You are now a fair distance from Birwood. You can see castle Camelot to the east.";
   castle_approach_2      : location "You are outside Camelot Castle. A great stone door is the only way in.";
   castle_porch           : location "You are in the porch of Camelot.";
   banquet_hall           : location "You are in an abandoned banquet hall (eating area). Furniture lays broken on the floor.";
   drafty_room            : location "You are in a drafty room. Wind blows through gaps in the walls creating howling noises.";
   ornate_antechamber     : location "You are in an antechamber covered in thin ice that even covers the paintings.";
   portcullis             : location "You are in a room which has an iron portcullis set into the northern wall.";
   salt_mine_1            : location "You are in an old salt mine. Tunnels lead to the west and south.";
   salt_mine_2            : location "You are in the west part of the mine. It looks like it's been abandoned.";
   salt_mine_3            : location "You are at the end of the mine. You can hear the drip of water.";
   worm_room              : location "You are in the south part of the mine. There been recent movement in the rocks near your feet.";
   cold_room              : location "You are in a bitterly cold room. Everything is coated in a thick layer of ice.";
   winch_room             : location "You are in the winch room.";
   armoury                : location "You are in the armoury. Empty weapon racks line the walls.";
   most_splendid_room     : location "You are in the most splendid room in the castle. Rugs and paintings adorn the floor and walls.";
   arthur                 : location "You are in a sparse and lonely room. A cold wind enters through a high window.";

}

########################################
#  Connections                         #
########################################

connections {

   from, direction, to = [
      hut,                  north,  road_1,
      road_1,               north,  road_2,
      road_2,               east,   road_3,
      road_3,               east,   road_4,
      road_4,               north,  foot_of_tree,
      road_4,               south,  lamp_seller_on_road,
      lamp_seller_on_road,  east,   demon_knight_road,
      lamp_seller_on_road,  south,  chasm,
      foot_of_tree,         up,     top_of_tree,
      //chasm,                south,  edge_of_birwood,
      edge_of_birwood,      south,  deep_inside_birwood,
      deep_inside_birwood,  west,   birwood_bush,
      demon_knight_road,    east,   castle_approach_1,
      castle_approach_1,    east,   castle_approach_2,
      castle_approach_2,    east,   castle_porch,
      castle_porch,         east,   banquet_hall,
      banquet_hall,         north,  portcullis,
      banquet_hall,         south,  drafty_room,
      portcullis,           north,  most_splendid_room,
      most_splendid_room,   west,   arthur,
      drafty_room,          east,   ornate_antechamber,
      drafty_room,          down,   salt_mine_1,
      ornate_antechamber,   east,   cold_room,
      cold_room,            north,  winch_room,
      winch_room,           east,   armoury,
      salt_mine_1,          west,   salt_mine_2,
      salt_mine_1,          south,  worm_room,
      worm_room,            south,  salt_mine_3,
   ]

}

########################################
#  Object                              #
########################################

objects {

   # Items we can pick-up (Objects)

   ladder           : object  "a ladder"                                    start_at="hut" ;
   red_fish         : object  "a red fish"                                  start_at="road_3" ;
   short_sword      : object  "a short sword"                               start_at="top_of_tree" ;
   coin             : object  "a coin"                                      start_at="ornate_antechamber" ;
   string           : object  "some string"                                 start_at="salt_mine_2" ;
   salt             : object  "some salt"                                   start_at="salt_mine_3" ;
   oil              : object  "can of oil"                                  start_at="cold_room" ;
   excalibur        : object  "Excalibur!"                                  start_at="armoury" ;
   long_pole        : object  "a long pole" ;
   rungs            : object  "some rungs" ;
   stone_key        : object  "a stone key" ;
   axe              : object  "a wood cutters' axe" ;
   lamp             : object  "a lamp" ;

   # Things or people that we cannot pick up (Scenery)

   old_woman        : scenery "an old woman selling lamps"                  start_at="lamp_seller_on_road" ;
   logs             : scenery "a pile of logs"                              start_at="deep_inside_birwood" ;
   bush             : scenery "a bush"                                      start_at="birwood_bush" ;
   demon_knight     : scenery "a Demon Knight guarding the east road"  start_at="demon_knight_road" ;
   trapdoor         : scenery "an old trapdoor"                             start_at="drafty_room" ;
   smashed_trapdoor : scenery "a smashed trapdoor" ;
   rockworm         : scenery "a Rockworm, guarding the south tunnel"       start_at="worm_room" ;
   ice_creature     : scenery "an Ice creature, guarding the north exit"    start_at="cold_room" ;
   winch            : scenery "a winch"                                     start_at="winch_room" ;
   spell            : scenery "a spell flying at you from Crania"           start_at="most_splendid_room" ;
   asleep_arthur    : scenery "King Arthur (asleep)"                        start_at="arthur" ;

}

########################################
#  Booleans                            #
########################################

booleans {
   is_ladder_standing : boolean "false" ;
   is_light_lit       : boolean "false" ;
}

########################################
#  Barriers                            #
########################################

barriers {

   castle_door : door {
     key   = stone_key
     from  = castle_approach_2
     to    = castle_porch
     on_unlock {
        : print "YOU UNLOCK IT WITH THE KEY, WHICH JAMS IN THE LOCK." ;
        : destroy "stone_key" ;
     }
     on_open {
        : set_graphic graphic = "castle_approach_2a" target = "castle_approach_2" ;
        : redescribe ;
     }
     on_close {
        : set_graphic graphic = "castle_approach_2"  target = "castle_approach_2" ;
        : redescribe ;
     }
   }

   tree : block {
      location          = top_of_tree
      message           = YOU CAN'T FIND YOUR GRIP
      block_when_not    = is_ladder_standing
      show_blocked_exit = false
   }


   knight : block {
      location            = castle_approach_1
      gosub               = lose_fight
      block_when_exists   = demon_knight
      show_blocked_exit   = true
   }

   trapdoor : block {
      location            = salt_mine_1
      message             = THE TRAPDOOR IS JAMMED SHUT!
      block_when_exists   = trapdoor
   }

   worm : block {
      location            = salt_mine_3
      gosub               = worm_attack
      block_when_exists   = rockworm
      show_blocked_exit   = true
   }

}

########################################
#  On Describe                         #
########################################

on_describe {
   : if (is_light_lit) {
      : print "THE LIGHT'S GONE OUT." ;
      : set_false "is_light_lit" ;
   }
}

########################################
#  On Describe                         #
########################################

on_tick {
   : if (is_present "rockworm" ) {
      : if (linger() == 3) {
         : print "THE ROCKWORM STARTS MOVING TOWARDS YOU" ;
      }
      : if (linger() == 4) {
         : gosub "worm_attack" ;
      }
   }
}

########################################
#  On Command                          #
########################################

on_command {
   : match "examine ladder"  {
      : if ( is_present "ladder" ) {
         : print "A LONG POLE WITH RUNGS ATTACHED." ;
      }
   }
   : match "examine woman"  {
      : if (is_present "old_woman") {
         : print "SHE LOOKS AT YOU WITH AN INTENSE GLARE." ;
      }
   }
   : match "examine lamp"  {
      : if (is_present "lamp") {
         : print "IT'S OLD AND TARNISHED." ;
      }
   }
   : match "examine fish"  {
      : if (is_present "red_fish") {
         : print "IT STINKS!" ;
      }
   }
   : match "examine sword"  {
      : if (is_present "short_sword") {
         : print "INSCRIBED UPON IT ARE THE WORDS 'GOOD LUCK' ~~ MERLIN." ;
      }
   }
   : match "examine bush"  {
      : if (is_present "bush" && has_not_created "stone_key") {
         : print "YOU FIND SOMETHING!" ;
         : create "stone_key" ;
         : press_any_key ;
         : redescribe ;
      }
   }
   : match "examine logs"  {
      : if (is_present "logs" && has_not_created "axe") {
         : print "YOU FIND AN AXE!" ;
         : create "axe" ;
         : press_any_key ;
         : redescribe ;
      }
   }

   : match "get ladder"  {
      : if (is_at "foot_of_tree" && is_beside "ladder") {
         : get ;
         : set_false "is_ladder_standing" ;
         : set_graphic target = "foot_of_tree" graphic = "foot_of_tree"  ;
         : redescribe ;
      }
   }

   : match "stand ladder;lean ladder;rest ladder"  {
      : if (is_carried "ladder" && is_at "foot_of_tree") {
         : drop ;
         : set_true "is_ladder_standing" ;
         : set_graphic target = "foot_of_tree" graphic = "foot_of_tree_2"  ;
         : redescribe;
      }
   }

    : match "fight knight;attack knight;challenge knight"  {
      : if (is_present "demon_knight") {
         : if (is_carried "short_sword") {
            : gosub "win_fight" ;
         }
         : else {
            : gosub "lose_fight" ;
         }
      }
    }

    : match "break ladder;smash ladder;disassemble ladder"  {
       : if (is_carried "ladder") {
          : print   "OK."       ;
          : destroy "ladder"    ;
          : create  "long_pole" ;
          : create  "rungs"     ;
          : press_any_key       ;
          : redescribe          ;
       }
    }

    : match "cross chasm; balance _; walk _"  {
      : if (is_at "chasm" && is_carried "long_pole") {
         : print "THE POLE HELPS YOU BALANCE...." ;
         : press_any_key ;
         : goto "edge_of_birwood" ;
         : redescribe ;
      }
      : if (is_at "chasm" && !is_carried "long_pole") {
         : print "YOU LOSE YOUR BALANCE....." ;
         : gosub "end_game" ;
      }
      : if (is_at "edge_of_birwood" && is_carried "long_pole") {
         : print "THE POLE HELPS YOU BALANCE...." ;
         : press_any_key ;
         : goto "chasm" ;
         : redescribe ;
      }
      : if (is_at "edge_of_birwood" && !is_carried "long_pole") {
         : print "YOU LOSE YOUR BALANCE....." ;
         : gosub "end_game" ;
      }
    }

   : match "give coin; buy lamp"  {
     : if (is_present "old_woman") {
        : if (is_carried "coin") {
           : print "THE OLD LADY TAKES YOUR COIN, GIVES YOU A BRASS LAMP, THEN DISAPPEARS INTO THIN AIR." ;
           : destroy "coin" ;
           : destroy "old_woman" ;
           : create "lamp" target="inventory" ;
           : set_graphic graphic = "lamp_seller_on_road_2"  target = "lamp_seller_on_road" ;
           : press_any_key ;
           : redescribe ;
        }
        : else {
           : match "buy lamp"  {
              : print "'CROSS MY PALM WITH SILVER!'" ;
           }
        }
     }
   }


   : match "smash trapdoor;chop trapdoor;break trapdoor"  {
     : if (is_present "trapdoor") {
        : if (is_carried "axe") {
           : print "USING THE AXE, YOU SMASH THE TRAPDOOR!" ;
           : destroy "trapdoor" ;
           : create "smashed_trapdoor" ;
              : destroy "axe" ;
           : set_graphic target = "drafty_room" graphic = "drafty_room_2" ;
           : pause "1600" ;
           : redescribe ;
        }
        : else {
           : print "A FRUITLESS EXERCISE!" ;
           : done ;
        }
     }
   }

   : match "light lamp; switch lamp; turn lamp"  {
     : if (is_present "lamp" && is_light_lit == false) {
       : set_true "is_light_lit" ;
       : if (is_present "rockworm") {
          : print "THE ROCKWORM'S SENSITIVE EYES ARE SURPRISED BY THE STRONG LIGHT AND IT RETREATS DOWN ITS BURROW ...." ;
          : destroy "rockworm" ;
          : set_graphic target = "worm_room" graphic = "worm_room_2" ;
          : press_any_key ;
          : redescribe ;
       }
       : else {
          : print "IT EMITS A BRIGHT LIGHT." ;
          : done ;
       }
     }
   }

}


########################################
#  Subroutines                         #
########################################

subroutines {

   // This subroutine is executed if we lose a fight with the knight
   lose_fight : subroutine {
      // Have to explicitly attack the knight, even if you have the sword.
      : print "THE KNIGHT WIELDS HIS SWORD DEFTLY AND ATTACKS YOU...." ;
      : gosub "end_game" ;
   }

   // This subroutine is executed if we win a fight with the knight.
   win_fight : subroutine {
      : print "A GREAT BATTLE ENSUES IN WHICH YOU ARE VICTORIOUS. THE KNIGHT TURNS TO DUST BEFORE YOUR EYES ALONG WITH YOUR SWORD!" ;
      : press_any_key ;
      : destroy "demon_knight" ;
      : destroy "short_sword" ;
      : set_graphic graphic = "demon_knight_road_2"  target = "demon_knight_road" ;
      : redescribe ;
   }

   end_game : subroutine {
      : press_any_key ;
      : clear_screen;
      : print_graphic "game_over";
      : print "Your quest is over .........." ;
      : turns ;
      : end_game ;
   }

   worm_attack : subroutine {
     : print "THE ROCKWORM RISES UP AND TAKES YOU IN ITS GLEAMING MANDIBLES." ;
     : gosub "end_game" ;
   }

}

// Placeholders used for documentation purposes only as graphic data is too large to place in document.
assets {
   graphics {
      armoury               : placeholder ;
      arthur                : placeholder ;
      banquet_hall          : placeholder ;
      birwood_bush          : placeholder ;
      castle_approach_1     : placeholder ;
      castle_approach_2     : placeholder ;
      castle_approach_2a    : placeholder ;
      castle_porch          : placeholder ;
      chasm                 : placeholder ;
      cold_room             : placeholder ;
      cold_room_2           : placeholder ;
      deep_inside_birwood   : placeholder ;
      demon_knight_road     : placeholder ;
      demon_knight_road_2   : placeholder ;
      drafty_room           : placeholder ;
      drafty_room_2         : placeholder ;
      edge_of_birwood       : placeholder ;
      ending_screen         : placeholder ;
      excalibur_loading     : placeholder ;
      foot_of_tree          : placeholder ;
      foot_of_tree_2        : placeholder ;
      game_over             : placeholder ;
      hut                   : placeholder ;
      lamp_seller_on_road   : placeholder ;
      lamp_seller_on_road_2 : placeholder ;
      most_splendid_room    : placeholder ;
      most_splendid_room_2  : placeholder ;
      ornate_antechamber    : placeholder ;
      portcullis            : placeholder ;
      portcullis_2          : placeholder ;
      road_1                : placeholder ;
      road_2                : placeholder ;
      road_3                : placeholder ;
      road_4                : placeholder ;
      salt_mine_1           : placeholder ;
      salt_mine_2           : placeholder ;
      salt_mine_3           : placeholder ;
      top_of_tree           : placeholder ;
      winch_room            : placeholder ;
      worm_room             : placeholder ;
      worm_room_2           : placeholder ;
   }
}

7.14. Defeating The Ice Creature

cold room

Defeating the ice creature is extremely simple, if a little cruel.

You must throw salt at the Ice Creature, and then it dissolves into nothingness.

What did the Ice Creature ever do to anyone apart from block the path to the winch? Why was the Ice creature guarding the winch? Did it expect that this would be its final job? Who will take care of the icicles now?

Anyway, this again is a simple blocking arrangement, then graphic swap (to a version of the graphic without the creature) upon typing the words THROW SALT when in the same room as the ice creature, and holding the salt.

First, let’s add the block, and the description of the block.

This block itself is not a 'sudden death' block. It just tells the player 'THE ICE CREATURE WILL NOT ALLOW IT …​'.

barriers {}
ice_creature : block {
   location            = winch_room
   message             = THE ICE CREATURE WILL NOT ALLOW IT ...
   block_when_exists   = ice_creature
   show_blocked_exit   = true
}

Now we add the on_command{} match command to respond to "throw salt". Perhaps you can figure out what to type now without reading the next part?

on_command {}
: match "throw salt"  {
   : if (is_present "ice_creature") {
      : if (is_carried "salt") {
         : print "THE CREATURE BEGINS TO MELT RAPIDLY..." ;
         : destroy "ice_creature" ;
            : destroy "salt" ;
         : set_graphic target = "cold_room" graphic = "cold_room_2" ;
         : press_any_key ;
         : redescribe ;
      }
      : else {
         : print "YOU DON'T HAVE ANY." ;
      }
   }
   : else {
      : print "NOT RIGHT NOW." ;
   }
}

The Ice Creature is another "sudden death" type monster if you stay in the room more than one turn.

We implement the "sudden death" here.

on_tick {}
: if (is_present "ice_creature") {
  : if (linger() == 1) {
     : print "THE ICE CREATURE TAKES YOU IN A FREEZING GRIP" ;
     : gosub "end_game" ;
  }
}

7.14.1. Code so far …​.

########################################
#  Adventuron                          #
########################################

start_at       = hut

########################################
#  Locations                           #
########################################

locations {

   hut                    : location "You are in an old hut. Sunlight shines in from a doorway to the north.";
   road_1                 : location "You are standing on a track. The hut is south.";
   road_2                 : location "You are where the road turns eastwards. You see small hills in the distance.";
   road_3                 : location "You are on a road surrounded by grass. Trees can be seen on a hill in the distance.";
   road_4                 : location "You are on a dusty path on the edge of Birwood.";
   lamp_seller_on_road    : location "You are at a crossroads.";
   chasm                  : location "You are stood on the edge of a huge chasm (a cliff). A tightrope spans the gap, but it looks dangerous.";
   edge_of_birwood        : location "You are on the edge of Birwood. A rope spans the chasm northwards." ;
   deep_inside_birwood    : location "You are deep inside Birwood. The trees are alive with the buzzing of tiny insects.";
   birwood_bush           : location "You are standing in Birwood. A gap in the trees lets a warm light filter through.";
   demon_knight_road      : location "You are in a dip in the road by dark Birwood. Birds can be heard above.";
   foot_of_tree           : location "You are at the bottom of a large stone tree that is bare of any branches. The road ends here.";
   top_of_tree            : location "You are in a stone room set in a large stone tree.";
   castle_approach_1      : location "You are now a fair distance from Birwood. You can see castle Camelot to the east.";
   castle_approach_2      : location "You are outside Camelot Castle. A great stone door is the only way in.";
   castle_porch           : location "You are in the porch of Camelot.";
   banquet_hall           : location "You are in an abandoned banquet hall (eating area). Furniture lays broken on the floor.";
   drafty_room            : location "You are in a drafty room. Wind blows through gaps in the walls creating howling noises.";
   ornate_antechamber     : location "You are in an antechamber covered in thin ice that even covers the paintings.";
   portcullis             : location "You are in a room which has an iron portcullis set into the northern wall.";
   salt_mine_1            : location "You are in an old salt mine. Tunnels lead to the west and south.";
   salt_mine_2            : location "You are in the west part of the mine. It looks like it's been abandoned.";
   salt_mine_3            : location "You are at the end of the mine. You can hear the drip of water.";
   worm_room              : location "You are in the south part of the mine. There been recent movement in the rocks near your feet.";
   cold_room              : location "You are in a bitterly cold room. Everything is coated in a thick layer of ice.";
   winch_room             : location "You are in the winch room.";
   armoury                : location "You are in the armoury. Empty weapon racks line the walls.";
   most_splendid_room     : location "You are in the most splendid room in the castle. Rugs and paintings adorn the floor and walls.";
   arthur                 : location "You are in a sparse and lonely room. A cold wind enters through a high window.";

}

########################################
#  Connections                         #
########################################

connections {

   from, direction, to = [
      hut,                  north,  road_1,
      road_1,               north,  road_2,
      road_2,               east,   road_3,
      road_3,               east,   road_4,
      road_4,               north,  foot_of_tree,
      road_4,               south,  lamp_seller_on_road,
      lamp_seller_on_road,  east,   demon_knight_road,
      lamp_seller_on_road,  south,  chasm,
      foot_of_tree,         up,     top_of_tree,
      //chasm,                south,  edge_of_birwood,
      edge_of_birwood,      south,  deep_inside_birwood,
      deep_inside_birwood,  west,   birwood_bush,
      demon_knight_road,    east,   castle_approach_1,
      castle_approach_1,    east,   castle_approach_2,
      castle_approach_2,    east,   castle_porch,
      castle_porch,         east,   banquet_hall,
      banquet_hall,         north,  portcullis,
      banquet_hall,         south,  drafty_room,
      portcullis,           north,  most_splendid_room,
      most_splendid_room,   west,   arthur,
      drafty_room,          east,   ornate_antechamber,
      drafty_room,          down,   salt_mine_1,
      ornate_antechamber,   east,   cold_room,
      cold_room,            north,  winch_room,
      winch_room,           east,   armoury,
      salt_mine_1,          west,   salt_mine_2,
      salt_mine_1,          south,  worm_room,
      worm_room,            south,  salt_mine_3,
   ]

}

########################################
#  Objects                             #
########################################

objects {

   # Items we can pick-up (Objects)

   ladder           : object  "a ladder"                                    start_at="hut" ;
   red_fish         : object  "a red fish"                                  start_at="road_3" ;
   short_sword      : object  "a short sword"                               start_at="top_of_tree" ;
   coin             : object  "a coin"                                      start_at="ornate_antechamber" ;
   string           : object  "some string"                                 start_at="salt_mine_2" ;
   salt             : object  "some salt"                                   start_at="salt_mine_3" ;
   oil              : object  "can of oil"                                  start_at="cold_room" ;
   excalibur        : object  "Excalibur!"                                  start_at="armoury" ;
   long_pole        : object  "a long pole" ;
   rungs            : object  "some rungs" ;
   stone_key        : object  "a stone key" ;
   axe              : object  "a wood cutters' axe" ;
   lamp             : object  "a lamp" ;

   # Things or people that we cannot pick up (Scenery)

   old_woman        : scenery "an old woman selling lamps"                  start_at="lamp_seller_on_road" ;
   logs             : scenery "a pile of logs"                              start_at="deep_inside_birwood" ;
   bush             : scenery "a bush"                                      start_at="birwood_bush" ;
   demon_knight     : scenery "a Demon Knight guarding the east road"  start_at="demon_knight_road" ;
   trapdoor         : scenery "an old trapdoor"                             start_at="drafty_room" ;
   smashed_trapdoor : scenery "a smashed trapdoor" ;
   rockworm         : scenery "a Rockworm, guarding the south tunnel"       start_at="worm_room" ;
   ice_creature     : scenery "an Ice creature, guarding the north exit"    start_at="cold_room" ;
   winch            : scenery "a winch"                                     start_at="winch_room" ;
   spell            : scenery "a spell flying at you from Crania"           start_at="most_splendid_room" ;
   asleep_arthur    : scenery "King Arthur (asleep)"                        start_at="arthur" ;

}

########################################
#  Booleans                            #
########################################

booleans {
   is_ladder_standing : boolean "false" ;
   is_light_lit       : boolean "false" ;
}

########################################
#  Blocks                              #
########################################

barriers {

   castle_door : door {
     key   = stone_key
     from  = castle_approach_2
     to    = castle_porch
     on_unlock {
        : print "YOU UNLOCK IT WITH THE KEY, WHICH JAMS IN THE LOCK." ;
        : destroy "stone_key" ;
     }
     on_open {
        : set_graphic graphic = "castle_approach_2a" target = "castle_approach_2" ;
        : redescribe ;
     }
     on_close {
        : set_graphic graphic = "castle_approach_2"  target = "castle_approach_2" ;
        : redescribe ;
     }
   }

   tree : block {
      location          = top_of_tree
      message           = YOU CAN'T FIND YOUR GRIP
      block_when_not    = is_ladder_standing
      show_blocked_exit = false
   }

   knight : block {
      location            = castle_approach_1
      gosub               = lose_fight
      block_when_exists   = demon_knight
      show_blocked_exit   = true
   }

   trapdoor : block {
      location            = salt_mine_1
      message             = THE TRAPDOOR IS JAMMED SHUT!
      block_when_exists   = trapdoor
   }

   worm : block {
      location            = salt_mine_3
      gosub               = worm_attack
      block_when_exists   = rockworm
      show_blocked_exit   = true
   }

   ice_creature : block {
      location            = winch_room
      message             = THE ICE CREATURE WILL NOT ALLOW IT ...
      block_when_exists   = ice_creature
      show_blocked_exit   = true
   }

}

########################################
#  On Describe                         #
########################################

on_describe {
   : if (is_light_lit) {
      : print "THE LIGHT'S GONE OUT." ;
      : set_false "is_light_lit" ;
   }
}

########################################
#  On Describe                         #
########################################

on_tick {
   : if (is_present "rockworm" ) {
      : if (linger() == 3) {
         : print "THE ROCKWORM STARTS MOVING TOWARDS YOU" ;
      }
      : if (linger() == 4) {
         : gosub "worm_attack" ;
      }
   }
   : if (is_present "ice_creature") {
     : if (linger() == 1) {
        : print "THE ICE CREATURE TAKES YOU IN A FREEZING GRIP" ;
        : gosub "end_game" ;
     }
   }
}

########################################
#  On Command                          #
########################################

on_command {
   : match "examine ladder"  {
      : if ( is_present "ladder" ) {
         : print "A LONG POLE WITH RUNGS ATTACHED." ;
      }
   }
   : match "examine woman"  {
      : if (is_present "old_woman") {
         : print "SHE LOOKS AT YOU WITH AN INTENSE GLARE." ;
      }
   }
   : match "examine lamp"  {
      : if (is_present "lamp") {
         : print "IT'S OLD AND TARNISHED." ;
      }
   }
   : match "examine fish"  {
      : if (is_present "red_fish") {
         : print "IT STINKS!" ;
      }
   }
   : match "examine sword"  {
      : if (is_present "short_sword") {
         : print "INSCRIBED UPON IT ARE THE WORDS 'GOOD LUCK' ~~ MERLIN." ;
      }
   }
   : match "examine bush"  {
      : if (is_present "bush" && has_not_created "stone_key") {
         : print "YOU FIND SOMETHING!" ;
         : create "stone_key" ;
         : press_any_key ;
         : redescribe ;
      }
   }
   : match "examine logs"  {
      : if (is_present "logs" && has_not_created "axe") {
         : print "YOU FIND AN AXE!" ;
         : create "axe" ;
         : press_any_key ;
         : redescribe ;
      }
   }

   : match "get ladder"  {
      : if (is_at "foot_of_tree" && is_beside "ladder") {
         : get ;
         : set_false "is_ladder_standing" ;
         : set_graphic target = "foot_of_tree" graphic = "foot_of_tree"  ;
         : redescribe ;
      }
   }

   : match "stand ladder;lean ladder;rest ladder"  {
      : if (is_carried "ladder" && is_at "foot_of_tree") {
         : drop ;
         : set_true "is_ladder_standing" ;
         : set_graphic target = "foot_of_tree" graphic = "foot_of_tree_2"  ;
         : redescribe;
      }
   }

    : match "fight knight;attack knight;challenge knight"  {
      : if (is_present "demon_knight") {
         : if (is_carried "short_sword") {
            : gosub "win_fight" ;
         }
         : else {
            : gosub "lose_fight" ;
         }
      }
    }

    : match "break ladder;smash ladder;disassemble ladder"  {
       : if (is_carried "ladder") {
          : print   "OK."       ;
          : destroy "ladder"    ;
          : create  "long_pole" ;
          : create  "rungs"     ;
          : press_any_key       ;
          : redescribe          ;
       }
    }

    : match "cross chasm; balance _; walk _"  {
      : if (is_at "chasm" && is_carried "long_pole") {
         : print "THE POLE HELPS YOU BALANCE...." ;
         : press_any_key ;
         : goto "edge_of_birwood" ;
         : redescribe ;
      }
      : if (is_at "chasm" && !is_carried "long_pole") {
         : print "YOU LOSE YOUR BALANCE....." ;
         : gosub "end_game" ;
      }
      : if (is_at "edge_of_birwood" && is_carried "long_pole") {
         : print "THE POLE HELPS YOU BALANCE...." ;
         : press_any_key ;
         : goto "chasm" ;
         : redescribe ;
      }
      : if (is_at "edge_of_birwood" && !is_carried "long_pole") {
         : print "YOU LOSE YOUR BALANCE....." ;
         : gosub "end_game" ;
      }
    }

   : match "give coin; buy lamp"  {
     : if (is_present "old_woman") {
        : if (is_carried "coin") {
           : print "THE OLD LADY TAKES YOUR COIN, GIVES YOU A BRASS LAMP, THEN DISAPPEARS INTO THIN AIR." ;
           : destroy "coin" ;
           : destroy "old_woman" ;
           : create "lamp" target="inventory" ;
           : set_graphic graphic = "lamp_seller_on_road_2"  target = "lamp_seller_on_road" ;
           : press_any_key ;
           : redescribe ;
        }
        : else {
           : match "buy lamp"  {
              : print "'CROSS MY PALM WITH SILVER!'" ;
           }
        }
     }
   }


   : match "smash trapdoor;chop trapdoor;break trapdoor"  {
     : if (is_present "trapdoor") {
        : if (is_carried "axe") {
           : print "USING THE AXE, YOU SMASH THE TRAPDOOR!" ;
           : destroy "trapdoor" ;
           : create "smashed_trapdoor" ;
              : destroy "axe" ;
           : set_graphic target = "drafty_room" graphic = "drafty_room_2" ;
           : pause "1600" ;
           : redescribe ;
        }
        : else {
           : print "A FRUITLESS EXERCISE!" ;
           : done ;
        }
     }
   }

   : match "light lamp; switch lamp; turn lamp"  {
     : if (is_present "lamp" && is_light_lit == false) {
       : set_true "is_light_lit" ;
       : if (is_present "rockworm") {
          : print "THE ROCKWORM'S SENSITIVE EYES ARE SURPRISED BY THE STRONG LIGHT AND IT RETREATS DOWN ITS BURROW ...." ;
          : destroy "rockworm" ;
          : set_graphic target = "worm_room" graphic = "worm_room_2" ;
          : press_any_key ;
          : redescribe ;
       }
       : else {
          : print "IT EMITS A BRIGHT LIGHT." ;
       }
     }
   }

   : match "throw salt"  {
      : if (is_present "ice_creature") {
         : if (is_carried "salt") {
            : print "THE CREATURE BEGINS TO MELT RAPIDLY..." ;
            : destroy "ice_creature" ;
              : destroy "salt" ;
            : set_graphic target = "cold_room" graphic = "cold_room_2" ;
            : press_any_key ;
            : redescribe ;
         }
         : else {
            : print "YOU DON'T HAVE ANY." ;
         }
      }
      : else {
         : print "NOT RIGHT NOW." ;
      }
   }

}


########################################
#  Subroutines                         #
########################################

subroutines {

   // This subroutine is executed if we lose a fight with the knight
   lose_fight : subroutine {
      // Have to explicitly attack the knight, even if you have the sword.
      : print "THE KNIGHT WIELDS HIS SWORD DEFTLY AND ATTACKS YOU...." ;
      : gosub "end_game" ;
   }

   // This subroutine is executed if we win a fight with the knight.
   win_fight : subroutine {
      : print "A GREAT BATTLE ENSUES IN WHICH YOU ARE VICTORIOUS. THE KNIGHT TURNS TO DUST BEFORE YOUR EYES ALONG WITH YOUR SWORD!" ;
      : press_any_key ;
      : destroy "demon_knight" ;
      : destroy "short_sword" ;
      : set_graphic graphic = "demon_knight_road_2"  target = "demon_knight_road" ;
      : redescribe ;
   }

   end_game : subroutine {
      : press_any_key ;
      : clear_screen;
      : print_graphic "game_over";
      : print "Your quest is over .........." ;
      : turns ;
      : end_game ;
   }

   worm_attack : subroutine {
     : print "THE ROCKWORM RISES UP AND TAKES YOU IN ITS GLEAMING MANDIBLES." ;
     : gosub "end_game" ;
   }

}

// Placeholders used for documentation purposes only as graphic data is too large to place in document.
assets {
   graphics {
      armoury               : placeholder ;
      arthur                : placeholder ;
      banquet_hall          : placeholder ;
      birwood_bush          : placeholder ;
      castle_approach_1     : placeholder ;
      castle_approach_2     : placeholder ;
      castle_approach_2a    : placeholder ;
      castle_porch          : placeholder ;
      chasm                 : placeholder ;
      cold_room             : placeholder ;
      cold_room_2           : placeholder ;
      deep_inside_birwood   : placeholder ;
      demon_knight_road     : placeholder ;
      demon_knight_road_2   : placeholder ;
      drafty_room           : placeholder ;
      drafty_room_2         : placeholder ;
      edge_of_birwood       : placeholder ;
      ending_screen         : placeholder ;
      excalibur_loading     : placeholder ;
      foot_of_tree          : placeholder ;
      foot_of_tree_2        : placeholder ;
      game_over             : placeholder ;
      hut                   : placeholder ;
      lamp_seller_on_road   : placeholder ;
      lamp_seller_on_road_2 : placeholder ;
      most_splendid_room    : placeholder ;
      most_splendid_room_2  : placeholder ;
      ornate_antechamber    : placeholder ;
      portcullis            : placeholder ;
      portcullis_2          : placeholder ;
      road_1                : placeholder ;
      road_2                : placeholder ;
      road_3                : placeholder ;
      road_4                : placeholder ;
      salt_mine_1           : placeholder ;
      salt_mine_2           : placeholder ;
      salt_mine_3           : placeholder ;
      top_of_tree           : placeholder ;
      winch_room            : placeholder ;
      worm_room             : placeholder ;
      worm_room_2           : placeholder ;
   }
}

7.15. Raising The Portcullis

winch room

The Winch Room contains the winch that will raise (open) the portcullis leading to Crania and Arthur.

The portcullis (a kind of gate/door that goes up and down). The portcullis is in a different room to the winch.

There are two 'puzzles' here.

The first 'puzzle' is that the winch is jammed and needs some oil.

Lucky for the player that there is a can of oil in the room where the ice creature met its salty demise.

How very convenient !

The second part of the puzzle is simply to turn the winch.

Turning the winch will remove the block on the most splendid room and change the graphic in the portcullis room to show an open door instead of a closed portcullis.

Isn’t programming neat?

Firstly, we will use two boolean variables.

At the start of the game we have not oiled or turned the winch, so they are both set to a value of false initially.

booleans {}
has_oiled_winch  : boolean "false" ;
has_turned_winch : boolean "false" ;

Next, let’s make a block for the most splendid room (which is north of the portcullis room). The block is a simple block that displays the message "YOU CAN’T GO THAT WAY.".

This block uses the 'block_when_not' condition, which means, block when a boolean variable contains a 'false' value.

barriers {}
portcullis : block {
   location               = most_splendid_room
   message                = YOU CAN'T GO THAT WAY.
   block_when_not         = has_turned_winch
}

We can read the block_when_not line as "block when has not turned the winch". Makes sense.

Finally, let’s wire up the command handler for OIL WINCH and TURN WINCH:

on_command {}
: match "oil winch"  {
   : if (is_present "winch") {
      : if (is_carried "oil") {
         : print "OK." ;
         : set_true "has_oiled_winch" ;
         : set_graphic target = "portcullis" graphic = "portcullis_2" ;
         : destroy "oil" ;
      }
      : else {
         : print "YOU HAVE NO OIL!" ;
      }
   }
   : else {
      : print "IT ISN'T HERE" ;
   }
}

: match "turn winch"  {
   : if (is_present "winch") {
      : if (has_oiled_winch) {
         : print "OK." ;
         : set_true "has_turned_winch" ;
      }
      : else {
         : print "IT'S STUCK!" ;
      }
   }
   : else {
      : print "IT ISN'T HERE" ;
   }
}

7.15.1. Using Boolean Variables within an 'if' condition

This block of code uses multiple if then else blocks of code, and it also shows the use of a boolean variable inside an if statement.

We can perform an conditional action based on if a boolean variable (or boolean expression) contains a true (or yes) answer, or a false (or no) answer.

7.15.2. How To Name Boolean Variables

It is usual in Adventuron is to name boolean variables starting with is_ or has_ because it makes it easier to understand what that the variable represents a true/false or yes/no answer.

Imagine that the has_oiled_winch boolean variable was called oiled_winch. It would be difficult to know if the identifier represented a fact (such as something is true or false), or an object.

The way we choose to name something is called a naming convention. These are are very common in programming, and it really makes things a lot easier if you follow a pattern - even if the pattern is unique to yourself.

7.15.3. Code so far …​.

########################################
#  Adventuron                          #
########################################

start_at       = hut

########################################
#  Locations                           #
########################################

locations {

   hut                    : location "You are in an old hut. Sunlight shines in from a doorway to the north.";
   road_1                 : location "You are standing on a track. The hut is south.";
   road_2                 : location "You are where the road turns eastwards. You see small hills in the distance.";
   road_3                 : location "You are on a road surrounded by grass. Trees can be seen on a hill in the distance.";
   road_4                 : location "You are on a dusty path on the edge of Birwood.";
   lamp_seller_on_road    : location "You are at a crossroads.";
   chasm                  : location "You are stood on the edge of a huge chasm (a cliff). A tightrope spans the gap, but it looks dangerous.";
   edge_of_birwood        : location "You are on the edge of Birwood. A rope spans the chasm northwards." ;
   deep_inside_birwood    : location "You are deep inside Birwood. The trees are alive with the buzzing of tiny insects.";
   birwood_bush           : location "You are standing in Birwood. A gap in the trees lets a warm light filter through.";
   demon_knight_road      : location "You are in a dip in the road by dark Birwood. Birds can be heard above.";
   foot_of_tree           : location "You are at the bottom of a large stone tree that is bare of any branches. The road ends here.";
   top_of_tree            : location "You are in a stone room set in a large stone tree.";
   castle_approach_1      : location "You are now a fair distance from Birwood. You can see castle Camelot to the east.";
   castle_approach_2      : location "You are outside Camelot Castle. A great stone door is the only way in.";
   castle_porch           : location "You are in the porch of Camelot.";
   banquet_hall           : location "You are in an abandoned banquet hall (eating area). Furniture lays broken on the floor.";
   drafty_room            : location "You are in a drafty room. Wind blows through gaps in the walls creating howling noises.";
   ornate_antechamber     : location "You are in an antechamber covered in thin ice that even covers the paintings.";
   portcullis             : location "You are in a room which has an iron portcullis set into the northern wall.";
   salt_mine_1            : location "You are in an old salt mine. Tunnels lead to the west and south.";
   salt_mine_2            : location "You are in the west part of the mine. It looks like it's been abandoned.";
   salt_mine_3            : location "You are at the end of the mine. You can hear the drip of water.";
   worm_room              : location "You are in the south part of the mine. There been recent movement in the rocks near your feet.";
   cold_room              : location "You are in a bitterly cold room. Everything is coated in a thick layer of ice.";
   winch_room             : location "You are in the winch room.";
   armoury                : location "You are in the armoury. Empty weapon racks line the walls.";
   most_splendid_room     : location "You are in the most splendid room in the castle. Rugs and paintings adorn the floor and walls.";
   arthur                 : location "You are in a sparse and lonely room. A cold wind enters through a high window.";

}

########################################
#  Connections                         #
########################################

connections {

   from, direction, to = [
      hut,                  north,  road_1,
      road_1,               north,  road_2,
      road_2,               east,   road_3,
      road_3,               east,   road_4,
      road_4,               north,  foot_of_tree,
      road_4,               south,  lamp_seller_on_road,
      lamp_seller_on_road,  east,   demon_knight_road,
      lamp_seller_on_road,  south,  chasm,
      foot_of_tree,         up,     top_of_tree,
      //chasm,                south,  edge_of_birwood,
      edge_of_birwood,      south,  deep_inside_birwood,
      deep_inside_birwood,  west,   birwood_bush,
      demon_knight_road,    east,   castle_approach_1,
      castle_approach_1,    east,   castle_approach_2,
      castle_approach_2,    east,   castle_porch,
      castle_porch,         east,   banquet_hall,
      banquet_hall,         north,  portcullis,
      banquet_hall,         south,  drafty_room,
      portcullis,           north,  most_splendid_room,
      most_splendid_room,   west,   arthur,
      drafty_room,          east,   ornate_antechamber,
      drafty_room,          down,   salt_mine_1,
      ornate_antechamber,   east,   cold_room,
      cold_room,            north,  winch_room,
      winch_room,           east,   armoury,
      salt_mine_1,          west,   salt_mine_2,
      salt_mine_1,          south,  worm_room,
      worm_room,            south,  salt_mine_3,
   ]

}

########################################
#  Objects                             #
########################################

objects {

   # Items we can pick-up (Objects)

   ladder           : object  "a ladder"                                    start_at="hut" ;
   red_fish         : object  "a red fish"                                  start_at="road_3" ;
   short_sword      : object  "a short sword"                               start_at="top_of_tree" ;
   coin             : object  "a coin"                                      start_at="ornate_antechamber" ;
   string           : object  "some string"                                 start_at="salt_mine_2" ;
   salt             : object  "some salt"                                   start_at="salt_mine_3" ;
   oil              : object  "can of oil"                                  start_at="cold_room" ;
   excalibur        : object  "Excalibur!"                                  start_at="armoury" ;
   long_pole        : object  "a long pole" ;
   rungs            : object  "some rungs" ;
   stone_key        : object  "a stone key" ;
   axe              : object  "a wood cutters' axe" ;
   lamp             : object  "a lamp" ;

   # Things or people that we cannot pick up (Scenery)

   old_woman        : scenery "an old woman selling lamps"                  start_at="lamp_seller_on_road" ;
   logs             : scenery "a pile of logs"                              start_at="deep_inside_birwood" ;
   bush             : scenery "a bush"                                      start_at="birwood_bush" ;
   demon_knight     : scenery "a Demon Knight guarding the east road"  start_at="demon_knight_road" ;
   trapdoor         : scenery "an old trapdoor"                             start_at="drafty_room" ;
   smashed_trapdoor : scenery "a smashed trapdoor" ;
   rockworm         : scenery "a Rockworm, guarding the south tunnel"       start_at="worm_room" ;
   ice_creature     : scenery "an Ice creature, guarding the north exit"    start_at="cold_room" ;
   winch            : scenery "a winch"                                     start_at="winch_room" ;
   spell            : scenery "a spell flying at you from Crania"           start_at="most_splendid_room" ;
   asleep_arthur    : scenery "King Arthur (asleep)"                        start_at="arthur" ;

}

########################################
#  Booleans                            #
########################################

booleans {
   is_ladder_standing : boolean "false" ;
   is_light_lit       : boolean "false" ;
   has_oiled_winch    : boolean "false" ;
   has_turned_winch   : boolean "false" ;
}

########################################
#  Blocks                              #
########################################

barriers {

   castle_door : door {
     key   = stone_key
     from  = castle_approach_2
     to    = castle_porch
     on_unlock {
        : print "YOU UNLOCK IT WITH THE KEY, WHICH JAMS IN THE LOCK." ;
        : destroy "stone_key" ;
     }
     on_open {
        : set_graphic graphic = "castle_approach_2a" target = "castle_approach_2" ;
        : redescribe ;
     }
     on_close {
        : set_graphic graphic = "castle_approach_2"  target = "castle_approach_2" ;
        : redescribe ;
     }
   }

   tree : block {
      location          = top_of_tree
      message           = YOU CAN'T FIND YOUR GRIP
      block_when_not    = is_ladder_standing
      show_blocked_exit = false
   }


   knight : block {
      location            = castle_approach_1
      gosub               = lose_fight
      block_when_exists   = demon_knight
      show_blocked_exit   = true
   }

   trapdoor : block {
      location            = salt_mine_1
      message             = THE TRAPDOOR IS JAMMED SHUT!
      block_when_exists   = trapdoor
   }

   worm : block {
      location            = salt_mine_3
      gosub               = worm_attack
      block_when_exists   = rockworm
      show_blocked_exit   = true
   }

   ice_creature : block {
      location            = winch_room
      message             = THE ICE CREATURE WILL NOT ALLOW IT ...
      block_when_exists   = ice_creature
      show_blocked_exit   = true
   }

   portcullis : block {
      location               = most_splendid_room
      message                = YOU CAN'T GO THAT WAY.
      block_when_not         = has_turned_winch
   }

}

########################################
#  On Describe                         #
########################################

on_describe {
   : if (is_light_lit) {
      : print "THE LIGHT'S GONE OUT." ;
      : set_false "is_light_lit" ;
   }
}

########################################
#  On Describe                         #
########################################

on_tick {
   : if (is_present "rockworm" ) {
      : if (linger() == 3) {
         : print "THE ROCKWORM STARTS MOVING TOWARDS YOU" ;
      }
      : if (linger() == 4) {
         : gosub "worm_attack" ;
      }
   }
   : if (is_present "ice_creature") {
     : if (linger() == 1) {
        : print "THE ICE CREATURE TAKES YOU IN A FREEZING GRIP" ;
        : gosub "end_game" ;
     }
   }
}

########################################
#  On Command                          #
########################################

on_command {
   : match "examine ladder"  {
      : if ( is_present "ladder" ) {
         : print "A LONG POLE WITH RUNGS ATTACHED." ;
      }
   }
   : match "examine woman"  {
      : if (is_present "old_woman") {
         : print "SHE LOOKS AT YOU WITH AN INTENSE GLARE." ;
      }
   }
   : match "examine lamp"  {
      : if (is_present "lamp") {
         : print "IT'S OLD AND TARNISHED." ;
      }
   }
   : match "examine fish"  {
      : if (is_present "red_fish") {
         : print "IT STINKS!" ;
      }
   }
   : match "examine sword"  {
      : if (is_present "short_sword") {
         : print "INSCRIBED UPON IT ARE THE WORDS 'GOOD LUCK' ~~ MERLIN." ;
      }
   }
   : match "examine bush"  {
      : if (is_present "bush" && has_not_created "stone_key") {
         : print "YOU FIND SOMETHING!" ;
         : create "stone_key" ;
         : press_any_key ;
         : redescribe ;
      }
   }
   : match "examine logs"  {
      : if (is_present "logs" && has_not_created "axe") {
         : print "YOU FIND AN AXE!" ;
         : create "axe" ;
         : press_any_key ;
         : redescribe ;
      }
   }

   : match "get ladder"  {
      : if (is_at "foot_of_tree" && is_beside "ladder") {
         : get ;
         : set_false "is_ladder_standing" ;
         : set_graphic target = "foot_of_tree" graphic = "foot_of_tree"  ;
         : redescribe ;
      }
   }

   : match "stand ladder;lean ladder;rest ladder"  {
      : if (is_carried "ladder" && is_at "foot_of_tree") {
         : drop ;
         : set_true "is_ladder_standing" ;
         : set_graphic target = "foot_of_tree" graphic = "foot_of_tree_2"  ;
         : redescribe;
      }
   }

    : match "fight knight;attack knight;challenge knight"  {
      : if (is_present "demon_knight") {
         : if (is_carried "short_sword") {
            : gosub "win_fight" ;
         }
         : else {
            : gosub "lose_fight" ;
         }
      }
    }

    : match "break ladder;smash ladder;disassemble ladder"  {
       : if (is_carried "ladder") {
          : print   "OK."       ;
          : destroy "ladder"    ;
          : create  "long_pole" ;
          : create  "rungs"     ;
          : press_any_key       ;
          : redescribe          ;
       }
    }

    : match "cross chasm; balance _; walk _"  {
      : if (is_at "chasm" && is_carried "long_pole") {
         : print "THE POLE HELPS YOU BALANCE...." ;
         : press_any_key ;
         : goto "edge_of_birwood" ;
         : redescribe ;
      }
      : if (is_at "chasm" && !is_carried "long_pole") {
         : print "YOU LOSE YOUR BALANCE....." ;
         : gosub "end_game" ;
      }
      : if (is_at "edge_of_birwood" && is_carried "long_pole") {
         : print "THE POLE HELPS YOU BALANCE...." ;
         : press_any_key ;
         : goto "chasm" ;
         : redescribe ;
      }
      : if (is_at "edge_of_birwood" && !is_carried "long_pole") {
         : print "YOU LOSE YOUR BALANCE....." ;
         : gosub "end_game" ;
      }
    }

   : match "give coin; buy lamp"  {
     : if (is_present "old_woman") {
        : if (is_carried "coin") {
           : print "THE OLD LADY TAKES YOUR COIN, GIVES YOU A BRASS LAMP, THEN DISAPPEARS INTO THIN AIR." ;
           : destroy "coin" ;
           : destroy "old_woman" ;
           : create "lamp" target="inventory" ;
           : set_graphic graphic = "lamp_seller_on_road_2"  target = "lamp_seller_on_road" ;
           : press_any_key ;
           : redescribe ;
        }
        : else {
           : match "buy lamp"  {
              : print "'CROSS MY PALM WITH SILVER!'" ;
           }
        }
     }
   }


   : match "smash trapdoor;chop trapdoor;break trapdoor"  {
     : if (is_present "trapdoor") {
        : if (is_carried "axe") {
           : print "USING THE AXE, YOU SMASH THE TRAPDOOR!" ;
           : destroy "trapdoor" ;
           : create "smashed_trapdoor" ;
              : destroy "axe" ;
           : set_graphic target = "drafty_room" graphic = "drafty_room_2" ;
           : pause "1600" ;
           : redescribe ;
        }
        : else {
           : print "A FRUITLESS EXERCISE!" ;
           : done ;
        }
     }
   }

   : match "light lamp; switch lamp; turn lamp"  {
     : if (is_present "lamp" && is_light_lit == false) {
       : set_true "is_light_lit" ;
       : if (is_present "rockworm") {
          : print "THE ROCKWORM'S SENSITIVE EYES ARE SURPRISED BY THE STRONG LIGHT AND IT RETREATS DOWN ITS BURROW ...." ;
          : destroy "rockworm" ;
          : set_graphic target = "worm_room" graphic = "worm_room_2" ;
          : press_any_key ;
          : redescribe ;
       }
       : else {
          : print "IT EMITS A BRIGHT LIGHT." ;
       }
     }
   }

   : match "throw salt"  {
      : if (is_present "ice_creature") {
         : if (is_carried "salt") {
            : print "THE CREATURE BEGINS TO MELT RAPIDLY..." ;
            : destroy "ice_creature" ;
              : destroy "salt" ;
            : set_graphic target = "cold_room" graphic = "cold_room_2" ;
            : press_any_key ;
            : redescribe ;
         }
         : else {
            : print "YOU DON'T HAVE ANY." ;
         }
      }
      : else {
         : print "NOT RIGHT NOW." ;
      }
   }

   : match "oil winch"  {
      : if (is_present "winch") {
         : if (is_carried "oil") {
            : print "OK." ;
            : set_true "has_oiled_winch" ;
            : set_graphic target = "portcullis" graphic = "portcullis_2" ;
            : destroy "oil" ;
         }
         : else {
            : print "YOU HAVE NO OIL!" ;
         }
      }
      : else {
         : print "IT ISN'T HERE" ;
      }
   }

   : match "turn winch"  {
      : if (is_present "winch") {
         : if (has_oiled_winch) {
            : print "OK." ;
            : set_true "has_turned_winch" ;
         }
         : else {
            : print "IT'S STUCK!" ;
         }
      }
      : else {
         : print "IT ISN'T HERE" ;
      }
   }

}


########################################
#  Subroutines                         #
########################################

subroutines {

   // This subroutine is executed if we lose a fight with the knight
   lose_fight : subroutine {
      // Have to explicitly attack the knight, even if you have the sword.
      : print "THE KNIGHT WIELDS HIS SWORD DEFTLY AND ATTACKS YOU...." ;
      : gosub "end_game" ;
   }

   // This subroutine is executed if we win a fight with the knight.
   win_fight : subroutine {
      : print "A GREAT BATTLE ENSUES IN WHICH YOU ARE VICTORIOUS. THE KNIGHT TURNS TO DUST BEFORE YOUR EYES ALONG WITH YOUR SWORD!" ;
      : press_any_key ;
      : destroy "demon_knight" ;
      : destroy "short_sword" ;
      : set_graphic graphic = "demon_knight_road_2"  target = "demon_knight_road" ;
      : redescribe ;
   }

   end_game : subroutine {
      : press_any_key ;
      : clear_screen;
      : print_graphic "game_over" ;
      : print "Your quest is over .........." ;
      : turns ;
      : end_game ;
   }

   worm_attack : subroutine {
     : print "THE ROCKWORM RISES UP AND TAKES YOU IN ITS GLEAMING MANDIBLES." ;
     : gosub "end_game" ;
   }

}

// Placeholders used for documentation purposes only as graphic data is too large to place in document.
assets {
   graphics {
      armoury               : placeholder ;
      arthur                : placeholder ;
      banquet_hall          : placeholder ;
      birwood_bush          : placeholder ;
      castle_approach_1     : placeholder ;
      castle_approach_2     : placeholder ;
      castle_approach_2a    : placeholder ;
      castle_porch          : placeholder ;
      chasm                 : placeholder ;
      cold_room             : placeholder ;
      cold_room_2           : placeholder ;
      deep_inside_birwood   : placeholder ;
      demon_knight_road     : placeholder ;
      demon_knight_road_2   : placeholder ;
      drafty_room           : placeholder ;
      drafty_room_2         : placeholder ;
      edge_of_birwood       : placeholder ;
      ending_screen         : placeholder ;
      excalibur_loading     : placeholder ;
      foot_of_tree          : placeholder ;
      foot_of_tree_2        : placeholder ;
      game_over             : placeholder ;
      hut                   : placeholder ;
      lamp_seller_on_road   : placeholder ;
      lamp_seller_on_road_2 : placeholder ;
      most_splendid_room    : placeholder ;
      most_splendid_room_2  : placeholder ;
      ornate_antechamber    : placeholder ;
      portcullis            : placeholder ;
      portcullis_2          : placeholder ;
      road_1                : placeholder ;
      road_2                : placeholder ;
      road_3                : placeholder ;
      road_4                : placeholder ;
      salt_mine_1           : placeholder ;
      salt_mine_2           : placeholder ;
      salt_mine_3           : placeholder ;
      top_of_tree           : placeholder ;
      winch_room            : placeholder ;
      worm_room             : placeholder ;
      worm_room_2           : placeholder ;
   }
}

7.16. Reflecting The Spell

most splendid room

Now that the portcullis is up, we have access to the MOST SPLENDID ROOM, which is a yellow version of a regular room - but this one has CRANIA, THE EVIL SORCERESS in it, and she’s throwing a spell your way.

We deal with the spell by typing REFLECT SPELL or DEFLECT SPELL whilst holding the sword, EXCALIBUR, which was in the armoury next to the winch room.

If you type those magic words, then the spell will be reflected back at CRANIA, and the room is then clear.

This is very easy to write the code for, it’s basically the same logic as the Ice Creature.

  1. Create the location block

  2. Create the command Handler

  3. Create the sudden-death timer

barriers {}
crania : block {
   location            = arthur
   message             = YOU CAN'T GET PAST
   block_when_exists   = spell
}
on_command{}
: match "reflect spell; deflect spell; use excalibur"  {
   : if (is_present "spell") {
      : if (is_carried "excalibur") {
         : print "EXCALIBUR REFLECTS THE SPELL! THE SORCERESS, PROMISING REVENGE, VANISHES!" ;
         : destroy "spell" ;
         : set_graphic  target = "most_splendid_room" graphic = "most_splendid_room_2";
         : press_any_key ;
         : redescribe ;
      }
      : else {
         : print "YOU WAVE YOUR HANDS BUT IT'S NO GOOD..." ;
      }
   }
   : else {
      : print "YOU CAN'T." ;
   }
}
on_tick{}
: if (is_present "spell") {
   : if (linger() == 1) {
      : print "THE SPELL HITS YOU HEAD ON, PETRIFYING YOU INSTANTLY." ;
      : gosub "end_game" ;
   }
}
########################################
#  Adventuron                          #
########################################

start_at       = hut

########################################
#  Locations                           #
########################################

locations {

   hut                    : location "You are in an old hut. Sunlight shines in from a doorway to the north.";
   road_1                 : location "You are standing on a track. The hut is south.";
   road_2                 : location "You are where the road turns eastwards. You see small hills in the distance.";
   road_3                 : location "You are on a road surrounded by grass. Trees can be seen on a hill in the distance.";
   road_4                 : location "You are on a dusty path on the edge of Birwood.";
   lamp_seller_on_road    : location "You are at a crossroads.";
   chasm                  : location "You are stood on the edge of a huge chasm (a cliff). A tightrope spans the gap, but it looks dangerous.";
   edge_of_birwood        : location "You are on the edge of Birwood. A rope spans the chasm northwards." ;
   deep_inside_birwood    : location "You are deep inside Birwood. The trees are alive with the buzzing of tiny insects.";
   birwood_bush           : location "You are standing in Birwood. A gap in the trees lets a warm light filter through.";
   demon_knight_road      : location "You are in a dip in the road by dark Birwood. Birds can be heard above.";
   foot_of_tree           : location "You are at the bottom of a large stone tree that is bare of any branches. The road ends here.";
   top_of_tree            : location "You are in a stone room set in a large stone tree.";
   castle_approach_1      : location "You are now a fair distance from Birwood. You can see castle Camelot to the east.";
   castle_approach_2      : location "You are outside Camelot Castle. A great stone door is the only way in.";
   castle_porch           : location "You are in the porch of Camelot.";
   banquet_hall           : location "You are in an abandoned banquet hall (eating area). Furniture lays broken on the floor.";
   drafty_room            : location "You are in a drafty room. Wind blows through gaps in the walls creating howling noises.";
   ornate_antechamber     : location "You are in an antechamber covered in thin ice that even covers the paintings.";
   portcullis             : location "You are in a room which has an iron portcullis set into the northern wall.";
   salt_mine_1            : location "You are in an old salt mine. Tunnels lead to the west and south.";
   salt_mine_2            : location "You are in the west part of the mine. It looks like it's been abandoned.";
   salt_mine_3            : location "You are at the end of the mine. You can hear the drip of water.";
   worm_room              : location "You are in the south part of the mine. There been recent movement in the rocks near your feet.";
   cold_room              : location "You are in a bitterly cold room. Everything is coated in a thick layer of ice.";
   winch_room             : location "You are in the winch room.";
   armoury                : location "You are in the armoury. Empty weapon racks line the walls.";
   most_splendid_room     : location "You are in the most splendid room in the castle. Rugs and paintings adorn the floor and walls.";
   arthur                 : location "You are in a sparse and lonely room. A cold wind enters through a high window.";

}

########################################
#  Connections                         #
########################################

connections {

   from, direction, to = [
      hut,                  north,  road_1,
      road_1,               north,  road_2,
      road_2,               east,   road_3,
      road_3,               east,   road_4,
      road_4,               north,  foot_of_tree,
      road_4,               south,  lamp_seller_on_road,
      lamp_seller_on_road,  east,   demon_knight_road,
      lamp_seller_on_road,  south,  chasm,
      foot_of_tree,         up,     top_of_tree,
      //chasm,                south,  edge_of_birwood,
      edge_of_birwood,      south,  deep_inside_birwood,
      deep_inside_birwood,  west,   birwood_bush,
      demon_knight_road,    east,   castle_approach_1,
      castle_approach_1,    east,   castle_approach_2,
      castle_approach_2,    east,   castle_porch,
      castle_porch,         east,   banquet_hall,
      banquet_hall,         north,  portcullis,
      banquet_hall,         south,  drafty_room,
      portcullis,           north,  most_splendid_room,
      most_splendid_room,   west,   arthur,
      drafty_room,          east,   ornate_antechamber,
      drafty_room,          down,   salt_mine_1,
      ornate_antechamber,   east,   cold_room,
      cold_room,            north,  winch_room,
      winch_room,           east,   armoury,
      salt_mine_1,          west,   salt_mine_2,
      salt_mine_1,          south,  worm_room,
      worm_room,            south,  salt_mine_3,
   ]

}

########################################
#  Objects                             #
########################################

objects {

   # Items we can pick-up (Objects)

   ladder           : object  "a ladder"                                    start_at="hut" ;
   red_fish         : object  "a red fish"                                  start_at="road_3" ;
   short_sword      : object  "a short sword"                               start_at="top_of_tree" ;
   coin             : object  "a coin"                                      start_at="ornate_antechamber" ;
   string           : object  "some string"                                 start_at="salt_mine_2" ;
   salt             : object  "some salt"                                   start_at="salt_mine_3" ;
   oil              : object  "can of oil"                                  start_at="cold_room" ;
   excalibur        : object  "Excalibur!"                                  start_at="armoury" ;
   long_pole        : object  "a long pole" ;
   rungs            : object  "some rungs" ;
   stone_key        : object  "a stone key" ;
   axe              : object  "a wood cutters' axe" ;
   lamp             : object  "a lamp" ;

   # Things or people that we cannot pick up (Scenery)

   old_woman        : scenery "an old woman selling lamps"                  start_at="lamp_seller_on_road" ;
   logs             : scenery "a pile of logs"                              start_at="deep_inside_birwood" ;
   bush             : scenery "a bush"                                      start_at="birwood_bush" ;
   demon_knight     : scenery "a Demon Knight guarding the east road"  start_at="demon_knight_road" ;
   trapdoor         : scenery "an old trapdoor"                             start_at="drafty_room" ;
   smashed_trapdoor : scenery "a smashed trapdoor" ;
   rockworm         : scenery "a Rockworm, guarding the south tunnel"       start_at="worm_room" ;
   ice_creature     : scenery "an Ice creature, guarding the north exit"    start_at="cold_room" ;
   winch            : scenery "a winch"                                     start_at="winch_room" ;
   spell            : scenery "a spell flying at you from Crania"           start_at="most_splendid_room" ;
   asleep_arthur    : scenery "King Arthur (asleep)"                        start_at="arthur" ;

}

########################################
#  Booleans                            #
########################################

booleans {
   is_ladder_standing : boolean "false" ;
   is_light_lit       : boolean "false" ;
   has_oiled_winch    : boolean "false" ;
   has_turned_winch   : boolean "false" ;
}

########################################
#  Blocks                              #
########################################

barriers {

   castle_door : door {
     key   = stone_key
     from  = castle_approach_2
     to    = castle_porch
     on_unlock {
        : print "YOU UNLOCK IT WITH THE KEY, WHICH JAMS IN THE LOCK." ;
        : destroy "stone_key" ;
     }
     on_open {
        : set_graphic graphic = "castle_approach_2a" target = "castle_approach_2" ;
        : redescribe ;
     }
     on_close {
        : set_graphic graphic = "castle_approach_2"  target = "castle_approach_2" ;
        : redescribe ;
     }
   }

   tree : block {
      location          = top_of_tree
      message           = YOU CAN'T FIND YOUR GRIP
      block_when_not    = is_ladder_standing
      show_blocked_exit = false
   }


   knight : block {
      location            = castle_approach_1
      gosub               = lose_fight
      block_when_exists   = demon_knight
      show_blocked_exit   = true
   }

   trapdoor : block {
      location            = salt_mine_1
      message             = THE TRAPDOOR IS JAMMED SHUT!
      block_when_exists   = trapdoor
   }

   worm : block {
      location            = salt_mine_3
      gosub               = worm_attack
      block_when_exists   = rockworm
      show_blocked_exit   = true
   }

   ice_creature : block {
      location            = winch_room
      message             = THE ICE CREATURE WILL NOT ALLOW IT ...
      block_when_exists   = ice_creature
      show_blocked_exit   = true
   }

   portcullis : block {
      location            = most_splendid_room
      message             = YOU CAN'T GO THAT WAY.
      block_when_not      = has_turned_winch
   }

   crania : block {
      location            = arthur
      message             = YOU CAN'T GET PAST
      block_when_exists   = spell
   }

}

########################################
#  On Describe                         #
########################################

on_describe {
   : if (is_light_lit) {
      : print "THE LIGHT'S GONE OUT." ;
      : set_false "is_light_lit" ;
   }
}

########################################
#  On Describe                         #
########################################

on_tick {
   : if (is_present "rockworm" ) {
      : if (linger() == 3) {
         : print "THE ROCKWORM STARTS MOVING TOWARDS YOU" ;
      }
      : if (linger() == 4) {
         : gosub "worm_attack" ;
      }
   }
   : if (is_present "ice_creature") {
     : if (linger() == 1) {
        : print "THE ICE CREATURE TAKES YOU IN A FREEZING GRIP" ;
        : gosub "end_game" ;
     }
   }
   : if (is_present "spell") {
      : if (linger() == 1) {
         : print "THE SPELL HITS YOU HEAD ON, PETRIFYING YOU INSTANTLY." ;
         : gosub "end_game" ;
      }
   }
}

########################################
#  On Command                          #
########################################

on_command {
   : match "examine ladder"  {
      : if ( is_present "ladder" ) {
         : print "A LONG POLE WITH RUNGS ATTACHED." ;
      }
   }
   : match "examine woman"  {
      : if (is_present "old_woman") {
         : print "SHE LOOKS AT YOU WITH AN INTENSE GLARE." ;
      }
   }
   : match "examine lamp"  {
      : if (is_present "lamp") {
         : print "IT'S OLD AND TARNISHED." ;
      }
   }
   : match "examine fish"  {
      : if (is_present "red_fish") {
         : print "IT STINKS!" ;
      }
   }
   : match "examine sword"  {
      : if (is_present "short_sword") {
         : print "INSCRIBED UPON IT ARE THE WORDS 'GOOD LUCK' ~~ MERLIN." ;
      }
   }
   : match "examine bush"  {
      : if (is_present "bush" && has_not_created "stone_key") {
         : print "YOU FIND SOMETHING!" ;
         : create "stone_key" ;
         : press_any_key ;
         : redescribe ;
      }
   }
   : match "examine logs"  {
      : if (is_present "logs" && has_not_created "axe") {
         : print "YOU FIND AN AXE!" ;
         : create "axe" ;
         : press_any_key ;
         : redescribe ;
      }
   }

   : match "get ladder"  {
      : if (is_at "foot_of_tree" && is_beside "ladder") {
         : get ;
         : set_false "is_ladder_standing" ;
         : set_graphic target = "foot_of_tree" graphic = "foot_of_tree"  ;
         : redescribe ;
      }
   }

   : match "stand ladder;lean ladder;rest ladder"  {
      : if (is_carried "ladder" && is_at "foot_of_tree") {
         : drop ;
         : set_true "is_ladder_standing" ;
         : set_graphic target = "foot_of_tree" graphic = "foot_of_tree_2"  ;
         : redescribe;
      }
   }

    : match "fight knight;attack knight;challenge knight"  {
      : if (is_present "demon_knight") {
         : if (is_carried "short_sword") {
            : gosub "win_fight" ;
         }
         : else {
            : gosub "lose_fight" ;
         }
      }
    }

    : match "break ladder;smash ladder;disassemble ladder"  {
       : if (is_carried "ladder") {
          : print   "OK."       ;
          : destroy "ladder"    ;
          : create  "long_pole" ;
          : create  "rungs"     ;
          : press_any_key       ;
          : redescribe          ;
       }
    }

    : match "cross chasm; balance _; walk _"  {
      : if (is_at "chasm" && is_carried "long_pole") {
         : print "THE POLE HELPS YOU BALANCE...." ;
         : press_any_key ;
         : goto "edge_of_birwood" ;
         : redescribe ;
      }
      : if (is_at "chasm" && !is_carried "long_pole") {
         : print "YOU LOSE YOUR BALANCE....." ;
         : gosub "end_game" ;
      }
      : if (is_at "edge_of_birwood" && is_carried "long_pole") {
         : print "THE POLE HELPS YOU BALANCE...." ;
         : press_any_key ;
         : goto "chasm" ;
         : redescribe ;
      }
      : if (is_at "edge_of_birwood" && !is_carried "long_pole") {
         : print "YOU LOSE YOUR BALANCE....." ;
         : gosub "end_game" ;
      }
    }

   : match "give coin; buy lamp"  {
     : if (is_present "old_woman") {
        : if (is_carried "coin") {
           : print "THE OLD LADY TAKES YOUR COIN, GIVES YOU A BRASS LAMP, THEN DISAPPEARS INTO THIN AIR." ;
           : destroy "coin" ;
           : destroy "old_woman" ;
           : create "lamp" target="inventory" ;
           : set_graphic graphic = "lamp_seller_on_road_2"  target = "lamp_seller_on_road" ;
           : press_any_key ;
           : redescribe ;
        }
        : else {
           : match "buy lamp"  {
              : print "'CROSS MY PALM WITH SILVER!'" ;
           }
        }
     }
   }


   : match "smash trapdoor;chop trapdoor;break trapdoor"  {
     : if (is_present "trapdoor") {
        : if (is_carried "axe") {
           : print "USING THE AXE, YOU SMASH THE TRAPDOOR!" ;
           : destroy "trapdoor" ;
           : create "smashed_trapdoor" ;
              : destroy "axe" ;
           : set_graphic target = "drafty_room" graphic = "drafty_room_2" ;
           : pause "1600" ;
           : redescribe ;
        }
        : else {
           : print "A FRUITLESS EXERCISE!" ;
           : done ;
        }
     }
   }

   : match "light lamp; switch lamp; turn lamp"  {
     : if (is_present "lamp" && is_light_lit == false) {
       : set_true "is_light_lit" ;
       : if (is_present "rockworm") {
          : print "THE ROCKWORM'S SENSITIVE EYES ARE SURPRISED BY THE STRONG LIGHT AND IT RETREATS DOWN ITS BURROW ...." ;
          : destroy "rockworm" ;
          : set_graphic target = "worm_room" graphic = "worm_room_2" ;
          : press_any_key ;
          : redescribe ;
       }
       : else {
          : print "IT EMITS A BRIGHT LIGHT." ;
       }
     }
   }

   : match "throw salt"  {
      : if (is_present "ice_creature") {
         : if (is_carried "salt") {
            : print "THE CREATURE BEGINS TO MELT RAPIDLY..." ;
            : destroy "ice_creature" ;
              : destroy "salt" ;
            : set_graphic target = "cold_room" graphic = "cold_room_2" ;
            : press_any_key ;
            : redescribe ;
         }
         : else {
            : print "YOU DON'T HAVE ANY." ;
         }
      }
      : else {
         : print "NOT RIGHT NOW." ;
      }
   }

   : match "oil winch"  {
      : if (is_present "winch") {
         : if (is_carried "oil") {
            : print "OK." ;
            : set_true "has_oiled_winch" ;
            : set_graphic target = "portcullis" graphic = "portcullis_2" ;
            : destroy "oil" ;
         }
         : else {
            : print "YOU HAVE NO OIL!" ;
         }
      }
      : else {
         : print "IT ISN'T HERE" ;
      }
   }

   : match "turn winch"  {
      : if (is_present "winch") {
         : if (has_oiled_winch) {
            : print "OK." ;
            : set_true "has_turned_winch" ;
         }
         : else {
            : print "IT'S STUCK!" ;
         }
      }
      : else {
         : print "IT ISN'T HERE" ;
      }
   }

   : match "reflect spell; deflect spell; use excalibur"  {
      : if (is_present "spell") {
         : if (is_carried "excalibur") {
            : print "EXCALIBUR REFLECTS THE SPELL! THE SORCERESS, PROMISING REVENGE, VANISHES!" ;
            : destroy "spell" ;
            : set_graphic  target = "most_splendid_room" graphic = "most_splendid_room_2";
            : press_any_key ;
            : redescribe ;
         }
         : else {
            : print "YOU WAVE YOUR HANDS BUT IT'S NO GOOD..." ;
         }
      }
      : else {
         : print "YOU CAN'T." ;
      }
   }

}


########################################
#  Subroutines                         #
########################################

subroutines {

   // This subroutine is executed if we lose a fight with the knight
   lose_fight : subroutine {
      // Have to explicitly attack the knight, even if you have the sword.
      : print "THE KNIGHT WIELDS HIS SWORD DEFTLY AND ATTACKS YOU...." ;
      : gosub "end_game" ;
   }

   // This subroutine is executed if we win a fight with the knight.
   win_fight : subroutine {
      : print "A GREAT BATTLE ENSUES IN WHICH YOU ARE VICTORIOUS. THE KNIGHT TURNS TO DUST BEFORE YOUR EYES ALONG WITH YOUR SWORD!" ;
      : press_any_key ;
      : destroy "demon_knight" ;
      : destroy "short_sword" ;
      : set_graphic graphic = "demon_knight_road_2"  target = "demon_knight_road" ;
      : redescribe ;
   }

   end_game : subroutine {
      : press_any_key ;
      : clear_screen;
      : print_graphic "game_over" ;
      : print "Your quest is over .........." ;
      : turns ;
      : end_game ;
   }

   worm_attack : subroutine {
     : print "THE ROCKWORM RISES UP AND TAKES YOU IN ITS GLEAMING MANDIBLES." ;
     : gosub "end_game" ;
   }

}

// Placeholders used for documentation purposes only as graphic data is too large to place in document.
assets {
   graphics {
      armoury               : placeholder ;
      arthur                : placeholder ;
      banquet_hall          : placeholder ;
      birwood_bush          : placeholder ;
      castle_approach_1     : placeholder ;
      castle_approach_2     : placeholder ;
      castle_approach_2a    : placeholder ;
      castle_porch          : placeholder ;
      chasm                 : placeholder ;
      cold_room             : placeholder ;
      cold_room_2           : placeholder ;
      deep_inside_birwood   : placeholder ;
      demon_knight_road     : placeholder ;
      demon_knight_road_2   : placeholder ;
      drafty_room           : placeholder ;
      drafty_room_2         : placeholder ;
      edge_of_birwood       : placeholder ;
      ending_screen         : placeholder ;
      excalibur_loading     : placeholder ;
      foot_of_tree          : placeholder ;
      foot_of_tree_2        : placeholder ;
      game_over             : placeholder ;
      hut                   : placeholder ;
      lamp_seller_on_road   : placeholder ;
      lamp_seller_on_road_2 : placeholder ;
      most_splendid_room    : placeholder ;
      most_splendid_room_2  : placeholder ;
      ornate_antechamber    : placeholder ;
      portcullis            : placeholder ;
      portcullis_2          : placeholder ;
      road_1                : placeholder ;
      road_2                : placeholder ;
      road_3                : placeholder ;
      road_4                : placeholder ;
      salt_mine_1           : placeholder ;
      salt_mine_2           : placeholder ;
      salt_mine_3           : placeholder ;
      top_of_tree           : placeholder ;
      winch_room            : placeholder ;
      worm_room             : placeholder ;
      worm_room_2           : placeholder ;
   }
}

7.17. Waking Arthur

arthur

7.17.1. Wake Up !

Waking Arthur is a very simple puzzle. Arthur is asleep, the obvious action is to try to wake him. Typing WAKE ARTHUR or WAKE KING should show the ending screen of the game (good ending), then end the game.

on_command{}
: match "wake arthur; wake king"  {
  : if (is_present "asleep_arthur") {
     : clear_screen;
     : print_graphic "ending_screen";
     : end_game ;
  }
}

7.17.2. Ending Screen

The ending screen is a graphic (in PNG format).

If you are building your own game, you can construct a textual message, or make your own ending graphic.

ending screen

7.17.3. A Completable Game

All puzzles have now been coded, and the game is now fully playable.

There are still some minor tasks to perform to make the experience better for the player, and to package the game, but it’s time to take a rest and enjoy what you have achieved so far.

7.17.4. Code So Far

########################################
#  Adventuron                          #
########################################

start_at       = hut

########################################
#  Locations                           #
########################################

locations {

   hut                    : location "You are in an old hut. Sunlight shines in from a doorway to the north.";
   road_1                 : location "You are standing on a track. The hut is south.";
   road_2                 : location "You are where the road turns eastwards. You see small hills in the distance.";
   road_3                 : location "You are on a road surrounded by grass. Trees can be seen on a hill in the distance.";
   road_4                 : location "You are on a dusty path on the edge of Birwood.";
   lamp_seller_on_road    : location "You are at a crossroads.";
   chasm                  : location "You are stood on the edge of a huge chasm (a cliff). A tightrope spans the gap, but it looks dangerous.";
   edge_of_birwood        : location "You are on the edge of Birwood. A rope spans the chasm northwards." ;
   deep_inside_birwood    : location "You are deep inside Birwood. The trees are alive with the buzzing of tiny insects.";
   birwood_bush           : location "You are standing in Birwood. A gap in the trees lets a warm light filter through.";
   demon_knight_road      : location "You are in a dip in the road by dark Birwood. Birds can be heard above.";
   foot_of_tree           : location "You are at the bottom of a large stone tree that is bare of any branches. The road ends here.";
   top_of_tree            : location "You are in a stone room set in a large stone tree.";
   castle_approach_1      : location "You are now a fair distance from Birwood. You can see castle Camelot to the east.";
   castle_approach_2      : location "You are outside Camelot Castle. A great stone door is the only way in.";
   castle_porch           : location "You are in the porch of Camelot.";
   banquet_hall           : location "You are in an abandoned banquet hall (eating area). Furniture lays broken on the floor.";
   drafty_room            : location "You are in a drafty room. Wind blows through gaps in the walls creating howling noises.";
   ornate_antechamber     : location "You are in an antechamber covered in thin ice that even covers the paintings.";
   portcullis             : location "You are in a room which has an iron portcullis set into the northern wall.";
   salt_mine_1            : location "You are in an old salt mine. Tunnels lead to the west and south.";
   salt_mine_2            : location "You are in the west part of the mine. It looks like it's been abandoned.";
   salt_mine_3            : location "You are at the end of the mine. You can hear the drip of water.";
   worm_room              : location "You are in the south part of the mine. There been recent movement in the rocks near your feet.";
   cold_room              : location "You are in a bitterly cold room. Everything is coated in a thick layer of ice.";
   winch_room             : location "You are in the winch room.";
   armoury                : location "You are in the armoury. Empty weapon racks line the walls.";
   most_splendid_room     : location "You are in the most splendid room in the castle. Rugs and paintings adorn the floor and walls.";
   arthur                 : location "You are in a sparse and lonely room. A cold wind enters through a high window.";

}

########################################
#  Connections                         #
########################################

connections {

   from, direction, to = [
      hut,                  north,  road_1,
      road_1,               north,  road_2,
      road_2,               east,   road_3,
      road_3,               east,   road_4,
      road_4,               north,  foot_of_tree,
      road_4,               south,  lamp_seller_on_road,
      lamp_seller_on_road,  east,   demon_knight_road,
      lamp_seller_on_road,  south,  chasm,
      foot_of_tree,         up,     top_of_tree,
      //chasm,                south,  edge_of_birwood,
      edge_of_birwood,      south,  deep_inside_birwood,
      deep_inside_birwood,  west,   birwood_bush,
      demon_knight_road,    east,   castle_approach_1,
      castle_approach_1,    east,   castle_approach_2,
      castle_approach_2,    east,   castle_porch,
      castle_porch,         east,   banquet_hall,
      banquet_hall,         north,  portcullis,
      banquet_hall,         south,  drafty_room,
      portcullis,           north,  most_splendid_room,
      most_splendid_room,   west,   arthur,
      drafty_room,          east,   ornate_antechamber,
      drafty_room,          down,   salt_mine_1,
      ornate_antechamber,   east,   cold_room,
      cold_room,            north,  winch_room,
      winch_room,           east,   armoury,
      salt_mine_1,          west,   salt_mine_2,
      salt_mine_1,          south,  worm_room,
      worm_room,            south,  salt_mine_3,
   ]

}

########################################
#  Objects                             #
########################################

objects {

   # Items we can pick-up (Objects)

   ladder           : object  "a ladder"                                    start_at="hut" ;
   red_fish         : object  "a red fish"                                  start_at="road_3" ;
   short_sword      : object  "a short sword"                               start_at="top_of_tree" ;
   coin             : object  "a coin"                                      start_at="ornate_antechamber" ;
   string           : object  "some string"                                 start_at="salt_mine_2" ;
   salt             : object  "some salt"                                   start_at="salt_mine_3" ;
   oil              : object  "can of oil"                                  start_at="cold_room" ;
   excalibur        : object  "Excalibur!"                                  start_at="armoury" ;
   long_pole        : object  "a long pole" ;
   rungs            : object  "some rungs" ;
   stone_key        : object  "a stone key" ;
   axe              : object  "a wood cutters' axe" ;
   lamp             : object  "a lamp" ;

   # Things or people that we cannot pick up (Scenery)

   old_woman        : scenery "an old woman selling lamps"                  start_at="lamp_seller_on_road" ;
   logs             : scenery "a pile of logs"                              start_at="deep_inside_birwood" ;
   bush             : scenery "a bush"                                      start_at="birwood_bush" ;
   demon_knight     : scenery "a Demon Knight guarding the east road"  start_at="demon_knight_road" ;
   trapdoor         : scenery "an old trapdoor"                             start_at="drafty_room" ;
   smashed_trapdoor : scenery "a smashed trapdoor" ;
   rockworm         : scenery "a Rockworm, guarding the south tunnel"       start_at="worm_room" ;
   ice_creature     : scenery "an Ice creature, guarding the north exit"    start_at="cold_room" ;
   winch            : scenery "a winch"                                     start_at="winch_room" ;
   spell            : scenery "a spell flying at you from Crania"           start_at="most_splendid_room" ;
   asleep_arthur    : scenery "King Arthur (asleep)"                        start_at="arthur" ;

}

########################################
#  Booleans                            #
########################################

booleans {
   is_ladder_standing : boolean "false" ;
   is_light_lit       : boolean "false" ;
   has_oiled_winch    : boolean "false" ;
   has_turned_winch   : boolean "false" ;
}

########################################
#  Blocks                              #
########################################

barriers {

   castle_door : door {
     key   = stone_key
     from  = castle_approach_2
     to    = castle_porch
     on_unlock {
        : print "YOU UNLOCK IT WITH THE KEY, WHICH JAMS IN THE LOCK." ;
        : destroy "stone_key" ;
     }
     on_open {
        : set_graphic graphic = "castle_approach_2a" target = "castle_approach_2" ;
        : redescribe ;
     }
     on_close {
        : set_graphic graphic = "castle_approach_2"  target = "castle_approach_2" ;
        : redescribe ;
     }
   }

   tree : block {
      location          = top_of_tree
      message           = YOU CAN'T FIND YOUR GRIP
      block_when_not    = is_ladder_standing
      show_blocked_exit = false
   }

   knight : block {
      location            = castle_approach_1
      gosub               = lose_fight
      block_when_exists   = demon_knight
      show_blocked_exit   = true
   }

   trapdoor : block {
      location            = salt_mine_1
      message             = THE TRAPDOOR IS JAMMED SHUT!
      block_when_exists   = trapdoor
   }

   worm : block {
      location            = salt_mine_3
      gosub               = worm_attack
      block_when_exists   = rockworm
      show_blocked_exit   = true
   }

   ice_creature : block {
      location            = winch_room
      message             = THE ICE CREATURE WILL NOT ALLOW IT ...
      block_when_exists   = ice_creature
      show_blocked_exit   = true
   }

   portcullis : block {
      location            = most_splendid_room
      message             = YOU CAN'T GO THAT WAY.
      block_when_not      = has_turned_winch
   }

   crania : block {
      location            = arthur
      message             = YOU CAN'T GET PAST
      block_when_exists   = spell
   }

}

########################################
#  On Describe                         #
########################################

on_describe {
   : if (is_light_lit) {
      : print "THE LIGHT'S GONE OUT." ;
      : set_false "is_light_lit" ;
   }
}

########################################
#  On Describe                         #
########################################

on_tick {
   : if (is_present "rockworm" ) {
      : if (linger() == 3) {
         : print "THE ROCKWORM STARTS MOVING TOWARDS YOU" ;
      }
      : if (linger() == 4) {
         : gosub "worm_attack" ;
      }
   }
   : if (is_present "ice_creature") {
     : if (linger() == 1) {
        : print "THE ICE CREATURE TAKES YOU IN A FREEZING GRIP" ;
        : gosub "end_game" ;
     }
   }
   : if (is_present "spell") {
      : if (linger() == 1) {
         : print "THE SPELL HITS YOU HEAD ON, PETRIFYING YOU INSTANTLY." ;
         : gosub "end_game" ;
      }
   }
}

########################################
#  On Command                          #
########################################

on_command {
   : match "examine ladder"  {
      : if ( is_present "ladder" ) {
         : print "A LONG POLE WITH RUNGS ATTACHED." ;
      }
   }
   : match "examine woman"  {
      : if (is_present "old_woman") {
         : print "SHE LOOKS AT YOU WITH AN INTENSE GLARE." ;
      }
   }
   : match "examine lamp"  {
      : if (is_present "lamp") {
         : print "IT'S OLD AND TARNISHED." ;
      }
   }
   : match "examine fish"  {
      : if (is_present "red_fish") {
         : print "IT STINKS!" ;
      }
   }
   : match "examine sword"  {
      : if (is_present "short_sword") {
         : print "INSCRIBED UPON IT ARE THE WORDS 'GOOD LUCK' ~~ MERLIN." ;
      }
   }
   : match "examine bush"  {
      : if (is_present "bush" && has_not_created "stone_key") {
         : print "YOU FIND SOMETHING!" ;
         : create "stone_key" ;
         : press_any_key ;
         : redescribe ;
      }
   }
   : match "examine logs"  {
      : if (is_present "logs" && has_not_created "axe") {
         : print "YOU FIND AN AXE!" ;
         : create "axe" ;
         : press_any_key ;
         : redescribe ;
      }
   }

   : match "get ladder"  {
      : if (is_at "foot_of_tree" && is_beside "ladder") {
         : get ;
         : set_false "is_ladder_standing" ;
         : set_graphic target = "foot_of_tree" graphic = "foot_of_tree"  ;
         : redescribe ;
      }
   }

   : match "stand ladder;lean ladder;rest ladder"  {
      : if (is_carried "ladder" && is_at "foot_of_tree") {
         : drop ;
         : set_true "is_ladder_standing" ;
         : set_graphic target = "foot_of_tree" graphic = "foot_of_tree_2"  ;
         : redescribe;
      }
   }

    : match "fight knight;attack knight;challenge knight"  {
      : if (is_present "demon_knight") {
         : if (is_carried "short_sword") {
            : gosub "win_fight" ;
         }
         : else {
            : gosub "lose_fight" ;
         }
      }
    }

    : match "break ladder;smash ladder;disassemble ladder"  {
       : if (is_carried "ladder") {
          : print   "OK."       ;
          : destroy "ladder"    ;
          : create  "long_pole" ;
          : create  "rungs"     ;
          : press_any_key       ;
          : redescribe          ;
       }
    }

    : match "cross chasm; balance _; walk _"  {
      : if (is_at "chasm" && is_carried "long_pole") {
         : print "THE POLE HELPS YOU BALANCE...." ;
         : press_any_key ;
         : goto "edge_of_birwood" ;
         : redescribe ;
      }
      : if (is_at "chasm" && !is_carried "long_pole") {
         : print "YOU LOSE YOUR BALANCE....." ;
         : gosub "end_game" ;
      }
      : if (is_at "edge_of_birwood" && is_carried "long_pole") {
         : print "THE POLE HELPS YOU BALANCE...." ;
         : press_any_key ;
         : goto "chasm" ;
         : redescribe ;
      }
      : if (is_at "edge_of_birwood" && !is_carried "long_pole") {
         : print "YOU LOSE YOUR BALANCE....." ;
         : gosub "end_game" ;
      }
    }

   : match "give coin; buy lamp"  {
     : if (is_present "old_woman") {
        : if (is_carried "coin") {
           : print "THE OLD LADY TAKES YOUR COIN, GIVES YOU A BRASS LAMP, THEN DISAPPEARS INTO THIN AIR." ;
           : destroy "coin" ;
           : destroy "old_woman" ;
           : create "lamp" target="inventory" ;
           : set_graphic graphic = "lamp_seller_on_road_2"  target = "lamp_seller_on_road" ;
           : press_any_key ;
           : redescribe ;
        }
        : else {
           : match "buy lamp"  {
              : print "'CROSS MY PALM WITH SILVER!'" ;
           }
        }
     }
   }


   : match "smash trapdoor;chop trapdoor;break trapdoor"  {
     : if (is_present "trapdoor") {
        : if (is_carried "axe") {
           : print "USING THE AXE, YOU SMASH THE TRAPDOOR!" ;
           : destroy "trapdoor" ;
           : create "smashed_trapdoor" ;
              : destroy "axe" ;
           : set_graphic target = "drafty_room" graphic = "drafty_room_2" ;
           : pause "1600" ;
           : redescribe ;
        }
        : else {
           : print "A FRUITLESS EXERCISE!" ;
           : done ;
        }
     }
   }

   : match "light lamp; switch lamp; turn lamp"  {
     : if (is_present "lamp" && is_light_lit == false) {
       : set_true "is_light_lit" ;
       : if (is_present "rockworm") {
          : print "THE ROCKWORM'S SENSITIVE EYES ARE SURPRISED BY THE STRONG LIGHT AND IT RETREATS DOWN ITS BURROW ...." ;
          : destroy "rockworm" ;
          : set_graphic target = "worm_room" graphic = "worm_room_2" ;
          : press_any_key ;
          : redescribe ;
       }
       : else {
          : print "IT EMITS A BRIGHT LIGHT." ;
       }
     }
   }

   : match "throw salt"  {
      : if (is_present "ice_creature") {
         : if (is_carried "salt") {
            : print "THE CREATURE BEGINS TO MELT RAPIDLY..." ;
            : destroy "ice_creature" ;
              : destroy "salt" ;
            : set_graphic target = "cold_room" graphic = "cold_room_2" ;
            : press_any_key ;
            : redescribe ;
         }
         : else {
            : print "YOU DON'T HAVE ANY." ;
         }
      }
      : else {
         : print "NOT RIGHT NOW." ;
      }
   }

   : match "oil winch"  {
      : if (is_present "winch") {
         : if (is_carried "oil") {
            : print "OK." ;
            : set_true "has_oiled_winch" ;
            : set_graphic target = "portcullis" graphic = "portcullis_2" ;
            : destroy "oil" ;
         }
         : else {
            : print "YOU HAVE NO OIL!" ;
         }
      }
      : else {
         : print "IT ISN'T HERE" ;
      }
   }

   : match "turn winch"  {
      : if (is_present "winch") {
         : if (has_oiled_winch) {
            : print "OK." ;
            : set_true "has_turned_winch" ;
         }
         : else {
            : print "IT'S STUCK!" ;
         }
      }
      : else {
         : print "IT ISN'T HERE" ;
      }
   }

   : match "reflect spell; deflect spell; use excalibur"  {
      : if (is_present "spell") {
         : if (is_carried "excalibur") {
            : print "EXCALIBUR REFLECTS THE SPELL! THE SORCERESS, PROMISING REVENGE, VANISHES!" ;
            : destroy "spell" ;
            : set_graphic  target = "most_splendid_room" graphic = "most_splendid_room_2";
            : press_any_key ;
            : redescribe ;
         }
         : else {
            : print "YOU WAVE YOUR HANDS BUT IT'S NO GOOD..." ;
         }
      }
      : else {
         : print "YOU CAN'T." ;
      }
   }

   : match "wake arthur; wake king"  {
      : if (is_present "asleep_arthur") {
         : clear_screen;
         : print_graphic "ending_screen";
         : end_game ;
      }
   }

}


########################################
#  Subroutines                         #
########################################

subroutines {

   // This subroutine is executed if we lose a fight with the knight
   lose_fight : subroutine {
      // Have to explicitly attack the knight, even if you have the sword.
      : print "THE KNIGHT WIELDS HIS SWORD DEFTLY AND ATTACKS YOU...." ;
      : gosub "end_game" ;
   }

   // This subroutine is executed if we win a fight with the knight.
   win_fight : subroutine {
      : print "A GREAT BATTLE ENSUES IN WHICH YOU ARE VICTORIOUS. THE KNIGHT TURNS TO DUST BEFORE YOUR EYES ALONG WITH YOUR SWORD!" ;
      : press_any_key ;
      : destroy "demon_knight" ;
      : destroy "short_sword" ;
      : set_graphic graphic = "demon_knight_road_2"  target = "demon_knight_road" ;
      : redescribe ;
   }

   end_game : subroutine {
      : press_any_key ;
      : clear_screen;
      : print_graphic "game_over" ;
      : print "Your quest is over .........." ;
      : turns ;
      : end_game ;
   }

   worm_attack : subroutine {
     : print "THE ROCKWORM RISES UP AND TAKES YOU IN ITS GLEAMING MANDIBLES." ;
     : gosub "end_game" ;
   }

}

// Placeholders used for documentation purposes only as graphic data is too large to place in document.
assets {
   graphics {
      armoury               : placeholder ;
      arthur                : placeholder ;
      banquet_hall          : placeholder ;
      birwood_bush          : placeholder ;
      castle_approach_1     : placeholder ;
      castle_approach_2     : placeholder ;
      castle_approach_2a    : placeholder ;
      castle_porch          : placeholder ;
      chasm                 : placeholder ;
      cold_room             : placeholder ;
      cold_room_2           : placeholder ;
      deep_inside_birwood   : placeholder ;
      demon_knight_road     : placeholder ;
      demon_knight_road_2   : placeholder ;
      drafty_room           : placeholder ;
      drafty_room_2         : placeholder ;
      edge_of_birwood       : placeholder ;
      ending_screen         : placeholder ;
      excalibur_loading     : placeholder ;
      foot_of_tree          : placeholder ;
      foot_of_tree_2        : placeholder ;
      game_over             : placeholder ;
      hut                   : placeholder ;
      lamp_seller_on_road   : placeholder ;
      lamp_seller_on_road_2 : placeholder ;
      most_splendid_room    : placeholder ;
      most_splendid_room_2  : placeholder ;
      ornate_antechamber    : placeholder ;
      portcullis            : placeholder ;
      portcullis_2          : placeholder ;
      road_1                : placeholder ;
      road_2                : placeholder ;
      road_3                : placeholder ;
      road_4                : placeholder ;
      salt_mine_1           : placeholder ;
      salt_mine_2           : placeholder ;
      salt_mine_3           : placeholder ;
      top_of_tree           : placeholder ;
      winch_room            : placeholder ;
      worm_room             : placeholder ;
      worm_room_2           : placeholder ;
   }
}

8. Finishing Up

8.1. Adding Polish

8.1.1. Some More Examine Commands

The fish is found early on in the game, and the player might naturally try to eat the fish. This response checks to see if the fish is present (present means in the same scene or held in the players hands). If the fish is present, and if "EAT FISH" is submitted as a comant, then it’s game over. The fish is rotten.

: match "eat fish"  {
   : if (is_present "red_fish") {
      : print "UHGH! THIS FISH IS ROTTEN!\nYOU START TO GET STOMACH PAINS." ;
      : gosub "end_game" ;
   }
}

8.1.2. Adding an intro tune

Adding an intro tune is a matter of calling a subroutine containing beeps with the correct pitches and millisecond timings when the game starts.

This action can be added at the start of the game.

Note : If using sound in your game, the game will automatically ask for consent for sound after the intro screen is shown.

on_startup {
   : gosub "intro_song" ;
}
subroutines {}
intro_song : subroutine {
  : beep millis = "256"  pitch = "0"  ;
  : beep millis = "512"  pitch = "3"  ;
  : beep millis = "256"  pitch = "5"  ;
  : beep millis = "512"  pitch = "7"  ;
  : beep millis = "256"  pitch = "8"  ;
  : beep millis = "256"  pitch = "7"  ;
  : beep millis = "512"  pitch = "5"  ;
  : beep millis = "256"  pitch = "2"  ;
  : beep millis = "512"  pitch = "-2" ;
  : beep millis = "256"  pitch = "0"  ;
  : beep millis = "256"  pitch = "2"  ;
  : beep millis = "256"  pitch = "3"  ;
  : beep millis = "256"  pitch = "2"  ;
  : beep millis = "512"  pitch = "2"  ;
  : beep millis = "256"  pitch = "7"  ;
  : beep millis = "256"  pitch = "8"  ;
  : beep millis = "256"  pitch = "3"  ;
  : beep millis = "256"  pitch = "0"  ;
}

How to write a song is a whole different subject, but pitch = 0 represents middle c, so you can experiment just by doing.

8.2. Setting up the "loading" screen

In the old days, games used to take a long time to load before you could play the game. Whilst they were loading, a graphic was displayed, to make the wait more interesting and build excitement for playing the game.

Adventuron supports an image such as this - an image to be displayed, before the player clicks the screen or touches the keyboard for the first time.

To set up an loading screen, it’s very simple.

We go to a blank line at the "root" level of the source code, then press CONTROL + SPACE, then select "loading_screen".

loading_screen = excalibur_loading

After doing this, pressing the "play" button, will display the loading screen instead of the ADVENTURON logo.

excalibur loading

8.2.1. Advanced Customisation

This section is to be complete pending version 1.0 of Adventuron …​

8.2.2. The 'if_examine' Command

So far we have just used the 'match' command to check for verbs and nouns, but as examine commands are very common, there also exists an 'if_examine' command, which requires the identifier of an object.

How to examine the fish with the 'match' command
: match "examine fish"  {
  : if (is_present "red_fish") {
     : print "IT STINKS!" ;
  }
}
How to examine a ladder with the 'examine' command
: if_examine "red_fish" {
   : print "IT STINKS!" ;
}

The examine command doesn’t require a check for if the object is present, and it doesn’t require a verb. It expects the identifier of an object.

It will automatically know which noun and verb to match from the id of the object.

We can now replace all our examine messages like this:

on_command {

: if_examine "ladder"       { : print "A LONG POLE WITH RUNGS ATTACHED." ; }
: if_examine "old_woman"    { : print "SHE LOOKS AT YOU WITH AN INTENSE GLARE." ; }
: if_examine "lamp"         { : print "IT'S OLD AND TARNISHED." ; }
: if_examine "red_fish" { : print "IT STINKS!" ; }
: if_examine "short_sword"  { : print "INSCRIBED UPON IT ARE THE WORDS 'GOOD LUCK' ~~ MERLIN." ; }
: if_examine "bush" {
   : if (has_not_created "stone_key") {
      : print "YOU FIND SOMETHING!" ;
      : create "stone_key" ;
      : press_any_key ;
      : redescribe ;
   }
}
: if_examine "logs" {
   : if (has_not_created "axe") {
      : print "YOU FIND AN AXE!" ;
      : create "axe" ;
      : press_any_key ;
      : redescribe ;
   }
}

/// Other commands here

}

8.2.3. Code So Far

########################################
#  Adventuron                          #
########################################

start_at       = hut
loading_screen = excalibur_loading

########################################
#  Locations                           #
########################################

locations {

   hut                    : location "You are in an old hut. Sunlight shines in from a doorway to the north.";
   road_1                 : location "You are standing on a track. The hut is south.";
   road_2                 : location "You are where the road turns eastwards. You see small hills in the distance.";
   road_3                 : location "You are on a road surrounded by grass. Trees can be seen on a hill in the distance.";
   road_4                 : location "You are on a dusty path on the edge of Birwood.";
   lamp_seller_on_road    : location "You are at a crossroads.";
   chasm                  : location "You are stood on the edge of a huge chasm (a cliff). A tightrope spans the gap, but it looks dangerous.";
   edge_of_birwood        : location "You are on the edge of Birwood. A rope spans the chasm northwards." ;
   deep_inside_birwood    : location "You are deep inside Birwood. The trees are alive with the buzzing of tiny insects.";
   birwood_bush           : location "You are standing in Birwood. A gap in the trees lets a warm light filter through.";
   demon_knight_road      : location "You are in a dip in the road by dark Birwood. Birds can be heard above.";
   foot_of_tree           : location "You are at the bottom of a large stone tree that is bare of any branches. The road ends here.";
   top_of_tree            : location "You are in a stone room set in a large stone tree.";
   castle_approach_1      : location "You are now a fair distance from Birwood. You can see castle Camelot to the east.";
   castle_approach_2      : location "You are outside Camelot Castle. A great stone door is the only way in.";
   castle_porch           : location "You are in the porch of Camelot.";
   banquet_hall           : location "You are in an abandoned banquet hall (eating area). Furniture lays broken on the floor.";
   drafty_room            : location "You are in a drafty room. Wind blows through gaps in the walls creating howling noises.";
   ornate_antechamber     : location "You are in an antechamber covered in thin ice that even covers the paintings.";
   portcullis             : location "You are in a room which has an iron portcullis set into the northern wall.";
   salt_mine_1            : location "You are in an old salt mine. Tunnels lead to the west and south.";
   salt_mine_2            : location "You are in the west part of the mine. It looks like it's been abandoned.";
   salt_mine_3            : location "You are at the end of the mine. You can hear the drip of water.";
   worm_room              : location "You are in the south part of the mine. There been recent movement in the rocks near your feet.";
   cold_room              : location "You are in a bitterly cold room. Everything is coated in a thick layer of ice.";
   winch_room             : location "You are in the winch room.";
   armoury                : location "You are in the armoury. Empty weapon racks line the walls.";
   most_splendid_room     : location "You are in the most splendid room in the castle. Rugs and paintings adorn the floor and walls.";
   arthur                 : location "You are in a sparse and lonely room. A cold wind enters through a high window.";

}

########################################
#  Connections                         #
########################################

connections {

   from, direction, to = [
      hut,                  north,  road_1,
      road_1,               north,  road_2,
      road_2,               east,   road_3,
      road_3,               east,   road_4,
      road_4,               north,  foot_of_tree,
      road_4,               south,  lamp_seller_on_road,
      lamp_seller_on_road,  east,   demon_knight_road,
      lamp_seller_on_road,  south,  chasm,
      foot_of_tree,         up,     top_of_tree,
      //chasm,                south,  edge_of_birwood,
      edge_of_birwood,      south,  deep_inside_birwood,
      deep_inside_birwood,  west,   birwood_bush,
      demon_knight_road,    east,   castle_approach_1,
      castle_approach_1,    east,   castle_approach_2,
      castle_approach_2,    east,   castle_porch,
      castle_porch,         east,   banquet_hall,
      banquet_hall,         north,  portcullis,
      banquet_hall,         south,  drafty_room,
      portcullis,           north,  most_splendid_room,
      most_splendid_room,   west,   arthur,
      drafty_room,          east,   ornate_antechamber,
      drafty_room,          down,   salt_mine_1,
      ornate_antechamber,   east,   cold_room,
      cold_room,            north,  winch_room,
      winch_room,           east,   armoury,
      salt_mine_1,          west,   salt_mine_2,
      salt_mine_1,          south,  worm_room,
      worm_room,            south,  salt_mine_3,
   ]

}

########################################
#  Objects                             #
########################################

objects {

   # Items we can pick-up (Objects)

   ladder           : object  "a ladder"                                    start_at="hut" ;
   red_fish         : object  "a red fish"                                  start_at="road_3" ;
   short_sword      : object  "a short sword"                               start_at="top_of_tree" ;
   coin             : object  "a coin"                                      start_at="ornate_antechamber" ;
   string           : object  "some string"                                 start_at="salt_mine_2" ;
   salt             : object  "some salt"                                   start_at="salt_mine_3" ;
   oil              : object  "can of oil"                                  start_at="cold_room" ;
   excalibur        : object  "Excalibur!"                                  start_at="armoury" ;
   long_pole        : object  "a long pole" ;
   rungs            : object  "some rungs" ;
   stone_key        : object  "a stone key" ;
   axe              : object  "a wood cutters' axe" ;
   lamp             : object  "a lamp" ;

   # Things or people that we cannot pick up (Scenery)

   old_woman        : scenery "an old woman selling lamps"                  start_at="lamp_seller_on_road" ;
   logs             : scenery "a pile of logs"                              start_at="deep_inside_birwood" ;
   bush             : scenery "a bush"                                      start_at="birwood_bush" ;
   demon_knight     : scenery "a Demon Knight guarding the east road"  start_at="demon_knight_road" ;
   trapdoor         : scenery "an old trapdoor"                             start_at="drafty_room" ;
   smashed_trapdoor : scenery "a smashed trapdoor" ;
   rockworm         : scenery "a Rockworm, guarding the south tunnel"       start_at="worm_room" ;
   ice_creature     : scenery "an Ice creature, guarding the north exit"    start_at="cold_room" ;
   winch            : scenery "a winch"                                     start_at="winch_room" ;
   spell            : scenery "a spell flying at you from Crania"           start_at="most_splendid_room" ;
   asleep_arthur    : scenery "King Arthur (asleep)"                        start_at="arthur" ;

}

########################################
#  Booleans                            #
########################################

booleans {
   is_ladder_standing : boolean "false" ;
   is_light_lit       : boolean "false" ;
   has_oiled_winch    : boolean "false" ;
   has_turned_winch   : boolean "false" ;
}

########################################
#  Blocks                              #
########################################

barriers {

   castle_door : door {
     key   = stone_key
     from  = castle_approach_2
     to    = castle_porch
     on_unlock {
        : print "YOU UNLOCK IT WITH THE KEY, WHICH JAMS IN THE LOCK." ;
        : destroy "stone_key" ;
     }
     on_open {
        : set_graphic graphic = "castle_approach_2a" target = "castle_approach_2" ;
        : redescribe ;
     }
     on_close {
        : set_graphic graphic = "castle_approach_2"  target = "castle_approach_2" ;
        : redescribe ;
     }
   }

   tree : block {
      location          = top_of_tree
      message           = YOU CAN'T FIND YOUR GRIP
      block_when_not    = is_ladder_standing
      show_blocked_exit = false
   }

   knight : block {
      location            = castle_approach_1
      gosub               = lose_fight
      block_when_exists   = demon_knight
      show_blocked_exit   = true
   }

   trapdoor : block {
      location            = salt_mine_1
      message             = THE TRAPDOOR IS JAMMED SHUT!
      block_when_exists   = trapdoor
   }

   worm : block {
      location            = salt_mine_3
      gosub               = worm_attack
      block_when_exists   = rockworm
      show_blocked_exit   = true
   }

   ice_creature : block {
      location            = winch_room
      message             = THE ICE CREATURE WILL NOT ALLOW IT ...
      block_when_exists   = ice_creature
      show_blocked_exit   = true
   }

   portcullis : block {
      location            = most_splendid_room
      message             = YOU CAN'T GO THAT WAY.
      block_when_not      = has_turned_winch
   }

   crania : block {
      location            = arthur
      message             = YOU CAN'T GET PAST
      block_when_exists   = spell
   }

}

########################################
#  On Startup                          #
########################################

on_startup {
   : gosub "intro_song" ;
}

########################################
#  On Describe                         #
########################################

on_describe {
   : if (is_light_lit) {
      : print "THE LIGHT'S GONE OUT." ;
      : set_false "is_light_lit" ;
   }
}

########################################
#  On Describe                         #
########################################

on_tick {
   : if (is_present "rockworm" ) {
      : if (linger() == 3) {
         : print "THE ROCKWORM STARTS MOVING TOWARDS YOU" ;
      }
      : if (linger() == 4) {
         : gosub "worm_attack" ;
      }
   }
   : if (is_present "ice_creature") {
     : if (linger() == 1) {
        : print "THE ICE CREATURE TAKES YOU IN A FREEZING GRIP" ;
        : gosub "end_game" ;
     }
   }
   : if (is_present "spell") {
      : if (linger() == 1) {
         : print "THE SPELL HITS YOU HEAD ON, PETRIFYING YOU INSTANTLY." ;
         : gosub "end_game" ;
      }
   }
}

########################################
#  On Command                          #
########################################

on_command {

   #########################################
   ## Examine Messages
   #########################################


   : if_examine "ladder"       { : print "A LONG POLE WITH RUNGS ATTACHED." ; }
   : if_examine "old_woman"    { : print "SHE LOOKS AT YOU WITH AN INTENSE GLARE." ; }
   : if_examine "lamp"         { : print "IT'S OLD AND TARNISHED." ; }
   : if_examine "red_fish" { : print "IT STINKS!" ; }
   : if_examine "short_sword"  { : print "INSCRIBED UPON IT ARE THE WORDS 'GOOD LUCK' ~~ MERLIN." ; }

   : if_examine "bush" {
      : if (has_not_created "stone_key") {
         : print "YOU FIND SOMETHING!" ;
         : create "stone_key" ;
         : press_any_key ;
         : redescribe ;
      }
   }

   : if_examine "logs" {
      : if (has_not_created "axe") {
         : print "YOU FIND AN AXE!" ;
         : create "axe" ;
         : press_any_key ;
         : redescribe ;
      }
   }

   : match "eat fish"  {
      : if (is_present "red_fish") {
         : print "UHGH! THIS FISH IS ROTTEN!\nYOU START TO GET STOMACH PAINS." ;
         : gosub "end_game" ;
      }
   }

   : match "get ladder"  {
      : if (is_at "foot_of_tree" && is_beside "ladder") {
         : get ;
         : set_false "is_ladder_standing" ;
         : set_graphic target = "foot_of_tree" graphic = "foot_of_tree"  ;
         : redescribe ;
      }
   }

   : match "stand ladder;lean ladder;rest ladder"  {
      : if (is_carried "ladder" && is_at "foot_of_tree") {
         : drop ;
         : set_true "is_ladder_standing" ;
         : set_graphic target = "foot_of_tree" graphic = "foot_of_tree_2"  ;
         : redescribe;
      }
   }

    : match "fight knight;attack knight;challenge knight"  {
      : if (is_present "demon_knight") {
         : if (is_carried "short_sword") {
            : gosub "win_fight" ;
         }
         : else {
            : gosub "lose_fight" ;
         }
      }
    }

    : match "break ladder;smash ladder;disassemble ladder"  {
       : if (is_carried "ladder") {
          : print   "OK."       ;
          : destroy "ladder"    ;
          : create  "long_pole" ;
          : create  "rungs"     ;
          : press_any_key       ;
          : redescribe          ;
       }
    }

    : match "cross chasm; balance _; walk _"  {
      : if (is_at "chasm" && is_carried "long_pole") {
         : print "THE POLE HELPS YOU BALANCE...." ;
         : press_any_key ;
         : goto "edge_of_birwood" ;
         : redescribe ;
      }
      : if (is_at "chasm" && !is_carried "long_pole") {
         : print "YOU LOSE YOUR BALANCE....." ;
         : gosub "end_game" ;
      }
      : if (is_at "edge_of_birwood" && is_carried "long_pole") {
         : print "THE POLE HELPS YOU BALANCE...." ;
         : press_any_key ;
         : goto "chasm" ;
         : redescribe ;
      }
      : if (is_at "edge_of_birwood" && !is_carried "long_pole") {
         : print "YOU LOSE YOUR BALANCE....." ;
         : gosub "end_game" ;
      }
    }

   : match "give coin; buy lamp"  {
     : if (is_present "old_woman") {
        : if (is_carried "coin") {
           : print "THE OLD LADY TAKES YOUR COIN, GIVES YOU A BRASS LAMP, THEN DISAPPEARS INTO THIN AIR." ;
           : destroy "coin" ;
           : destroy "old_woman" ;
           : create "lamp" target="inventory" ;
           : set_graphic graphic = "lamp_seller_on_road_2"  target = "lamp_seller_on_road" ;
           : press_any_key ;
           : redescribe ;
        }
        : else {
           : match "buy lamp"  {
              : print "'CROSS MY PALM WITH SILVER!'" ;
           }
        }
     }
   }


   : match "smash trapdoor;chop trapdoor;break trapdoor"  {
     : if (is_present "trapdoor") {
        : if (is_carried "axe") {
           : print "USING THE AXE, YOU SMASH THE TRAPDOOR!" ;
           : destroy "trapdoor" ;
           : create "smashed_trapdoor" ;
              : destroy "axe" ;
           : set_graphic target = "drafty_room" graphic = "drafty_room_2" ;
           : pause "1600" ;
           : redescribe ;
        }
        : else {
           : print "A FRUITLESS EXERCISE!" ;
           : done ;
        }
     }
   }

   : match "light lamp; switch lamp; turn lamp"  {
     : if (is_present "lamp" && is_light_lit == false) {
       : set_true "is_light_lit" ;
       : if (is_present "rockworm") {
          : print "THE ROCKWORM'S SENSITIVE EYES ARE SURPRISED BY THE STRONG LIGHT AND IT RETREATS DOWN ITS BURROW ...." ;
          : destroy "rockworm" ;
          : set_graphic target = "worm_room" graphic = "worm_room_2" ;
          : press_any_key ;
          : redescribe ;
       }
       : else {
          : print "IT EMITS A BRIGHT LIGHT." ;
       }
     }
   }

   : match "throw salt"  {
      : if (is_present "ice_creature") {
         : if (is_carried "salt") {
            : print "THE CREATURE BEGINS TO MELT RAPIDLY..." ;
            : destroy "ice_creature" ;
              : destroy "salt" ;
            : set_graphic target = "cold_room" graphic = "cold_room_2" ;
            : press_any_key ;
            : redescribe ;
         }
         : else {
            : print "YOU DON'T HAVE ANY." ;
         }
      }
      : else {
         : print "NOT RIGHT NOW." ;
      }
   }

   : match "oil winch"  {
      : if (is_present "winch") {
         : if (is_carried "oil") {
            : print "OK." ;
            : set_true "has_oiled_winch" ;
            : set_graphic target = "portcullis" graphic = "portcullis_2" ;
            : destroy "oil" ;
         }
         : else {
            : print "YOU HAVE NO OIL!" ;
         }
      }
      : else {
         : print "IT ISN'T HERE" ;
      }
   }

   : match "turn winch"  {
      : if (is_present "winch") {
         : if (has_oiled_winch) {
            : print "OK." ;
            : set_true "has_turned_winch" ;
         }
         : else {
            : print "IT'S STUCK!" ;
         }
      }
      : else {
         : print "IT ISN'T HERE" ;
      }
   }

   : match "reflect spell; deflect spell; use excalibur"  {
      : if (is_present "spell") {
         : if (is_carried "excalibur") {
            : print "EXCALIBUR REFLECTS THE SPELL! THE SORCERESS, PROMISING REVENGE, VANISHES!" ;
            : destroy "spell" ;
            : set_graphic  target = "most_splendid_room" graphic = "most_splendid_room_2";
            : press_any_key ;
            : redescribe ;
         }
         : else {
            : print "YOU WAVE YOUR HANDS BUT IT'S NO GOOD..." ;
         }
      }
      : else {
         : print "YOU CAN'T." ;
      }
   }

   : match "wake arthur; wake king"  {
      : if (is_present "asleep_arthur") {
         : clear_screen;
         : print_graphic "ending_screen";
         : end_game ;
      }
   }

}


########################################
#  Subroutines                         #
########################################

subroutines {

   // This subroutine is executed if we lose a fight with the knight
   lose_fight : subroutine {
      // Have to explicitly attack the knight, even if you have the sword.
      : print "THE KNIGHT WIELDS HIS SWORD DEFTLY AND ATTACKS YOU...." ;
      : gosub "end_game" ;
   }

   // This subroutine is executed if we win a fight with the knight.
   win_fight : subroutine {
      : print "A GREAT BATTLE ENSUES IN WHICH YOU ARE VICTORIOUS. THE KNIGHT TURNS TO DUST BEFORE YOUR EYES ALONG WITH YOUR SWORD!" ;
      : press_any_key ;
      : destroy "demon_knight" ;
      : destroy "short_sword" ;
      : set_graphic graphic = "demon_knight_road_2"  target = "demon_knight_road" ;
      : redescribe ;
   }

   end_game : subroutine {
      : press_any_key ;
      : clear_screen;
      : print_graphic "game_over" ;
      : print "Your quest is over .........." ;
      : turns ;
      : end_game ;
   }

   worm_attack : subroutine {
     : print "THE ROCKWORM RISES UP AND TAKES YOU IN ITS GLEAMING MANDIBLES." ;
     : gosub "end_game" ;
   }

   intro_song : subroutine {
      : print_graphic "excalibur_loading" ;
      : beep millis = "256"  pitch = "0"  ;
      : beep millis = "512"  pitch = "3"  ;
      : beep millis = "256"  pitch = "5"  ;
      : beep millis = "512"  pitch = "7"  ;
      : beep millis = "256"  pitch = "8"  ;
      : beep millis = "256"  pitch = "7"  ;
      : beep millis = "512"  pitch = "5"  ;
      : beep millis = "256"  pitch = "2"  ;
      : beep millis = "512"  pitch = "-2" ;
      : beep millis = "256"  pitch = "0"  ;
      : beep millis = "256"  pitch = "2"  ;
      : beep millis = "256"  pitch = "3"  ;
      : beep millis = "256"  pitch = "2"  ;
      : beep millis = "512"  pitch = "2"  ;
      : beep millis = "256"  pitch = "7"  ;
      : beep millis = "256"  pitch = "8"  ;
      : beep millis = "256"  pitch = "3"  ;
      : beep millis = "256"  pitch = "0"  ;
   }

}

// Placeholders used for documentation purposes only as graphic data is too large to place in document.
assets {
   graphics {
      armoury               : placeholder ;
      arthur                : placeholder ;
      banquet_hall          : placeholder ;
      birwood_bush          : placeholder ;
      castle_approach_1     : placeholder ;
      castle_approach_2     : placeholder ;
      castle_approach_2a    : placeholder ;
      castle_porch          : placeholder ;
      chasm                 : placeholder ;
      cold_room             : placeholder ;
      cold_room_2           : placeholder ;
      deep_inside_birwood   : placeholder ;
      demon_knight_road     : placeholder ;
      demon_knight_road_2   : placeholder ;
      drafty_room           : placeholder ;
      drafty_room_2         : placeholder ;
      edge_of_birwood       : placeholder ;
      ending_screen         : placeholder ;
      excalibur_loading     : placeholder ;
      foot_of_tree          : placeholder ;
      foot_of_tree_2        : placeholder ;
      game_over             : placeholder ;
      hut                   : placeholder ;
      lamp_seller_on_road   : placeholder ;
      lamp_seller_on_road_2 : placeholder ;
      most_splendid_room    : placeholder ;
      most_splendid_room_2  : placeholder ;
      ornate_antechamber    : placeholder ;
      portcullis            : placeholder ;
      portcullis_2          : placeholder ;
      road_1                : placeholder ;
      road_2                : placeholder ;
      road_3                : placeholder ;
      road_4                : placeholder ;
      salt_mine_1           : placeholder ;
      salt_mine_2           : placeholder ;
      salt_mine_3           : placeholder ;
      top_of_tree           : placeholder ;
      winch_room            : placeholder ;
      worm_room             : placeholder ;
      worm_room_2           : placeholder ;
   }
}

8.3. Exporting As HTML

8.3.1. Packaging as a HTML File

Now we have a game that plays well in the Adventuron editor, it’s time to package the game as a HTML File.

To do this we must fill in the game info section.

game_information {
   game_name             = Excalibur : Sword of Kings
   game_shortname        = Excalibur
   ported_by             = xxxxx
   written_by            = Ian Smith / Shaun McClure
   copyright_message     = (C) Adventuron Software Limited
   year                  = 1987
   game_version          = 1.0.0
   short_synopsis        = Rescue King Arthur In Camelot
}

Now, click the menu button at the bottom right, then click the "Compile" option.

Adventuron will display a message, which you should read, then produce a HTML file containing the game.

When you make something new, you automatically are granted copyright. Copyright gives you the right to choose how to sell something and who is allowed to copy you.

Excalibur is copyright of Adventuron Software Limited for the purpose of using in this tutorial. Producing a HTML version is to demonstrate the feature. You are not permitted to redistribute your HTML copy of Excalibur.

8.3.3. Distributing Your Own Game

Adventuron is not licensed for commercial use, and games created with Classroom embed Adventuron into the generated HTML files.

As long as you make your own adventure that does not break the license terms, you can share HTML versions of your own creations, providing you do not charge a fee for your game.

Your packaged game will be independent of the Adventuron website, and also available to play without an internet connection. It is very important for archival purposes.

8.3.4. Adventuron Engine License (1.0.0 Prerelease)

/* ADVENTURON 1.0.0 Prerelease - NON COMMERCIAL-USE EULA                           */
/* Copyright (C) 2017 - 2021 Adventuron Software Limited                           */
/* ADVENTURON Engine is permitted to be redistributed for personal non-commercial  */
/* use except when game content contains one or more of the following items:       */
/*  (1) Hate Speech (such as racism, sexism, ableism, homophobia, religious
        hatred, etc).                                                              */
/*  (2) Content for which you do not own the intellectual property rights.         */
/*  (3) Adult content (including innuendo), express or implied, that is not        */
/*      clearly marked/warned via the title screen as such.                        */
/*  (4) Pornograpic Content.                                                       */
/*  (5) Illegal content.                                                           */
/*  (6) Grossly offensive material, express or implied.                            */
/*  (7) Content involving the exploitation of minors, express or implied.          */
/*  (8) Libellous speech or content, express or implied.                           */
/*  (9) Harassment, threats or intimidation, express or implied.                   */
/*                                                                                 */
/* The software is provided "as is", without warranty of any kind, express or      */
/* implied, including but not limited to the warranties of merchantability,        */
/* fitness for a particular purpose and noninfringement. In no event shall         */
/* the authors or copyright holders be liable for any claim, damages or            */
/* other liability, whether in an action of contract, tort or otherwise,           */
/* arising from, out of or in connection with the software or the use or           */
/* other dealings in the software.                                                 */

8.4. Congratulations

congratulations

8.4.1. Congratulations

Congratulations, you have completed this tutorial.

You have now constructed an illustrated text adventure using the Adventuron game system.

The concepts used in this tutorial can be used to create all sorts of games.

Be careful about creating game featuring copyright characters. For example, games involving famous comic book characters would not be legal to distribute.

Of course you are free to experiment with anything you like privately, but it’s more fun to make a game that you can share with other people.

8.4.2. Advanced Features Of Adventuron

This tutorial demonstrated how to create a basic text adventure in Adventuron, and in doing so, ignores many of the advanced features.

When you are more comfortable with Adventuron, there are many more features to be discovered, such as container support, advanced parser (use full sentences rather than verb noun), gamebook mode, chiptune support, hyperlinks, export to 8-bit machines, dynamic graphics, loops, maths, attribute support, and much more.

Please stay tuned for additional documentation.

8.4.3. Full set of commands

Adventuron contains many many commands and conditions, but only a few of these are required if you are building a simple adventure game such as Exclalibur.

These are all the commands and conditions that Excalibur uses.

Table 5. Commands
Command Description

: match

Execute some commands if a verb or noun (or both) match a pattern.

: if

Perform some commands only if a condition is satisfied (the condition evaluates to true)

: else

Perform some commands only if the condition in a preceeding if is NOT satisfied. Must follow an :if command.

: else_if

Perform some commands only if a condition is satisfied (the condition evaluates to true). Must follow an :if command.

: print

Displays some text to the player

: create

Creates an object in the game (creates in current scene by default).

: destroy

Destroy an object in the game.

: press_any_key

Tells the game to wait until the player either presses a key on the keyboard, or clicks the mouse, or touches the touchscreen.

: pause

Pauses a number of milliseconds. One second is 1,000 milliseconds, so if you want to wait for 2 seconds, use the : pause "2000"; command.

: done

Stop executing commands and wait for input by the player.

: clear_screen

Clears the current screen. This happens automatically when the player navigates to a different location, but sometimes we may wish to refresh the screen when the player does not move.

: redescribe

Tells the game to clear the screen, then to redescribe the current scene, including the contents of the scene.

: gosub

Execute the commands contained in a nominated subroutine.

: set_true

Sets a boolean variable to contain a TRUE value.

: set_false

Sets a boolean variable to contain a FALSE value.

: set_integer

Sets an integer (an integer is a number) variable to a specified value.

: increment

Adds 1 to the value of the specified integer variable (an integer variable holds a number).

: end_game

Display the end_game text, then wait for the player to press or click something, and then restart the game. Typically you would want to give the player some specific information before using this command (like display a failure screen).

: beep

Play a sound tone at a specified pitch and duration.

: turns

Display the current amount of turns taken in the game.

: inventory

Display the items that the player is carrying.

: set_graphic

Change the graphic that is drawn when the player enters a scene. The game will remember the changed graphic. This is useful for if the location should look different in response to some event that has happened in the game.

: show_graphic

Print a graphic at the current line of the display (inline). This only happens once, and does not change any graphic that will be displayed when the player re-enters a scene.

: set_theme

Change the current theme of the game to the specified new theme. A theme is the way that the game is configured to be drawn or laid out. This is an ADVANCED command.

: block

Blocks access to a location on the map. All entrances to the location from all directions are blocked, and a customizable message will be displayed to the player if they attempt to access the location.

: unblock

Unblocks access to a location. The message is removed, and now the location will be listed as an exit direction in neighbouting locations/scenes.

Table 6. Boolean Expression Items
Condition Description

VARNAME

Is a boolean with id matching VARNAME currently holding a TRUE value?

COND1 || COND2

Is condition1 OR condition2 returning a positive answer?

COND1 && COND2

Is condition1 AND condition2 returning a positive answer?

!COND1

Is condition1 holding a FALSE value?

EXPRESSION1 == EXPRESSION2

Is expression1 returning the same value as expression2?

is_present

Is an object carried or in the same scene as the player?

has_not_created

Has the object not yet been created?

is_at

Is the player at the specific scene?

is_carried

Is the player holding the specified item (in the inventory).

is_beside

Is the specified item in the same location as the player, but not in the player’s inventory?

is_just_entered

Did the player just enter the current location from a different location?

Table 7. Integer Expression Items
Condition Description

linger()

Returns the number of turns since we arrived in the current scene. This resets to zero when the player moves to a new location.

Table 8. Events Handling
Event Type Description

on_startup{}

This code block will be executed before any other block when a game is first started. It will NOT be executed if loading a saved game, but it will be executed on a new game.

on_command{}

The on_command{} block is executed after the player submits a command (via keyboard / mouse / joypad / speech / touch / etc). Typically this section contains one or more : match {} items, which are used to check for a particular verb / noun combination.

on_describe{}

The on_describe{} block is executed when a scene is redescribed (this may not be every turn). This may happen due to a code executed in the on_command {} block, or due to the player moving to a new location.

on_tick{}

The on_tick{} block is executed after the on_command{} block, and if the scene has just been changed, it is executed after the on_describe{} block tooand can be used for actions that occur in the game world, independent of what the player just typed.

8.5. End of Tutorial B

You have now completed Tutorial B.

Click here to go to the Adventuron User Guide.