Official Blog of the Adventuron Text Adventure Creation System

Saturday 21 November 2020

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:

  1. Parser verb/noun input (type in a command to the game, and see a response to the command).
  2. Exploration + barrier mechanics (a map linked together via compass directions with optional obstacles that block onward progress until a puzzle or puzzles are solved).
  3. Each location has a short location descriptions.
  4. Concise / easy to scan object-list (interactive items in the location).
  5. Large numbers of in-game objects entities.
  6. Ability to take, drop, objects, and use other verbs with objects, in order to manipulate the state of the game world.
  7. Instant refresh of object list / exit list.
  8. Dense puzzles / fast fun gameplay.
  9. 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.
  10. Focus on environmental puzzles over narrative.
  11. Enumerated goals (either collect object and place in treasure room, or complete a numbered set of objectives).
  12. 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.
In treasure hunt games, the users own interactions form the basis of their "story", and objects lists are an excellent way of conveying game world state.

If you want to, you can imply a lot of story from the state of the game via objects that have been created or destroyed or swapped.

You don't need to narrate something that happened if the player can see the thing that happened via a change in objects in the current location object list.

A wonderful treasure hunt style game is OVER HERE! by Aureas (gameplay starts at 05:00) :



Another treasure hunt style game, Treasures of Hollowhill, by John Blythe (written in Adventuron). The game uses object lists to convey the current state of the location.



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.


Tuesday 21 July 2020

LOOK, SEARCH, & EXAMINE


What follows is a very personal opinion on the use of LOOK, SEARCH and EXAMINE in the context of interactive fiction / text adventure games.

Traditional IF/TA games typically allow the player to move around quasi-geographic locations in an environment - described in some detail initially. Nouns representing scenery and objects within a location in the environment may be interrogated to find out more information, to discover new layers of descriptions, or even discover new objects.

There are largely three verbs that are employed in this interrogation. EXAMINE and LOOK are generally synonyms, and refer to the act of looking at an object. SEARCH is an additional verb that generally means rummaging or deeply looking at or inside or atop of an object (or noun). 

Many text adventure / IF games take the approach that examining and object and searching an object are two different actions and therefore should be represented by separate verbs. Superficially, this makes perfect sense. Looking at a bag is not looking inside a bag after all.

The former is the act of looking at something (somewhat passively), and the latter is the act of digging through or thoroughly looking at the contents of something (an active action).

When the player types EXAMINE an object should be looked at, when the player types SEARCH, the object should be thoroughly examined inside and out.

Whilst EXAMINE (or the common synonym LOOK) is almost unavoidably required for the purposes of revealing new clues or sub-items that would not fit in the location text (examine and look are synonyms in Adventuron by default), SEARCH is something that really essentially means EXAMINE MORE (in the context of the object).

There is a correctness to keeping SEARCH and EXAMINE separate, but just like gameplay physics in 3d action games does not represent reality, perhaps we need less correctness for the purposes of gameplay in IF/TA.

So let’s get started …

The problem with using SEARCH is that, except when clearly signposted, the player has no idea when something should be examined and when something can additionally be searched.

Some games never use SEARCH, and some games use SEARCH for a few or just one object.
This is purely my own opinion, but SEARCH, if in your game, should be a synonym for EXAMINE (or look).

Making the responses to EXAMINE and SEARCH is padding at best (EXAMINE could fulfil the same role), frustrating at least (if the player knows SEARCH is a verb in the game, then when they are stuck they now have to scour the games for new nouns to SEARCH), and game breaking at worst (the player has played games without SEARCH and thinks that EXAMINE is the same as search, and therefore the game is unwinnable for the player).

There may perhaps be benign uses of search such as items that literally beg to be searched, such as piles of leaves or bodies, but I would still say that the problem with implementing SEARCH as a separate action even if just once in your game is that now the player has uncertainty if every noun in the game will yield progress if they try SEARCH on it too.

To make SEARCH and EXAMINE different response handlers is to invite the player to have to SEARCH and EXAMINE every object, once the moment comes in the game where they get stuck.
In the case of the pile of leaves, you could code a joint EXAMINE and SEARCH routine that yields the same result. If there is an object hidden in the leaves, then reveal it with the examine after describing the leaves.

If an object is clearly signposted as being searchable, then the separate SEARCH is redundant, tell the player upon examination that an additional search was performed if a search action is required to move the game forward.

