Building A Classic Treasure-Hunt style Text-Adventure with Adventuron
This article provides a basic template for building classic treasure hunt text-adventure games using Adventuron.
What are the traits of treasure-hunt text-adventure games?
Features of a traditional treasure hunt game are:
- Parser verb/noun input (type in a command to the game, and see a response to the command).
- Exploration + barrier mechanics (a map linked together via compass directions with optional obstacles that block onward progress until a puzzle or puzzles are solved).
- Each location has a short location descriptions.
- Concise / easy to scan object-list (interactive items in the location).
- Large numbers of in-game objects entities.
- Ability to take, drop, objects, and use other verbs with objects, in order to manipulate the state of the game world.
- Instant refresh of object list / exit list.
- Dense puzzles / fast fun gameplay.
- No need to scan for nouns in location description. All interactive nouns will be in player inventory or in the current location object list. This greatly reduces player friction as they do not have to scan a large amount of text for interesting nouns. The object list is very fast to scan.
- Focus on environmental puzzles over narrative.
- Enumerated goals (either collect object and place in treasure room, or complete a numbered set of objectives).
- Per-location graphics that appear at the top of the page, cleardown / refresh of screen when moving to new location. Graphics can change in response to the state of the game changing.
The following code is offered as a template, from which to create said styled games.
Annotated Source
For more information about the Adventuron code syntax, see the user manual.
The first few lines describe the configurion of the starting location, the treasure location, and the method that Adventuron should use to redescribe a location.
We tell Adventuron to start outside the cave (which corresponds to the ID of a location defined in the next section).
The treasure room is set as the "treasure_room" location ID.
We tell adventuron to use the "auto_beta" redescribe mode, which will make adventuron automatically update the object and exit list on a screen (by automatically redescribing) when they change.
If something is printed before the object list updates, then a press_any_key command is automatically placed after the print statement. This makes it really easy to write command handlers without worrying about manually refreshing the screen.
start_at = outside_cave treasure_room = treasure_room redescribe = auto_beta
This section just adds two locations, one of which is the special "treasure room" location. We told Adventuron that the "treasure_room" location was the treasure room in the last code snippet.
locations { outside_cave : location "You are outside the cave of magic." ; treasure_room : location "You are in the treasure room" ; }
This section is use to create connections from each location to other locations. Each connection is bidirectional, unless the "_oneway" suffix is added to the direction, e.g. "north_oneway".
connections { from, direction, to = [ outside_cave, north, treasure_room, ] }
We set up the objects in the game here. There are two items that are flagged as treasures, and two that are not. The golden_horn does not exist when the game starts (as it was not given a start location), but it is still counted as a treasure that must be placed in the treasure room by the game.
The game has one (terrible) "puzzle", which is that the player should blow the horn for the horn to transform into the treasure version of the horn, the golden horn. That logic is not contained here but we need to define the non treasure and the treasure version of the horn as shown below:
objects { lamp : object "a lamp" at = "outside_cave" msg="a <red<10>> herring."; spoon : object "a spoon" at = "outside_cave" treasure = "true"; horn : object "a horn" at = "outside_cave" msg="Waiting to be blown."; golden_horn : object "a golden horn" treasure = "true" ; }
(OPTIONAL)
The on_startup {} block is used to display a message at the start of the game. We use the "press_any_key" command to wait for user input (ENTER key, mouse button, tap touchscreen).
on_startup { : print "Deposit the two treasures in the treasure room to win." ; : press_any_key ; }
(OPTIONAL)
The on_describe {} block is used to execute logic that will run when the location is redescribed (manually) or a location is entered into the first time.
In this case we just tell the player how to interact with the game. We use the <SOMETEXT<SOMECOLOR>> format to colour the text.
Text formatting codes can be found in the user manual.
on_describe { : if (is_just_entered () && is_at "outside_cave") { : print "<Right click objects to see common verbs, or click directions to go in that direction.<14>>" ; : print "<Type 'HELP' to see a list of common commands.<13>>" ; } }
The on_command {} block is used to execute conditional commands based on what the player has typed (or spoken).
In this super simple game, the player needs to type "blow horn" to swap the normal horn for the golden horn. The logic checks to see if the horn is carried, and if so, it swaps it. If the golden horn is carried, then blowing the horn again will do nothing.
Information on conditional statements and commands can be found in the Adventuron tutorials.
on_command { : match "blow horn" { : if (is_carried "horn") { : swap o1 = "horn" o2 = "golden_horn" ; : print "You blow the horn, and the horn turns to <gold<#r>>." ; } : else_if (is_carried "golden_horn") { : print "You blow the horn, and nothing happens." ; } } }
(Optional)
Adventuron supports theming your game, so that you can achieve a desired look and feel.
Treasure hunt games can benefit from displaying a status bar showing the amount of treasures deposited in the treasure room. They also benefit from a terse layout.
Below is a suggested layout, but themes are very adaptable, and you can skin your game to your own requirements.
themes { my_theme : theme { theme_settings { capitalization = upper font = plotter_bold_extended layout = SB G D O X layout_mobile = SB G DO X columns = 48 } colors { treasure_pen = #r status_bar_paper = #00e status_bar_pen = #fff } screen { paragraph_spacing_multiplier = "1" padding_horz = "1"} system_messages { inventory_list_header = "Carrying:\s" object_list_header = "Items here:\s" exit_list_header_concise = "Exits:\s" treasure_message = "Treasure!" } status_bar { : fixed_text "STINGS QUEST II" ; : treasure_score ; } } }
Adding Graphics
To learn how to add graphics to your game, read the following section of tutorial A.
Final Source (Without Graphics)
start_at = outside_cave treasure_room = treasure_room redescribe = auto_beta locations { outside_cave : location "You are outside the cave of magic." ; treasure_room : location "You are in the treasure room" ; } connections { from, direction, to = [ outside_cave, north, treasure_room, ] } objects { lamp : object "a lamp" at = "outside_cave" msg="a <red<10>> herring."; spoon : object "a spoon" at = "outside_cave" treasure = "true"; horn : object "a horn" at = "outside_cave" msg="Waiting to be blown."; golden_horn : object "a golden horn" treasure = "true" ; } on_startup { : print "Deposit the two treasures in the treasure room to win." ; : press_any_key ; } on_describe { : if (is_just_entered () && is_at "outside_cave") { : print "<Right click objects to see common verbs, or click directions to go in that direction.<14>>" ; : print "<Type 'HELP' to see a list of common commands.<13>>" ; } } on_command { : match "blow horn" { : if (is_carried "horn") { : swap o1 = "horn" o2 = "golden_horn" ; : print "You blow the horn, and the horn turns to <gold<#r>>." ; } : else_if (is_carried "golden_horn") { : print "You blow the horn, and nothing happens." ; } } } themes { my_theme : theme { theme_settings { capitalization = upper font = plotter_bold_extended layout = SB G D O X layout_mobile = SB G DO X columns = 48 } colors { treasure_pen = #r status_bar_paper = #00e status_bar_pen = #fff } screen { paragraph_spacing_multiplier = "1" padding_horz = "1"} system_messages { inventory_list_header = "Carrying:\s" object_list_header = "Items here:\s" exit_list_header_concise = "Exits:\s" treasure_message = "Treasure!" } status_bar { : fixed_text "STINGS QUEST II" ; : treasure_score ; } } }
Adventuron Christmas Jam
If you are exited to build a treasure-hunt style game (or any other kind of text adventure) - with a Christmas theme, then do check out the Adventuron Christmas Jam (ends December 21st 2020). There are lots of prizes, such as a Raspberry Pi 400, retro books and more.
If you have any questions about Adventuron, check out the forum here.