Skip to content
Alex Komoroske edited this page Nov 14, 2021 · 31 revisions

Basic Design

Simulations consist of input parameters, which are fed to a simulation function that then splits out an array of runs. Each run is one run of the simulation, and consists of one or more frames. Frames are the individually renderable frames that might plausibly be output in an animation.

A simulation has a few things it does:

  • A generator function which takes the simOptions object, a seedValue, and a runIndex and produces a run. Given the same inputs it should deterministically produce the same resulting run. The harness will call this n times to generate n runs. It will generate a seed based on concatenating the overall options object's seed with the run number. If the overall options object has an undefined seed then it will generate a new seed at the start of every sim based on the current time. The frame output is a plain old javascript object, and its shape will be specific to this simulator.
  • A renderer, which is a custom element that will be provided its frame object via a frame property.
  • A frame scorer, which given a frame returns the 'score' of that frame. The score is an array of numbers that should vary between 0 and 1.0 (the specific length of the array is specific to the simulation, but will typically be 1). The score for the final frame is the score for the overall run.
  • An options validator, which is given the simOptions and returns an array of strings describing problems in the configuration, or null or an empty array if the simOptions are valid
  • A frame validator, which given a frame and the simOptions returns an array of strings describing problems in the frame, or null or an empty array if the frame is valid
  • A success scorer, which takes a run score and decides if it should be considered success, failure, or indeterminate. It does this by returning a number. 0.0 is considered full failure, 1.0 is considered full success, and negative numbers are considered indeterminate. The harness will consider any run that is not 1.0 to be a failure.
  • A simOptions config that returns the names, allowed values, and description of each field

The harness renders additional UI, for example controls to vary the inputs to the simulation. It also provides affordances to snapshot runs of the simulation into pngs and gifs, and renders each run in a summary pane with animation controls for it.

{
  "seed": "abc",
  "size": [350, 400],
  "n": 10,
  "colors": {
    "primary": "#CCFF00",
    "secondary": "rgba(255,200,100,0.1)"
  },
  "sim": "schelling-org",
  "simOptions": {
    //Simulator specific options
  }
}

schelling-org

The first simulator type is schelling-org. It renders orange boxes for options, each with an error bar, and either a web of individuals, each of whom makes a choice, or a flat list of individuals with walls between. The individuals are rendered as emojis.

The simOptions for schelling-org look like:

{
  "collaborators": {
    "seed": 345,
    "n": 8,
    "communication": true,
  },
  "projects": {
    "seed": "abcd",
    "n": 4,
    "averageValue": 0.5,
    "averageError": 0.25,
  }
}

Collaborators and projects can have a seed parameter. If set, then instead of using the global generator seed provided it will use that seed. This is useful for randomizing other things but keeping the initial bit of the projects and collaborators consistent from run to run.

Renderers

The renderers should be factored nicely to make common things (like webs of individuals with some state) easy to render.

The harness also creates css-variables with certain colors, e.g. --primary-color and --secondary-color

The harness also renders out controls that allow changing all options of the options object,including simOptions. If there is a "seed" property it renders as a dice roll icon.

Clone this wiki locally