Develop

Queries

Updated: Sep 4, 2026
Queries are live entity sets. Each query declares required components, excluded components, and optional predicates over component fields.

Required and excluded components

class RenderUISystem extends createSystem({
  worldPanels: {
    required: [PanelUI],
    excluded: [ScreenSpace],
  },
}) {
  update() {
    for (const entity of this.queries.worldPanels.entities) {
      updateWorldPanel(entity);
    }
  }
}
Membership updates when an entity gains or loses one of the listed components.

Filter by component values

IWSDK re-exports the elics predicate helpers eq, ne, lt, le, gt, ge, isin, and nin.
import { createSystem, lt } from '@iwsdk/core';

class DangerHUDSystem extends createSystem({
  lowHealth: {
    required: [Health],
    where: [lt(Health, 'current', 30)],
  },
}) {
  update() {
    for (const entity of this.queries.lowHealth.entities) {
      showLowHealthState(entity);
    }
  }
}
Use fields that exist on the declared component. The built-in Transform schema contains position, orientation, scale, and parent; it does not contain distance fields.

Query derived values

Store a derived scalar in an application component when a predicate needs it.
const ViewerDistance = createComponent('ViewerDistance', {
  meters: { type: Types.Float32, default: 0 },
});

class NearbySystem extends createSystem({
  nearby: {
    required: [ViewerDistance, Transform],
    where: [lt(ViewerDistance, 'meters', 10)],
  },
}) {
  update() {
    for (const entity of this.queries.nearby.entities) {
      updateNearbyEntity(entity);
    }
  }
}
Calculate ViewerDistance.meters in the system that owns that derived state and write it with setValue().

Entity-reference predicates

Types.Entity fields hold nullable entity references.
const Target = createComponent('Target', {
  entity: { type: Types.Entity, default: null },
});

class TargetingSystem extends createSystem({
  locked: {
    required: [Target],
    where: [ne(Target, 'entity', null)],
  },
  free: {
    required: [Target],
    where: [eq(Target, 'entity', null)],
  },
}) {}

Update predicate fields

Calling setValue() reevaluates queries whose where predicates depend on that component.
entity.setValue(Health, 'current', 20);
setValue() does not accept Vec2, Vec3, or Vec4 fields. Mutate those fields through getVectorView(), but do not use them in where predicates: vector-view writes do not trigger predicate reevaluation. Maintain a scalar field for filtering and update that scalar with setValue().

React to membership changes

init() {
  const stopQualify = this.queries.lowHealth.subscribe('qualify', (entity) => {
    attachWarning(entity);
  });
  const stopDisqualify = this.queries.lowHealth.subscribe(
    'disqualify',
    (entity) => {
      detachWarning(entity);
    },
  );

  this.cleanupFuncs.push(stopQualify, stopDisqualify);
}
See Component for schema fields and System for lifecycle behavior.