Commit Graph

15 Commits

Author SHA1 Message Date
Fr0zka 10dbe64b06 feat(opstack C3): TunnelNetwork + Underwater in the ported list -- 8 of 8
UsesOperatorStackForChunk now returns true for both, so the archetype switch has a complete
operator-stack twin: per-strate opt-in, every archetype equivalence-tested bit for bit against its
original function.

This changes nothing by itself. The flag still requires bUseOperatorStack ticked on a strate asset,
which is Jahni's call and was deliberately NOT done. What HAS changed is that the flag is no longer
a no-op anywhere: ticking it on any strate now really switches that strate onto the stack.

Not done, and it is the next real prize: ClassifyTile still uses hand-written guards and does not
consume ClassifyBox. That is where measured tile-skipping becomes frames.

DOCS
- CODEMAP 3.2d: ported list 6 of 8 -> 8 of 8; the BuildTunnelNetworkStack row rewritten (19 ops, one
  builder for two archetypes); six new rows for the detail modifiers, each carrying the thing a
  reader would otherwise have to rediscover -- roughness reads STRATE params, terrace re-queries the
  SDF, the cliff's comment disagrees with its code, columns have no strate parameter at all, and
  LocalParams() is the override whose EffectOverBox is too optimistic on a strate with an op pool.
  Also corrected the stale "never compare the two paths" line: C10 is closed and all eight
  equivalence tests compare bit for bit.
- CODEMAP 3.3 UsesOperatorStackForChunk row: same list, plus the warning that the flag is now a real
  switch rather than a harmless tick.
- OPSTACK-PLAN: status header and the Phase 2 order both updated; the three-stage TunnelNetwork
  breakdown and the calls-not-transcribes rule recorded there rather than only in the code.
- OPSTACK-PROGRESS: the closing entry for this unattended run -- every commit in order, the five
  original-code findings ported as-is, the two decisions that are not reversible by taste, the
  ClassifyBox optimism C1 introduced and that must be fixed before ClassifyTile consumes it, what
  breaks first per group, and the likely compile-error spots.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-28 03:46:17 +02:00
Fr0zka ef5bda3d8a feat: TunnelNetwork stage A — the SDF spine, wrapping BuildChunkCache
The last archetype is ~1080 lines with 13 detail modifiers, a two-region
cache and a per-room op override. Porting it whole before anything can be
verified is ~600 unverified lines on top of ~200 — the pattern this
refactor has dodged six times. So: three stages.

Stage A = vertical scale, base rock, cave warp, room graph (+ pits and
chimneys), carve, worms, structural post. 6 ops. It is verifiable NOW
because every detail modifier is amplitude-gated and FStrateGenerationParams
already defaults them all to zero — zeroing SurfaceRoughness sends the
ORIGINAL down exactly the path stage A ported.

TunnelNetwork stays OFF in UsesOperatorStackForChunk until stage C.

The decision that matters: FRoomGraphSource CALLS BuildChunkCache and
EvaluateSDFCached rather than transcribing them. That is where §8.4's
two-region window-invariance discipline lives; a transcription would fork
it, and the fork would be "validated" by a test comparing it to the
original. Only the ~60 lines of glue are transcribed.

FRAME ops are retired. All three candidates are now ported and none needed
one: CaveWarp's scope is exactly one operator (pits/chimneys read unwarped
coords), VerticalScale is a one-line pure function, and the island warp was
already local. Not missing infrastructure — one idea seen three times from
a distance.

Also: check 3 was going to compare two interleaved param sets against the
original, which would have FAILED — the original's SDF cache key has no
params, so it serves B the rooms it built for A. Comparing there measures
its bug, not the port. Rewritten against each stack evaluated alone. The
same reasoning suggests a live production staleness across Gradient
transitions; filed in AUDIT §C2 as SUSPECTED with the check that would
confirm it, since it rests on a premise I have not verified.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-27 18:28:06 +02:00
Fr0zka 96e75abe57 feat: port FloatingIslands — the stack that runs backwards
6 of 8 archetypes ported. This one starts from VOID and FILLS where the
other four start from ROCK and CARVE, which is what it was worth doing:
neither end of the pile needed a new operator, only the opposite sign.

  FConstantRockSource -> FConstantFieldSource(+/-Base)   AllSolid <-> AllAir
  FSdfCarveOp         -> FSdfConvertOp(Sign = +/-1)      carve    <-> fill
  FSdfRoughnessMod                                       4th archetype, unchanged

Only the island blob source is new. Multiplying by +/-1 is exact in
IEEE-754, so the three already-green ports are bit-for-bit untouched.

ClassifyBox can return AllAir for the first time in the plugin, and an
island strate is by construction mostly empty — the test counts AllSolid
and AllAir separately so an aggregate cannot hide whether that fired.

