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

Advanced Scripting:Ad Hoc Functions

An ad hoc function is when an author writes their own Javascript function that works outside of AdventureJS's common methods. Authors are welcomed, even encouraged, to write their own ad hoc functions.

Ad hoc functions can be defined anywhere in your game code. Just be sure that you define it in a way that it is accessible from where you want to call it. The code sample below shows several ad hoc functions that work in concert with AdventureJS functions. The room in this example is kind of unusual – we're using one room to pretend to the player that it is multiple rooms – so we're using ad hoc functions to create more complex dynamic descriptions.


// Our randomDirection() function returns a random direction.
// It, in turn, calls an AdventureJS utility function. 
// A.pickRandom() takes an array of strings and returns one item.
const randomDirection = function () {
  return A.pickRandom([
    "north",
    "northeast",
    "northwest",
    "east",
    "west",
    "south",
    "southeast",
    "southwest",
  ]);
};

// randomLostPhrase() takes it one step further. 
// It calls randomDirection(), which in turn calls
// A.pickRandom()
// We're nesting randomization calls to build phrases
// with more variety.
const randomLostPhrase = function () {
  return A.pickRandom([
    `It's all but impossible to pinpoint a direction. Is there some clearing to the ${randomDirection()}? `,
    `{We} can't get {our} bearing in the storm. Is that the shadow of a camel to the ${randomDirection()}?`,
    `{We're} completely disoriented. Is there a figure to the ${randomDirection()}?`,
  ]);
};

// stagger() does more of the same
const stagger = function (direction) {
  return A.pickRandom([
    `{We} stagger into the scouring winds, in what {we} hope is a ${direction} direction. `,
    `{We} try to creep forward in what seems to be a ${direction} direction. `,
    `{We} hunch into the disorienting wind in a ${direction} direction.`,
    `{We} struggle against the winds in what may be a ${direction} direction. `,
    `{We} slide in the sands, trying to move in a ${direction} direction. `,
    `{We} stumble, and fall, and catch {ourself}, and keep going, hopefully in a ${direction} direction. `,
  ]);
};

// now we're ready to use our ad hoc functions to create 
// a room with complexly randomized descriptions

DesertDrifter.createAsset({
  class: "Room",
  name: "Lost in a Sandstorm",
  contains: "sand", // shortcut to fill a room with sand
  descriptions: {
    // descriptions.firstlook is only shown the first time
    // a room is seen 
    firstlook: function () {
      return `Within a few short steps, the ferocious winds have buffeted {us} and blinded {us} and deafened {us}, pushing {us} from the relative safety of the camel string and stripping {us} of any sense of direction. `;
    },
    look: function () {
      return A.pickRandom([
        `The ferocious winds continue to buffet, blind and deafen {us}, pushing {us} deeper from safety. `,
        `The storm hits {us} in the face like an open blast furnace. {We} squint into the heat but can't make out any features. `,
        `Sheets of blown sand obscure any possible landmarks. What little you can see vibrates with heat haze. `,
        `{We} can barely see through the rimes of sand encrusting {our} eyelids. `,
      ]);
    },
    listen: `Room descriptions sound. `,
    exits: function () {
      return randomLostPhrase();
    },
  },

  // We define every exit from the room so that all directions
  // appear to be possible exits. When an exit has a description
  // but no destination, AdventureJS prints the description 
  // when a player tries to use the exit. 
  // Most of our directions call the ad hoc methods we established.
  exits: {
    down: `{We} try digging a scrape to lay in against the storm, but the winds blow the sands back at us faster than {we} can dig. `,
    up: `Would that we could flee the storm on an ebony horse like Prince Achmed. Alas, {we} are firmly grounded. `,
    east: {
      destination: "Lost in a Sandstorm",
      descriptions: { travel: stagger("easterly") },
    },
    west: {
      destination: "Lost in a Sandstorm",
      descriptions: { travel: stagger("westerly") },
    },
    north: {
      destination: "Lost in a Sandstorm",
      descriptions: { travel: stagger("northerly") },
    },
    northeast: {
      destination: "Lost in a Sandstorm",
      descriptions: { travel: stagger("northeasterly") },
    },
    northwest: {
      destination: "Lost in a Sandstorm",
      descriptions: { travel: stagger("northwesterly") },
    },
    south: {
      destination: "Lost in a Sandstorm",
      descriptions: { travel: stagger("southerly") },
    },
    southeast: {
      destination: "Lost in a Sandstorm",
      descriptions: { travel: stagger("southeasterly") },
    },
    southwest: {
      destination: "Lost in a Sandstorm",
      descriptions: { travel: stagger("southwesterly") },
    },
  },

  // By contrast, area_events and area_scenery rely on the 
  // built-in getStringArrayFunction() method – which is called
  // automatically in certain contexts –
  // to provide a random item from an array of strings.
  // Contrast this to the ad hoc functions above. This is
  // the easier way to do it, but it doesn't work well with
  // Javascript template literals due to issues of scope.
  area_events: {
    frequency: 0.5,
    randomize: true,
    array: [
      `The harsh winds buffet {us}, nearly pushing {us} from {our} feet. `,
      `{We} stagger beneath the crushing winds. `,
      `The bitter winds whip at {us}. `,
      `A sudden gust whips sand up into {our} robes. `,
      `{Our} eyes burn with grit. `,
      `The wind shrieks like a ghūl in {our} ears. `,
      `{Our} ears are congested with fine sand. Did {we} hear a child's cry? `,
      `{We} choke on the thick air, and wrap a fold of {our} robe across {our} mouth. `,
      `The deafening wind fills {our} ears. Or is that the roar of {our} own blood? `,
    ],
  },

  area_scenery: {
    wind: {
      enabled: true,
      descriptions: {
        feel: {
          randomize: true,
          array: [
            `The wind scours the little bit of exposed skin on {our} face. `,
            `The wind stings every part of {us} that it can reach. `,
            `The wind burns and abraids {our} exposed skin. `,
          ],
        },
        look: {
          randomize: true,
          array: [
            `The wind blows sheets of sand across {our} view. `,
            `All {we} can see is the sand whipping around {us}. `,
            `The windblown sand obscures all visibility. `,
          ],
        },
        listen: {
          randomize: true,
          array: [
            `The wind shrieks like a ghūl. `,
            `The wind roars in {our} ears. `,
            `The wind growls and rumbles like a jungle full of cats. `,
          ],
        },
      },
    },
    sound: {
      enabled: true,
      description: {
        randomize: true,
        array: [
          `The wind's brutal growl is almost deafening. `,
          `The harsh screech of the wind fills {our} ears. `,
          `{We} only wish {we} could shut {our} ears to it. `,
          `It's a terrifying, relentless howl. `,
        ],
      },
    },
  },
});

>

Further reference

Learn more about game.getStringArrayFunction()

What are Javascript template literals?

What is scope?