If the SEARCH is difficult to predict that it will yield a different result to an EXAMINE, then all the more reason to not not require an input the player is unlikely to type (except via a grind pass of the nouns).

If you don’t want to code a combined handler for EXAMINE and SEARCH, then code a single routine that will point the player towards examining “Examining objects will also search them if necessary.”.

As long as the player views SEARCH and EXAMINE as the same then they will not think they have to brute force nouns when the going gets tough. The moment they find one different response for SEARCH, then they now know that they have to grind, or even worse, they are not aware to SEARCH.

If parser-based IF/TA ever has a hope of being acceptable again to a winder audience, then in my view, then reducing parser friction is the only priority.

Almost all graphical adventures have an EXAMINE feature, but not one of them (to the best of my knowledge) has a SEARCH features, because it’s redundant. Imagine there was a SEARCH verb in Monkey Island, and one object something hidden inside. Would that add or detract from your enjoyment of the game?

This isn’t saying that a game can’t be complex, but a game should not be designed to integrate TWO grind mechanics. The EXAMINE mechanic is somewhat of a necessary grind evil, given that examining nouns in a room has next to no creative input from the player. Doubling up the grind, however “correct”, has an adverse impact on game flow (imho).

I’m advocating for making SEARCH and EXAMINE interchangeable ESPECIALLY when the game has an object that must logically be searched. It’s a small precision compromise, but I wholeheartedly believe it’s the right thing to do.

LOOKING IN or LOOKING ON something is different to search in my view. Containers are clearly understood by humans and it’s entirely natural to look in a container therefore if a grind instinct was invoked on LOOK IN and LOOK ON, you will be dealing with a very small (and non frustrating subset) of nouns in the game.

I see no reason why a LOOK IN or LOOK ON can’t be a separate handler without triggering a grind instinct in the player. LOOK UNDER is something I generally don’t think is a good idea to have a different response (to EXAMINE) for as again it could invoke grinding (player trying to look under everything after they get one positive response).

I do think that we are on the cusp of a mainstream IFTA comeback, but if we want to escape the prejudice of the past with regards to parser friction, we should do some work ourselves to meet the player half way.

Tuesday 26 November 2019

TWO - A Two Word Text Adventure


I recently released TWO, which is a two word text adventure game, written in Adventuron Classroom.



The idea behind TWO is to strip away anything resembling a story, and just focus on puzzles.

The game is available to play here:

https://adventuron.itch.io/two

The treasure hunt genre was chosen for the game because it doesn't require a story and a two word game is a puzzle box rather than IF.

The game plays well on mobile:



"I see more than two words on the screen."

Here are the quite arbitrary rules:


  • Every location has a maximum of two words description.
  • Every object has a maximum of two words description (multiple objects may be listed in a location).
  • Apostrophe'd words count as one word, but no using the - characters to connect words.
  • Every response message is a maximum of two words.
  • The intro text is a maximum of two words.
  • The game over text is a maximum of two words.
  • Items in lists have their own two word allocations (such as directions, objects).

I really enjoyed this exercise in puzzle building, and I think that minimal parser based games really suit mobile as a platform. I'll be creating a gamejam around this rules shortly.

