Let your imagination wander ...
secondWorld, or World2, is an interactive web/browser based text adventure game platform. You can play, create, or modify highly interactive and complex text adventures ('Worlds') of any size. You can even combine Worlds together.
Players interact with World2 through simple imperative commands that start with a verb: take the golden sword, unlock the front door with the rusty key, go garden, etc.
Worlds are stored in single .wld2 JSON file that contains all the data that drives a game. You can download these locally, load, edit, or play these files with the secondWorld web app.
Simple: a single object model, a single js executable, a single json data file for an entire game.
Flexible: fully configurable input and output text, can even be translated into other languages.
Extensible: Worlds can be built in modules and combined with each other. World2 data can be consumed by other applications via a simple JSON file format.
Powerful: Write games that interact with natural language. The W2 Meta script language enables highly interactive complex puzzles. Create simple Worlds in minutes, complex Worlds in hours, and an epic Zork sized World in days.
Free and Open Source: for everyone who loves text adventure games, logic and problem solving, and telling stories.
dreamTime is an epic sized interactive text adventure game that takes you through deep forests, mountains, caverns, ghost cities, ice fields, deserts, and a rainbow at the end. Solve puzzles to collect treasure, meet intersting beings, and battle evil monsters!
At any time you can save the current state of the World2. This will promt you to download a .wld2 file, a single JSON file that stores the entire content of the game in its current state. Next time, just select 'Launch Player' from the menu and select 'Open World' and select your previously saved .wld2 file. You will be right back in the game where you left off.
secondWorld is a single page javascript web application that includes both a Play View and Edit View. You can toggle between these views in real time. Edit View splits the screen so that you can continue playing and testing as you make changes.
In Edit View, you view, modify, and create Entities ( what are these? ). Click into the Entity field to search Entities by name, then modify attributes, states, and behaviors and remember to 'Save Entity'. The Save button will show green for a success, red prompting you to correct for inline errors.
At any time you can save your work just as in Play View, 'Save World'.
secondWorld models the world as the interaction between objects. secondWorld uses a versatile single object model where all persons, places, or things are modeled as Entities.
Entities have Properties (basic information), States that describes the object as it is now, and Behaviors that respond to your commands and modify other Entities.
Entities are connected to each other through Parent - Child relationships. If you are in a 'room', then you are a child of 'room'. If you possess an umbrella, the umbrella is a child to you. Objects can be children of other objects (these are called containers, eg. an egg can be the child of an easter basket), and rooms can even be contained by parent 'room regions'. At any moment, the Entities that matter are those in your Space. It is the Entities in your Space will react (eg. trigger Behaviors) based on your commands.
An Entity must have a unique Name. In most cases, an Entity has a Parent (it belongs to something, such as Object belongs to a Room, your possessions belong to you, etc.). An Entity must be assigned an inital State, 0 is the default. Count is optional, and has many uses, and defaults to 0. Finally, a set of set Properties can be set to change the Default Behavior of the Entity.
Name. Must be unique, short (1-2 words recommended, and at least 2 chars), and ideally, lowercase for consistency. Examples: silver sword, cluster of apples, wicker basket, house, rabid dog, etc. The Entity Name is how you will reference the entity from other entities.
Parent. Ultimately, every entity needs to belong somewhere (or to someone). Objects around you, including you as a player, are owned by a Room. A possession of yours is owned by you. As you move from Room to Room, you change your Parent to the new Room. A Room can be unassigned or point to world as its Parent. Things, Rooms, world, and me are all Entities. A parent relationship is not needed if the Entity is a Room or is not in play.
State. A State number is required. A State is used to describe the object as it is in the current moment. States are tracked as numbers starting at 0.
Count. Count is a number that can be used for multiple purposes: to track internal state, strength, achievement or merit, or the quantity of an Entity. Integers are recommended, but decimals supported. A Players Count are displayed in the default Player View as Points.
These are mostly static attributes that define the Default Behavior of the Entity:
container | container>
size>
open | closed
notake
noput
strength
quantity
class>
Include the container property on Objects that can hold other Entities (basket, box, barrel, phone booth, etc.) This allows put X into Y and take X from Y Default Actions. Otherwise you will get a you can't do that error.
Other Entities including 'me' and any Entity that can be your Parent (eg. a Room) are containers by default and don't need this specified.
To specify a limit on the number of objects that can be contained, follow container with a number: container>5, container>20, etc. Put the container property on the 'me' Entity to limit how much your character can carry.
By default, all Entities are size 1. However, to limit a container to fewer large objects, assign a size with a number to larger Entities: size>2, size>15, etc.
Sizes will be added up to not exceed the container limit. Example: if a basket Entity is assigned container>10. It will fit 5 objects of default size>1, 1 object of size>4, but will no longer fit an additional Entity of size>2.
Containers themselves must be given a fixed size. They will keep their size regardless if they are empty or full. A backpack Entity can be a container>10,size>5, meaning the backpack can hold size>10 worth of objects but only weighs a size>5. This makes sense in that a container can help you carry more.
By default, containers are open. Meaning: they are transparent, you can see, put in, and take from the container. If closed you can not see contents or take from or put into the container. Also, if you are in a container, open allows you to see out (eg. if you are in a boat, a car, a telephone booth), closed does not (if you are in a box). Use Behavior actions to change the property to either open or closed.
Some objects are not meant to be taken by default. This includes most Beings such as characters in your story, or massive objects such as telephone booth, metal vat, car, etc.
More unusual, but interesting, once you either have or take an object, this will not let you put it down by default. This Entity could be a guiding spirit, voice in your head, faithful dog, memory enhancement chip, etc.
strength only affects the description output. Use this property if you are using Count to track a Being's strength and you want the user to know how many strength points they have, typically used for battle situations. An entity's Count will be shown as: the {swamp monster} has a stregth of 8.
As with strength, quantity only affects the description output. Use this property if you are using Count to track the Quanity of an Entity. Use this for such things as matches, coins, poison darts, etc. You can even use decimals. You have a bag full of donuts. You have 5 of these. or You have Xuru currency. You have 7.25 of these.
Allows you to flexibly classify any Entity with one or more Classifications. These classifications can be checked in Behaviors. With classification multiple Entities can be used interchangeably to solve puzzles, battle, etc. Typical classifications include: class>weapon, class>treasure, class>reaching tool, etc.* See advanced configuration.
The State describes the Entity to the Player. There is one description for every possible State. At a minimum, a State 0 Description is required. Use full sentences that end in a period. In Abridged mode, only the first sentence will be displayed.
For a Place or Room, State should answer the question: Where are you?
You are under a ladder.., All around you is water.., You are in the Golden Castle ...
For a Thing or Being, State should start with a noun phrase and answer the question: Here is …
.. A large barrel full of apples. .. An old key. .. A frightening swamp monster.
The State of the Entity determines which State Description to show the Player. The State is what an Entity ‘is’ at any given time. A ‘glass ball’ may begin first in State 0: ‘A clear blue ball’, after certain actions, it turns into State 1: ‘A glowing sphere’, and finally, State 2: ‘A cracked glass ball’.
A Behavior consists of: Conditions and Actions.
Conditions are the ‘IF statement’ that check the User Input and (optionally) the Properties of other Entities. Actions are the ‘THEN statement’ that act on other Entities, changing their State, Parent, or Count. Condition fields are in white, Action fields in brown.
There are two types of Conditions: User Input Conditions and Meta Command Conditions. User Input Conditions (first line) match the user's input text: verb, noun (eg. object), and optionally: preposition, and indirect object.
Preposition and Object are optional, but IF they are specified, they will be required. Prepositions and Objects enrich the game experience and the puzzel quality, use them!
For each part of speech it is recommended to list a ‘bag of words’ to match several possible inputs, example: dig|get|pull rock|pile|dirt with|using shovel.
You can even leave the verb and/or noun empty as a ‘wildcard’. But beware, this means this Condition is likely to fire more frequently.
Conditions and Actions are built with a very simple but powerful logic language, World2 Meta Commands.
Both Conditions (IF statements) and Actions (THEN statements) use the Meta Commands syntax. Conditions check if an Entity belongs to a certain parent, IF an Entity is in a certain State, or IF an Entity has a certain Count. Actions set the Parent, State, and Count of other Entities.
Meta commands are comma separated and are logically ANDed together, they must all be true for the action to trigger:
{Entity Name} > {some command}, ...
Parent Relationship. The most common and most simple thing to do is to check the parent of or assign the parent to an Entity.
gold treasure>pirate
As a Condition, this statement is 'true' if the gold treasure belongs to the pirate. As an Action, this statement assigns the gold treasure to the pirate. This is how objects are given possession. You can check a negative condition as follows:
gold treasure>!pirate
This statement is true if the pirate does not have the gold treasure. This statement can't be used as an Action.
me>red room
As a Condition this statement is true if you the Player (me) is in the red room. As an Action, this statement moves me to the red room. Just as I or other beings can possess objects, spaces or rooms possess you (and other objects). red room is now my parent. You write this type of command for every 'go' action. Easy again!
State. You will often need to check the State and set the State of an Entity. Conditions can check any of the following:
iron gate>S=0
iron gate>S!5
iron gate>S>1
iron gate>S<5
If the iron gate in state 0? Is it not in state 5? Is it in a state > 1? Is it in a state <5?
Actions can set or change the State of any Entity:
iron gate>S=3
iron gate>S+1
iron gate>S-1
Set iron gate to state 3, increase iron gate state by 1, decrease iron gate state by 1. Note that Actions have additional +,- operators, and no <,>,! operators.
Count. Count has many uses. An Entity's Count can represent merit (points earned), a quantity (how many left, eg. matches), a strength (remaining strength), or as an internal state to manage a complex puzzle (number of tries, progress, etc.). Count commands are exactly the same as State commands, using a 'C':
knight>C>20
Condition: does the knight have more than 20 count (points)? Valid Condition operators: =, !, <, >
knight>C-4
Action: take away 4 points from the knight. Valid Action operators: =, +, -
Condition Examples
evil wizard>tower
Condition: Is the evil wizard in the tower?
sea monster>C<10,sea monster>pond
Condition: Does the sea monster have less than 10 points (Count) AND is it in the pond?
gold cup>S!2,sword>me,me>C>20
Condition: Is the gold cup not in State 2 AND do I have the sword AND do I have more than 20 points (Count)?
key>!me,vulture>S>2,vulture>P=bedroom
Condition: Do I not have the key AND is the vulture in a State above 2 AND is the vulture in the bedroom?
The player is always referred to as ‘me’ in Condition and Action statements. Eg:
me>room5,me>C+7,sword>me, ..
For advanced players: World2 actually allows the Player to play as any Entity. By default, the Player plays as the ‘me’ Entity. Regardless of which Entity you are playing, Conditions and Actions will always recognize ‘me’ as the current Player. Always use ‘me’ in your Conditions and Actions when referring to ‘the Player’.
Random Condition You can make a Condition triggered randomly by adding a special 'R' condition R={% probability, 0-99} anywhere on the Condition statement.
R=40,me>haunted house
If you are in the haunted house, execute this action 40% of the time ...
THING> and CLASS> are further advanced and powerful concepts in World2. Here you write Behaviors that act not on a specific Entity but on a classifications of Entities. See advanced configuration.
Everything that ‘happens’ in World2 is through one or more Entities changing: State, Parent, or Count. An Action often also outputs a message to the Player.
evil wizard>tower
Action: move the evil wizard to the tower
gold nugget>thief,me>C-8,cave>S=3
Action: move the gold nugget to the thief, deducts 8 points from me, sets the cave to State 3.
jewel>me,me>C+25,me>magic carpet
Action: give the jewel to me, award me 25 points, and move me to the magic carpet.
Special Action Commands open | closed. By default containers are open. You can set the default property to closed or toggle via an Action. Closed does not allow you to see into (or out of) the container and not take from or put into the container. To toggle behavior in an Action, use this command: {Entity}:open or {Entity}:closed.
time machine>open , time machine>closed
Normally, you will also want to change State when opening and closing (eg. State 1: "a sealed metal vault" v. State 2: "an open vault"). continue. Use continue to execute Room Actions and Default Actions in addition to this Action. Use ‘continue’ if you want to give the user a message (something humorous, perhaps) and still want all further Behaviors triggered as well.
Example: everytime you ‘go’ somewhere, you want to print a message ‘your feet ache’. Normally, further ‘go’ Conditions will be ignored, but with ‘continue’, you ensure that Room and Default Conditions are executed.
me>C-5,continue
Takes away 5 points from me, (gives the user a message), AND process defaults
autorun. If Conditions are met, an autorun Action will force a next move in 5 seconds. Exactly the same as if you hit ‘enter’. Use with a wildcard event (eg. no verb or noun) that will execute no matter what (eg. a monster making an attack, a continual change in the Room, etc.)
me>vampire room,autorun
As long as you are in the vampire room, the game will force a move each 5 seconds.
PARENT> and CHILD> are advanced and powerful concepts in World2. You will want to first get experience in the basics first. However, when ready, these functions will take your world to a new dimension. See advanced configuration.
World2 will interpret the following commands automatically if no other Entity in your Space gets to it first
Take, Take * from|out of *
Put, Put * in|into|on *
Look
Inventory
Brief
Verbose
These verbs will trigger auto behavior by default if no other Entity in the same Room (or the Room itself) does not have a Behavior defined for these verbs.
World2 accepts simple imperative phrases starting with a verb. To minimize unexpected behavior, World2 does not process compound sentences and will simply stop at the first and. Accepted phrase types include:
{verb} {noun} {prep} {obj}
kill the green dragon with the golden sword
{verb} {prep} {prep} {noun}
go down through the tunnel, go up into the escape hatch, go down around bend
{verb} {prep} {noun}
throw around the ball, go through the waterfall, lean against the wall
{verb} {noun}
get the golden goose
{verb} {prep}
get out, go down, crawl through
{verb} {noun} {prep}
place bar sideways, follow the staircase up, lay carpet down, throw the rope across
{verb} {obj} {noun}
give the wizard the pearl, feed the pig an oat, show the man a book
{verb}
inventory, look, run, yell
World2 will process entered words at least 2 characters in length, it will not match single letters as words.
World2 will map a variety of common verbs to ‘high frequency’ verbs for you automatically. If a user enters ‘get’ World2 will also understand this as ‘take’. Use these Verbs in your Condition Statements.
In your Conditions, you can add multiple word combinations (eg. bag of words) but you don’t need to put ‘get’, ‘gather’, etc. each time, just use ‘take’. Here are the preprogrammed high frequency verb mappings:
take <- get, grab, gather, collect
put <- drop, lower
look <- see, examine, inspect
brief <- abridge, abridged, short
verbose <- long, wordy
go <- walk, run, head
jump <- leap
push <- press, shove
close <- shut
open <- lift, raise
hit <- punch, strike, slam, kick, stab, kill
break <- smash, shatter, destroy
say <- talk, speak, chat
ask <- question, inquire
yell <- scream, shout
Note: World2 will not map Nouns or Objects to other words, it will simply do a 2 character (or more) match against your word list.
If you specify a preposition and/or indirect object in the Behavior User Input fields, then the preposition and indirect object will be required by the player. The following Condition:
verb: open noun: mailbox prep: with using obj: can opener
will not pass if the user types:
open mailbox
The Condition will pass if the user types in all four parts of speech, such as any of the following:
open mailbox with can
open mailbox with opener
open mailbox using can opener
open mail with ca
open mailbox using op
...
On any given turn, the Entities that matter are those in your Space.
The red Entities make up your Space. These are the Entities that are in a Parent/Child relationship with you. These Entities listen to and respond to your Actions. There may be hundreds of other rooms and objects in the World2, however, only the Entities in your Space react to you in a given turn.
Entities respond to User Commands from 'bottom to top' in the following order:
1. Me
2. Entities in your Room (Things in Room) & Entities in your possession (My Things)
3. Your Room
4. Your World (the the Entity above/parent of your Room)
5. and finally, Default Actions (take, put, look, inventory, brief, verbose)
Once an action executes (eg. the User Input Conditions and Condition statements are met), World2 will move on to the next Entity and check its actions, it will not continue to process conditions/actions on the same Entity. This avoids many unexpected recursive and annoying behavior (trust us on this one!)
Also important: once an Action fires, World2 will no longer process actions from your Room or Default Actions. This is so that Conditions from Entities can override standard behavior. This way, you can prevent a Player from ‘going’, ‘taking’, ‘putting’, etc. in the default way.
In certain advanced scenarios, you will want to set the Parent of an Entity to the Parent of another Entity. For example, if the Player is being transported in a container (eg. a magic carpet, a car, a phone booth ..) and wants to 'get out' of the container at anytime, the Player needs to parent to the same Parent as their container. Here you should use the special command me>PARENT>{my container}.
me>PARENT>red car
In other words: move an Entity (usually 'me') to the same Room as my Container. If I am in red car (me:P=red car), and my car happens to be in garage (red car:P=garage), by getting out of the car, I want to be moved to the Room of my car (me:P=PARENT!red car) which moves 'me' to garage. You can also use PARENT! to make any other Entity magically appear in the same room as you, regardless of where you are:
genie>PARENT>me
You can also assign an Entity to the child of a parent Entity. Since an Entity can have many children, this assignment is random. For example, you can have a troll randomly appear in one of many rooms in a cave. You must first create a special parent Entity, in this case, for all the rooms in the cave (eg. cave rooms). Then, through an action you assign the troll randomly to one of the Rooms:
troll>CHILD>cave rooms
One of the Rooms that look up to cave rooms will be choosen at random, creating a sense of agency and motion. By repeatidly calling this same action, the troll will move around the cave rooms at random. You can also move your character at random as if through a portal. Assign certain 'portal' locations to a common Parent portal rooms and then, move your character at random to one of these locations:
me>CHILD>portal rooms
Earlier we saw how the class> property allows you to assign a classification(s) to an Entity (eg. class>weapon, class>treasure). The CLASS command allows you to check the value of an Entity's classification.
This is done together with the THING command. Put THING in place of either the verb or noun in the Coniditon statement. Then check the classification of THING. You can also check the parent, state, or count of THING.
THING>CLASS>weapon
THING is a placeholder for a range of Objects to solve a puzzle or fight a battle. You can kill the ork with a range of 'THINGS' as long as they are of 'CLASS' weapon.
Think of the different ways a Player may write a command. Put in several possible verbs, nouns, prepositions, and objects as appropriate (eg. bag of words) to 'catch' different User Input wording. You may even create several Behaviors with the same Action to catch all possibilities.
Behaviors are always processed in order. For proper behavior, use very specific Condition logic AND put Conditions in the following order: put the blocking logic first, then success logic, and catch all logic last
1. Blocking Logic is specific logic that prevents you from doing something you need a tool to do that, theres no way to get in, etc. Make sure to put in all necessary Conditions (state, parent, count) so that a success condition does not get falsely matched. For example don't let me pass if I don't have the golden cup AND the dragon is still in the dungeon AND the gate is in state 0 (eg. closed, for example):
golden cup:P!me,dragon:P=dungeon,gate:S=0
2. Success Logic is typically the solution to the puzzel. IF I have the golden cup AND the dragon is dead (eg. disappeared to the 'world') AND the gate is in state 1 (eg. open):
golden cup:P=me,dragon:P=world,gate:S=1
3. Catch All Logic are very general 'hints' and humorous comments, etc. (eg. ‘Try again’, ‘You swing and miss!’, 'You don't seem to have what you need to do this').
Stated above, make sure to add hint actions and 'catch all' actions at the end of your Behaviors, particularly for your puzzles.
Put hint Behaviors after success Behaviors. Hints will be more general, likely not include either the verb or noun, and so will need to be put toward the end.
Hints move the story along and guide the Player to what they should be looking at and trying.
Beings are more complex Entities. They are living (?) things that can move, react, talk, attack based on your actions. In fact, any Entity can do these things, for a very creative effect! For Beings, it helps to:
Useful debugging information is generated during Play Mode, including parsed input, Entities processed, Actions triggered. To enable:
Additional game configuration can be done in the AdventureConfig.js file. Here you can change:
High Use Verbs and mappings
Prepositions
Default behavior text (“You don’t seem to have this here”, ..)
Help text
World2 was developed by Dirk Koechner, a 'single page app written by one person without a framework' advocate and enthusiast. He was enamored since youth with text adventure games, such as Zork, and had dreamed for a long time to build a clear powerful tool to create text based interactive games. Other projects include writing a music composition software. He lives with his family near Munich, Germany.