ScriptBind.js

From Spheriki

Jump to: navigation, search

IMPORTANT: ScriptBind.js has been superseded by persist.js. If you're making a new game, use persist.js instead of this.

ScriptBind.js is a module that helps organise the development of RPGs in Sphere in two ways:

  1. Links maps to script files automatically by file name.
  2. Allows maps and persons to have local variables.


Contents

Usage

Download the script and install like other custom scripts. Then include it:

RequireScript("ScriptBind.js");

Call the initialisation in your game() function:

function game() {
  ScriptBind.start();
  // ...
}

Organising maps

Whenever you make a map, you will need to make a matching script in scripts/maps/, e.g. a map FunkyTown.rmp would have a script named scripts/maps/FunkyTown.js.

Map scripts

A map script is a JavaScript object expression. An empty one (though useless) looks like this:

({});

Maps have standard members that are automatically triggered by ScriptBind. See the API for standard map functions.

Adding map events

Just add one or more of the standard map functions as so (TextBox.display() is a fake function, BTW):

({
  mapEnter: function () {
    TextBox.display("The town of Blah");
  },
  mapLeaveEast: function () {
    ChangeMap("Glurp.rmp");
    SetPersonX(GetInputPerson(), 8);
  }
});

If you like, you can space it out in the file instead:

function mapEnter() {
  TextBox.display("The town of Blah");
}

function mapLeaveEast() {
  ChangeMap("Glurp.rmp");
  SetPersonX(GetInputPerson(), 8);
}

({
  mapEnter: mapEnter,
  mapLeaveEast: mapLeaveEast
});

Adding persons

Persons are also members inside the map scripts, but they're objects rather than functions. Their names need to match in the map and in the script:

({
  mapEnter: function () {
    TextBox.display("The town of Blah");
  },
  mapLeaveEast: function () {
    ChangeMap("Glurp.rmp");
    SetPersonX(GetInputPerson(), 8);
  },
  
  /**
   * Dude_1
   */
  Dude_1: {
  }
});

You can add events to your person:

  /**
   * Dude_1
   */
  Dude_1: {
    talk: function () {
      TextBox.display("d00d");
    }
  }

Here's an alternative form that some may prefer:

function mapEnter() {
  TextBox.display("The town of Blah");
}

function mapLeaveEast() {
  ChangeMap("Glurp.rmp");
  SetPersonX(GetInputPerson(), 8);
}

/**
 * Dude_1
 */
function Dude_1() {
  function talk() {
  }
  
  return {
    talk: talk
  };
}

({
  mapEnter: mapEnter,
  mapLeaveEast: mapLeaveEast,
  
  Dude_1: Dude_1()
});

Giving your persons state

Instead of a plain JavaScript object, we can create and call a function that returns an object instead.

  /**
   * Dude_1
   */
  Dude_1: (function () {
    return {
      talk: function () {
        TextBox.display("d00d");
      }
    };
  })()

This is just a more complex form of this:

(function () {/* lol code */})();

We can add a variable and use it:

  /**
   * Dude_1
   */
  Dude_1: (function () {
    var talked_to = false;
    
    return {
      talk: function () {
        if (!talked_to) {
          TextBox.display("d00d");
          talked_to = true;
        } else {
          TextBox.display("We already chilled.");
        }
      }
    };
  })()

If we want to have the person remember that he was spoken to, we need to save and load the variable.

  /**
   * Dude_1
   */
  Dude_1: (function () {
    var talked_to = false;
    
    return {
      save: function () { return {talked_to: talked_to}; },
      load: function (state) { talked_to = state.talked_to; };
      talk: function () {
        if (!talked_to) {
          TextBox.display("d00d");
          talked_to = true;
        } else {
          TextBox.display("We already chilled.");
        }
      }
    };
  })()

If you'd prefer that things be more readable, the following can be used instead:

/**
 * Dude_1
 */
function Dude_1() {
  var talked_to = false;
  
  function save() {
    return {
      talked_to: talked_to
    };
  }
  
  function load(state) {
    talked_to = state.talked_to;
  }
  
  function talk() {
      if (!talked_to) {
        TextBox.display("d00d");
        talked_to = true;
      } else {
        TextBox.display("We already chilled.");
      }
  }
  
  return {
    save: save,
    load: load,
    talk: talk
  };
}

Giving a map state

Instead of this pattern:

