ecs

A system's view of the world. It holds exactly the components the system declared — reading or writing anything else fails the run.

VerbReturns
queryevery entity holding the components named, one row each
firstone component's value on the first entity holding it
getone component's value on one entity
setwrites one entity's components
sinceevery value written to a streamed component since the system last ran
// ambient — never imported
ecs.query(select: Select): Row[]
ecs.first<C>(component: C): Value<C> | undefined
ecs.get<C>(entity: string, component: C): Value<C> | undefined
ecs.set(write: Write | Write[]): void
since<C>(component: C): Written<C>[]          // on the run's argument

A component is named by its short name — "pose" — or its full name, "body/pose".

query

Every entity holding all of components, one row each, in entity order.

const rows = ecs.query({
    components: ["sight"],                      // must all be held — these decide the rows
    optional: ["depth"],                        // read when held, undefined when not
    where: { sight: { channel: "/vision" } },   // equality, as data
})

for (const row of rows) {
    row.id          // the entity
    row.sight       // its value
    row.meta.sight  // { at, rev } — when it was written, which change it is
}

where matches by value: a record on the fields given, a list element for element, anything else exactly. A row is a copy — changing it changes nothing. Writes go through set.

first and get

The common case — one value.

const pose = ecs.first("pose")                // undefined if no entity holds one
const room = ecs.get("room", "temperature")   // undefined if "room" holds none

set

Writes one entity's components at once. An entity exists as soon as something is written to it.

ecs.set({
    id: "self",
    components: {
        pose: next,       // a value writes
        target: null,     // null removes
    },                    // anything left out is untouched
})

ecs.set([             // several entities in one call
    { id: "left", components: { wheel: left } },
    { id: "right", components: { wheel: right } },
])

Writing a value equal to the one held records nothing.

since

For a component the system streams: every value written since it last ran, oldest first — including repeats, since two equal readings are still two readings.

run({ since }) {
    for (const felt of since("imu")) {
        felt.entity   // who it was written to
        felt.value    // the value
        felt.at       // when
    }
}

Errors

ErrorWhen
ECS_UNDECLAREDreading or writing a component the system didn't declare
ECS_SHAPEa value that doesn't match the component's type
ECS_NOT_STREAMEDsince on a component the system doesn't stream

Each fails the run, and is recorded with the system, the tick and the component named.