Pre-release
AdventureJS Docs Downloads
Score: 0 Moves: 0
Tutorial explaining how to use dispensaries in AdventureJS. tutorial, dispensary, dispenser, dispenses

Basic Scripting:Dispensaries

The dispensary system allows one tangible asset to dispense instances of another class. For instance, allowing a user to take individual grapes from a bunch of grapes; one nut from a bag of nuts; one marble from a sack of marbles; one piece of chicken from a bucket; etc. Dispensaries are meant for small fungible tangible things like grains of sand or pebbles or coins or fruits. Any tangible asset can be a dispenser and any tangible class can be dispensed.

TMI Wait, any tangible class?

Well, we say any, and technically that's true. The dispensary system was made to support small fungible tangible things, and you could try, if you wanted, to dispense doors or walls or exits, which are all tangible. We haven't placed any guardrails or error checking around this feature and technically there's nothing stopping you doing it, though you might not find the results useful. Caveat emptor, is all we're saying.

Example

In the following example we show a custom Pistachio class being set up as a dispensary, and a nut sack asset to dispense pistachios.

MyGame.createClass({
  class: "Pistachio",
  extend: "Edible",
  singular: "pistachio",
  plural: "pistachios",
  description: `It's a pistachio. `,

  // We set the dispensary property of the class 
  // that gets dispensed. 
  dispensary: {
    
    // max_extant is the maximum number of dispensed assets  
    // that can be active at the same time
    // Set it, for example, to 1, or 3, or -1 for infinity.
    // Be careful with infinite dispensers though.
    max_extant: 1,

    // max_count is the maximum number of assets that can be 
    // dispensed from this asset, forever.
    // Set it, for example, to 10, or 100, or -1 for infinity.
    max_count: 5,
  },
  doEat: function () {
    // move into limbo
  },
  doDrop: function () {
    // move into limbo
  },
  doTake: function () {
    // move single pistachio into player
  },
});

MyGame.createAsset({
  class: "Luggage",
  name: "nut sack",
  place: { in: "Hero" },
  synonyms: ["nutsack",],
  description: `A small pouch containing a handful of pistachios. `,
  // dispensers exist within aspects
  // if a player takes a pistachio, it will come from in the nut sack
  aspects: { in: { dispense: "Pistachio" } },
});
TMI Under the hood

The AdventureJS parser compares input against items in the game to decide whether or not the particular words that were input are "known". In other words, in order for an asset to be pulled out of the aether, there must first be an instance of it in the world. So, when a dispensary is defined, a platonic instance of that class is created: a special asset that the player has no access to, that only exists to make the class's synonyms findable.

This method is admittedly slightly hacky. In theory, we could alternately have done this by exposing class names to be compared against player input, but that way quickly lead to bigger complications, and this way fit the model we were already using, so there you go.