scene:change { scene }
Moves the player.
- type: scene:change
data: { scene: cellar }
The engine has four key building blocks, and they make up most of what a Stage game does. Learn just these and you'll already be most of the way there.
Triggers are things that happen, such as rendering a response to the player, adjusting a measure, adding an object to the inventory and more.
Every name is the thing it acts on, then what it does to it, so the triggers that belong together sit together. The one exception is response, which is just the game talking.
scene:change { scene }Moves the player.
- type: scene:change
data: { scene: cellar }
inventory:add { object, announce? }Gives the player an object.
- type: inventory:add
data: { object: brass-key, announce: true }
inventory:remove { object }Takes it from their hands, leaving it in the room.
- type: inventory:remove
data: { object: brass-key }
object:move { object, to, announce? }Puts an object in a scene, inventory, offstage, bin, held: somebody, or here. With object: player it takes the player to a room instead, which is handy when a character shoves them somewhere.
- type: object:move
data: { object: lantern, to: offstage }
object:remove { object }Throws an object away, into the bin.
- type: object:remove
data: { object: letter }
object:move-tagged { tag, from, to, announce? }Moves everything carrying a tag from one place to another in one firing.
- type: object:move-tagged
data: { tag: wet, from: cellar, to: bin }
flag:set { flag, value? }Sets a flag, defaulting to true.
- type: flag:set
data: { flag: door-unlocked }
response { text }Says something to the player.
- type: response
data: { text: "The door creaks open." }
game:end { journal? }Ends the game, and says what it's remembered as.
- type: game:end
data: { journal: "Escaped the house before dawn." }
game:save { name? }Keeps the playthrough, once the turn is over.
- type: game:save
data: { name: before-the-cellar }
measure:adjust { subject, measure, by? | to? }Moves a measure, or sets it outright.
- type: measure:adjust
data: { subject: player, measure: health, by: -1 }
achievement:unlock { id }Unlocks a credit that outlives the playthrough.
- type: achievement:unlock
data: { id: first-escape }
journal:logWrites down that the player tried, even where whatever gated it turned them back.
- type: journal:log
character:obeyOnly in an ordered action: the moment the character does what they were told, the way the player would. Triggers before it happen first, triggers after it afterwards. Once per list.
- type: character:obey
turn:pass { count }Makes what the player did take that many turns, so everything that happens each turn happens that many times.
- type: turn:pass
data: { count: 3 }
sound:play { id }Plays one of the game's sounds, once, or until it's stopped if it loops. Games written before it was renamed call it audio:play, which still works.
- type: sound:play
data: { id: rain }
sound:stop { id }Stops a looping sound. Its older name, audio:stop, still works too.
- type: sound:stop
data: { id: rain }
image:show { id }Shows one of the game's images, until something hides it.
- type: image:show
data: { id: cellar }
image:hide { id }Hides a image.
- type: image:hide
data: { id: cellar }
A condition is a way to gate against a trigger happening, either game state or chance. The conditions field is a list of them,
and every one must match before the subsequent Triggers will fire. The first to fail is the one whose failure path is activated.
Conditions are named the same way as triggers: the thing being asked about, then the question. chance, any-of and all-of keep their short names, because they don't ask about anything in particular.
inventory:has { object }Matches when the object is in the inventory.
- type: inventory:has
data: { object: brass-key }
object:here { object }Matches when the object is carried or in the current scene.
- type: object:here
data: { object: lantern }
character:here { character }Matches when the character is in the current scene and can be seen there.
- type: character:here
data: { character: groundskeeper }
character:obeying { character }Matches when that character is doing this because they were told to. character: player matches whenever nobody else is carrying out an order, which is every ordinary turn. Handy for a button only the robot can reach.
- type: character:obeying
data: { character: robot }
object:in { object, location }Matches when the object is in location: a scene id, inventory, offstage, bin, held: somebody (held:player for the player), or in: something.
- type: object:in
data: { object: lantern, location: cellar }
object:handled { object }Matches when the player has had the object in their hands at some point, carried now or not.
- type: object:handled
data: { object: letter }
flag:is { flag, value? }Matches when the flag equals value, or is truthy when value is omitted.
- type: flag:is
data: { flag: door-unlocked }
scene:visited { scene?, times? }Matches when the scene has been entered at least times (default 1).
- type: scene:visited
data: { scene: cellar, times: 2 }
scene:is { id? } or { tag? }Matches when the player is standing in that room, or in any room declaring that word.
- type: scene:is
data: { tag: outdoors }
action:performed { object?, action?, preposition?, indirect?, scene?, times? }Matches when a matching action has fired at least times (default 1).
- type: action:performed
data: { action: open, object: door }
measure:within { subject, measure, min?, max? }Matches when the measure stands within the bounds given, each inclusive.
- type: measure:within
data: { subject: player, measure: health, max: 2 }
inventory:within { of?, min?, max? }Matches when what the player is holding stands within the bounds given.
- type: inventory:within
data: { max: 3 }
object:tagged { tag, location }Matches when something carrying the tag is at location - the same places object:in reads.
- type: object:tagged
data: { tag: wet, location: cellar }
chance { name, of, index, no-repeat? }Is luck with you? Each pass uses name, of and index, which can be either a number, an array of numbers or a spread ([1..5], one through five). If you want the condition to only fire once if there's a match, use no-repeat: true.
- type: chance
data: { name: thunder, of: 6, index: 1 }
any-of { conditions }Matches when at least one of the conditions matches.
- type: any-of
data:
conditions:
- type: flag:is
data: { flag: door-unlocked }
- type: inventory:has
data: { object: brass-key }
all-of { conditions }Matches when every one of the conditions matches.
- type: all-of
data:
conditions:
- type: flag:is
data: { flag: door-unlocked }
- type: inventory:has
data: { object: brass-key }
A measure is a number that belongs to the player or to a thing and can move during
play - health, how full a lamp's oil is, whatever your game needs to keep count of.
It's bounded rather than open-ended: give it a min and a max, and a start to
begin a playthrough at, and Stage keeps it inside those bounds for you.
id string, requiredWhat the measure is called.
min numberThe lowest it can fall to.
max numberThe highest it can rise to.
start numberWhat it begins a playthrough at.
thresholds Threshold[]Triggers that fire the moment it crosses into a new range.
A game can carry its own sounds: a creak when a door opens, rain while the player's
outside. You list them once, in your game's sounds file, [id].game.sounds.yml, and play them
by id with a sound:play trigger wherever something happens. Stage packs each file into the
game, so it plays wherever the game's played.
- id: creak
file: sounds/creak.wav
- id: rain
file: sounds/rain.ogg
loop: true
The file is the list of sounds itself, and each one takes these fields:
id string, requiredWhat triggers call the sound.
file string, requiredWhere the file is, from the top of your game's folder: a WAV, Ogg or MP3.
loop booleanKeeps it playing until a sound:stop ends it, and through a save and a load.
A game can carry images too: a room as the player walks in, a face when somebody speaks. You
list them once, in your game's images file, [id].game.images.yml, and show one by id with an
image:show trigger. Every image needs an alt, which says what it shows for a player
who can't see it. For an image that's only decoration, write alt: '', empty quotes, rather than
leaving it out.
- id: garden
file: images/garden.png
alt: A walled garden, four beds of flowers either side of a pale path.
The file is the list of images itself, and each one takes these fields:
id string, requiredWhat triggers call the image.
file string, requiredWhere the file is, from the top of your game's folder: a PNG, JPEG or WebP.
alt string, requiredWhat the image shows, in words, or '' for decoration.
An action is a thing that can be done to an object, a character, a room, the player or the game
itself - gates and then a list. It's usually the player doing it. conditions and once are the gates, each saying why
it refused; triggers is what happens when every gate has let the player through,
prose included.
id string, requiredThe id of the verb this answers to.
preposition stringThe significant preposition this answers to, such as the under in "look under"; omit for the plain form.
indirect stringThe id of the second object or topic required; omit to accept any.
conditions Condition[]What must be true first - see Conditions
once blockPresent to fire only the first time; its failure is what later attempts get.
triggers Trigger[]Everything that happens when it works - see Triggers