Two bounds that would have been holes if assumed rather than derived:
the island bound is one-sided (a hairline thread of matter hangs below
each island down its axis, so only the TOP may reject), and the domain
warp displaces X and Y independently, so the pad needs WarpAmp*sqrt(2).

Also: AUDIT C1 was NOT closed. The 2026-07-27 sweep matched `SeedF * K`
and this archetype's warp spells it `(float)S * K`, so one site survived
— at seed 2e9 the warp flattens and every island snaps back to a perfect
circle. Fixed in both paths in one pass so the equivalence test stays a
valid oracle. Expect island silhouettes to change at large seeds.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-27 17:50:36 +02:00
Fr0zka 3acb3fbc6b feat: port VerticalShafts — three ops reused from Maze unchanged
The port that tests the thesis rather than the fidelity. Previous ports asked whether
the decomposition reproduces the original; this one asks whether operators actually
get reused across archetypes, which is section 2.5's claim and the only reason to do
this refactor instead of tidying the switch.

ConstantRock, SdfRoughness and SdfCarve are Maze's, reused without a line changed.
In the switch, GetMazeDensity and GetVerticalShaftDensity are two ~100-line functions
with nothing visibly in common; as operators they are the same three ops with a
different source and different tuning (freq 0.1 vs 0.12, window rough+4 vs R+rough+2).

New: FShaftFieldSource (infinite cylinders + hash-gated connectors into the SDF
channel) and FShaftLedgeMod (banded shelves on the +X/+Y half so the shaft stays
climbable).

Deviation from section 6, stated: it suggested splitting the source so the XY-pure
cylinder half could get an exact box verdict. Kept as one op because the connectors
derive from the same 3x3 roll and the ledge mod needs the shaft list anyway, so
splitting means rolling twice or sharing a cache between two ops. Forfeited: the exact
verdict on the cylinder half. Kept: a conservative EffectOverBox testing circles and
connector reach.

FShaftLedgeMod gates on the POST-roughness Sdf as the stack left it; re-deriving it
would use the pre-roughness value and shift every ledge. Reading the channel rather
than recomputing is what the two-channel sample is for.

Compile fix: FCells was declared below the functions returning it. Member bodies are
deferred, return types are not.

Ported: Maze, FlatPlain, CrystalChamber, SurfaceWorld (biomes included),
VerticalShafts — 5 of 8.

UNVERIFIED: not compiled past the FCells fix.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-27 17:11:07 +02:00
Fr0zka 921a9fb666 feat: height-space operator family — SurfaceWorld step 1, and C10 is solved
Maze and Slab now report BIT-IDENTICAL: FPSemantics = Precise, set for
cross-platform play, dissolved the ULP residue. Hypothesis 3 had the right
mechanism all along — under /fp:fast the compiler transforms by surrounding
context with no isolable axis, which is exactly why five one-variable experiments
all came back negative. Removing the permission removed the difference. Nobody
solved C10; C9 got fixed for an unrelated reason and C10 fell out of it.

SurfaceWorld step 1 forced an architectural decision. DECOMPOSITION section 5 notes
the height ops operate on Z values rather than density, then lists them as children
of FHeightfieldSource. Writing them made the consequence unavoidable: they do not
fit IVoxelDensityOp. No input Z (they produce one), XY-pure per column rather than
per voxel, and they write neither channel. Forcing them in would need a per-voxel
channel for a column property, or one opaque op — section 2.5's failure mode.

So height space gets its own contract: VoxelHeightOp.h (FVoxelHeightSample with
Height + Relief, IVoxelHeightOp, FVoxelHeightStack) and five ops. Relief is the
original's M — produced by the structural source, consumed by the terrace gate.
Section 0.1 found density needed a second channel; this found terrain needs a
second space.

The type system now forbids for free what AUDIT 6.3 warns about: a height stack
cannot hold Z-dependent data because there is no Z in the signature.

Deliberately staged — this touches nothing on the density path. If height space had
not decomposed cleanly, it shows up here for one test rather than after building the
adapter, the column cache integration and the dispatch on top.

The test runs twice; the second pass is load-bearing because the F20 terrain ops are
off by default, so a defaults-only run leaves all four modifiers untested. It also
brute-forces MaxDisplacement, since a false bound would later be a hole.

ComputeSurfaceTerrainZ moved private -> public for the test, same justification as
GetSlabDensity. Old declaration removed.

UNVERIFIED: not compiled.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-27 16:06:50 +02:00
Fr0zka 644339def5 feat: Phase 2 first port — FlatPlain + CrystalChamber collapse into one op
Jahni closed OPSTACK-DECOMPOSITION 3.1: the slab noise Z term was not
intentional character. Phase 1 also closed — the visual A/B on Maze passed.

Two changes, deliberately together, kept attributable by the test:

