Repository navigation
[M2-SCENE-01] Reference isometric scene generator (deterministic, seed-driven) - #93
Merged
Merged
Conversation
…d-driven) The M2-SCENE-01 step: a headless, seed-deterministic generator for the worst-case isometric reference scene of PRD §4 — the scene every visual and performance acceptance test renders (M2-PERF-01, M2-AC-01, M2-GOLD-01, M2-SAMPLE-01). New public header src/laige-render/include/laige/render/iso_reference_scene.h (header-only, no GL calls): - buildIsoReferenceScene(seed, variant): the Full variant is the §8.1 budget scene (50 000 sprites on a 256x256 stepped-terrain grid of uniform-height plateaus — each sprite standing on its PRNG-chosen tile, positions exact dyadic 2^-16), plus the 3 preset-factor parallax layers, 8 continuous particle emitters, and a 2-widget UI on the 1280x720 reference screen; the Small variant is the same composition scaled to 1 000 sprites / 32x32 for fast unit tests. Same seed, same bytes, every build and P0 platform (ARCH-010 — Prng substreams + the exact dyadic position scale, no FMA-susceptible float composition in the builder). - The versioned little-endian binary scene format (v1): the reader treats the bytes as untrusted input (SCALE-004) — full domain validation of every field plus the exact total length; any violation fails the whole read with MalformedInput (ARCH-007 — the version gate rejects anything but 1). - writeIsoReferenceScene: atomic temp + rename (a killed run never leaves a partial file). - IsoReferenceSceneWorld<Backend> (move-only) + loadIsoReferenceScene (first failure wins; TileMap in unique_ptr — the house empty<=>stopped idiom, TileMap has no default constructor) + declareIsoReferenceScene: the one-call whole-world pass (parallax + terrain tiles + 50k sprites with their isoDepthKey depth keys + live particles), O(frame items), zero allocation. The scene's atlas plan pins 14 (atlas, material, blend) groups — under the §8.1 30-draw-call budget, asserted by the test suite. New headless tool tools/scene-iso/laige-scene-iso (the step's generator CLI): --seed/--variant/--out, atomic write, round-trip self-check (byte-identical + clean re-parse), machine-greppable summary line, exit 0/2. Verification: - tests/laige-render/scene_iso_tests.cpp (ctest -R scene_iso): builder determinism (same-seed bytes identical, different-seed differ, both variants), the 7 malformed-input cases, round-trip deep equality, load + declare on both backends (per-batch instance counts, in-group depth-key monotonicity, the 14-group draw-call property), the UI pass (2 quads, 1 batch, 2 depth overrides), and the 1 000-frame zero-allocation declare loop (both backends). - The scene_iso_cli ctest entry runs the roadmap's Verify clause in executable form: the tool twice per variant with the same seed, output files compared byte for byte. - The scene format's untrusted-input surface gets a fuzz target (fuzz_scene_iso_parse, 1 000 bounded runs every commit, corpus = valid small + full scenes as mutate/truncate bases — TEST-005 / SCALE-005). Also fixed (found by the scene loader's first use of the move): StringTable::operator=(StringTable&&) recursed into itself (`*this = StringTable(std::move(o))` is again a move-assignment — infinite recursion). The move assignment now moves the members in place; regression test TextStringTable.MoveAssignment. docs/api/iso_reference_scene.md (the API + format + Performance section), the docs/README.md index link, the roadmap Shipped block, and laige-api.json regenerated last. budgets.json unchanged (17 entries — the generation budget is the tool's; the per-frame declare cost is part of the composite 50k render-CPU budget, M2-PERF-01).
Unary minus applied to kIsoDepthLayerBias (a uint32 constant) before the int32 cast warned C4146 on MSVC (treated as an error by the house policy). Cast to int32 first, then negate — the iso_depth_key.h clamp's own pattern (-static_cast to the signed type).
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.
M2-SCENE-01: Reference isometric scene generator
Implements roadmap step M2-SCENE-01 (roadmap/M2-rendering-2.5d.md, marked shipped): a headless, seed-deterministic generator for the worst-case isometric reference scene of PRD §4 — the scene every visual and performance acceptance test renders (downstream: M2-PERF-01, M2-AC-01, M2-GOLD-01, M2-SAMPLE-01).
What lands
src/laige-render/include/laige/render/iso_reference_scene.h(header-only, no GL calls):buildIsoReferenceScene(seed, variant)— the Full variant is the §8.1 budget scene: 50 000 sprites on a 256×256 stepped-terrain grid of uniform-height plateaus (each sprite standing on its PRNG-chosen tile; positions exact dyadic 2^-16 — no FMA-susceptible composition, ARCH-010), 3 preset-factor parallax layers, 8 continuous particle emitters, a 2-widget UI on the 1280×720 reference screen. The Small variant scales the same composition to 1 000 sprites / 32×32 for fast unit tests. Same seed → same bytes, every build and P0 platform.MalformedInput; the version gate rejects anything but 1 (ARCH-007).writeIsoReferenceScene— atomic temp + rename (a killed run never leaves a partial file).IsoReferenceSceneWorld<Backend>(move-only) +loadIsoReferenceScene(first failure wins) +declareIsoReferenceScene— the one-call whole-world pass (parallax + terrain tiles + 50k sprites withisoDepthKeydepth keys + live particles), O(frame items), zero allocation. The scene's atlas plan pins 14 (atlas, material, blend) groups — under the §8.1 30-draw-call budget, asserted by the tests.tools/scene-iso/laige-scene-iso(--seed/--variant/--out): atomic write, round-trip self-check (byte-identical + clean re-parse), machine-greppable summary line, exit 0/2.tests/laige-render/scene_iso_tests.cpp,ctest -R scene_iso): builder determinism (same-seed byte identity both variants, different-seed differ), the 7 malformed-input cases, round-trip deep equality, load + declare on both backends (per-batch instance counts, in-group depth-key monotonicity, the 14-group draw-call property), the UI pass (2 quads / 1 batch / 2 depth overrides), and the 1 000-frame zero-allocation declare loop (both backends).scene_iso_cli(ctest): the tool twice per variant with the same seed, output files compared byte for byte — the roadmap Verify clause in executable form.fuzz_scene_iso_parse(1 000 bounded runs every commit, corpus = valid small + full scenes as mutate/truncate bases) for the untrusted-input parser surface (TEST-005 / SCALE-005).docs/api/iso_reference_scene.md(API table, wire layout, Performance section, misuse warnings),docs/README.mdindex link, roadmap Shipped block.laige-api.jsonregenerated last (1815 symbols, 48 headers).Engine bug fixed along the way
The scene loader's first use of the
StringTablemove hit a real bug:StringTable::operator=(StringTable&&)recursed into itself (*this = StringTable(std::move(o))is again a move-assignment → infinite recursion, stack overflow). Fixed insrc/laige-render/include/laige/render/text_items.h(member moves applied in place); regression testTextStringTable.MoveAssignment.Notes
budgets.jsonunchanged (17 entries): the generation budget is the tool's (thescene_iso_cli60 s timeout guards it), and the per-frame declare cost is part of the composite 50k render-CPU budget measured by M2-PERF-01.