Commit Graph

4 Commits

Author SHA1 Message Date
Christopher Wiebe 57fe6bf173 M1: Headless parity verified between Tools and Godot
Proves Theriapolis.Core works untouched under Godot's csproj — the worldgen
pipeline produces byte-identical output whether invoked from the Tools CLI
or from inside the Godot process. This is the determinism contract surviving
the port.

Architecture test:
  CoreNoDependencyTests now forbids Godot.* and GodotSharp in addition to
  Microsoft.Xna and MonoGame. Both bans stay in force for the duration of
  the port so neither engine can leak into Core.

Determinism oracle:
  New worldgen-hash Tools command runs the full pipeline and prints FNV-1a
  hashes for every channel (elevation, moisture, temperature, biomes,
  settlements, polylines) plus per-stage hashes. Pairs with the Godot
  smoke-test for cross-process verification.

Godot-side smoke test:
  SmokeTest.cs runs WorldGenerator.RunAll inside the Godot process; Main.cs
  fires it on --smoke-test <seed>. Resolves Content/Data via res:// walk-up.
  M0 hello-world behaviour preserved when launched without the flag.

Verification (seed 12345):
  - dotnet run -- worldgen-hash and Godot --headless --smoke-test agree on
    all 6 channels and all 14 per-stage hashes (diff produces zero output)
  - 10-run sweeps stable on both sides post-determinism-fix
  - dotnet test: 708/708 pass

Closes M1 of theriapolis-rpg-implementation-plan-godot-port.md.
Next: M2 (world map render).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-30 21:38:15 -07:00
Christopher Wiebe b3da447673 Fix MoistureGen/TemperatureGen non-determinism (FastNoiseLite race)
FastNoiseLite lazily populates its internal _perm[512] table on the first
GetNoise call via EnsurePerm(). When called concurrently from a Parallel.For
loop, threads race on this initialization and may read a partially-populated
table, producing different moisture/temperature values per row across runs.

Empirical: a 10-run worldgen-hash sweep on seed 12345 produced 4+ distinct
moisture hashes and 3+ distinct temperature hashes. All other channels
(elevation, biomes, settlements, polylines) remained stable; biomes only
because their bucket thresholds happened to absorb the upstream float noise.

The fix is the same one ElevationGenStage:125-130 and BorderDistortionGenStage:
102-104 already apply: call GetNoise once on the main thread before the
Parallel.For so _perm is fully initialized when worker threads start reading.
MoistureGenStage and TemperatureGenStage were missing this; now they have it.

WorldgenDeterminismTests didn't catch this because xUnit's WorldCache fixture
runs both pipeline variants in the same process, where consecutive runs hit
the same JIT/thread-pool state and produce the same corrupted output. The
Godot port surfaced it by invoking Core from a fresh process with different
threading.

Verified: post-fix 10-run sweep produces stable hashes on all six channels
(0xA8F99BB9795D8CF8 moisture, 0xAA05F3FB1523F6C3 temperature, seed 12345).
708/708 tests still pass.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-30 21:37:55 -07:00
Christopher Wiebe 59e86af7a2 M0: Scaffold Theriapolis.Godot project (hello-world)
First milestone of the Godot port. Establishes the new project structure
and verifies the toolchain is wired up end-to-end.

- Godot.NET.Sdk/4.6.2 targeting net8.0; references Theriapolis.Core
- project.godot configured for borderless fullscreen at native resolution
  (per port plan §10 resolved decisions); F11 toggles to windowed
- Main.tscn + Main.cs hello-world; nearest-neighbor texture filtering
- icon.svg placeholder (T in gild on dark)
- Added to Theriapolis.sln

Verification:
- dotnet build Theriapolis.Godot.csproj: 0 errors, 0 warnings
- dotnet build Theriapolis.sln: 0 errors (6 pre-existing warnings unrelated)
- dotnet test: 708/708 pass in 26s (unchanged from master)
- Godot 4.6.2 opens project; fullscreen + F11 toggle confirmed visually

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-30 20:52:35 -07:00
Christopher Wiebe b451f83174 Initial commit: Theriapolis baseline at port/godot branch point
Captures the pre-Godot-port state of the codebase. This is the rollback
anchor for the Godot port (M0 of theriapolis-rpg-implementation-plan-godot-port.md).
All Phase 0 through Phase 6.5 work is included; Phase 7 is in flight.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-30 20:40:51 -07:00