System
Updated: Sep 4, 2026
Systems implement behavior. They process live query sets and expose optional configuration as reactive signals.
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;
}
}
}
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.
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.
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.
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.