Customize Output:Placeholders
Placeholders let authors write dynamic strings without writing code. The
following example prints
"open" or
"closed" depending on the state of the
icy door asset.
MyGame.createAsset({
class: "Door",
name: "icy door",
description: "The icy north door is { icy door [is] open [or] closed }."
});
You can see that the icy door description features a
{placeholder} wrapped in curly braces. Inside the curly braces are several
[conditionals] wrapped in square brackets. In AdventureJS, a {placeholder}
indicates that a string contains dynamic information to be processed, and
[conditionals] provide a very simple form of logic. In this example, the
placeholder { icy door [is] open [or] closed } is roughly
equivalent to this code:
if( MyGame.$("icy door").$is("open")){
return "open";
} else {
return "closed"
};
Types of Placeholders
As the above example shows, placeholders can streamline the process of printing asset states. Several other forms of placeholders are available as well. Expand any item to see examples.
Pronouns and contractions
Use pronoun and contraction placeholders to write text that adapts to the
game's
person
setting. We use plural pronouns as lookup keys for our pronouns table,
because that is the only set of pronouns where every item is unique (for
example, consider our|ours vs his|his). See
Customize Output: Pronouns
to learn more about working with pronouns.
MyGame.createAsset({
class: "Chest",
name: "brass chest",
description: `It's a small but sturdy looking chest bound in brass. `,
is: {
closed: true,
},
dov: {
open: {
on_failure:
`{We} {don't} see a way to do that. `
},
},
});
{we}
Converts to I, we, you, they, he, she, it.
{us}
Converts to me, us, you, them, him, her, it.
{we'd}
Converts to I'd, we'd, you'd, they'd, he'd,
she'd, it'd.
{we've}
Converts to I've, we've, you've, they've, he's,
she's, it's.
{we'll}
Converts to I'll, we'll, you'll, they'll, he'll,
she'll, it'll.
{we're}
Converts to I'm, we're, you're, they're, he's,
she's, it's.
{our}
Converts to my, our, your, their, his, her, its.
{ours}
Converts to mine, ours, yours, theirs, his, hers,
its.
{ourself}
Converts to myself, ourself, yourself,
themself, himself, herself, itself.
{ourselves}
Converts to myself, ourselves, yourself,
themself, himself, herself, itself.
{don't}
Converts to don't or doesn't.
{haven't}
Converts to haven't or hasn't.
{weren't}
Converts to weren't or wasn't.
{have}
Converts to have or has.
{were}
Converts to were or was.
{are}
Converts to are or is.
Conditionals
{ asset [is] property [or] property }
asset is the name of your asset, and the words following
[is] and [or] are properties on the asset, such
as asset.is.open and asset.is.closed. The idea
here is to use matching state properties such as open | closed, locked |
unlocked, sealed | unsealed.
MyGame.createAsset({
class: "Chest",
name: "brass chest",
description: `It's a small but sturdy looking chest bound in brass{ brass chest [is] open [or] closed }. `,
is: {
closed: true,
},
});
{ asset [is] property [then] text }
asset is the name of your asset, and the word following
[is] is a property on the asset, such as
asset.is.open. If the property is true, then the text
following [then] will be printed. If an invalid property is
used, the game will print "unknown state".
MyGame.createAsset({
class: "Chest",
name: "brass chest",
description: `It's a small but sturdy looking chest bound in brass{ brass chest [is] open [then] and lined with yolk colored satin }. `,
is: {
closed: true,
},
});
{ asset [is] property [then] text [else] text }
asset is the name of your asset, and the word following
[is] is a property on the asset, such as
asset.is.open. If the property is true, then the text
following [then] will be printed, otherwise the text
following [else] will be printed. If an invalid property is
used, the game will print "unknown state".
MyGame.createAsset({
class: "Chest",
name: "brass chest",
description: `It's a small but sturdy looking chest bound in brass{ brass chest [is] open [then] and lined with yolk colored satin [else] and sealed with wax }. `,
is: {
closed: true,
},
});
Identify exit by direction
Most assets can be specified in placeholders by their name or id. Exits
don't have names, and though they do have ids, those ids are created at
runtime and aren't shared back with the author. Exits can be identified
simply by providing the direction they exit to. The game's print method
understands that a direction refers to an exit in the current room. So for
example
{ north [is] open [or] closed }.
MyGame.createAsset({
class: "Exit",
direction: "north",
place: { in: "South Room" },
destination: "North Room",
description: `The north exit is { north [is] open [or] closed }. `,
is: {
closed: true,
},
});
Author Variables
Authors may create game variables that are saved within the game scope in
such a way as to be written to saved game files and subject to
undo commands. In this example, we want the chest to have one
description before it's opened, another when it's open, and a third after
it's been opened then closed. These variables can be printed with a
placeholder. See
Basic Scripting: Game Variables
for more info.
MyGame.createAsset({
class: "Chest",
name: "brass chest",
description: `It's a small but sturdy looking chest bound in brass which is currently {chest_state}. `,
doOpen: function () { MyGame.setVar("chest_state", "yawning open") },
doClose: function () { MyGame.setVar("chest_state", "slightly ajar") },
});
MyGame.setVar("chest_state", "tightly shut");
Adverbs
This is a goofy little gimmick we threw in for fun. Use it to add a tiny random element to canned responses.
{ success_adverb }
Randomly pick an adverb from game.dictionary.success_adverbs
MyGame.createAsset({
class: "Chest",
name: "brass chest",
description: `It's a small but sturdy looking chest bound in brass. `,
dov: {
open: {
on_first_success:
`{We} succeed {success_adverb} in opening the chest! `
},
},
});
{ fail_adverb }
Randomly pick an adverb from game.dictionary.failure_adverbs
MyGame.createAsset({
class: "Chest",
name: "brass chest",
description: `It's a small but sturdy looking chest bound in brass. `,
dov: {
open: {
on_failure:
`{We} fail {fail_adverb} to open the chest. `
},
},
});
Further Reference:
Placeholders vs Template Literals
Template literals are a native Javascript ES6 feature. If you're just starting out with AdventureJS and/or Javascript, you may not need to think about this right now. If you're an experienced Javascript user, you may find that placeholders look similar to template literals. However, they are distinctly different.
Placeholders...
- do not have a leading dollar sign {}
- can be placed within any string delimiters including single quotes '...', double quotes "...", or backtick characters `...`
- have no scope to speak of, as they only provide variables to a handler method
- are not evaluated until they are printed to the display
Template literals...
- have a leading dollar sign ${}
- must be placed within backtick `...` characters
- permit active Javascript, scoped to the method they are running in
- are evaluated as soon as they are encountered at runtime
AdventureJS placeholders can be mixed & matched with Javascript template
literals. Placeholders can even be nested inside template literals and vice
versa, because they are evaluated separately. Placeholders can be used in any
string that outputs to the game display. However, template literals must be
returned by functions, rather than stored in string properties, to avoid
errors on game startup by letting them be evaluated too soon. Here's an
example that assumes that
aurora_color stores a string that describes a color:
MyGame.createAsset({
class: "Window",
name: "frosted window",
description: function () {
return `The frosted window
${MyGame.$("frosted window").$is("closed") ?
"is closed, obscuring the aurora. " :
"is open, revealing the {aurora_color} light of the aurora." }`;
},
});
To learn more about template literals, we recommend the MDN reference library.