feat: 0_height hillshade snapshot + TCRV blueprint section + harness (terrain-water task 05)

0_height: hypsometric storm-ladder tint x Lambert NW hillshade over
the curved heights, captured after topography in both curve modes —
relief is finally visible. Renumbers nothing.

TCRV (50 B, emitted when the curve is on): curve version + input knots
+ output bands, so blueprints are self-describing about the map their
heights went through (H7 spirit). Parsed into
WorldBlueprint.TerrainCurve (null = raw legacy profile); server treats
it as metadata. Round-trip harness compares it when present.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Stewart Howe 2026-08-07 15:24:33 -04:00
parent 67868638be
commit e7de292b3d
5 changed files with 142 additions and 1 deletions

View file

@ -120,6 +120,7 @@ public partial class RoundTripHarness : Node
ok &= CompareRoads("Rugged", a.RuggedRoads, b.RuggedRoads);
ok &= CompareRoads("Trail", a.TrailRoads, b.TrailRoads);
ok &= CompareWater(a, b);
ok &= CompareTerrainCurve(a, b);
if (ok)
GD.Print($"[Harness] Semantic equality holds: {a.MapSize}x{a.MapSize} grid, " +
@ -185,6 +186,29 @@ public partial class RoundTripHarness : Node
return ok;
}
private bool CompareTerrainCurve(WorldBlueprint a, WorldBlueprint b)
{
if (a.TerrainCurve == null && b.TerrainCurve == null)
{
GD.Print("[Harness] TCRV: absent in source — nothing to compare (and none reappeared).");
return true;
}
if (a.TerrainCurve == null || b.TerrainCurve == null)
{
GD.PrintErr("[Harness] TCRV presence mismatch between source and reread.");
return false;
}
var ca = a.TerrainCurve; var cb = b.TerrainCurve;
bool same = ca.Version == cb.Version;
float[] fa = { ca.T1, ca.T2, ca.T3, ca.T4, ca.HMaxCal, ca.Sea, ca.OrangeCeil, ca.RedCeil, ca.PlateauLo, ca.PlateauHi, ca.PeakCap, ca.TailSlope };
float[] fb = { cb.T1, cb.T2, cb.T3, cb.T4, cb.HMaxCal, cb.Sea, cb.OrangeCeil, cb.RedCeil, cb.PlateauLo, cb.PlateauHi, cb.PeakCap, cb.TailSlope };
for (int i = 0; i < fa.Length; i++)
if (System.BitConverter.SingleToInt32Bits(fa[i]) != System.BitConverter.SingleToInt32Bits(fb[i])) same = false;
if (!same) { GD.PrintErr("[Harness] TCRV fields differ."); return false; }
GD.Print($"[Harness] TCRV equal (curve v{ca.Version}).");
return true;
}
private bool CompareRoads(string tier, List<Vector2[]> a, List<Vector2[]> b)
{
if (a.Count != b.Count)