scrimshaw

1.0.0 • Public • Published

scrimshaw

Magical blueprints for procedural generation of content.

Installing

To install, use npm:

npm install scrimshaw

Alternately, you can find the source on Github.

Getting Started

scrimshaw provides the Scrimshaw object. You can require it directly:

var Scrimshaw = require('scrimshaw');

Reference

scrimshaw provides a simple interface that is designed to be extensible. In fact, by itself, the base Scrimshaw won't do very much at all.

Scrimshaw

A Scrimshaw is a plan for building a procedural data object. You define a Scrimshaw "subclass" with static and dynamic members, a list of attributes to export, and an output type to fill with the results.

var Scrimshaw = require('scrimshaw');

// We'll use the Ivoire framework for our randomization,
// but you could use anything:
var Ivoire = require('ivoire');

// A simple NPC
var NPC = function NPC() {};
NPC.prototype.say = function (message) {
  console.log(this.name + " says " + message);
}

var NPCScrimshaw = Ivoire.Scrimshaw.extend({
  export_attributes: [
    'name',
    'sex',
    'job'
  ],

  // Instead of the default vanilla object, make an NPC object. If
  // make_type is a function, it must return the object it is making.
  make_type: function () { return new NPC() },

  // This Ivoire instance isn't in `exported_attributes`, so it won't be copied
  // to the generated object.
  ivoire: new Ivoire(),

  // Static attributes are simple values
  job: "worker",

  // Dynamic attributes are functions
  sex: function () {
    return this.ivoire.pick(['male', 'female'])
  },

  name: function () {

    // We use the special `#get()` function to access other attributes. This
    // ensures that the value we receive will be constant for each instance of the
    // scrimshaw.
    var sex = this.get('sex');

    if (sex == 'male') {
      return this.ivoire.pick(['Joseph', 'Samuel']);
    } else {
      return this.ivoire.pick(['Josie', 'Samantha']);
    }
  }
});

// Pass in an ivoire instance to the generator:
var npc = NPCScrimshaw.generate();

// Or don't, which will give a randomly-seeded NPC:
npc = NPCScrimshaw.generate();
console.log(npc.name, npc.sex);
npc.say("Hello, world!");


// We can extend an existing scrimshaw to make new derived scrimshaws:
var PoliceNPCScrimshaw = NPCScrimshaw.extend({
  job: "police"
});

var police_npc = PoliceNPCScrimshaw.generate();
console.log(npc.name, npc.sex);
police_npc.say("Hello, citizen!");

The base Scrimshaw provides a minimal interface and a pattern for extension. You create a scrimshaw by extending another scrimshaw, or the base Scrimshaw. You specify which "attributes" to export (the export_attributes array) and the type to export the attributes to (make_type, defaulting to {}). Then you define the attributes as static members or dynamic functions. Dynamic attributes can depend on other attributes using the #get() method.

#create()

Syntax

scrimshaw.create()

Usage

#create() will create a new copy of the scrimshaw in question, with a fresh cache.

#export()

Syntax

scrimshaw.export([overrides])

Usage

#export() will evaluate all #exported_attributes and export them to the result of #make_type. #export() is idempotent: because #get() caches the results of dynamic attributes, subsequent calls to #export() should produce identical results.

If an overrides object is provided to #export(), the attributes will be exported from an extended version of the scrimshaw instead. This allows dependent dynamic attributes to be affected by the overrides.

#export(overrides) should be idempotent for subsequent calls with identical overrides.

#extend()

Syntax

scrimshaw.extend(body)

Usage

To create a new scrimshaw, extend an existing one, or the base Scrimshaw object, providing attributes and overrides:

var NPCScrimshaw = Scrimshaw.extend({
  export_attributes: [
    'job'
  ],
  job: "worker"
});

var PoliceNPCScrimshaw = NPCScrimshaw.extend({
  job: "police"
});

var SecretaryNPCScrimshaw = NPCScrimshaw.extend({
  job: "secretary"
})

#generate()

Syntax

scrimshaw.generate([overrides])

Usage

Generate a new make_type, exporting attributes from a new scrimshaw with a fresh cache, and ignoring any existing cache on this scrimshaw.

var RandomScrimshaw = Scrimshaw.extend({
  export_attributes: [
    'foo'
  ],
  foo: function () {
    return Math.random();
  }
});

// Subsequent calls to `#generate()` produce fresh instances.
var bar = RandomScrimshaw.generate();
var baz = RandomScrimshaw.generate();
bar.foo != baz.foo;

If overrides are provided to #generate(), the scrimshaw will be extended with the overrides before exporting its attributes. This allows us to specify, for instance, a custom randomizer object at generation time:

var RandomScrimshaw = Scrimshaw.extend({
  export_attributes: [
    'foo'
  ],

  foo: function () {
    // Note: `ivoire` will be undefined on the unmodified scrimshaw.
    ivoire = this.get('ivoire');
    return ivoire.natural();
  }
});

// Subsequent calls to `#generate()` produce fresh instances.  Supplying
// the `ivoire` object in the overrides satisfies the dependency in `foo`.
var bar = RandomScrimshaw.generate({ivoire: new Ivoire({seed: 42})});
var baz = RandomScrimshaw.generate({ivoire: new Ivoire({seed: 43})});

// If the same seed were used for both calls, the resulting instances would
// have been the same:
bar.foo != baz.foo;

#get(name)

Syntax

scrimshaw.get(name)

Usage

To access a static or dynamic attribute on a scrimshaw, always use #get(). This will work with either a static or dynamic attribute, and will ensure that a dynamic variable remains constant for the scrimshaw instance.

var RandomScrimshaw = Scrimshaw.extend({
  export_attributes: [
    'foo'
  ],
  foo: function () {
    return Math.random();
  }
});

Acknowledgements

The idea for Scrimshaw comes from the "Blueprints" concept developed by Sean Howard, though his ideas are much richer than currently implemented in scrimshaw. I have also developed a similar library for Python, called blueprint.

Dependents (0)

Package Sidebar

Install

npm i scrimshaw

Weekly Downloads

0

Version

1.0.0

License

BSD

Last publish

Collaborators

  • eykd