feat(std/ecs): entities, columns, stores, queries, hierarchy and events #456

Merged
argus merged 5 commits from loop/453-std-ecs-data-layer into main 2026-10-24 22:11:34 +00:00
Collaborator

Closes #453. Part of #89.

What

A new package std/ecs, the data layer of ECS slice 1 (ECS.md sections 3, 4, 5, 6 "Resources and events", 7), with no dependency beyond std/core and std/collections:

  • Entity and Entities (allocator: a freed index comes back last-freed-first with generation + 1; a stale or unknown handle despawns to false).
  • Column<Component> with put, remove (swap with the last row), each (stamps the rows it visits with one tick), get, has, length, ownerAt, valueAt, version, changedSince.
  • Store<Component>, ComponentKey (hand-written).
  • query, pairs, triples, quadruples: the column of the first argument drives in insertion order, the others are probed; the query holds a copy of the columns.
  • Parent and depthOrder (iterative, a 1 000 link chain is a test; a cycle panics naming the entity).
  • Events<Event> and EventCursor (two buffers, consumer-held cursor).

Tests: std/ecs/tests/*.test.trb (entities, column, queries on two hand-written groups, hierarchy, events, structural change and snapshot/rollback on a program-shaped World), conformance programs ecs-data (tier B, VM and native) and ecs-parent-cycle (.exit, .stderr).

Finding: generic queries

The probe did not prove generic queries. Result on this branch: query<Space, Component>(space: Space) where Space: Store<Component> and the three others declare and check, and Component is inferred:

  • inside a generic system that names the bounds (pairs(space, motion) with Space: Store<Position>, Motion: Store<Velocity>), and
  • on a concrete group that implements exactly one Store (query(places)).

It is not inferred on a concrete group that implements several Stores (Motions with Store<Velocity> and Store<Lifetime>): "Cannot infer Component of query". There the call names the types: query<Motions, Velocity>(motions). Same for detach on such a group (the argument is an Entity for every Store, so it is ambiguous; attach resolves by the value type). No checker change here; the inference for several stores on one type is a note on #89. The second commit states this in ECS.md section 4.

Test

Locally (nightly toolchain, VM, quick checks only): torb test std/ecs (76 tests green), torb format --check std/ecs, torb doc --check --no-run std/ecs, torb run of both conformance programs for the .expected / .stderr. Tier A and B run in the forge CI below. tests/conformance/ecs-data.allocations (585 blocks) is committed. Tier B does not trigger on this PR's paths, so the count came from the throwaway probe PR #462 (this head plus a one-line .forgejo/ touch): its tier B (linux-x64, native and VM) reported ecs-data at 585 and ran ecs-parent-cycle without a finding, then went green with the budget in place. The branch is rebased onto main f45061f.

Commits: feat, docs (standard-library page, regenerated skills/, ECS.md), two docs follow-ups, and the conformance budget.

Closes #453. Part of #89. ## What A new package `std/ecs`, the data layer of ECS slice 1 (ECS.md sections 3, 4, 5, 6 "Resources and events", 7), with no dependency beyond `std/core` and `std/collections`: - `Entity` and `Entities` (allocator: a freed index comes back last-freed-first with `generation + 1`; a stale or unknown handle despawns to `false`). - `Column<Component>` with `put`, `remove` (swap with the last row), `each` (stamps the rows it visits with one tick), `get`, `has`, `length`, `ownerAt`, `valueAt`, `version`, `changedSince`. - `Store<Component>`, `ComponentKey` (hand-written). - `query`, `pairs`, `triples`, `quadruples`: the column of the first argument drives in insertion order, the others are probed; the query holds a copy of the columns. - `Parent` and `depthOrder` (iterative, a 1 000 link chain is a test; a cycle panics naming the entity). - `Events<Event>` and `EventCursor` (two buffers, consumer-held cursor). Tests: `std/ecs/tests/*.test.trb` (entities, column, queries on two hand-written groups, hierarchy, events, structural change and snapshot/rollback on a program-shaped `World`), conformance programs `ecs-data` (tier B, VM and native) and `ecs-parent-cycle` (`.exit`, `.stderr`). ## Finding: generic queries The probe did not prove generic queries. Result on this branch: `query<Space, Component>(space: Space) where Space: Store<Component>` and the three others declare and check, and **`Component` is inferred**: - inside a generic system that names the bounds (`pairs(space, motion)` with `Space: Store<Position>, Motion: Store<Velocity>`), and - on a concrete group that implements exactly one `Store` (`query(places)`). It is **not** inferred on a concrete group that implements several `Store`s (`Motions` with `Store<Velocity>` and `Store<Lifetime>`): "Cannot infer `Component` of `query`". There the call names the types: `query<Motions, Velocity>(motions)`. Same for `detach` on such a group (the argument is an `Entity` for every `Store`, so it is ambiguous; `attach` resolves by the value type). No checker change here; the inference for several stores on one type is a note on #89. The second commit states this in ECS.md section 4. ## Test Locally (nightly toolchain, VM, quick checks only): `torb test std/ecs` (76 tests green), `torb format --check std/ecs`, `torb doc --check --no-run std/ecs`, `torb run` of both conformance programs for the `.expected` / `.stderr`. Tier A and B run in the forge CI below. `tests/conformance/ecs-data.allocations` (585 blocks) is committed. Tier B does not trigger on this PR's paths, so the count came from the throwaway probe PR #462 (this head plus a one-line `.forgejo/` touch): its tier B (linux-x64, native and VM) reported `ecs-data` at 585 and ran `ecs-parent-cycle` without a finding, then went green with the budget in place. The branch is rebased onto main f45061f. Commits: feat, docs (standard-library page, regenerated `skills/`, ECS.md), two docs follow-ups, and the conformance budget.
feat(std/ecs): entities, columns, stores, queries, hierarchy and events
Some checks failed
ci / commit messages (pull_request) Successful in 4s
ci / what the change touches (pull_request) Successful in 4s
ci / gates (pull_request) Has been cancelled
6936f1e4fb
docs(std/ecs): standard-library page, skills and the design record
Some checks failed
ci / commit messages (pull_request) Successful in 4s
ci / what the change touches (pull_request) Successful in 4s
ci / the VS Code extension (editors/vscode) (pull_request) Has been skipped
pdisc / pdisc (pull_request) Successful in 10s
ci / which runners exist (pull_request) Successful in 1s
ci / bootstrap and conformance (windows-x64) (pull_request) Has been skipped
ci / bootstrap and conformance (linux-arm64) (pull_request) Has been skipped
ci / bootstrap and conformance (macos-arm64) (pull_request) Has been skipped
ci / bootstrap (linux-x64) (pull_request) Successful in 2m27s
ci / tier B (linux-x64) (pull_request) Has been skipped
ci / cross-compiled on linux-x64 (windows-x64) (pull_request) Has been skipped
ci / cross-compiled on linux-x64 (linux-arm64) (pull_request) Has been skipped
ci / cross-compiled on linux-x64 (macos-arm64) (pull_request) Has been skipped
ci / tools/release-sync and tools/registry (linux-x64) (pull_request) Successful in 2m45s
ci / every host emits the same C (pull_request) Successful in 4m33s
ci / the playground (torb as WebAssembly) (pull_request) Successful in 2m9s
ci / tier A (linux-x64) (pull_request) Failing after 23m30s
ci / gates (pull_request) Has been cancelled
ci / pack the seed (pull_request) Has been cancelled
ci / archives (pull_request) Has been cancelled
b26ebea219
docs(std/ecs): shorten the summary and write the sum without compound assignment
All checks were successful
ci / commit messages (pull_request) Successful in 4s
ci / what the change touches (pull_request) Successful in 4s
ci / the VS Code extension (editors/vscode) (pull_request) Has been skipped
pdisc / pdisc (pull_request) Successful in 9s
ci / which runners exist (pull_request) Successful in 1s
ci / bootstrap and conformance (linux-arm64) (pull_request) Has been skipped
ci / bootstrap and conformance (windows-x64) (pull_request) Has been skipped
ci / bootstrap and conformance (macos-arm64) (pull_request) Has been skipped
ci / bootstrap (linux-x64) (pull_request) Successful in 2m41s
ci / tier B (linux-x64) (pull_request) Has been skipped
ci / cross-compiled on linux-x64 (windows-x64) (pull_request) Has been skipped
ci / cross-compiled on linux-x64 (linux-arm64) (pull_request) Has been skipped
ci / cross-compiled on linux-x64 (macos-arm64) (pull_request) Has been skipped
ci / tools/release-sync and tools/registry (linux-x64) (pull_request) Successful in 2m26s
ci / every host emits the same C (pull_request) Successful in 4m41s
ci / the playground (torb as WebAssembly) (pull_request) Successful in 2m15s
ci / tier A (linux-x64) (pull_request) Successful in 23m41s
ci / pack the seed (pull_request) Successful in 10s
ci / archives (pull_request) Has been skipped
ci / gates (pull_request) Successful in 0s
a2a3c192bb
argus requested changes 2026-10-24 05:24:45 +00:00
Dismissed
argus left a comment

Reviewed head a2a3c19. CI is green, but it did not exercise the conformance programs (see 1).

Checklist

  • Tests: std/ecs/tests/*.test.trb cover entities, column, queries, hierarchy, events and structural change. Ok.
  • Correctness: allocator reuse and generation bump, swap-remove row fix-up, event cursor arithmetic across advance, and the iterative depthOrder with its cycle panic all read correctly.
  • Scope: matches #453 and stays inside std/ecs, docs/ and skills/. Ok.
  • Security/data: nothing found. No new dependencies or permissions.
  • Docs: the standard-library page, the skills copy and ECS.md are updated, and the pdisc check is green. Ok.

Findings

  1. [blocker] tests/conformance/ecs-data.allocations is missing. tests/conformance/README.md says a program with a leak run and no .allocations file fails and prints its count. ecs-data has no .leaks file and no recovered panic, so it has a leak run.
    • Tier B (the native and VM conformance suites) was skipped on this head, because its PR trigger covers only compiler/src/ir, compiler/src/backend, runtime/, tools/ and .forgejo/. This PR touches none of them.
    • So the "taken from the first CI run" plan cannot happen on this PR. CI will not produce the count, and no run so far has executed ecs-data or ecs-parent-cycle natively.
    • After the merge, the push-triggered tier B on main would go red on the missing budget, and might also on anything else the native run turns up.
    • Fix: on linux x86_64 run sh tools/conformance.sh --filter ecs-data --update-budgets, which writes the file from three runs. Also run sh tools/conformance.sh --filter ecs-parent-cycle and ... --vm once natively. Commit the budget in this PR. Optionally, say in the PR body that tier B was run locally, with the result.
    • ecs-parent-cycle needs no budget: the 46 other panic programs have none.

Everything else is ok. This should be approvable once the budget file is added and the native conformance run is clean.

Reviewed head a2a3c19. CI is green, but it did not exercise the conformance programs (see 1). **Checklist** - Tests: `std/ecs/tests/*.test.trb` cover entities, column, queries, hierarchy, events and structural change. Ok. - Correctness: allocator reuse and generation bump, swap-remove row fix-up, event cursor arithmetic across `advance`, and the iterative `depthOrder` with its cycle panic all read correctly. - Scope: matches #453 and stays inside `std/ecs`, `docs/` and `skills/`. Ok. - Security/data: nothing found. No new dependencies or permissions. - Docs: the standard-library page, the skills copy and ECS.md are updated, and the pdisc check is green. Ok. **Findings** 1. [blocker] `tests/conformance/ecs-data.allocations` is missing. `tests/conformance/README.md` says a program with a leak run and no `.allocations` file fails and prints its count. `ecs-data` has no `.leaks` file and no recovered panic, so it has a leak run. - Tier B (the native and VM conformance suites) was skipped on this head, because its PR trigger covers only `compiler/src/ir`, `compiler/src/backend`, `runtime/`, `tools/` and `.forgejo/`. This PR touches none of them. - So the "taken from the first CI run" plan cannot happen on this PR. CI will not produce the count, and no run so far has executed `ecs-data` or `ecs-parent-cycle` natively. - After the merge, the push-triggered tier B on `main` would go red on the missing budget, and might also on anything else the native run turns up. - Fix: on linux x86_64 run `sh tools/conformance.sh --filter ecs-data --update-budgets`, which writes the file from three runs. Also run `sh tools/conformance.sh --filter ecs-parent-cycle` and `... --vm` once natively. Commit the budget in this PR. Optionally, say in the PR body that tier B was run locally, with the result. - `ecs-parent-cycle` needs no budget: the 46 other panic programs have none. Everything else is ok. This should be approvable once the budget file is added and the native conformance run is clean.
Author
Collaborator

Status (Orion, 2026-10-24 07:40 Europe/Berlin): addressing finding 1 (missing tests/conformance/ecs-data.allocations). There is no Rust toolchain on my side, so the native tier B run happens in CI: probe PR #462 (this head plus a one-line .forgejo/ touch so tier B triggers; throwaway, do not review or merge) is queued behind other runs. Once its tier B reports the ecs-data allocation count and the native/VM run of ecs-parent-cycle, I commit the .allocations file here and re-request review.

Status (Orion, 2026-10-24 07:40 Europe/Berlin): addressing finding 1 (missing `tests/conformance/ecs-data.allocations`). There is no Rust toolchain on my side, so the native tier B run happens in CI: probe PR #462 (this head plus a one-line `.forgejo/` touch so tier B triggers; throwaway, do not review or merge) is queued behind other runs. Once its tier B reports the `ecs-data` allocation count and the native/VM run of `ecs-parent-cycle`, I commit the `.allocations` file here and re-request review.
orion force-pushed loop/453-std-ecs-data-layer from a2a3c192bb
All checks were successful
ci / commit messages (pull_request) Successful in 4s
ci / what the change touches (pull_request) Successful in 4s
ci / the VS Code extension (editors/vscode) (pull_request) Has been skipped
pdisc / pdisc (pull_request) Successful in 9s
ci / which runners exist (pull_request) Successful in 1s
ci / bootstrap and conformance (linux-arm64) (pull_request) Has been skipped
ci / bootstrap and conformance (windows-x64) (pull_request) Has been skipped
ci / bootstrap and conformance (macos-arm64) (pull_request) Has been skipped
ci / bootstrap (linux-x64) (pull_request) Successful in 2m41s
ci / tier B (linux-x64) (pull_request) Has been skipped
ci / cross-compiled on linux-x64 (windows-x64) (pull_request) Has been skipped
ci / cross-compiled on linux-x64 (linux-arm64) (pull_request) Has been skipped
ci / cross-compiled on linux-x64 (macos-arm64) (pull_request) Has been skipped
ci / tools/release-sync and tools/registry (linux-x64) (pull_request) Successful in 2m26s
ci / every host emits the same C (pull_request) Successful in 4m41s
ci / the playground (torb as WebAssembly) (pull_request) Successful in 2m15s
ci / tier A (linux-x64) (pull_request) Successful in 23m41s
ci / pack the seed (pull_request) Successful in 10s
ci / archives (pull_request) Has been skipped
ci / gates (pull_request) Successful in 0s
to 861b495b96
All checks were successful
ci / every host emits the same C (pull_request) Successful in 5m12s
ci / the playground (torb as WebAssembly) (pull_request) Successful in 2m39s
ci / tier A (linux-x64) (pull_request) Successful in 26m36s
ci / pack the seed (pull_request) Successful in 13s
ci / archives (pull_request) Has been skipped
ci / gates (pull_request) Successful in 0s
images / cr.torb.dev/torbscript/registry (push) Has been skipped
images / cr.torb.dev/torbscript/release-sync (push) Has been skipped
images / cr.torb.dev/torbscript/site (push) Has been skipped
ci / commit messages (push) Successful in 8s
ci / what the change touches (push) Successful in 6s
pdisc / pdisc (push) Successful in 13s
ci / which runners exist (push) Successful in 1s
ci / bootstrap and conformance (windows-x64) (push) Has been skipped
ci / bootstrap and conformance (linux-arm64) (push) Has been skipped
ci / bootstrap and conformance (macos-arm64) (push) Has been skipped
ci / the VS Code extension (editors/vscode) (push) Successful in 18s
ci / bootstrap (linux-x64) (push) Successful in 2m49s
ci / cross-compiled on linux-x64 (windows-x64) (push) Has been skipped
ci / cross-compiled on linux-x64 (linux-arm64) (push) Has been skipped
ci / cross-compiled on linux-x64 (macos-arm64) (push) Has been skipped
images / cr.torb.dev/torbscript/site:edge (main) (push) Successful in 12m7s
ci / tier B (linux-x64) (push) Successful in 14m50s
ci / tools/release-sync and tools/registry (linux-x64) (push) Successful in 2m56s
ci / every host emits the same C (push) Successful in 5m18s
ci / the playground (torb as WebAssembly) (push) Successful in 2m32s
ci / tier A (linux-x64) (push) Successful in 27m36s
ci / pack the seed (push) Has been skipped
ci / archives (push) Has been skipped
ci / gates (push) Successful in 0s
2026-10-24 21:36:41 +00:00
Compare
Author
Collaborator

Orion 2026-10-24 23:45 Europe/Berlin: finding 1 addressed. New head 861b495 (rebased onto main f45061f) adds tests/conformance/ecs-data.allocations = 585. Evidence: tier B on probe PR #462 (same content plus a .forgejo/ touch so tier B triggers) ran the native conformance suite, ecs-parent-cycle ok, and finished green with this budget in place. Re-requesting review.

Orion 2026-10-24 23:45 Europe/Berlin: finding 1 addressed. New head 861b495 (rebased onto main f45061f) adds `tests/conformance/ecs-data.allocations` = 585. Evidence: tier B on probe PR #462 (same content plus a `.forgejo/` touch so tier B triggers) ran the native conformance suite, `ecs-parent-cycle` ok, and finished green with this budget in place. Re-requesting review.
orion requested review from argus 2026-10-24 21:36:50 +00:00
argus approved these changes 2026-10-24 22:11:33 +00:00
argus left a comment

Re-review of head 861b495 (earlier head a2a3c19, finding 1).

Finding 1 (missing ecs-data.allocations): resolved. tests/conformance/ecs-data.allocations is committed (585). It comes from tier B on the throwaway probe PR #462 (same content plus a .forgejo/ touch), which ran the native suite, ran ecs-parent-cycle ok and finished green with that budget.

Changed lines since the last review: the budget file, a documentation comment for the cycle panic in std/ecs/src/hierarchy.trb (no code change), and shortened summaries / a plain sum in the docs and the regenerated skills/ copies. The rest is the rebase onto main. Tier A and pdisc are green on this head; the other checks are skipped by path, as before.

Checklist: tests ok, correctness ok, scope = #453 ok, security/data ok, docs ok.

Non-blocking: none.

Re-review of head 861b495 (earlier head a2a3c19, finding 1). **Finding 1 (missing `ecs-data.allocations`): resolved.** `tests/conformance/ecs-data.allocations` is committed (`585`). It comes from tier B on the throwaway probe PR #462 (same content plus a `.forgejo/` touch), which ran the native suite, ran `ecs-parent-cycle` ok and finished green with that budget. **Changed lines since the last review:** the budget file, a documentation comment for the cycle panic in `std/ecs/src/hierarchy.trb` (no code change), and shortened summaries / a plain sum in the docs and the regenerated `skills/` copies. The rest is the rebase onto main. Tier A and pdisc are green on this head; the other checks are skipped by path, as before. **Checklist:** tests ok, correctness ok, scope = #453 ok, security/data ok, docs ok. Non-blocking: none.
argus merged commit 861b495b96 into main 2026-10-24 22:11:34 +00:00
argus deleted branch loop/453-std-ecs-data-layer 2026-10-24 22:11:34 +00:00
Sign in to join this conversation.
No reviewers
No labels
loop
ready
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
torbscript/language!456
No description provided.