2012-12-14

How to use Parameters and Variables in Custom Twine Macros

The last article looked at basic macros in Twine. We'll expand on that article by looking at parameters and using an internal variable. First the code example:

try {
  version.extensions['recallMacro'] = { major:1, minor:0, revision:0 };
  macros['recall'] = {
    handler: function(place, macroName, params, parser) {
      if(params.length > 0) {
        this.m = params[0];
      }
      new Wikifier(place, this.m);
    },
    init: function() {
      this.m = "A blank slate";
    },
    m: null,
  };
} catch(e) {
  throwError(place,"recall Setup Error: "+e.message); 
}

Let's go through the code a piece at a time (not necessarily in written order).

try {
  version.extensions['recallMacro'] = { major:1, minor:0, revision:0 };
  macros['recall'] = {
    ...
  };
} catch(e) {
  throwError(place,"recall Setup Error: "+e.message); 
}

This is boilerplate code that is explained in the last article.

    init: function() {
      this.m = "A blank slate";
    },
    m: null,

This code declares a variable as part of the macro called "m". Throughout the macro we refer to this variable using this.m. The variable is declared within the macro to avoid polluting the global namespace and to avoid variable name clashes there. Note that m is declared with an initial value of null and the value of m is set within the init() method. This practice makes the macro work better if the story is restarted without refreshing the page.

    handler: function(place, macroName, params, parser) {
      if(params.length > 0) {
        this.m = params[0];
      }
      new Wikifier(place, this.m);
    },

This code checks the length of the params array. If there is something in the params array then the first parameter is saved into this.m. In all cases the contents of this.m are printed.

Once you have added this macro to your story then try adding the following tweecode to a passage in your story:

Initial state: <<recall>>
Store John: <<recall John>>
Store Ben: <<recall Ben>>
What is stored?: <<recall>>

Using parameters and variables in Twine macros is a great way to increase the power of the macro. Storing variables as properties inside the macro object avoids any name clashes with other macros.