Interface Material

Description of a material that can occupy a bitmap cell.

Material id 0 is reserved for air and is never registered. Registered material ids must be in the range 1..255 so they fit in one byte.

interface Material {
    burnDuration?: number;
    color: number;
    density: number;
    destructible: boolean;
    destructionResistance: number;
    flammable?: boolean;
    flowDistance?: number;
    friction: number;
    id: number;
    name: string;
    restitution: number;
    settleAfterTicks?: number;
    settlesTo?: number;
    simulation?: SimulationKind;
    textureKey?: string;
}

Properties

burnDuration?: number

Lifetime in ticks for cells of this material when its simulation is 'fire'. After this many ticks the cell turns to air (id 0). Required for 'fire' materials — registering a fire material without burnDuration throws. Must be in 1..256 (the cellTimers Uint8Array saturates at 255, so values above 256 would never reach the threshold and the cell would silently burn forever). Ignored for non-fire materials.

Worked example: burnDuration: 4. A freshly-lit fire cell:

  • Tick 0 (just lit): timer 0 → 1.
  • Tick 1: timer 1 → 2.
  • Tick 2: timer 2 → 3.
  • Tick 3: timer 3 → 4, threshold reached → cell turns to air.

So the cell is alive at the start of ticks 0..3 and dies during tick 3. burnDuration: N means "die on the Nth tick" (lives N ticks total, including the tick it was lit on). For demo 09's "burn long enough to walk a wood plank" feel we use burnDuration: 40 (~⅔ s at 60 fps).

color: number

Fallback flat color, packed as 0xRRGGBB. Used when no texture is set.

density: number

Mass density for derived debris bodies.

destructible: boolean

When false, the material cannot be carved (indestructible bedrock).

destructionResistance: number

0..1, scales destruction radius for carve operations on this material.

flammable?: boolean

If true, an adjacent 'fire'-simulation cell can ignite this material — converting it in-place to the fire material id. Combine with 'static' for solid burnables (wood, dry grass) or with 'oil' for flammable liquids.

Defaults to false when omitted.

flowDistance?: number

Optional override for the maximum number of cells this fluid can flow horizontally per tick when blocked from vertical motion. Higher = more "responsive" spread; lower = more granular / viscous. Reasonable values per kind:

  • water: 4 (default; fast leveling)
  • oil: 3 (slightly viscous, floats on water)
  • lava: 2 (treacly)
  • gas: 6 (aggressive)
  • honey: 1 (barely flows)

Must be in 0..16. 0 disables horizontal flow entirely — useful for granular materials with simulation: 'sand'. Ignored for 'static' and 'fire' materials. When omitted, fluids fall back to the module-default 4; 'sand'- simulation materials always use 0 regardless of this field.

friction: number

Friction coefficient applied to debris bodies.

id: number

Stable id stored in the bitmap. Must be in the range 1..255.

name: string

Human-readable name. Used for debugging and material lookup.

restitution: number

Restitution (bounciness) applied to debris bodies.

settleAfterTicks?: number
settlesTo?: number

If a fluid cell of this material doesn't move for settleAfterTicks consecutive ticks, it's promoted in place to material id settlesTo. The promoted material is typically a 'static'-simulation variant of the same visual color so the pile becomes part of the static collider mesh.

Both fields must be set together for settling to engage — registering with one but not the other throws at registration time. settleAfterTicks must be in 1..256 (the cellTimers Uint8Array saturates at 255, so a threshold above 256 would never be reached and the cell would silently never promote).

Worked example: settleAfterTicks: 3. A sand cell that lands and can't move:

  • Tick 0 (just landed): didn't move; timer 0 → 1.
  • Tick 1: didn't move; timer 1 → 2.
  • Tick 2: didn't move; timer 2 → 3, threshold reached → promote.

So the cell is promoted on the third stationary tick. settleAfterTicks: N means "promote on the Nth stationary tick" — the cell lives N - 1 full ticks as the moving variant before the Nth tick promotes it. For ~½ s at 60 fps use settleAfterTicks: 30; demo 09 uses this.

Bridges fluid sim and physics: a sand pile that's been at rest long enough becomes part of the terrain and dynamic bodies can stand on it.

simulation?: SimulationKind

Simulation kind for the cellular-automaton step. Defaults to 'static' when omitted — i.e. existing v1 materials behave identically without changes.

textureKey?: string

Optional Phaser texture key for tiled rendering.