({
  // map events
  // persons
});

Use this:

(function () {
  // local variables/functions
  
  return {
    save: function () { return {/* stuff to save */}; },
    load: function (state) { /* reload stuff from state */ },
    // map events
    // persons
  };
})();

Here's an example: it shows a welcome message once when entering the map, and then never again.

(function () {
  var been_here = false;
  
  return {
    save: function () { return {been_here: been_here}; },
    load: function (state) { been_here = state.been_here; },
    mapEnter: function () {
      if (!been_here) {
        TextBox.display("Welcome to the Town of Blah!");
        been_here = true;
      }
    }
  };
})();

This example can also be spaced out, instead of using the above form:

var been_here = false;

function save() {
  return {
    been_here: been_here;
  };
}

function load(state) {
  been_here = state.been_here;
}

function mapEnter() {
}

({
  save: save,
  load: load,
  mapEnter: mapEnter
});


API

Functions

  • ScriptBind.start() - Begins automatic script binding. Call this first. Warning: Overrides any default map scripts.
  • ScriptBind.stop() - Stops automatic script binding. Not compulsory. Warning: Overrides any default map scripts.
  • ScriptBind.saveState() - Refreshes the state of the world, saving person and map variables. Call this before saving your game.
  • ScriptBind.setPathPrefix(prefix) - Change the location to look for map scripts. Default is ../scripts/maps/.
  • String ScriptBind.getPathPrefix() - Obtain the current path prefix.
  • ScriptBind.setStrictness(boolean) - Go into strict mode. Defaults to false. In strict mode, any functions that ScriptBind expects in a map script which aren't found will raise a JavaScript exception.
  • boolean ScriptBind.isStrict() - Returns true if ScriptBind is in strict mode.

Function hooks

By default, ScriptBind saves all world state in ScriptBind.world. This behaviour can be overridden by assigning new functions to these hooks.

  • ScriptBind.loadMapState(mapName) - Called after a map has been loaded, but before the mapEnter script.
  • ScriptBind.saveMapState(mapName, mapState) - Called before a map is left, but after the mapLeave scripts.
  • ScriptBind.loadPersonState(mapName, personName) - Called after a person is created, but before their create script.
  • ScriptBind.savePersonState(mapName, personName, personState) - Called before a person is destroyed, but after their destroy script.

Hopefully, the arguments should be obvious. You may substitute these functions for your own if you wish, so long as they have the same function signature i.e. same arguments.

Variables

  • ScriptBind.world - A JavaScript object containing the state of the world, all maps and all persons. Has the following member structure:
    • state - Object. Empty so you can place world variables in it as members.
    • maps - Object. Holds all maps as members in a dictionary by map name. (ScriptBind.world.maps[mapName])
      • state - Object. Holds the state for the one map.
      • persons - Object. Holds all persons as members in a dictionary by person name. (ScriptBind.world.maps[mapName].persons[personName]).
      • Each member of persons is accessed by name of a person, and holds the state directly.

The state of the world can be accessed by:

ScriptBind.world.state

The state of a map can be accessed by:

ScriptBind.world.maps["MyMap"].state

The state of a person on a map can be accessed by:

ScriptBind.world.maps["MyMap"].persons["MyPerson"]

Note that persons store their state directly, not in a "state" member.


Standard map functions

Most of these functions map directly to map scripts.

  • mapEnter() - Function. Called when the map is entered.
  • mapLeave() - Function. Called when the map is left for any reason, including termination of the map engine.
  • mapLeaveNorth(), mapLeaveEast(), mapLeaveSouth(), mapLeaveWest() - Function. Called when the input person leaves the map on the north, east, south and west edges respectively.
  • Object save() - Function. Called when the map state should be saved. Only useful with a closure.
  • load(state) - Function. Called when the map state can be loaded. Only useful with a closure.

Standard person functions

Most of these functions map directly to person events.

  • create() - Function. Called after the person is created.
  • destroy() - Function. Called before the person is destroyed.
  • talk() - Function. Called when the person is talked to by the input person.
  • touch() - Function. Called when the person is touched by the input person.
  • generator() - Function. Called for every map update for which the person's command queue is empty.
  • Object save() - Function. Called when the person state should be saved. Only useful with a closure.
  • load(state) - Function. Called when the person state can be loaded. Only useful with a closure.


External links


See also

Personal tools