Develop

System

Updated: Sep 4, 2026
Systems implement behavior. They process live query sets and expose optional configuration as reactive signals.

Define a system

createSystem(queries, schema) accepts query descriptors and an optional configuration schema. Define init(), update(), and destroy() in the subclass body, not inside the query object.
import {
  Transform,
  Types,
  createComponent,
  createSystem,
} from '@iwsdk/core';

const Velocity = createComponent('Velocity', {
  x: { type: Types.Float32, default: 0 },
});

class MotionSystem extends createSystem(
  {
    moving: { required: [Transform, Velocity] },
  },
  {
    speed: { type: Types.Float32, default: 1 },
  },
) {
  update(delta: number) {
    const speed = this.config.speed.peek();
    for (const entity of this.queries.moving.entities) {
      const velocity = entity.getValue(Velocity, 'x')!;
      entity.object3D!.position.x += velocity * speed * delta;
    }
  }
}

Lifecycle methods

  • init() performs one-time setup after registration.
  • update(delta, time) runs on every World update.
  • destroy() releases system-owned resources.
  • Query subscriptions report when an entity qualifies or disqualifies.

Configuration signals

Each schema field becomes a signal at this.config.<field>.
const currentSpeed = this.config.speed.peek();
this.config.speed.value = 2;

const unsubscribe = this.config.speed.subscribe((value) => {
  console.log('New speed', value);
});
Use .peek() when a read should not create a signal dependency, .value for tracked reads and writes, and .subscribe() to run a callback after a change. Release application-created subscriptions during cleanup.

Register a system

world.registerComponent(Velocity);
world.registerSystem(MotionSystem, {
  priority: 0,
  configData: { speed: 1.5 },
});
Systems run in ascending priority. More-negative values run earlier. Choose a priority only when the system has an ordering dependency.
IWSDK uses these feature priorities:
  • Locomotion: -5
  • Input: -4
  • Canvas pointer forwarding: -3.5
  • Grabbing: -3

Create and destroy entities

Systems inherit helpers from the ECS base system.
const entity = this.createEntity();
entity.addComponent(Health);

// Later:
entity.destroy();
Use this.world.createTransformEntity() instead when the entity needs an object3D and Transform.

Shared state

this.globals references world.globals. Use it for a small amount of shared application state whose lifetime belongs to the World.
this.globals.navigationMesh = navigationMesh;
Prefer components for per-entity state and typed application services for larger subsystems.