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.
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)],
},
}) {}
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);
}