[M1-ECS-05] Deterministic iteration order - #21
Merged
Merged
Conversation
The documented iteration contract over the World::each visit order: - visit order pinned: archetypes in ascending archetype id (= the order a component set is first seen by a mutation — creation order), entities within an archetype in ascending slot id, empty query ascending slot id; the order is a pure function of the world state, never of the operation history - dense-id-order scheme documented: rows stay in ascending slot-id order through insert/remove (binary search + memmove shift, archetype.h invariants I1-I4); two histories converging on the same state therefore visit identically - no unordered containers in the iteration path: the iteration touches only the fixed 256-record archetype table (id-ordered scan), packed slot columns, per-slot direct-index records, and membership-only 256-bit guard sets — the entity->archetype map the step anticipated is direct indexing, not even a hash (a stricter reading of the allowance); the one hash structure in laige-sim (the component type-key index) is lookup-only and never iterated, and sits on the setup path, not any tick - convergence property test: two worlds whose operation sequences interleave create/destroy differently (serial scripts + end destroys vs. PRNG-scattered dead-destroys + round-robin component steps + PRNG-placed scratch pairs) converge on the identical final state — including the entity->id assignment — and iterate identically for five queries, verified per-visit against an independent oracle (free-list simulation + first-seen archetype order); component moves are structural throughout (adds of absent / removes of present components), so the dense-id scheme is pinned, not assumed - KAT test pins the exact degenerate visit sequences; machine-greppable iter-order lines record seed, PRNG pair count, visit counts, and the FNV-1a hash of the visit sequences — byte-identical across g++/Clang/ASan/TSan/release trees, default and LAIGE_TEST_SEED-overridden seeds New: tests/laige-sim/iter_order_tests.cpp (IterOrder.* in the shared laige-sim_tests executable), CTest entry iter_order (the step's Verify command; added to the TSan property list); no public API added — laige-api.json unchanged (452 symbols, scanner rerun clean); no src include-graph change (comments only; include lint clean). Docs: docs/api/iteration_order.md (the contract: order, dense-id scheme, no-unordered-containers table, convergence property, ARCH-010 determinism scope, Performance section per DOC-004) + cross-refs in query.md/entity.md/archetype.md/ component_registry.md, docs/README.md, src/laige-sim/README.md; roadmap checkbox + progress board updated.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
M1-ECS-05 from roadmap/M1-heartbeat.md: the documented deterministic iteration contract over the
World::eachvisit order, plus the convergence property test.What changed
docs/api/iteration_order.md): archetypes in ascending archetype id (= the order a component set is first seen by a mutation — creation order), entities within an archetype in ascending slot id, empty query ascending slot id. The order is a pure function of the world state, never of the operation history.laige-sim(the component type-key index) is lookup-only, never iterated, and setup-path only.tests/laige-sim/iter_order_tests.cpp, CTestiter_order): two worlds whose operation sequences interleave create/destroy differently — A: serial per-entity scripts + end-phase dead destroys; B: the same create phase (LIFO requires it for the identical entity→id assignment) with PRNG-scattered dead-destroys, round-robin component steps in per-round PRNG permutations, and PRNG-placed scratch pairs — converge on the identical final state including the entity→id assignment and iterate identically for five queries, verified per-visit against an independent oracle. Component moves are structural throughout, pinning the dense-id scheme. A KAT pins the exact degenerate visit sequences; the greppableiter-order … fnv1a=0x…line is byte-identical across all instantiations, trees, and seeds.laige-api.jsonunchanged (452 symbols, scanner rerun clean); no include-graph change; include lint OK.Verification
ctest -R iter_ordergreen (the step Verify command):build(g++),build-asan,build-tsan,build-clang,build-releaselaige-sim_testssuite green onbuild(no regressions)0x12fc225187f3b359byte-identical across g++/Clang/ASan/release trees and acrossLAIGE_TEST_SEEDoverridesUntested: no new runtime system, so no benchmark/diagnostics scope; the no-unordered-containers half is verified by inspection (CI source scan lands in M1-DET-01).