1. Design: GetSlabDensity's floor and ceiling noise lose their Z terms. A floor
   height no longer depends on the altitude you sample it from. The ceiling keeps
   its + 3000.0f, which is a decorrelation offset, not a Z term. The world
   re-tunes once — a different slice of the noise field, not a worse one.

2. Refactor: the now-XY-pure function ports to FSlabVoidSource + FGridColumnMod
   plus the three structural ops. BuildSlabStack has NO branch on archetype
   because GetSlabDensity never had one — CrystalChamber is FlatPlain with a
   bigger CeilingRoughness. 8 archetypes -> 7.

SlabEquivalence compares against the reference AS IT IS NOW and runs the whole
battery on both slots, so green means the port is a pure refactor and any visual
delta is attributable to the Z-term removal alone. The attribution comes from the
test, not from splitting it across two builds.

The payoff 3.1 was actually about: FSlabVoidSource::ClassifyBox is exact and needs
no sampling. FBM is contractually [-1,1], so both surfaces live in Z bands with
known bounds — a tile below the floor band is provably solid, a tile between the
bands provably air. ClassifyTile proves zero tiles for these archetypes today.
FGridColumnMod answers Identity when no column reaches the box, which is what lets
the source's AllAir verdict survive the fold.

UNVERIFIED: not compiled.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-27 15:30:26 +02:00
Fr0zka 974e795b66 fix: call PrepareChunk and guard the degenerate strate on the wired path
Read the step-3 wiring against the equivalence test before spending a build.
The symbols all line up; the two PATHS did not.

- GetDensityAt never called FVoxelOpStack::PrepareChunk, though the test does.
  All seven concrete bodies are empty today so behaviour is unchanged — which is
  the reason to fix it now: the first op to hoist real per-chunk work would have
  been green in test and silently wrong in game. Builds an FVoxelOpContext in the
  same refetch block (chunk, seed, layout version, strate Z bounds). Step stays 1;
  GetDensityAt does not know the mesher's sampling step (T2.b).

- GetMazeDensity early-outs to air on a degenerate strate (height <= 0) and the
  stack has no such early-out by design. Unguarded that is air on one path and
  spine/seal-of-a-zero-height-band on the other, so the wired path now falls back
  to the switch there — the reference behaviour is the behaviour.

Docs: VoxelDensityOpStack.h's banner still claimed nothing here feeds the game,
and CODEMAP 3.2d repeated it. Both now state what is wired (GetDensityAt) and
what is not (ClassifyTile, hand-written guards, Phase 2), with C10's never-compare
rule at the point of use. CODEMAP gains UsesOperatorStackForChunk and
bUseOperatorStack rows, and BuildMazeStack's degenerate-strate precondition.

UNVERIFIED: not compiled.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-27 15:15:59 +02:00
Fr0zka 8a33bcb42a docs: CODEMAP rows + progress entry for the Phase 1 Maze port
CODEMAP gains 3.2c (VoxelDensityPrimitives), 3.2d (the operator stack and its
factories), FVoxelOpSample under 3.2b, and the two new tests under 3.12.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-27 02:33:00 +02:00
Fr0zka 831ee2fbf7 docs: Q3 tick the stale PENDING BUILD markers + CODEMAP rows for the new symbols
Q3: fable-idea F20 phases 1/2 and F18, REVIEW_FINDINGS perf pass 2 and batch 3,
and ARCHITECTURE's biome full-param redesign were all still carrying
"CODE-COMPLETE, PENDING BUILD" markers dated 07-04/-06/-08. Jahni confirmed on
2026-07-26 that everything is built and working (AUDIT-2026-07.md §0), so the
documents were misreporting project state. Ticked with the date they were
ticked, not just the date they were built.

Deliberately NOT ticked: ARCHITECTURE's F6 master material graph. Its C++ half
is built, but the material graph itself is editor-side work that is genuinely
still open, and ticking it would recreate the problem this queue item fixes.

CODEMAP discipline for this batch: new §3.2b (the VoxelDensityOp contract), new
§3.12 (Private/Tests), the EVoxelTileClass move into §3.2, and
FChunkBiomeCache::Invalidate under the biome types row.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-27 02:06:32 +02:00
Fr0zka 69fa73e07e tmp 2026-07-26 02:11:11 +02:00
Fr0zka cb61c8b2e4 potential perf regression 2026-07-04 11:30:43 +02:00
Fr0zka 6875614002 Fix Decoration Placement 2026-06-26 19:15:04 +02:00
Fr0zka e6cd852129 Another pass 2026-06-23 08:30:13 +02:00
Fr0zka db558d9e14 j 2026-06-16 03:39:22 +02:00
Fr0zka f030eec08a Upload of all files, starting point 2026-06-09 20:21:29 +02:00