Pre-release
AdventureJS Docs Downloads
Score: 0 Moves: 0
Tutorial explaining how to work with placeholders in AdventureJS. tutorial, placeholders

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.