Example Creature Definition

Every creature has a JSON configuration file that defines everything about it — what servos it has, how they’re wired up, what voice it uses, and how the joystick maps to its movements. This file is read by the Controller at startup and uploaded to the Creature Server, so the server and Console always know the active configuration.

Here’s Beaky’s current definition as an example:

{
  "name": "Beaky",
  "id": "4754fc0e-1706-11ef-931d-bbb95a696e2e",
  "version": "0.1.0",
  "description": "The lead at April's Creature Workshop!",
  "channel_offset": 1,
  "audio_channel": 1,
  "universe": 2,
  "mouth_slot": 4,
  "position_min": 0,
  "position_max": 1023,
  "head_offset_max": 0.4,
  "servo_frequency": 50,
  "type": "parrot",
  "voice": {
      "voice_id": "Nggzl2QAXh3OijoXD116",
      "model_id": "eleven_turbo_v2_5",
      "stability": 0.3,
      "similarity_boost": 0.72
  },
  "speech_loop_animation_ids": [
    "87450ac7-4947-4078-a049-13dd767708df",
    "4ee4ea7a-029e-4015-ae8f-84247c92dee6"
  ],
  "idle_animation_ids": [
      "0282df2c-ec7f-4869-8a09-43216e3bd715",
      "ea849c1f-e81e-4877-ad4f-b3af827aedc6"
  ],
  "motors": [
    {
      "type": "servo",
      "id": "neck_left",
      "name": "Neck Left",
      "output_header": 0,
      "output_module": "A",
      "min_pulse_us": 800,
      "max_pulse_us": 2250,
      "smoothing_value": 0.90,
      "inverted": true,
      "default_position": "center"
    },
    {
      "type": "servo",
      "id": "neck_right",
      "name": "Neck Right",
      "output_header": 1,
      "output_module": "A",
      "min_pulse_us": 800,
      "max_pulse_us": 2250,
      "smoothing_value": 0.90,
      "inverted": false,
      "default_position": "center"
    },
    {
      "type": "servo",
      "id": "neck_rotate",
      "name": "Neck Rotate",
      "output_header": 2,
      "output_module": "A",
      "min_pulse_us": 650,
      "max_pulse_us": 2500,
      "smoothing_value": 0.80,
      "inverted": true,
      "default_position": "center"
    },
    {
      "type": "servo",
      "id": "body_lean",
      "name": "Body Lean",
      "output_header": 4,
      "output_module": "A",
      "min_pulse_us": 1200,
      "max_pulse_us": 1800,
      "smoothing_value": 0.96,
      "inverted": true,
      "default_position": "min"
    },
    {
      "type": "servo",
      "id": "beak",
      "name": "Beak",
      "output_module": "A",
      "output_header": 3,
      "min_pulse_us": 1900,
      "max_pulse_us": 2700,
      "smoothing_value": 0.4,
      "inverted": false,
      "default_position": "min"
    }
  ],
  "inputs": [
    {
      "name": "head_tilt",
      "slot": 2,
      "width": 1,
      "joystick_axis": 2
    },
    {
      "name": "head_height",
      "slot": 3,
      "width": 1,
      "joystick_axis": 3
    },
    {
      "name": "neck_rotate",
      "slot": 0,
      "width": 1,
      "joystick_axis": 0
    },
    {
      "name": "stand_rotate",
      "slot": 1,
      "width": 1,
      "joystick_axis": 1
    },
    {
      "name": "body_lean",
      "slot": 5,
      "width": 1,
      "joystick_axis": 5
    },
    {
      "name": "beak",
      "slot": 4,
      "width": 1,
      "joystick_axis": 4
    },
    {
      "name": "chest",
      "slot": 7,
      "width": 1,
      "joystick_axis": 7
    }
  ]
}

Top-Level Fields

The top of the file identifies the creature and sets up how it fits into the network.

  • name and id — The creature’s display name and its UUID. The ID is what everything in the system uses internally.
  • channel_offset — Where this creature’s DMX channels start within its E1.31 universe. Multiple creatures can share a universe as long as their channels don’t overlap.
  • audio_channel — Which audio output channel the server uses for this creature’s speech.
  • universe — The E1.31 (sACN) universe this creature lives on.
  • mouth_slot — Which input slot corresponds to the beak/mouth. The server uses this to know which channel to write lip sync data to.
  • position_min / position_max — The range of values used in animations. Positions are stored as integers from 0 to 1023 and mapped to the servo’s pulse width range at playback time.
  • head_offset_max — How much random head movement to add during idle animations, as a fraction of the total range. This keeps the creature from looking too robotic when looping.
  • servo_frequency — PWM frequency in Hz. Standard hobby servos expect 50Hz.
  • type — The creature type (e.g. “parrot”). Used by the Console for display purposes.

Voice

The voice block tells the server how to generate speech for this creature via ElevenLabs. Each creature has its own voice with tuned settings for how it should sound.

  • voice_id — The ElevenLabs voice to use.
  • model_id — Which ElevenLabs model to use for synthesis.
  • stability — Lower values make the voice more expressive and varied. Beaky’s is set pretty low (0.3) because she’s dramatic.
  • similarity_boost — How closely to match the original voice sample.

Animation Lists

Creatures have two pools of animations that the server draws from automatically:

  • speech_loop_animation_ids — Animations that play while the creature is speaking. These are short loops of natural-looking movement that make the creature look alive while it talks. The beak channel is overridden with lip sync data.
  • idle_animation_ids — Animations that play when the creature isn’t doing anything else. The server picks from this list and loops through them to keep the creature moving.

Motors

The motors array defines every servo in the creature. This is what the Creature Controller hardware uses to know how to drive each motor safely.

  • type — The motor type. Currently "servo" for PWM servos, but also supports "dynamixel" for Dynamixel smart servos.
  • id — A machine-readable identifier used in animations and code.
  • output_module / output_header — Which controller board module (A, B, C, or D) and which pin on that module this servo is connected to.
  • min_pulse_us / max_pulse_us — The absolute minimum and maximum pulse widths in microseconds that this servo is allowed to reach. This is a safety measure to prevent the servo from being driven past its mechanical limits and damaging the creature.
  • smoothing_value — A value from 0 to 1 that controls how much the servo’s movement is smoothed. Higher values mean slower, smoother motion. Beaky’s body lean is set to 0.96 because it’s a large, heavy movement that should be gradual. Her beak is 0.4 because it needs to be snappy for speech.
  • inverted — Whether the servo’s direction is flipped. This depends on how the servo is physically mounted.
  • default_position — Where the servo goes on startup. Can be "min", "max", or "center".

Inputs

The inputs array maps joystick axes to animation channels. This is what makes the joystick work — each input defines which axis on the joystick controls which channel in the creature’s animation data.

  • name — A human-readable label for this input.
  • slot — Which channel in the creature’s DMX frame this input writes to.
  • width — How many channels this input uses. (Currently always 1, but the system supports wider inputs for future use.)
  • joystick_axis — Which axis on the joystick controls this input.

You’ll notice there are more inputs than motors — that’s because some inputs (like head_tilt and head_height) are virtual. They’re combined by the controller into the actual servo positions for neck_left and neck_right. Tilting the joystick one way makes both neck servos move together (height), and tilting it the other way makes them move in opposite directions (tilt). This is much more intuitive than trying to control each servo independently.