Table of Contents
Before you start…
…you should skim through the Adventure Script Player short manual. You probably should also try to play an example game, if you haven’t played any already.
The Basics
Learning Adventure Script isn’t hard and doesn’t require any knowledge whatsoever. In fact Adventure Script was designed to be easy. Believing is always the first step so repeat after me:
It’s easy.
I’m 100% capable of learning it.
I can do it.
Introducing Mary and Lucy
Let’s start from somewhere, look at the following line:
say "Mary looked at Lucy"
You can probably deduce that it will display the quoted text to the player. Now look at this line:
say mary "Lucy you monster! You seduced my mother's sister's fifth child which is also somehow my brother's ex-wife!"
This time we specified who will say the quoted text – Mary. As the first example had no speaker it was treated as narration. But who is Mary? We need to introduce her:
object mary "Mary the Wicked"
Let’s also introduce Lucy:
object lucy "Lucy the Spiteful"
And let’s put them into a room:
location room "Palace living room" object mary "Mary the Wicked" object lucy "Lucy the Spiteful"
That’s a lot of things to explain but they all should be quite intuitive.
Objects
Let take a look at Mary. object informs that we are introducing a… well… object? Like a knife, unicorn anything else you can think off. Then comes the object’s identifier, in Mary’s case mary. Think of it as of a computer file’s name. It will be used to refer to Mary – like we did by writing say mary in one of the first examples. After the object’s identifier comes the object’s name written in quotes. This is how Mary will be displayed to the person playing the game.
Locations
That was easy, now what’s a location? A location is a well… you know… a location. In life locations usually consist of stuff (objects) in them. The same here! Easy right? Marvelous! Let’s move on. Locations just like objects have identifiers and names. How do we specify which objects are in a which locations? That’s where indentation comes in. There’s a tabulator before Mary and Lucy informing that they are in fact in the living room. You can make tabulators with the Tab key on your keyboard. Keep in mind that a tabulator is not the same thing as multiple Space! (but it looks the same)
Skipping stuff
Let’s take a quick look at the next example:
location cave object "angry dwarf"location "Quite magical Forest" object elfobject knife "rusty knife"
First of all the dwarf is in a cave, the elf is in a forest and the knife is in no specific location whatsoever. But look, the object and location declarations look different! The cave doesn’t have a name and the dwarf doesn’t have a identifier! How can that be! Well, we can skip one of these elements, but not both. When we skip the name it becomes the same as the identifier. When we skip the identifier we can not refer to this location (or object) later on.
Our first game
Let’s go back to Lucy and Mary and write something that actually does something. To do so we need do learn how to write events. First of all we need an on create event that fires when the games starts. Let’s keep it simple:
on create goto roomlocation room "Palace living room" object mary "Mary the Wicked" object lucy "Lucy the Spiteful"
And look! It’s a actually working game! You can see it in action here! If you feel courageous enough you can also open it in the editor. We will get to how to use it in the next chapter.
Making stuff do things
Let’s learn about events. Without them the game can’t really do anything. Every event starts with an on and then is followed by the event name. There’s lot of different events but for now let’s just introduce two:
on prompt– executed each time an location or object is displayed to the playeron use– executed when the player selects the “use” option in the opened object’s menu
See them in action in he following example:
on create goto roomlocation room "Palace living room" on prompt say "Two angry women are arguing here. It's awfully loud." object mary "Mary the Wicked" on prompt say mary "I'm busy shouting at Lucy, go away" on use say "You stab Mary in the heart. She dies. Lucy shuts up. She looks quite content." hide mary object lucy "Lucy the Spiteful" on prompt say lucy "Wanna taste ma fists? No? Then stop looking at me!" on use say "You try to stab Lucy. She grabs your hand in mid air." say lucy "Oh, I will enjoy this..." say "You get slowly punched to death." goto endlocation end "Game Over" on prompt say "You died. Welp, that's what you get for killing people."
You can (and should) play this game or open it in the editor.
So, as you can see, an event consists of actions in the same way that a location consists of objects. That means that actions need to be indented (with tabulators) to be included in an event. But what are these “actions”? For know let’s introduce some of them (listed below).
Basic actions
say "text"– display narrationsay object "text"– display a dialog lineequip object– put an object into inventoryunequip object– remove an object from inventoryshow object– make an object visible in it’s locationhide object– make an object invisible in it’s locationgoto location– change current location
Actions are executed one-by-one, in the order they where written. goto is a special action as it ends the event after being executed. What does that mean? Well, let’s consult an example:
on create goto room say "Don't mess with Lucy!!"location room "Palace living room" on prompt say "Two angry women are arguing here. It's awfully loud."
“Don’t mess with Lucy!!” will never be displayed as the goto room action terminates the on create event. I hope that’s clear.
Skipping stuff
We’ve done one more thing in the last example. Look at the living room’s on prompt event. It looks different! If an event has only one action you can write it the same line without an indent! This makes the games much more compact and easier to read.
Commenting stuff
Comments are a useful thing – they are just portions of text that have no affect on the game. They are added to leave some information for the person reading the game’s code. Like side-notes on a draft of a book. Read the comments in the following example to understand how to write them:
# single line comments #= and mutliple line commentsaka "block comments" =# # comments can ignore # indentation rules # as they are ignored object dwarf # comments can also end a line...object #= ...and be inside a line =# dwarf
I will use comments to explain or highlight things directly inside the examples.
Conditioning stuff
You probably noticed that after Mary died the living’s room prompt still said “Two angry women are arguing here. It’s awfully loud.”. Let’s fix it:
on create goto room # a one-action event written in a single linelocation room "Palace living room" on prompt if mary.hidden # this is new! say "It got quiet. Mary is in a pool of blood on the floor. Lucy's looks at you cautiously" else say "Two angry women are arguing here. It's awfully loud." object mary "Mary the Wicked" on prompt say mary "I'm busy shouting at Lucy, go away" on use # this event has two actions so it can't be written in a single line say "You stab Mary in the heart. She dies. Lucy shuts up. She looks quite content." hide mary object lucy "Lucy the Spiteful" on prompt say lucy "Wanna taste ma fists? No? Then stop looking at me!" on use say "You try to stab Lucy. She grabs your hand in mid air." say lucy "Oh, I will enjoy this..." say "You get slowly punched to death." goto endlocation end "Game Over" on prompt say "You died. Welp, that's what you get for killing people."
You can play this game or open it in the editor.
Two things have changed. First, the one-action events where made compact. Second, the living’s room on prompt event changed, and look! A condition! Conditions allow to selectively preform actions, choosing them with regard to some kind of information (in our example the visibility of Mary). So how does one write a condition?
Conditions
First comes an if, then an expression (which can be quite complex – we will get to that later on). In our example the expression is equal to mary.hidden. After the if and the expression we write indented actions that are to be executed only if the expression is true. Actions belong to conditions, just like actions belong to events or objects belong to locations. After we finish adding actions to the condition we can (but not have to) write else followed by another portion of indented actions. These actions will be executed only if the expression was false. In other words:
if expression # to be executed only when 'expression' is true action action ...# the condition can end here or we can add 'else' as shown belowelse # to be executed only when 'expression' is false action action ...
Skipping stuff
Again we can make things more compact. If a condition has only one action we can write it in a single line:
if mary.hidden say "It got quiet. Mary's in a pool of blood on the floor and Lucy's looks at you cautiously"else say "Two angry women are arguing here. It's awfully loud."
or even (but it’s ugly so don’t do it too much):
if mary.hidden say "It got quiet. Mary's in a pool of blood on the floor and Lucy's looks at you cautiously" else say "Two angry women are arguing here. It's awfully loud."
side-note: because of a bug shortened conditions get colored incorrectly. In the examples above the
sayactions are white when they should be yellow. Unfortunately no good solution was found to resolve this issue.
Referring to stuff
But there’s still one thing unexplained. What does mary.hidden mean? We got to the hard part – mary.hidden is a variable. Remember how I told you that object and location identifiers are like file names? Well, there’s more to that.
Containers
In fact objects, locations and even events are more like folders. We will call them containers as they contain things. Let’s continue the file and folder analogy:
hiddenis a file (with contents equal to true or false) inside of a folder calledmary.maryis a folder inside of a folder calledroom(the living room)roomis a folder inside a folder calledrootrootis the topmost folder (like theC:drive of your computer).
Variables
So what is a variable? If folders were an analogy to containers and files were an analogy to values then by saying “a variable” we mean a folder or a file. It’s anything in the game that we can somehow reference (refer to). So how do we refer to things? The easiest (but highly unpractical) way is to use full paths – for example the hidden value inside mary has a full path equal to root.room.mary.hidden (it’s just like a file path, but with dots instead of slashes). Paths can be shortened depending from the context they are used in. That may sound a bit cryptic but it’s really simple and intuitive. When inside the living room mary refers to Mary The Wicked. There could be other variables named mary somewhere else and to reference them we would need to use appropriate paths.
Contexts
To understand better what a context is take a look at the following example:
object knifelocation cave object knifelocation meadow object dwarf
Imagine that with each level of indentation you climb a tower. While on this tower you can look only directly below. When asked for an item you find the closest item matching the description in the range of your sight. In the example above while on the ground you see a knife, and two towers – the meadow and the cave. As you can’t look up, you don’t know whats on top of them. Once you climb a tower, let’s say the meadow tower, you find a dwarf. You can also look directly below to see the knife on the ground and the base of the cave tower, but you can’t look sideways to see what’s on top of it. If you climb the cave tower, you will see two knifes – one from the tower and one on the ground. But the knife on the tower is closer, so you prefer it. Also, while on the cave tower you can’t see the dwarf. He’s on the neighboring tower and you can’t look sideways.
To summarize let’s list all the different contexts in the example above and show how to refer to each variable from inside each of them:
The root context:
| Full path | Shortest path |
|---|---|
root.knife |
knife |
root.cave |
cave |
root.cave.knife |
cave.knife |
root.meadow |
meadow |
root.meadow.dwarf |
meadow.dwarf |
The cave context:
| Full path | Shortest path |
|---|---|
root.knife |
root.knife |
root.cave |
cave |
root.cave.knife |
knife |
root.meadow |
meadow |
root.meadow.dwarf |
meadow.dwarf |
The meadow context:
| Full path | Shortest path |
|---|---|
root.knife |
knife |
root.cave |
cave |
root.cave.knife |
cave.knife |
root.meadow |
meadow |
root.meadow.dwarf |
dwarf |
Skipping stuff
Yes, it’s this paragraph once again. The thing is that full paths can skip the root and start from a dot character. In other words .meadow.dwarf is a abbreviation of root.meadow.dwarf (but doesn’t have to be same thing as meadow.dwarf – there could be a meadow in the current context different from the meadow in the root context).
Combining stuff
Let’s take a break from variables and do something fun. It’s time to put the inventory into use. As it has been already said, objects can be put in and out the inventory using the equip and unequip actions. It has also been said in the Adventure Script Player manual that objects inside the inventory can be combined with each other and with objects inside the current location. So how do define what should happen when the players decides to combine something? Take a look at the following example game:
on create goto room # 'equipped' is a object modifier. We will talk about them some time later.# Thanks to it the knife will be in the inventory when the game startsequipped object knife "Knife" on prompt say "A blunt knife. Still good for stabbing" on use say "You stab yourself. You die. What have you been thinking?" goto end on combine bow say "You stab a bow. It's stupid. The bow breaks." unequip bow on combine room.mary # notice that we can not simply write 'mary' -- we are not in the 'room' location say "You stab Mary in the heart. She dies. Lucy shuts up. She looks quite content." hide room.mary on combine room.lucy say "You try to stab Lucy. She grabs your hand in mid air." say room.lucy "Oh, I will enjoy this..." say "You get slowly punched to death." goto end # 'any' matches any object. on combine any say "Unfortunately you can't stab that" object bow "Toy bow" on prompt say "Looks dangerous. It even came with a toy arrow." location room "Palace living room" on prompt if mary.hidden say "It got quite. Mary is in a pool of blood on the floor. Lucy's looks at you cautiously" else say "Two angry women are arguing here. It's awfully loud." object "Weapon stand" on prompt say "There are some fine weapon here!" on combine bow say "It won't do much damage to it" on use # [object].equipped is true if an object is inside the inventory if bow.equipped say "Only toy swords left." else say "The bow looks useful." equip bow object mary "Mary the Wicked" on prompt say mary "I'm busy shouting at Lucy, go away" on use say mary "You want to USE me? Right." say "You get punched in the face." on combine bow say mary "Yes, I'm terrified. Show me that arrow, will you?" say "You find yourself with an arrow in your eye. You die" goto end object lucy "Lucy the Spiteful" on prompt say lucy "Wanna taste ma fists? No? Then stop looking at me!" on use say lucy "Of course you can use me!" say "You get punched in the face." say lucy "That was sarcasm." say "You get punched in the face." on combine bow say mary "Is that a toy bow? You want to HURT me with that?" say "You get disarmed and Mary breaks the bow in half." unequip bow location end "Game Over" on prompt say "You died. Welp, that's what you get for messing with insane women."
You can play this game or open it in the editor.
The on combine event
As you probably noticed the on combine event is a bit different from the events we’ve been using so far. After the usual on and the event’s name comes a third element – the target object. An on combine event is executed when the player combines the target object with the object that the event is defined in. It is also executed when the reversed situation occurs – an on combine bow event inside the knife could be rewritten as an on combine knife inside the bow and would still do the same thing.
Wildcard targets
A wildcard target is a special target that matches any object. We used it in the example above in the knife object. When two objects are combined and they don’t have an appropriate on combine event, then a event with a wildcard target is executed instead (if one is defined). To create an on combine event with a wildcard target we simply write any instead of the target object.
What if both objects have an on combine event with a wildcard target? When combining two objects the second one always have priority. Consider the player used the bow on the knife and they both have a event with a wildcard target. The knife’s on combine any event will be executed (but only if there was no on combine knife inside the bow and no on combine bow inside the knife). If it’s still unclear try playing the following example and combine the bow with the knife and then the knife with the bow (in the inventory).
on create goto testequipped object knife on combine any say "Knife wildcard"equipped object bow on combine any say "Bow wildcard"location test
Like always, you can also open this example it the editor.
Talking with stuff
One more thing left in this chapter – writing dialogs. I won’t hide that creating complex dialog trees is quite tricky, as it requires understanding what trees are. That’s why for now I will only show you how to make really simple dialogs. Let’s start with a example:
on create goto meadow object axe "Dwarf's Axe" on prompt say "A beautiful example of dwarf craftsmanship." location meadow "Meadow" on prompt say "A boundless meadow, covered with a variety of spring flowers." object dwarf "Sad looking dwarf" on prompt say "A beardless, clean and cinnamon smelling dwarf." on use goto foo on combine axe say dwarf "Oh my..." say "You take a swing but the handle breaks and the blade falls on your head. You die." goto end dialog foo on prompt say dwarf "Yes, stranger?" option "Who are you?" say dwarf "I am a dwarf!" option "Why are you on a meadow?" say dwarf "I love grass, I hate caves. I'm quite an outcast." option axegive "Give me your axe" say dwarf "It sounds reasonable. Here take it." hide axegive equip axe option "I have to go" say dwarf "See you later!" goback location end "Game over" on prompt say "You died."
You can play this game or open it in the editor.
Two new elements appeared in this example: dialogs and contained in them options.
Dialogs
Dialogs are basically containers for options, but they can also contain events. When in a dialog, options are displayed to the player in a similar way that objects are displayed in a location.
To create a dialog write dialog followed by an identifier. Then add appropriately indented events and options. For now let’s consider only the on prompt event, executed each time the dialog is displayed to the player.
To enter a dialog use the goto action the same way you would enter a location. To exit a dialog use the goback action (described below) or enter a location with the goto action.
In the example above the dialog was placed inside an object (the dwarf). Notice that when the player is inside the dialog the header says “Dialog with Sad looking dwarf”. We can also place the dialog inside a location or in the root context but then the header will simply say “Dialog”.
Options
Options are something between events and objects. Just like objects they have identifiers and names but inside they contain actions like events. These actions are executed when the player clicks on a option inside a dialog.
Options can be hidden and shown using the hide and show actions just like objects. A hidden option will not be displayed to the player.
Inside options a special goback action is available. Use it to exit the current dialog. Keep in mind that that just like goto it terminates the current option after being executed.
To create an option write option followed by an identifier and a name. Then add any amount of appropriately indented actions.
A short interlude…
…is recommended for reading the Adventure Script Editor manual. You already know enough to create and modify simple games. After reading it try playing with examples in this document. Add some objects, write some events – it will help you understand things a hundred times faster. If you make a mistake the editor will display an error, which for now will probably seem like cryptic gibberish. Don’t worry, we will get to them some time later. For now all I have for you is a small tip – if you see enigmatic baloney like this:
stack trace:
[5] /runtime/game.as:rret:57
[4] /game/main.as:bow:5
[3] /runtime/runtime.as:safecall:87
[2] /runtime/game.as:rrot:117
[1] /game/main.as:root:4
then it means that you made a mistake somewhere near line 5 of the /game/main.as file it the bow object. Always look at the topmost line of such messages that has a file from your project in it. The number on it’s end will be the number of the line that caused the error to occur.
One more thing before we move further: there is an useful print command that can be used to print any variable / value / expression in the editor’s event log. Just like this.
Events
This chapter will focus on describing events in more detail. The last section contains a reference of all available events. Some sections of this chapter describe advanced features of Adventure Script. Beginners should skip them.
Object events
All object events have exactly the same functionality: when defined in an object they are displayed to the player in the object screen and executed when the player clicks on them. What’s more object events are user-defined, meaning you can create any object event you want, like stab or pickpocket.
There are three object events predefined inside the dafults.as file that is included to each new project. Let’s took a look at them right now:
defineevent "use" "use" "fa-gears"defineevent "talk" "talk to" "fa-comments"defineevent "pickup" "pick up" "receive"
An object event is added by writing defineevent followed by the event name in quotes. Then come three optional parameters also written in quotes: the display name, icon and background color. For example to define an on stab event with red background and dagger icon we would write:
defineevent "stab" "Backstab" "curved-dagger" "tomato"on create goto Romelocation Rome object Cesar on stab say "Ouch!"
You can play this game or open it in the editor.
Object events need to be introduced before they are used for the first time. In the example above writing the defineevent after the Cesar object would result in the following error:
RUNTIME_ERROR: unknown event stab
System events
System events are executed on various occasions and unlike object events are hard-coded (no new system events can be added). Different types of these events can be defined inside different elements of the game. For example the on create event can only be defined in the root namespace (context), while the on prompt event can be defined in locations, objects and dialogs. A full list of different events with their desccirpion can be found in the event reference.
Template events
This section describes a feature that may prove to be harder to understand. Feel free to skip it and come back to it later.
A template event is an event defined outside of its normal context. For example an on equip event defined inside a location. All elements inside a context with a template event will inherit this event unless they define their own event of the same type overriding the template event. The following example demonstrates an on use template event:
on create goto meadowon use say "Hello from the root context!" # template event location meadow on prompt say "Trying using the dwarf and the elf." on use say "Hello from the meadow context!" # template event, # overrides the template event in the root context object dwarf on prompt say "Use me." on use say "Hello from the dwarf context!" # normal event, # overrides the template event in the meadow context object elf on prompt say "Use me." # no 'on use' event, the template event in the meadow context will be inherited object "passage to the cave" on trigger goto cave location cave on prompt say "Trying using the knife and the bow." object knife on prompt say "Use me." # normal event, # overrides the template event in the root context on use say "Hello from the knife context!" object bow on prompt say "Use me." # no 'on use' event, the template event in the root context will be inherited object "passage to the meadow" on trigger goto meadow
You can play this game or open it in the editor.
Predefined template events
The defaults.as file comes with the following template events predefined:
on equipon unequipon combine anyon inventory
Feel free to change them to further customize your games.
Limitations
Not all events can have template events. Consult the event reference for further information on this matter.
Accessing the caller context
A template event’s context it equal to the context it has been defined in (just like normal events). This makes it impossible to determine in which context the event was called (executed) in – for example a template on equip event has been called. But what object was equipped?
To solve this issue a special variable context was made accessible inside all events. This variable points to the context that the event was called on. For example the on equip template event inside defaults.as has the following definition:
on equip say "Equipped \name{$context}."
Inside non-template events context is equal to parent.
Canceling events
All events can be canceled. Canceling an event causes it to immediately terminate and usually causes some special effect. These effects have been described in the event reference.
To cancel an event simply write return true in it’s body. The following example demonstrates cancelling an on inventory event:
on create goto testlocation test on prompt say "Try opening the inventory." on inventory say "This can not be done!" return true
You can play this game or open it in the editor.
To terminate an event without triggering the special effect use return false or simply return.
Disabling events
This section describes an advanced feature of Adventure Script.
Events can be disabled. Disabled events are ignored as if they were not defined. Following functions (actions) are used to disable an event:
disable container "event name"disable container "combine" objectdisable container "combine" .rt.game.wildcardobject
And similarly to enable an disabled event:
enable container "event name"enable container "combine" objectenable container "combine" .rt.game.wildcardobject
Container should be a namespace / location / object / dialog containing the event to be disabled. The event name needs to be written in quotes. Writing disable container "combine" will disable all combine events inside the chosen container. To disable a specific combine event the target object has to be specified. To disable the wildcard combine event .rt.game.wildcardobject has to be used as the target object. An event can be also disabled by adding the disabled modifier to it’s declaration.
An example demonstrating how disabling and enabling events works is shown below.
on create goto teston trigger say "Hello from root!"location test "disable demo" on prompt say " .ontrigger.disabled = $.ontrigger.disabled\br .test.ontrigger.disabled = $.test.ontrigger.disabled\br .test.run.ontrigger.disabled = $.test.run.ontrigger.disabled\br " on trigger say "Hello from test!" object run on trigger say "Hello from run!" on prompt say "All trigger events disabled" goto test object 'disable root "trigger"' on trigger disable root "trigger" object 'disable test "trigger"' on trigger disable test "trigger" object 'disable run "trigger"' on trigger disable run "trigger" object 'enable root "trigger"' on trigger enable root "trigger" object 'enable test "trigger"' on trigger enable test "trigger" object 'enable run "trigger"' on trigger enable run "trigger"
You can play this game or open it in the editor.
Manually calling events
This section describes an advanced feature of Adventure Script.
Events can be called (executed) manually using the do function with a syntax similar to the enable / disable functions:
do container "event name"do container "combine" object
Container should be a namespace / location / object / dialog containing the event to be called. The event name needs to written in quotes. If the container does not have the specified event, then a appropriate template event is executed (if present).
If no event or template event is found the function returns none. In other cases it returns the value returned by the event it executed.
Event reference
This section may make use of concepts not yet explained, like namespaces or string interpolation. For now ignore fragments you don’t understand and come back to them later.
Complete Adventure Script event reference:
- on create
- on prompt
- on enter
- on leave
- on inventory
- on trigger
- on equip
- on unequip
- on show
- on hide
- on combine
- object events
on create
This event is executed once the game start. Is should set the initial location of the game. Can not be canceled.
Can be defined in:
- root namespace
on prompt
Executed upon displaying a location / object / dialog screen. Used primary to set the prompt. Canceling this event has no special effect.
Can be defined in:
- locations
- objects
- dialogs
on enter
In locations this event is executed when the player enters the location this event is defined in. The player’s location needs to change for this event to be executed – using goto to the current location will not execute this event. Canceling this event prevents the location change – the players stays in the location he was trying to leave.
In dialogs this event is executed when the player changes or moves down in a dialog sub-tree. This is explained in more detail in the dialogs chapter. Canceling this event prevents the dialog change.
Can be defined in:
- locations
- dialogs
on leave
In locations this event is executed when the player leaves the location this event is defined in. The player’s location needs to change for this event to be executed – using goto to the current location will not execute this event. Canceling this event prevents the location change – the players stays in the location he was trying to leave.
In dialogs this event is executed when the player changes or moves up in a dialog sub-tree. This is explained in more detail in the dialogs chapter. Canceling this event prevents the dialog change.
Can be defined in:
- locations
- dialogs
on inventory
Executed before the inventory opens. Used primary to set the inventory prompt. Canceling this event will prevent the inventory from opening. This allows restricting the player access to the inventory when needed. The following on inventory event is predefined in the defaults.as file:
on inventory say "Inventory contents"
Can be defined in:
- locations
- namespaces (as template)
on trigger
Executed when the player selects an object from the location screen, just before the execution of the on prompt event. This event causes an automatic return to the location screen upon finish – the object screen doesn’t get displayed and the on prompt event doesn’t get executed. Canceling this event resumes the normal flow – the object screen gets displayed normally after executing the on prompt event.
Simple example:
on create goto Meadowlocation Meadow on prompt say "Dwarfs on a meadow!" object "Normal dwarf" on prompt say "This is the normal dwarf" object "Trigger dwarf" on trigger say "This is the trigger dwarf"
You can play this game or open it in the editor.
Can be defined in:
- objects
- locations (as template)
- namespaces (as template)
on equip
This event is executed when an object is added to the inventory. Canceling this event causes the object to not be added to the inventory. The following on equip event is predefined in the defaults.as file:
on equip say "Equipped \name{$context}."
Can be defined in:
- objects
- locations (as template)
- namespaces (as template)
on unequip
This event is executed when an object is removed from the inventory. Canceling this event causes the object to not be removed from the inventory. The following on unequip event is predefined in the defaults.as file:
on unequip say "Unequipped \name{$context}."
Can be defined in:
- objects
- locations (as template)
- namespaces (as template)
on show
This event is executed when an object is set visible via the show action. This event will not be executed if the object was already visible. Canceling this event causes the object’s visibility state to stay unchanged.
- objects
- locations (as template)
- namespaces (as template)
on hide
This event is executed when an object is hidden via the hide action. This event will not be executed if the object was already hidden. Canceling this event causes the object’s visibility state to stay unchanged.
- objects
- locations (as template)
- namespaces (as template)
on combine
Combine events are executed when two objects are combined by the player. They’ve been described in more detail in the previous chapter. Canceling these event has no special effect. The following wildcard on combine event is predefined in the defaults.as file:
on combine any say "This can not be done."
Combine events also expose a special target variable in their body allowing referring to the target object when the wildcard target is used. Short demonstration of this feature:
on create goto testlocation test on prompt say "Try combining objects in your inventory" on combine any say "context: $context" say "target: $target" hidden equipped object knife hidden equipped object bow hidden equipped object arrow
You can play this game or open it in the editor.
object events
Events displayed to the player in the object screen. Executed upon selection by the player. Canceling these events has no special effect. Read more about object events here.
Can be defined in:
- objects
- locations (as template)
- namespaces (as template)
Variables
The first chapter introduced variables, but did not specify how to modify their values or how to create new ones. This chapter will return to this subject and explain it in much more detail.
Why do I need variables?
Let’s start by answering the question from this section’s header. I’ll do it with a short example:
defineevent 'ignite'on create goto cave location cave on prompt if torch.lit say "IT'S THE SPANISH INQUISITION!" else say "It's too dark to see anything." object torch on prompt if torch.lit say "It's ignited." else say "It's not ignited." on ignite if torch.lit say "It's already ignited" else set torch.lit say "You ignite the torch."
You can play this game or open it in the editor.
Of course similar functionality could be achieved by defining an ignited torch and an unignited torch then hiding the first one and showing the second one. Variables are there to make things simpler. If you don’t want to use them you don’t have to. But do use them.
Special variables
They are four special variables that are available in every context:
rootreferring to the root contextselfreferring to the current contextparentreferring to the parent contextsuperreferring to the super element (used in inheritance)
It is very important to understand what self refers to. Take a short look a the following code:
object example on use hide self # error!
The on use event will fail with an error saying that we can’t hide an event. That shouldn’t be a surprise as self in the on use refers to the event itself, not to the object example. To hide this object we should write hide parent or hide example. Notice that thanks to parent we can write events that manipulate objects without identifiers:
object "I'm an object without an identifier" on use hide parent # it works!
The set command
To modify and create variables use the set command. Writing set path will set the variable referred by path to true. Writing unset path will set it to false. Other values, like numbers or strings can be set by writing set path expression where expression is any valid expression.
The set command can be used anywhere in the game’s code – not only in events. Commands outside events will be executed before the game starts.
Setting a variables value to none deletes it.
Some variables may be locked meaning that only the game itself can modify their value.
Invalid paths
Consider that you want to save a file on your computer. You are asked for a file path. If you provide a path to an existing file, this file will be overwritten. If you provide a path to an nonexistent file but all the folders on the way to it exist, this file will be created. If you provide a path with a nonexistent folder an error will be reported.
The same rule applies to variable paths in Adventure Script. A path is valid as long as all path elements excluding the last exist. Otherwise a NULL_REFERENCE error is reported.
A valid path to a nonexistent variable will always be resolved as a special none value. In conditions none is treated them same way as false.
Creating variables
To create a variable simply use the set command with a valid path to a nonexistent variable. There is but one limitation – the path needs to explicitly specify in which container to create the variable (in layman’s terms it has to have at least one dot in it). This is shown on the example below:
set foo # invalidset root.foo # validobject cave set boo # invalid set self.boo # valid set cave.boo # also valid
System variable reference
Many elements of the game have variables automatically created in them by the game itself. Like hidden inside objects or disable inside events. These variables can be accessed and modified like any other variable in the game. This section will show what system variables are available and what is their meaning.
text (string)
The text variable is present in location, objects and options and is equal to their name. Changing it will alter the way they are displayed. Example:
on create goto cavelocation cave on prompt say "Is this realy a cave?" object dwarf on trigger say dwarf "The cave is a LIE!" set cave.text "The Great Meadow" # change the cave name
You can play this game or open it in the editor.
hidden (boolean)
The hidden variable is present in objects and options. It is set by the show and hide functions (actions). Manually changing it’s value will change the object’s visibility state but will not trigger the on hide and on show events.
equipped (boolean)
The equipped variable is present in objects. It is set by the equip and unequip functions (actions). This variable is locked and can not be changed manually.
disabled (boolean)
The disabled variable is present in events. It is set by the disable and enable functions (actions). Manually changing it’s value has the exact same event as using the disable and enable functions.
icon (string)
The icon variable is present in objects and options. Changing it’s value will change the the displayed icon. Example:
on create goto meadowlocation meadow on prompt say "Look at the paw!" object dwarf set self.icon "fa-paw"
You can play this game or open it in the editor.
bgcolor (string)
The bgcolor variable is present in objects and options. Changing it’s value will change the the displayed background color. Example:
on create goto meadowlocation meadow on prompt say "It's not pink, it's salmon!" object dwarf set self.bgcolor "pink"
You can play this game or open it in the editor.
.data.location (location)
This variable holds the current location. It is locked and can not be changed manually.
.data.inventory (array)
This variable holds the inventory in form of an array of objects. It is locked and can not be changed manually.
Modifiers
Modifiers can be added to definitions of game elements. There are three basic modifiers:
hidden– works with objects and options, causes them to be hidden when the game startsequipped– works with objects, causes them to be equipped when the game startsdisabled– works with events, causes them to be disabled when the game starts
Modifiers need to be specified as the first element of a definition. A single definitions can have more then one modifier, for example to define a hidden and equipped object knife one can simply write:
hidden equipped object knife
The order of modifiers doesn’t matter.
Defining new modifiers
Understanding how to add new types of modifiers requires basic knowledge about functions and namespaces.
A new type of modifier can be added to the game by defining a one argument function in the .data.modifiers namespace. The function’s name will become the name of the new modifier. Upon creating a game element preceded by this modifier the function will be called with the element passed in the argument. An example custom doorway modifier is defined in the defaults.as file:
function data.modifiers.doorway o::object set o.icon 'entrance'
This modifier sets the icons of the objects preceded by it to the ‘entrance’ icon. Note that the argument’s type has been set to object, allowing this modifiers to be used only on objects.
Strings
Text values written in quotes are called strings. This chapter will describe them in detail. The probably most interesting part of this chapter will be about patterns which are used to format the text displayed to the player.
String syntax
Don’t read this section if you don’t know squat about programing.
There are two types of strings – single quoted (') and double quoted (") strings. There is a slight difference between them.
Double quoted strings are interpolated and can use patterns. They also ignore white spaces used inside them (just like paragraphs in HTML). The $, ~, " and / symbols inside them need to be escaped with the / escape character.
Single quoted strings are literal strings, only the ' and / need to be escaped inside them (also by the / escape character).
Both type of strings can be multi-line, what has already been shown for example in this section’s example on prompt event.
HTML entitles inside strings are automatically escaped during compilation. This feature can be disabled by writing #!unescaped_strings in the begin of a source file. Doing so allows usage of raw HTML inside such file. Be warned that every tag that’s not a span or br gets stripped by the Adventure Script Player.
String interpolation
Don’t read this section if you don’t know squat about programing.
Double quoted strings support string interpolation with the use of the $ character:
- variables can be inserted into strings by writing
$variable - expressions can be inserted into strings by writing
$(expression) ${function a b c}is a syntax sugar for$({function a b c})
Short example:
print "variables inside strings: $.data.location"print "expressions inside strings: $(16+32)"print "function calls inside strings: ${math.pow 2 5}"
Patterns
Patterns are a useful feature of Adventure Script that among other things allow formatting the text displayed to the user. Using predefined patterns i very easy but creating new ones can be tricky and requires much more knowledge.
Formatting of headers and prompts in the Adventure Script Player’s screens is realized by patterns defined in the defaults.as. Feel free to modify them to further customize your games.
Each pattern has a name. For example the pattern bold can be used to make a portion of text bold. To use this pattern inside a string write a \ followed by the pattern name (bold) and the text to be made bold surrounded in curly brackets ({ and }). Just like this:
say "The word \bold{meadow} is made bold."
bold is a one-argument pattern, as you only specify the text to be made bold. Some patterns can have more arguments, for example to use the color pattern you have to specify the color and the text. To make a portion of text red one would write:
say "The word \color{red}{meadow} is made red."
In this example the first argument is ‘red’ (the color) and the second is ‘meadow’ (the text). Arguments are written one after another, each one surrounded in curly brackets.
Patterns can be mixed together, for example:
say "\bold{This text is in bold. \color{red}{This text is bold and red}}"
All available patterns are listed in the pattern reference.
Creating patterns
This section describes an advanced feature of Adventure Script.
Patterns can be defined in two different ways: as template strings or pattern functions.
Template string patterns
A pattern can be defined by writing pattern followed by a name and template string. A template string is a string with placeholder variables. Placeholder variables are numbered from zero, each number corresponding to subsequent arguments of a pattern. For example the color pattern is defined in the following way:
pattern color "<span style=\"color:$0\">$1</span>"
Function patterns
A pattern can be defined by writing pattern followed by a name and a function body. Arguments of the pattern are created automatically and are called _n where n is the argument number (starting from zero). The function body should return the result string. For example the nbsp pattern is defined in the following way:
pattern nbsp if {istype _0 'string'} set _0 {atof _0} local out '' while _0 > 0 set out out+' ' set _0 _0-1 return out
Pattern reference
Adventure Script predefined pattern reference:
Example usage of all of these patterns has been shown in the code below:
on create goto testlocation test "Patterns demo" on prompt say "\span{font-style:normal}{ \bold{bold text}\br \emph{italic text}\br \color{red}{colored text}\br \bgcolor{red}{coloted background}\br multiple\nbsp{4}spaces\br ~~multiple~~~~spaces~~\br \span{font-family:'Comic Sans MS'}{styled span}\br \name{$test} }"
You can play this game or open it in the editor.
\bold{text}
Makes text bold.
Arguments:
- text fragment
\emph{text}
Makes text italic.
Arguments:
- text fragment
\color{color}{text}
Set text’s color.
Arguments:
- color
- text fragment
\bgcolor{color}{text}
Set text’s background color.
Arguments:
- color
- text fragment
\nbsp{number}
Inserts multiple non-breaking spaces. Writing a ~ inside a string is a shortcut for \nbsp{1}.
Arguments:
- number of non-breaking spaces to be inserted
\br
Inserts a line break.
No arguments.
\span{style}{text}
Inserts a styled HTML span element. Only the following CSS properties are allowed:
- color
- background-color
- font-style
- font-weight
- font-family
- text-decoration
Arguments:
- list of CSS properties (the content of the
styleHTML attribute). - text fragment
\name{variable}
Inserts the name of a game element.
Arguments:
- path to the element
\ignore{argument}
Does nothing with a pattern argument.
Arguments:
- pattern argument
Dialogs
This chapter is sh*t. I’ll write a better one someday.
A dialog tree is created by defining dialogs inside dialogs. The position of a dialog in a dialog tree effects the way on enter and on leave events are executed. There are two special actions that can be used inside dialog options:
goback– moves one level up in the dialog treequit– exits the whole dialog tree
Play the following example and observe how the on enter and on on leave are executed:
on create goto demo dialog main on enter say "I entered the main dialog" on leave say "I left the main dialog" on prompt say "Hello from the main dialog" option "enter first child" goto firstchild option "enter second child" goto secondchild option "enter inner child" goto firstchild.innerchild option "exit" quit option "goback" goback dialog firstchild on enter say "I entered the first child dialog" on leave say "I left the first child dialog" on prompt say "Hello from the first child dialog" option "enter main" goto main option "enter second child" goto secondchild option "enter inner child" goto innerchild option "exit" quit option "goback" goback dialog innerchild on enter say "I entered the inner child dialog" on leave say "I left the inner child dialog" on prompt say "Hello from the inner child dialog" option "enter main" goto main option "enter first child" goto firstchild option "enter second child" goto secondchild option "exit" quit option "goback" goback dialog secondchild on enter say "I entered the second child dialog" on leave say "I left the second child dialog" on prompt say "Hello from the second child dialog" option "enter main" goto main option "enter first child" goto firstchild option "enter inner child" goto firstchild.innerchild option "exit" quit option "goback" goback location demo on prompt say "Open the dialog and observe how events are executed." object "start dialog" on trigger goto main
You can play this game or open it in the editor.
The on enter event is executed when the player moves up in the dialog tree (for example from firstchild to innerchild). The on leave event is executed when the player moves down in the dialog tree (for example from innerchild to firstchild). When the player moves sideways both events are executed (for example from firstchild to secondchild).
Expressions
Ugh, this chapter came out to be unreadable for people without basic programing skills.
A expressions is a mix of values, variables and operators.
Values
Adventure Script has the following scalar types:
- string (
"text"or'text') - undefined (
none) - numeric
- number (
12or12.12or1.12e10or0x12or0b10010) - boolean (
trueandfalse)
- number (
Operators
Operators in Adventure Script in the order of their precedence:
| Operator | Description | Argument types | Example | Result |
|---|---|---|---|---|
||, or |
logical or | any | false or 2 |
2 |
&&, and |
logical and | any | false and 2 |
false |
| |
bitwise or | numeric | 1 | 3 |
3 |
^ |
bitwise xor | numeric | 1 ^ 3 |
2 |
& |
bitwise and | numeric | 1 & 3 |
1 |
== |
equal to | any | 1 == 1 |
true |
=== |
typed equal to | any | 0 === false |
false |
!= |
not equal to | any | 1 != 1 |
false |
!== |
typed not equal to | any | 0 !== false |
true |
< |
greater then | numeric | 2 < 1 |
true |
<= |
greater equal | numeric | 2 <= 2 |
true |
> |
greater then | numeric | 2 > 1 |
false |
>= |
greater equal | numeric | 2 >= 2 |
true |
<< |
left shift | numeric | 1 << 3 |
8 |
>> |
right shift | numeric | 8 >> 3 |
1 |
- |
minus | numeric | 2 - 1 |
1 |
+ |
add | string, numeric | 2 + 1 |
3 |
* |
multiplication | numeric | 2 * 1 |
3 |
/ |
division | numeric | 2 / 1 |
2 |
% |
modulus | numeric | 2 % 1 |
0 |
!,not |
logical negation | any | !true |
false |
~ |
bitwise negation | numeric | ~1 |
-2 |
@ |
reference extraction | @variable |
reference | |
( … ) |
grouping operator | (1+2)*3 |
9 | |
[ … ] |
array literal | [1 2 3] |
array | |
{ … } |
function call | {math.pow 2 3} |
8 | |
c?a:b |
ternary operator | true?'a':'b' |
‘a’ |
Notes:
- logical operators are short circuited
- addition operator (
+) can be used on strings to preform string concatenation - unary minus is weird:
2 - 1is not the same thing as2 -1but the same thing as(2 -1) - content of each type off brackets can be spread over multiple lines
Type system
Complete type hierarchy in Adventure Script:
- any
- undefined
- reference
- unbounded
- defined
- array
- scalar
- string
- numeric
- number
- boolean
- container
- callable
- function
- dispatcher
- pattern
- event
- option
- namespace
- dialog
- inheritable
- location
- object
- callable
Notes:
- the only valid value of type
undefinedis none referencecan not be serialized (breaks save-games)- every sub-type of
containercan own member variables - every sub-type of
callablecan be called - every sub-type of
namespacehas it’s body executed during the build process - every sub-type of
inheritablecan inherit from elements of the same type
Namespaces
A namespace is the base type of dialogs, locations and objects. Namespaces have two main functionalities:
- they can have other namespaces and functions defined inside them
- any code written directly inside them will be executed during the build process
The special root variable points to a predefined topmost namespace called root with the parent variable equal to none.
Creating namespaces
Namespaces can be created to scope your code, for example to define a group of locations in a chapter1 namespace for convince. To create a namespace write namespace followed by a identifier. For example this is how the data.modifiers namespace is defined inside Adventure Script run-time:
namespace data.modifiers function equipped obj::object equip obj false function hidden obj::container hide obj false function disabled obj::event disable obj
Extending namespaces
Remember that dialogs, locations and objects are namespaces. Everything that can be done with namespaces can also be done with them.
A already created namespace can be extended with additional elements outside of it’s block. This can be done in the following two ways.
Extend keyword
Write the extend keyword followed by a namespace you want to extend, then open a block. Everything in this block will be executed it that namespace’s context.
Every Adventure Script source file extends the root namespace this way. This is done automatically but could be written as:
extend root # source file contents
Path as identifier
Another way to extend a namespace is to use a path instead of an identifier in a element defection. For example this is done in the defaults file to define a custom modifier:
function data.modifiers.doorway o::object set o.icon 'entrance'
This feature is quite useful when writing dialog trees. It can keep the indention level reasonably low by defining all inner dialogs on the same indention level.
Functions
This chapter assumes you have basic programing skills.
To call a function in Adventure Script one simply writes the function name (or a expression that resolves to a function) followed by a white-space separated list of arguments if form of expressions. So for example say lucy "hello" calls the function say with lucy and "hello" as the arguments. In fact every “action” presented in this manual (say, goto, equip, …) was a function. But not set and unset, they are keywords.
Function calls can also be part of expressions. The syntax is exactly the same, but the call needs be surrounded by curly brackets ({ ... }).
Here is a example of a complex function call taken from the Adventure Script run-time:
{index {index {index stack -2} 'options'} input}
It is equivalent to the following line written in a C-like language:
(index(index(index(stack,-2),'options'),input))()
Fun fact: functions, as well as everything else in the game can be named like a keyword as long as the name is enclosed in back-quotes (so you can define a
function `function`).
Arguments
Function arguments are specified after the function name in form of a white-space separated list of names. Arguments can be typed and untyped and can be passed by value or reference. A argument type is specified by writing ::type after it’s name (for example x::number). By default every argument is untyped and passed by value. To pass an argument by reference add the reference extraction operator (@) before the argument name. The argument may still specify a type. A good example of a function using untyped arguments passed by reference is the swap function:
function swap @a @b local c a set a b set b c
More about references and the reference extraction operator in the references section below.
When a value of an invalid type is passed to a function with a typed argument a TYPE_ERROR error is raised. All sub-types of the specified type are considered valid (for example specifying ::any is equivalent to an untyped argument).
When a function is called with a different amount of arguments then specified in the definition a INVALID_ARRITY error is raised.
Variadic functions
Variadic functions can be defined by adding the variadic modifier to a function definition. The arguments can be accessed by calling the arguments function, which will return them in form of an array. Named arguments may still be specified. The amount of named arguments determines the minimal arrity – calling the function with less arguments then the amount of the named arguments will result in a INVALID_ARRITY error. The concat function is a example of a variadic function without named arguments:
variadic function concat local arr {arguments} local i 0 local str '' while i < {length arr} local e {index arr i} set str str+{istype e 'string'}?e:{tostring e} set i i+1 return str
Locals
Adventure Script supports classical block-scoped locals. To define a local use the local keyword followed by a name and a optional initial value. If the initial value is not specified none will be used. Look at the the concat function in the section above for a example.
While and elseif
The only loop supported in Adventure Script is the while loop with the following syntax:
while expression commands
Inside the while loop break and continue can be used.
Adventure Script also supports any number of elseif blocks inside conditions:
if expression commandselseif expression commandselse commands
References
Adventure Script supports PHP style references. References are created by the reference extraction operator (@). A newly created reference is unbounded and after it gets assigned to any variable it becomes bounded. Accessing a bounded references accesses the value of the referenced variable. Ugh, you know what? Just look at the example:
local a 5local b @alocal c blocal d @bset a a+1print a # 6print b # 6print c # 5print d # 6
Using the reference extraction operator on a reference makes an unbounded copy of it.
Warning: references don’t get serialized – they can’t be a part of save-games. Leaving a reference hanging somewhere in a global variable will crash the save process. So don’t do that.
Multiple dispatch
Multiple dispatch is implemented via dispatchers. The syntax is sadly pure crap. Here is the definition of the tostring dispatcher and some of it’s member functions:
dispatcher tostringfunction tostring_container value::container extends tostring return "${path value}::${typeof value}"function tostring_numeric value::numeric extends tostring return value+''function tostring_string value::string extends tostring return '"'+value+'"'function tostring_any value::any extends tostring return '::'+{typeof value}function tostring_none value::undefined extends tostring return 'none'
A dispatcher is created by writing the dispatcher keyword followed by a name. Any function can be added to the dispatcher by writing extends after it’s argument list, followed by a path to the target dispatcher. Alternatively the push function can be used with the first argument equal to the target dispatcher and the second to the function to be added.
Inheritance
OOP means something to you? No? Then you probably won’t understand a thing.
Locations and objects support inheritance in form of something similar to a prototype chain. The problem is that Adventure Script does not have prototypes or classes, only instances. Personally I think the resulting instance-to-instance inheritance chain is weird and confusing. And I wrote it!
To make A inherit from B write extends B at the end of the A definition (for example object A extend B). The identifier can be skipped – is such case it will be taken form to element we inherit from (in other words we can write object extend B to create a object B in the current context that inherits from the original B object… that didn’t help, didn’t it)?
Assume we write A.something:
- if
somethingis inAwe will access it - if
somethingis insideBand not inAwe will access it - if
somethingis neither inAandBit will be created inB
To create / access a variable something inside A regardless if it’s in B:
- Write
self.somethingfrom insideA - Use the
indexfunction
To create / access a variable something inside B regardless if it’s in A:
- Write
super.somethingfrom insideA - Write
B.something
Of course events get inherited just like everything else.
Inheritance has been used in the example game. Open it and take a look at the object steve and how it’s added to the home location.
Understanding errors
There are three types of errors:
- parse errors
- VM errors
- runtime errors
Parse errors
The thing is nobody taught me how to write a compiler with nice error routines so I didn’t write them at all. Yup, that means that parse errors suck and they do it big time. Don’t even bother reading them. Just check the line number.
This code (missing say before "Hello!")
on prompt "Hello!"
will result in something like this: Expecting 'NL', 'VARNAME', 'IF', 'WHILE', 'INDT', '{', 'CONTINUE', 'YIELD', 'BREAK', 'RETURN', 'THROW', 'LOCAL', 'SET', 'UNSET', got 'STRING_START'. Beautiful isn’t it?
VM errors
There are four VM errors you are likely to see:
NULL_REFERENCE– you tried to resolve an invalid pathVALUE_IS_CONSTANT– you tried to set a locked variableINVALID_ARRITY– you called a function with an incorrect number of argumentsTYPE_ERROR– you called a function with an incorrect argument type
Each VM error includes a stack trace that allows localizing the error in the code.
Runtime errors
Here are some common runtime errors:
target destination for <type> <name> is not empty– two elements have the same identifier in the same context (namespace)got NaN in math– you f*** up some calculationsrestricted– you tried to call a function that you aren’t allowed to callcould not find compatible function in dispatcher– you called a dispatcher function with an invalid set of argumentsambiguity in dispatcher– their are conflicting functions in a dispatcheruse of unknown modifier– you probable misspelled a modifierevent <name> can not be defined in <type>– you defined an event in a context it can’t be defined in (see here)unknown event– you probably misspelled an event nameduplicated target <object> in 'on combine' event– there are two events for the same target object in aon combineeventobject <name> not found in event 'on combine <object>' of <namespace>– an object specified as the target of aon combineevent was not found. The stack trace won’t be helpful for this error<name> in event 'on combine <object>' of <namespace> has wrong type– the target of aon combineevent is not an object. The stack trace won’t be helpful for this errorunknown goto destination <name>– you usedgotoon something that’s not a location / object / dialog
Each VM error includes a stack trace that allows localizing the error in the code.
Stack traces
A stack trace shows what the virtual machine was doing in the moment the error occurred. Let’s take a look at an example stack trace and explain what information if holds:
stack trace:
[5] /runtime/game.as:rret:57
[4] /game/main.as:bow:5
[3] /runtime/runtime.as:safecall:87
[2] /runtime/game.as:rrot:117
[1] /game/main.as:root:4
The error occurred on line 57 of the file /runtime/game.as during executing the rret function. This is unhelpful as this file is part of the Adventure Script standard library and not your code. Let’s look at the line below to see where the rret function was executed – on line 5 of the /game/main.as file. This is the last line of your code executed before the error happened and most likely the localization of the error.
Runtime function reference
This chapter lists all functions available to the user.
All run-time functions are defined in the
rtnamespace and exported to the global context (root namespace). You can freely overwrite these exports.
General functions
index ::array ::number
returns an array array element with the given index in form of a bounded reference (see example below). Negative numbers can be used to index from the end.
local T [1 2 3 4 5]print {index T 2} # 3print {index T -2} # 4set {index T 2} 8 # sets T[2] to 8local v {index T 2} # v holds the VALUE 8local r @{index T 2} # r holds a reference to T[2]set v 9 # T[2] is still 8set r 9 # T[2] is now 9
index ::string ::number
returns a character with the given position. Negative numbers can be used to index from the end.
index ::container ::string
returns a container’s member in form of a bounded reference. index a b is equivalent to resolve 'self.'+b a.
length ::array
returns the length of a array
length ::string
returns the length of a string
push ::array [::any…]
adds elements to the end of an array
push ::dispatcher ::function
adds a function to a dispatcher
slice ::array ::number [::number]
see https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/slice
slice ::string ::number [::number]
see https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/String/slice
tostring ::any
returns the passed value converted to a string
find ::array ::any [::number]
see https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf
find ::string ::any [::number]
see https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/String/indexOf
export ::container
copies all elements from a container to the root namespace
export ::container ::string [::string…]
copies specified elements from a container to the root namespace
resolve ::string ::container
evaluates a path in a given context without searching through the given context’s parents. The result is returned in form of a bounded reference.
fullresolve ::string ::container
evaluates a path in a given context. The result is returned in form of a bounded reference.
exists::string ::container
checks if a path is valid in a given context. Returns a boolean value.
lock @::any
locks a variable
islocked @::any
checks if a variable is locked. Returns a boolean value.
istype @::any ::string
checks if a variable is of a given type (or it’s sub-type). Returns a boolean value.
typeof @::any
returns variable’s type as string
nameof ::container
returns container’s identifier as string
print [::any…]
prints values on the console / IDE event log
apply ::function ::array
calls a function with the argument list equal to the given array
arguments
returns current function’s argument list in form of an array
members ::container
returns all member names of a container in form of an array of strings
path ::container
returns a containers full-path in form of a string
atof ::string
converts a string to a number and returns it
concat [::any…]
converts all arguments to strings and returns a single joined string
swap @::any @::any
swaps two variables in-place
Math functions
see https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Math
- math.random
- math.abs ::numeric
- math.ceil ::numeric
- math.floor ::numeric
- math.round ::numeric
- math.sin ::numeric
- math.cos ::numeric
- math.acos ::numeric
- math.asin ::numeric
- math.atan ::numeric
- math.sqrt ::numeric
- math.tan ::numeric
- math.exp ::numeric
- math.log ::numeric
- math.pow ::numeric ::numeric
- math.atan2 ::numeric ::numeric
- math.min [::number…]
- math.max [::number…]
Note that Adventure Script functions raise errors on Infinity and NaN.
Array functions
array.create
returns an empty array
array.wrap [::any…]
returns an array created from the passed arguments (does the same thing as the [ ... ] operator)
array.pop ::array
removes and returns an element from the top
array.shift ::array
removes and returns an element from the beginning
array.unshift ::array ::any
adds element to the beginning
array.clear ::array
clears an array
Game functions
say ::string
displays narration
say ::object ::string
displays dialog line said by an object
show ::object [::boolean=true]
shows an object. If second argument is false doesn’t execute on show.
show ::option
shows an option
hide ::object [::boolean=true]
hides an object. If second argument is false doesn execute on hide.
hide ::option
hides an option
equip ::object [::boolean=true]
equips an object. If second argument is false doesn’t execute on equip.
unequip ::object [::boolean=true]
unequips an object. If second argument is false doesn’t execute on unequip.
enable ::event
enables an event
enable ::namespace ::string [::object]
enables an event in the specified namespace. Third argument is the target object for combine events.
disable ::event
disables an event
disable ::namespace ::string [::object]
disables an event in the specified namespace. Third argument is the target object for combine events.
defineevent ::string [::string [::string [::string] ] ]
defines an object event with the specified name, text, icon and background color
do ::namespace ::string
executes an event in the specified namespace
dialogowner ::dialog
returns the object owning the specified dialog
goto ::any
goes to location / dialog / object screen. This function preforms a long jump.
goback
goes one level up in the dialog tree. This function preforms a long jump.
quit
quits the dialog tree. This function preforms a long jump.