The link above has the full game, as well as full clues, encoded with base64, to avoid spoiling later puzzles. It also has a puzzle dependency chart for the game downloadable as an SVG, a preview (probably non readable, available here. Don't read onward if you want to avoid spoilers ...






































































































Sunday 28 July 2019

Video Tutorial - Beginners Guide To Coding An Illustrated Text Adventure Game



I very quickly put together a little video on how to create a simple text adventure game involving event hooks, command processors, locations, connections, objects and a block.



Full game available to play here : https://adventuron.itch.io/cave


Source (Non Graphic Version)

start_at                 = lakeside

//loading_screen           = loading_screen

game_information {
   game_name                    = The Cave of Magic
   game_shortname               = Magic Cave
   written_by                   = Chris Ainsley
   year                         = 2019
   short_synopsis               = Find the treasure
   game_version                 = 1.0.0
}

locations {
   forest       : location "You are on the forest path.\nTall <TREES<4>> tower over you on both sides." ;
   outside_cave : location "You are standing outside <THE CAVE OF MAGIC<5>>" ;
   inside_cave  : location "You are inside <THE CAVE OF MAGIC<5>>" ;
   lakeside     : location "You are by the side of a <BEAUTIFUL LAKE<2>>." ;
}
objects {
   troll    : scenery "an enormous troll" start_at = "outside_cave" ;
   sleeping_troll : scenery "an enormous troll (sleeping)" ;
   apple    : object  "an apple" ;
   treasure : object  "a pile of treasure" start_at = "inside_cave" ;
}
connections {
   from, direction, to = [
      lakeside, north, forest, 
      forest, north, outside_cave, 
      outside_cave, north, inside_cave, 
   ]
}
on_startup {
   // : print_graphic "outside_cave" ;
   : print "^c^THE MAGIC CAVE AWAITS YOU" ;
   : beep millis = "100"  pitch = "0" ;
   : beep millis = "100"  pitch = "2" ;
   : beep millis = "100"  pitch = "4" ;
   : beep millis = "100"  pitch = "6" ;
   
   : press_any_key ;
   : beep millis = "100"  pitch = "6" ;
   : beep millis = "100"  pitch = "4" ;
   : beep millis = "100"  pitch = "2" ;
   : beep millis = "100"  pitch = "0" ;
}
on_command {
   : match "pick apple;get apple"  {
      : if (is_at "forest" && has_not_created "apple") {
         : create "apple" ;
         : redescribe;         
      }
   }
   : match "examine trees"  {
      : if (is_at "forest") {
         : print "Apple trees." ;
      }
   }
   : match "examine troll;talk troll"  {
      : print "<\"I'm so hungry\"<3>>, says the enormous TROLL in the deepest possible voice." ;
   }
   : match "give apple"  {
      : if (is_present "troll" && is_carried "apple") {
         : print "The troll grabs the apple from you hungrily. Unfortunately (for the troll), the apple is an <ENCHANTED APPLE<12>>, and sends the troll directly to sleep." ;
         : destroy "apple" ;
         : swap o1 = "troll"  o2 = "sleeping_troll" ;
         : press_any_key ;
         : redescribe;
      }
   }
   
   : match "eat apple"  {
      : if (is_present "apple") {
         : print "Unfortunately, the apple was an <ENCHANTED APPLE<12>>, and you will now go to sleep - forever." ;
         : print "^r^<GAME OVER<2>>" ;
         : end_game ;         
      }
   }
   
}

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

on_describe {
   
   : if (is_present "troll") {
      : beep millis = "100"  pitch = "-2" ;
      : beep millis = "100"  pitch = "-4" ;
      : beep millis = "300"  pitch = "-8" ;
      : print "The troll says, <\"THE CAVE IS MINE, GO AWAY\"<2>>." ;
   }
   
}

on_tick {
   : if (is_at "inside_cave" ) {
      : beep millis = "200"  pitch = "0" ;
      : beep millis = "400"  pitch = "10" ;
      : print "^r^CONGRATULATIONS !" ;
      : print "^r^YOU WON THE GAME !" ;
      : print "^r^YOUR RANKING IS : JUNIOR ADVENTURER !" ;
      : press_any_key ;
      : clear_screen;
      //: print_graphic "logo" ;
      
      : print "This tiny adventure was written using Adventuron." ;
      : print "Adventuron is a free text adventure creation language and development system." ;
      : print "Visit the website, and make a world of your own." ;
      : print "^r^<www.adventuron.io<12>>" ;
      : end_game ;
   }
}

barriers {
   block_cave : block {
      location               = inside_cave
      message                = THE TROLL IS GUARDING THE CAVE.
      block_when_exists      = troll
      show_blocked_exit      = true
   }
}




Source (With Graphics Embedded as Base64 Text)


start_at                 = lakeside

loading_screen           = loading_screen

game_information {
   game_name                    = The Cave of Magic
   game_shortname               = Magic Cave
   written_by                   = Chris Ainsley
   year                         = 2019
   short_synopsis               = Find the treasure
   game_version                 = 1.0.0
}

locations {
   forest       : location "You are on the forest path.\nTall <TREES<4>> tower over you on both sides." ;
   outside_cave : location "You are standing outside <THE CAVE OF MAGIC<5>>" ;
   inside_cave  : location "You are inside <THE CAVE OF MAGIC<5>>" ;
   lakeside     : location "You are by the side of a <BEAUTIFUL LAKE<2>>." ;
}
objects {
   troll    : scenery "an enormous troll" start_at = "outside_cave" ;
   sleeping_troll : scenery "an enormous troll (sleeping)" ;
   apple    : object  "an apple" ;
   treasure : object  "a pile of treasure" start_at = "inside_cave" ;
}
connections {
   from, direction, to = [
      lakeside, north, forest, 
      forest, north, outside_cave, 
      outside_cave, north, inside_cave, 
   ]
}
on_startup {
   
   : print_graphic "outside_cave" ;
   
   : print "^c^THE MAGIC CAVE AWAITS YOU" ;
   : beep millis = "100"  pitch = "0" ;
   : beep millis = "100"  pitch = "2" ;
   : beep millis = "100"  pitch = "4" ;
   : beep millis = "100"  pitch = "6" ;
   
   : press_any_key ;
   : beep millis = "100"  pitch = "6" ;
   : beep millis = "100"  pitch = "4" ;
   : beep millis = "100"  pitch = "2" ;
   : beep millis = "100"  pitch = "0" ;
}
on_command {
   : match "pick apple;get apple"  {
      : if (is_at "forest" && has_not_created "apple") {
         : create "apple" ;
         : redescribe;         
      }
   }
   : match "examine trees"  {
      : if (is_at "forest") {
         : print "Apple trees." ;
      }
   }
   : match "examine troll;talk troll"  {
      : print "<\"I'm so hungry\"<3>>, says the enormous TROLL in the deepest possible voice." ;
   }
   : match "give apple"  {
      : if (is_present "troll" && is_carried "apple") {
         : print "The troll grabs the apple from you hungrily. Unfortunately (for the troll), the apple is an <ENCHANTED APPLE<12>>, and sends the troll directly to sleep." ;
         : destroy "apple" ;
         : swap o1 = "troll"  o2 = "sleeping_troll" ;
         : press_any_key ;
         : redescribe;
      }
   }
   
   : match "eat apple"  {
      : if (is_present "apple") {
         : print "Unfortunately, the apple was an <ENCHANTED APPLE<12>>, and you will now go to sleep - forever." ;
         : print "^r^<GAME OVER<2>>" ;
         : end_game ;         
      }
   }
   
}

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

on_describe {
   
   : if (is_present "troll") {
      : beep millis = "100"  pitch = "-2" ;
      : beep millis = "100"  pitch = "-4" ;
      : beep millis = "300"  pitch = "-8" ;
      : print "The troll says, <\"THE CAVE IS MINE, GO AWAY\"<2>>." ;
   }
   
}

on_tick {
   : if (is_at "inside_cave" ) {
      : beep millis = "200"  pitch = "0" ;
      : beep millis = "400"  pitch = "10" ;
      : print "^r^CONGRATULATIONS !" ;
      : print "^r^YOU WON THE GAME !" ;
      : print "^r^YOUR RANKING IS : JUNIOR ADVENTURER !" ;
      : press_any_key ;
      : clear_screen;
      : print_graphic "logo" ;
      
      : print "This tiny adventure was written using Adventuron." ;
      : print "Adventuron is a free text adventure creation language and development system." ;
      : print "Visit the website, and make a world of your own." ;
      : print "^r^<www.adventuron.io<12>>" ;
      : end_game ;
   }
}

barriers {
   block_cave : block {
      location               = inside_cave
      message                = THE TROLL IS GUARDING THE CAVE.
      block_when_exists      = troll
      show_blocked_exit      = true
   }
}

######################################
#  Themes                            #
######################################

themes {
   my_theme : theme {
      settings {
         layout                  = H G D X O
         experimental_enable_crt = true
      }
      screen {
         paragraph_spacing_multiplier                = 0.5
      }
   }
}

assets {
   graphics {
      lakeside       : base64_png "iVBORw0KGgoAAAANSUhEUgAAAIAAAAAoCAMAAAABrwJ6AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAMAUExURQAAAADPAADPz///AP///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHGCbIwAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAZdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjAuMjHxIGmVAAABBElEQVRYR+3T0RKCIBCFYaje/5lb4FfEgBFZYKbxu2iK4OzRzLwWewo8BbYCH48PM6V3YEGNGz+BbsmmAn608g1a8hAeL2N2gZ97uOQOHKkX8JfY8KBkChARsNbs8un/+wlaPQWeAmMLhD9jwNJZQwGTYrVXNYdRZezrcc4gOeedYFFw8iZTvUyGFbFNENeO8zuSW3BSkHkVp4jpRJggvY69DgEqiBTMyWCDE874V02kC0buWHbYK/QLeMwRldne6bMVvO3GwIj1lPEzU3ylojbbMww94quxmGVzBRy2DcIQp1RgZAUGBPMLEL+ZXYDwqFiAA9pIj2Y/hMRH+QLs1kf+ztovLtcqnejM1JkAAAAASUVORK5CYII=";
      forest         : base64_png "iVBORw0KGgoAAAANSUhEUgAAAIAAAAAoCAMAAAABrwJ6AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAMAUExURQAAAAAAzwDPAM8AAP8AAP//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHgbSMAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAZdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjAuMjHxIGmVAAAB3ElEQVRYR+2R0XaDMAxD2Vj//5fnyDeJYwKFbmMvvZwxsCSswvLmza/xWeD6gDOeI3bz2t9hmjjSnuPpnTzaCFqF6WsFyBaYDCAlqubnjsbXIOkwC2j8pXOkawkJVyBXYdpgDF6knLPYK0q5ALEGY2C4pYvx7ehawdMoZ8x/AaMJR6qiJyEygFRgMuFQPKiQZd1n0Loa37IT1Q3KzsHRPNxlUI93cGWM/Tw5B4sx3NcHtAe56jAKFNtUcDw2BYfI9wNyNxgaK/+LQ//6by9X3BHb4GplO+nIHmG+rmu93A8bpBKIlTjqv8NZlo+CYhUb2/7Vr14pgGaEF+VXGduvyNigrFcBxfy8h1wJpM58WnhaoII/gZhBDezNzxcgHb4g4wkY4tcelY7NTheI8a0WwRRBGSRGFwp4fk/r6PEJJJ7NtbhUoEoT7QGz/V1vBfx2ipllmrlCASaVsgPYCgwbxAMPHQMyTX6l4dJcAzYbM9sm7vvHBjK9XMAbyMkgsonb27PjVwuUBu7kPrKJ/8EbsAb2t2PL8bp/aCDTTwoUdmw57l8gfQOZ7irQjoBM9xTo+2MDmW4q0Pb/V4FwdGS6pUDcHxrIdE+BsP9/CgxHQ6Y7CsTt5ajIdKXAsnwDCusRZcRkfHUAAAAASUVORK5CYII=";
      outside_cave   : base64_png "iVBORw0KGgoAAAANSUhEUgAAAIAAAAAoCAMAAAABrwJ6AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAMAUExURQAAAAAAzwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEyzCWUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAZdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjAuMjHxIGmVAAAATElEQVRYR+3OsQ0AIAzEwLD/0jSpIEmFLCHZ5Td/YWZmn7bOcqe6/1hB9UYK6i9O0D1Rgv6HEUwvhGD+AAQCBAgQIECAAAECBDwGRGyT6ABKL7FnoAAAAABJRU5ErkJggg==";
      inside_cave    : base64_png "iVBORw0KGgoAAAANSUhEUgAAAIAAAAAoCAMAAAABrwJ6AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAMAUExURQAAAAAAzwAA/wD/AP8AAP//AP///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOYrpxQAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAZdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjAuMjHxIGmVAAAB3klEQVRYR+WWy4LCIAxFO6PO/3+ykFwgQB5AdTVnYSskOSmW1kvjB0cBDykTX+FzDbyIPz68MBjzgQagHMBkyO0G4OuhdUBAwL0GyEb84ihATMCtBmCqcBcP+kwgyudGA9CAcveB3AXifM4bIM+gHUCky3EDcBBP8VkOGYS6nDYARQCCPc4ayMXrvdZtAPmbPL/UAMpPiLWvIMXBbkAHhRN0rSStayHhdUEWQ3VHrAb0aPPqxc/QP5KQZ2M0sOmvTIuBRBu9gcDv7/4epJqoDRh+BVgUEBCiNWD5UVqCGQUEhJ2oK2CAipsg2WK2mf6xgUe7F7RHQAHJFpNuwW/r2rOBQKLL6LP9GRRO9Ls9M26NGs6pFoPQ85daXLZD2/4422vAvX7UG7uY1yJF4IShBItO6fr7qvNIpQ6ndaHfhWMNpDPwKz6M14nuS4VGLYQ09OfayoInMD27CUzqNOuCvxjU929j631YtUv+/hrLhhf9tL2YJ/NESkGqTvEu+hNUXkF9POV4TrOAeN2fQfUIDqUMGzbv+RlYHIM7WSD1iV9AbTTkPYgIh+w+vf5yZMpjJ4MTigxI8sPr7xX0jSl3I2YCdv5/TZCHfRjZx/z/tUyyizcxBte57b/Jf/Jf1xueGxqz721j7wAAAABJRU5ErkJggg==";
      loading_screen : base64_png "iVBORw0KGgoAAAANSUhEUgAAAIAAAABgCAIAAABaGO0eAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAQ+SURBVHhe7ZddspswDEaziy6nr53p4rOFPt7nbiC1I1Bl+QeDLQnn6sw3rW0IhPNBaB+34bn97RjhBRjjBRjjBRjjBRjjBRjjBRjjBRjjBRjjBRjjBRjjBRjjBRjjBRjjBehRdO0FiBMUQ2DM8AIEQe+IF6ABeC+a9QJkqXlHvAApDtUDXsBkwHu/RC9gGqe8I17AHC5b8wLm4AUY4wUY4wUY4wUY4wUY4wUY4wUY4wUY4wUY88kFvF55AmwlxpAPKYAJvRArli+AeTyf5JnQZ9UCqLU8cXu22BN9liyAWTtM3scjndIos1gBTFYzJx4C2ocyKxWAjvacUHwqmixTAHNUTr5b8YNHR9NkjQKYIIWocfcCEilkzBJ3zBZL6djtfVI1blpAYmQkA4fSYW4Bo2EKsqT3byq38Xz0JB6Mr/CvV8kQlz/PPjj6PQLs+i8nV8lyuANGgSkF3Mh+IxceEQXGCxC133urykWawQIm2L8MMzUYK0YKmGOfiejPXNjBaUQZKWAO7GpvGFGueZxmP8Cutp39RVp/Nwg0KsoFlVr2J6tMO2seXJOzNmfapzAFLHF7ttiRc59C2HqIHKeEzrdfu0JcP5uRf+yzdRo5+p2K3PvsOjEMtpUlbs8WewKwxVqE6NQqYh9g11lMDtvhbBoHIc9Q0qsQPWYF7QP0OjtTg+2GYbCtPRHiUK64fWC/yIs/JpgabLcLEaLtV8k+wC445MIbtT/9ZYvSUKxqH2BXXk5lt462msbJYemh8IsJUbNsYB/Bix/N2KEQOp5OUbSlfQrVoRZKvjKd3PVd7OegozwTETpsDab7vvYPoeIOE3fPFll0oMbXuPcpdD0PeZc2dBc2aYLSF7j3+zWxPQup7KMPeF/APoVZy20uRFC/mP0cor7we0JzQ5a3vzRu3xK3b4nbt8TtW+L2LXH7lrh9S2baj//zLCVu+v0j5D2M0OnrL88x4VtjKF9fW3Z+/voTsk3S6fPxZIF1TSafElwH0HugXQCT3lUA9U7HqJ50UCuASTcpQPB8tACgXcAJqHEKkR7Zp+0CYNEE2XPXCmCJ6/sTgDmgXQBLxxOAgR10ED9ZowA6jYMe6ZR2AUhaAEinY33piMZZawVsk6wA7KCrD9oBjisFBNA72g+wG1+tD41zgH3WQa2AON47wBwD3iEALYCO3zD7AHaA2TaIIX6CO8Ps6/Ot7Zvj9i25kf3815a+MDAN4OUB7w/6IgHKb5FwNhoA3hM0BHxnjP9w4QntQfW0A2a8vwCabdOuPumASg/gFIyjelIA9T7YAT2zMVR6AKeHxhloHP/cBumN/3+KxotgATuDxhnLFIA5pF0ASwQLgAFOAeECbkS7gH7aBSCFAgA2/T4FBFA6DgKXCwDOFQBjmIJ3LIDUQDv4tD5APdoPjBSQjEkBdBxB73Ba+BPU0xDA+6fZdxxFHo9/8ttiddHMrZsAAAAASUVORK5CYII=";
      logo           : base64_png "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";
   }
}