Gododin Gododin Documentation

Linked repository document

Boid flock evaluation — original findings

examples/boid_flock/eval/reviews/2026-09-12-original.md

This document retains its design, example or evidence context. References outside this guide show their repository paths.

View original Markdown · Download · Return to the guide

Assistant review on 2026-09-12, against baseline 30dcf4c (also present in bb12f77). User requested “Review the other evals as well, fix when needed”. This record preserves the original judgments; follow-up dispositions belong in the coordinated batch record. Paths and line numbers below refer to the baseline.

Pinned Odin subsystem command passed all 13 tests in 13.11 ms: odin test examples/boid_flock/subsystem -o:speed -out:examples/boid_flock/.gododin/review-subsystem-tests. No Godot process was launched during this source review.

  • F1 — blocker: the run gate can pass without rendering. test.sh:110–117 returns after a headless PASS whose verification is explicitly skipped. The promised subsequent windowed tier never runs. Lines 112/149 swallow engine exit status; lines 96/157 accept a screenshot from a previous run; lines 65–68 choose the newest publication directory without checking accepted/current source identity. Missing tools also return success at lines 35–47. Success condition: mandatory configured prerequisites, current accepted artifact, distinct explicit tiers, real exit/error checks, fresh capture and zero owners.
  • F2 — should-fix: interactive and failure exits leak staging. main.gd:84–85 and 237–242 quit without shutdown; no exit hook exists. Native flock.odin:66–69 can free only the pure arena. Normal Escape/close and failure paths therefore leave the retained foreign owner alive. Success: each exit invokes cooperative cleanup, with zero foreign values and instances in the final Host receipt.
  • F3 — should-fix: setup/resize failure ownership is unsound. Native flock.odin:119–127 leaks local staging when simulation allocation fails. 280–299 changes engine capacity before an old-owner retirement failure yet claims it undoes the resize; the engine remains new-sized against old staging. frames_submitted and verification windows also remain stale after resize. Success: partial setup retains or retires each owner; resize adopts a coherent new extent and retains any failed retirement for cleanup; verify refuses until a frame has been submitted for the current extent.
  • F4 — should-fix: the native scene also runs a hidden GDScript flock. main.tscn:59–62 merely hides Baseline while gd_flock.gd:63–64 steps regardless of visibility. Default native play and the native eval both execute 400 hidden GDScript agents. Success: inactive mode never processes; eval asserts this.
  • F5 — should-fix: the comparison is a different simulation and population. gd_flock.gd:95–127 integrates in place while Odin gathers acceleration before integrating all agents (subsystem/flock.odin:552–715). It omits the total acceleration clamp at native lines 673–679 and seeds with a different RNG (gd_flock.gd:44–57). The cap of 500 versus native 10,000 contradicts “same visible work” (README.md:42–44). Success: matched initialization, two passes, bounded rules and same-count comparison; explicitly state numerical tolerance and separately retain the original native 1,000/10,000 workload.
  • F6 — should-fix: mode/count UI can error or misreport. main.gd:124 uses %PredatorHint without the scene setting unique_name_in_owner. Count changes apply only via drag_ended (131–140), excluding keyboard/wheel changes. Returning from baseline does not apply its requested count to native; baseline stats derive population from the slider (172) instead of actual state. Success: each control action has an applied state, actual counts are displayed, switching modes performs no invalid node lookup, and errors are surfaced.
  • F7 — should-fix: invalid live parameters poison simulation state. Native flock.odin:151–159 accepts NaN weights, infinite values and overflow during f64→f32 narrowing. Pure steering_valid:189–196 validates only perception/speed, allowing invalid weights/predator coordinates to produce NaN state. Success: finite full live-parameter admission before mutation, including narrowed values.
  • F8 — should-fix: correctness and warm-allocation claims lack their oracles. Hash tests check placement/permutation, while replay uses the same algorithm. README.md:136 calls a physics oracle impossible, although an independent small-flock all-pairs one-step comparison is possible. Structural hash checks do not detect warm allocation regressions (README.md:114–116). Success: all-pairs differential cases across cell/wall/perception changes and instrumented zero allocations/frees for warm step, writer and queries.
  • F9 — should-fix: offline eval silently tolerates failed work and rewrites evidence. eval/main.odin:109–110 ignores return values in the measured loop; malformed/unknown arguments at 28–40 silently select defaults. test.sh:61 always invokes --write, replacing the historical receipt; the writer also hardcodes host identity. Success: bounded strict arguments, all work asserted, emitted measurements retained separately, original receipt immutable.
  • F10 — nit: “bitwise” checks are numeric float comparisons. subsystem/flock.odin:803,836 uses !=, so +0 and -0 compare equal. Success: compare u32 representations and include a signed-zero regression.
  • F11 — nit: README facts overreach or diverge. README.md:106–107 names 158.1/6705.9 µs while its linked receipt records 146.221/6484.661. Density at lines 183–184 is 0.09259 agents/unit³, not 0.037. A single MultiMesh submission does not imply one total draw call when shadow passes are enabled (90–91, scene:83). Success: link measurements without duplicated mutable numbers and bound renderer/CPU claims to actual measurements.

The pure Odin storage/ownership layout and deterministic iteration are otherwise clear, and the existing same-seed digest assertion is real evidence for replay. It does not prove physics correctness, visual quality, or total scene performance.