Repository navigation
Commit 03b2ff3
authored
[M1-SAMPLE-01] hello.laige (headless template) (#40)
* [M1-SAMPLE-01] hello.laige headless template game (samples/hello)
M1-SAMPLE-01 (roadmap/M1-heartbeat.md, NFR-13.5, PRD §9.4/§13, TEST-004,
ADR 0002, ARCH-010, CORE-008): the first complete Laige game — the
headless template that every game project (human or AI agent) starts
from: one component, one system, one entity, deterministic by default,
records and replays its own log.
- samples/hello/: hello.cpp (99 code lines < the PRD §9.4 budget of
100; the NFR-13.5 "heavily commented" requirement lives in the
~76 comment lines and does not count), config.json (canonical
60 Hz / 8-entity / 256-churn / 0x1F055EED / fpx16_16 config),
hello.laige (provisional manifest — M3-ASSET-01 owns the real
format), LICENSE, README.md (the full contract: files, build/run,
CLI + stream + exit codes, the game walkthrough, replay, tests,
line budget).
- The game: PlayerPos (M::Vec2, LAIGE_COMPONENT + LAIGE_DETERMINISM_SAFE
at namespace scope — the marks specialize laige::detail traits and
cannot live in an anonymous namespace), MovePlayer (LAIGE_SYSTEM;
constant +1/tick per axis wrapped in the [-16, 16] box; the each
Status is cast away per the FR-1.3/query-guard contract — asserts in
debug, warns in release), one entity at the box center. The config
is embedded in the binary (config.json is the declarative record
consumed by `laige-run --headless` — the hello_config_valid CTest
keeps the two in step); the registration order is part of the replay
identity (ADR 0002).
- stdout contract (docs/api/detcheck.md): the tick-0 line plus one
World::stateHash line per completed tick — 301 lines at 300 ticks —
the detcheck scenario stream; stderr: the engine logging facade +
the `hello {headless|replay} ticks=N status=ok` summary; exit codes
0 ok / 1 run failure (runSystems/writeFrame/finish) / 2 usage/IO/
identity (strict arg parse; paired options; --log/--replay exclusive).
- Replay: --replay LOG records its own run (debug builds only —
parity with the engine's startReplayRecording policy; exit 2 under
NDEBUG), --log LOG loads the log, checks the replay identity
against its own (world, config) via replayIdentityDiff (mismatch =
rejected replay, never a silent divergence), and re-runs the log's
frame count through the same tick loop; record → replay is
byte-identical (hello_replay CTest). laige-replay cannot replay a
game log (it registers only the built-ins — different identity);
the scenario binary carries the mode (docs/api/replay.md).
- Build: samples/hello/CMakeLists.txt (laige_apply_engine_policy +
laige_apply_simmath_policy, links laige-sim, RUNTIME_OUTPUT_DIRECTORY
= samples/hello/bin so the CI detcheck step invokes it from the
repository root with no arguments — the shared-path caveat is
documented in the README); wired into the root CMakeLists (the
sample is a shipped project) and .gitignore (samples/*/bin/).
- CI: tests/sample/ — 9 CTest entries with TSan env blocks and
generated scripts (the tests/replay pattern): hello_scenario
(no-arg run, 301-line structural check, stderr summary), hello_replay
(record → replay byte-identical; Debug-gated — recording is an
NDEBUG-gated feature), hello_replay_missing / _malformed (exit 2 +
`hello: replay:` naming), hello_mode_exclusive, hello_usage_unknown /
_missing_value (exit 2), hello_config_valid (laige-run --headless
consumes config.json, status=ok), hello_line_budget (CMake-core
counter — code lines = non-blank, non-// lines; the script protects
semicolons before the CMake list split and spells the whitespace
class explicitly, since CMake regexes have no POSIX classes).
- CI wiring: the detcheck job's real-scenario step (ci.yml +
ci-pull.yml) self-activates now that samples/hello/bin/hello is
built in the job — two no-arg runs must both exit 0 (M1-DET-04
swaps this for the build-asan vs build two-configuration
comparison); the ci.yml step comment was stale and now matches.
- Docs: detcheck.md (the real scenario now exists — the CI status and
hash-scope paragraphs updated), replay.md (scope: the scenario
binary's own loadReplay + replayIdentityDiff + tick loop),
building.md (the two hello command rows + the target note),
docs/README.md (M1 progress + the Getting-started link).
Local verification: cmake -S . -B build -DCMAKE_BUILD_TYPE=Debug +
build warning-clean (-Wall -Werror); ctest 76/76 on the Debug tree
(incl. the 9 hello entries) and 9/9 on a fresh ASan+UBSan tree
(build-asan, -DLAIGE_ASAN=ON); Release tree spot check — no-arg run
exits 0, --replay exits 2 (the NDEBUG gate); the CI forms from the
repository root: `./samples/hello/bin/hello` (301 lines, exit 0) and
`./build/bin/laige-detcheck --run-a=samples/hello/bin/hello
--run-b=samples/hello/bin/hello` (both exit 0, streams byte-identical);
laige-determinism-lint OK (20 files, 0 violations),
laige-include-lint OK (37 files, 1/10 vendored); api-manifest: the
sample adds no public header (no drift — the api tests pass in the
full suite). No float/double tokens in the sample source. Untested
locally: the MSVC/AppleClang paths and the CI-only TSan lane
(single-threaded binary; the ASan+UBSan run covers the memory side).
Compat: additive only — no existing symbol, behavior, or CI gate
changed.
* [M1-SAMPLE-01] roadmap: check M1-SAMPLE-01, board 17/25, change log
- roadmap/M1-heartbeat.md: M1-SAMPLE-01 box checked (the step's
Verify holds: CI builds hello, runs it, replay is bit-exact
(hello_replay CTest + the detcheck job's real-scenario step), and
the game-code line count is < 100 checked in CI
(hello_line_budget — 99 code lines).
- roadmap/README.md: Progress Board M1 15 -> 17 done (also picks up
the M1-DET-03 box that was checked without a board update), status
in progress (M1-SAMPLE-01); Change Log line for 75d1df6.1 parent 50a1000 commit 03b2ff3
20 files changed
Lines changed: 817 additions & 22 deletions
File tree
- .github/workflows
- docs
- api
- getting-started
- roadmap
- samples/hello
- tests
- sample
- fixtures
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
354 | 354 | | |
355 | 355 | | |
356 | 356 | | |
357 | | - | |
358 | | - | |
359 | | - | |
| 357 | + | |
| 358 | + | |
| 359 | + | |
| 360 | + | |
| 361 | + | |
360 | 362 | | |
361 | 363 | | |
362 | 364 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
6 | 6 | | |
7 | 7 | | |
8 | 8 | | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
9 | 14 | | |
10 | 15 | | |
11 | 16 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
242 | 242 | | |
243 | 243 | | |
244 | 244 | | |
| 245 | + | |
| 246 | + | |
| 247 | + | |
| 248 | + | |
| 249 | + | |
| 250 | + | |
| 251 | + | |
245 | 252 | | |
246 | 253 | | |
247 | 254 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
22 | 22 | | |
23 | 23 | | |
24 | 24 | | |
25 | | - | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
26 | 30 | | |
27 | 31 | | |
28 | 32 | | |
| |||
35 | 39 | | |
36 | 40 | | |
37 | 41 | | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
38 | 46 | | |
39 | 47 | | |
40 | 48 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
14 | 14 | | |
15 | 15 | | |
16 | 16 | | |
17 | | - | |
18 | | - | |
19 | | - | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
20 | 22 | | |
21 | 23 | | |
22 | 24 | | |
| |||
159 | 161 | | |
160 | 162 | | |
161 | 163 | | |
162 | | - | |
163 | | - | |
164 | | - | |
165 | | - | |
| 164 | + | |
| 165 | + | |
| 166 | + | |
166 | 167 | | |
167 | 168 | | |
168 | 169 | | |
| |||
190 | 191 | | |
191 | 192 | | |
192 | 193 | | |
193 | | - | |
194 | | - | |
195 | | - | |
196 | | - | |
| 194 | + | |
| 195 | + | |
| 196 | + | |
| 197 | + | |
| 198 | + | |
| 199 | + | |
| 200 | + | |
| 201 | + | |
| 202 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
349 | 349 | | |
350 | 350 | | |
351 | 351 | | |
352 | | - | |
353 | | - | |
354 | | - | |
355 | | - | |
| 352 | + | |
| 353 | + | |
| 354 | + | |
| 355 | + | |
| 356 | + | |
| 357 | + | |
| 358 | + | |
356 | 359 | | |
357 | 360 | | |
358 | 361 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
38 | 38 | | |
39 | 39 | | |
40 | 40 | | |
| 41 | + | |
| 42 | + | |
41 | 43 | | |
42 | 44 | | |
43 | 45 | | |
| |||
58 | 60 | | |
59 | 61 | | |
60 | 62 | | |
61 | | - | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
62 | 73 | | |
63 | 74 | | |
64 | 75 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
271 | 271 | | |
272 | 272 | | |
273 | 273 | | |
274 | | - | |
| 274 | + | |
275 | 275 | | |
276 | 276 | | |
277 | 277 | | |
| |||
0 commit comments