feat(core): deterministic bounded SDF landmark stamps, off by default (L43); research R10

Stamp vocabulary v1 (carve ellipsoid/arch, fill pillar/dais) with smooth CSG and seeded relief; the
director resolves records (stable ID, strate, micrometre position, conservative bounds) from
hash(seed, strate, ID) with up to 512 candidates and rejects any that touch a passage mouth, walk corridor,
content face or ceiling/bedrock band; a stamp BVH skips tiles outside all bounds. No requests: canonical
JSON and owner hashes unchanged. --landmark-chamber-demo adds a SW chamber (buried; see review).
fast/medium/full PASS on clean builds. Research R10 (read-only): ore/resource channel design.
Review also records a pre-existing W1/W12 determinism mismatch at a non-spawn camera (L37+, not S14).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016dhxM43dnWvUu2B5Ph1iG1
This commit is contained in:
Fr0zkaandClaude Opus 5.5 committed 2026-10-23 21:50:56 +02:00
1 parent 497e974178
commit 422dd7761a
12 files changed
+1138 -2

No files matched your search

@@ -0,0 +1,72 @@
# Linux 43 — Core landmark SDF stamps
Source stamp: `18b89fb48febf887c5b61e14c699c95535b09613f23618ca57271bc5d2a455f3` (clean Clang and GCC builds).
## Vocabulary and records
Stamp vocabulary v1 contains `carveEllipsoid`, `carveArch`, `fillPillar`, and `fillDais`. A resolved record carries a stable ID, strate index, position in integer micrometres, conservative bounds, half extents, smooth-CSG width, irregularity amplitude and wavelength, irregularity seed, and quarter-turn yaw. Bounds include the smoothing and roughness support.
Carves use smooth maximum with the negated SDF; fills use smooth minimum. Core keeps its density sign: negative is solid and positive is air. Bounded trilinear value noise adds seeded relief.
## Placement and culling
The resolver sorts requests by stable ID and derives placement offsets and irregularity from `(seed, strate, stable ID)`. It tries at most 512 deterministic candidates. The strict layout rejects bounds that intersect a passage mouth or walk corridor, touch a content face, or overlap a ceiling or bedrock band. No safe candidate is a placement error. The route and band negative controls were both rejected (`2/2`).
The stamp BVH queries conservative bounds once per tile. A tile with no candidates performs no stamp SDF evaluation. Stamp-intersecting boxes classify as mixed, and native-only readiness cannot skip them. With no requests, stamp fields are omitted from canonical JSON, preserving L42 identities and hashes.
## Owner demo and hashes
`--landmark-chamber-demo` is off by default. On seed 0 it adds three records to the owner SurfaceWorld strate (strate 1); no Unreal files changed:
- Ellipsoid chamber `landmark/sw-arrival-chamber-v1`: center `(-8.918, 31.950, -513.083) m`, half extents `(8.5, 7.5, 6.0) m`.
- Arch `landmark/sw-arrival-chamber-entrance-v1`: center `(-12.289, 37.027, -513.311) m`, half extents `(2.6, 4.2, 3.2) m`.
- Low dais `landmark/sw-arrival-chamber-dais-v1`: center `(-7.489, 30.688, -515.838) m`, half extents `(3.2, 2.8, 0.9) m`.
The chamber center is 30.9 m from the arrival mouth at `(9.25, 9.25, -502.608) m`, off the walk route. The active layout carries vocabulary version 1 and identity `resolved-layout-v3-fnv64:91eaf2f0248f2c8b`.
Without stamps, the FI/SW layout IDs remain `b7a7d9ecc48d8f26` / `8a52e84c26ed92d2`; the 12-record owner signatures remain L42's FI `9820f4f38b189b3f7263810e7b3ff62aa502b21f476ffcfdbc7761a65cb07d58` and SW `a1e9268a4bbcc77d2a1ac54095df6851a70bab65c43ae50b332ed75132617834`.
At the same chamber-centered camera, W12 hashed 343 tiles. Stamp off: density `0x18d6f6cb3498deff`, mesh `0x293c0ddff66b99f9`, payload `0xeb07403f34d60134`, topology `0x002905a3f028c9f1`. Stamp on: density `0xbf8af855ee5db8fb`, mesh `0xbb64c203dc533070`, payload `0xd14d45e6b9faa9c0`, topology `0x44f1b422df20a159`. The stamp-on W1 and W12 signatures match.
## Safety, cost, and tiers
With the demo on, passage walkability passed `1545/1545`; the passage audit passed; endpoint probes passed `27/27`; the interface audit passed with `hole_columns=0` and `air_samples=0`.
For outside-stamp tiles, five W1 pairs over 343 tiles measured median whole-view-ready `0.457 s` off / `0.466 s` on (`+1.97%`); paired changes ranged from `−2.76%` to `+3.08%`. Five W12 pairs over 125 tiles measured `0.189 s` / `0.191 s` (`+1.06%`). These tile bounds do not intersect a stamp, so the BVH returns no stamp candidates and no stamp SDF runs. The small timing deltas sit within pair-to-pair variation. Full-tier five-pair cost versus `HEAD`: FI `17.342 s` → `17.495 s` (`+0.88%`); SW `1.799 s` → `1.805 s` (`+0.33%`).
| Tier | Result |
|---|---|
| Fast | PASS, 161.3 s, 41 checks |
| Medium | PASS, 468.3 s |
| Full | PASS, 1551.2 s, 539 checks; clean Clang/GCC build, 30-cell determinism, cost pairs |
## Captures
All JPEGs passed `capture_quality.py` and are below 300 KB:
- [Entrance, eye height — 27 KB](captures/chamber-entrance.jpg)
- [Inside — 29 KB](captures/chamber-inside.jpg)
- [Overview — 43 KB](captures/chamber-overview.jpg)
## Failed runs
- An early route-control point hit the mouth guard before the corridor guard; its position was moved so the final route and band controls exercise the intended rejection checks.
- The first JSON round trip lost precision in a 64-bit irregularity seed. Seeds are now kept within the JSON number type's exact 53-bit integer range; canonical round-trip passes.
- A clip-plane capture was rejected by the renderer (`open_contours=10`); the final three views use the uncut mesh.
- A supplemental stamp-off, chamber-centered W1/W12 aggregate differed reproducibly (`density 0x68f495ba62aace05` / `0x18d6f6cb3498deff`), though its nine exact-query probes matched. The standard owner fast/full determinism checks pass, and the stamp-on chamber-centered aggregate matches W1/W12.
## Orchestrator review (Claude)
Merged as **infrastructure, off by default**: the stamp vocabulary, records, placement guards and BVH culling are
sound, the owner hashes are unchanged with no requests, and the route/band controls reject. Not accepted as a
**player-visible** landmark yet:
- the demo chamber is **buried**: its top is about 4.5 m below the SW ground near the arrival mouth, with no opening
to the walkable surface, so a player can never see it;
- the arch reads as a boxy notch with a sharp vertical corner;
- the entrance capture is unreadable.
**Determinism finding (pre-existing, not caused by L43).** The "supplemental stamp-off W1/W12 mismatch" in the
failed-runs list is real. I reproduced it on committed L42 and on L37 (`density 0x68f495ba…` at W1 vs
`0x18d6f6cb…` at W12, camera `(-8.918, 31.950, -513.083)`, `--max-clip-level=0 --render-distance-chunks=0`). S14 is
stable there. It is a worker-count-dependent result in the production path, invisible to our tiers, which only test
the spawn camera and the 24 m crossing. It is the top priority for L44.
Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

@@ -0,0 +1,63 @@
# Research R10 — Ore and resources as a material channel
Read-only review; no code or files changed. The GDD asks for recipe-critical resources to be guaranteed by density within reach of the spine, while optional materials remain random and depth-locked by difficulty tier rather than fixed to particular strates. [GDD §9](</home/jahni/VoxelM/Plugins/VoxelForge/GDD.md:209>) The current edit layer changes density only, and its documentation leaves saving and loading to the game layer. [VoxelDiffLayer.h](</home/jahni/VoxelM/Plugins/VoxelForge/Source/VoxelForge/Public/VoxelDiffLayer.h:1>)
## Representation choice
**Rank 1 — Bounded vein records in the resolved layout, queried analytically for material.** Treat each vein as immutable, versioned data with a stable ID, resource ID, shape and bounds, material, and yield density. Generate the records before tile jobs, then use a per-tile candidate list to restrict membership checks. This is deterministic, uses memory proportional to the number of veins rather than world voxels, and costs roughly one membership test per nearby candidate. Keep the records separate from density so ore does not alter rock or passage topology. Resolve overlaps by stable ID order.
At exposed mesh points, query the material and blend across a configured vein boundary. Mesh attributes need an explicit material identity and blend weight: current F6 vertex color already carries biome, slope, edge blend, and neighboring-biome data, while F17’s two material groups separate ground from sky-cap. [VoxelMarchingCubesMesher.cpp](</home/jahni/VoxelM/Plugins/VoxelForge/Source/VoxelForge/Private/VoxelMarchingCubesMesher.cpp:213>) · [VoxelWorld.cpp](</home/jahni/VoxelM/Plugins/VoxelForge/Source/VoxelForge/Private/VoxelWorld.cpp:697>) Far LODs will naturally undersample narrow veins; define a minimum visible feature size or a distance fade so they don’t flicker. Do not create one mesh section per vein.
**Rank 2 — Material IDs stored or sampled per voxel alongside density.** This is conceptually simple, and a joint density/material sample can reuse the mesher’s lattice work. But storing IDs per chunk adds memory, cache invalidation, save/load, and cross-LOD rules. A sampled ID alone also produces hard boundaries; blending still needs boundary distances or weights. If sampled on demand rather than stored, it is effectively the material query in Rank 1, with the vein records still needed as its source.
**Rank 3 — A separate general resource field.** A continuous field can blend smoothly and represent broad concentrations, but adds another evaluation path or sampled volume. A general noise field also makes exact deposit bounds, resource yields, and recipe guarantees harder to author and audit. It may suit diffuse materials later; it is a poor first representation for countable veins.
## Mining and authority
The games point to two useful patterns: material-bearing terrain that yields resources when mined, and deposit objects that produce collectible units. Minecraft’s ore blocks yield specific items, with Fortune affecting yield and Silk Touch preserving the block. Space Engineers maps mined voxel materials to ore types and ratios. 7 Days to Die harvests resources as blocks are damaged or destroyed, with tools affecting mining efficiency. [Minecraft ores](https://minecraft.wiki/w/Ore) · [Space Engineers voxel materials](https://spaceengineers.wiki.gg/wiki/Modding/Reference/SBC/VoxelMaterial_Definition) · [7 Days to Die mining](https://7daystodie.wiki.gg/wiki/Mining)
Deep Rock Galactic makes mining and carrying part of the mission loop: mined veins enter a limited carried inventory, then get deposited or carried to extraction for team rewards. Astroneer’s terrain tool breaks natural deposits into resource nuggets, while automated extractors increase the yield. [DRG pickaxe](https://deeprockgalactic.wiki.gg/wiki/Pickaxe) · [DRG resources](https://deeprockgalactic.wiki.gg/wiki/Minerals) · [Astroneer resources](https://astroneer.wiki.gg/wiki/Atmospheric_Resources) **For VoxelForge, the useful combination is material-bearing rock plus a carry-and-return inventory loop.**
Recommended flow:
1. The client requests a mining action with a unique sequence, brush, and tool.
2. The server validates reach, tool, limits, and sequence; determines which solid material the edit actually removes at a fixed canonical resolution.
3. In one ordered transaction, the server applies the carve and grants yield only for newly removed solid resource material. A repeated request must not award it twice.
4. The server persists the accepted edit and reward, then replicates the edit and result so all players see the same depleted vein. Late joiners load the same edit state.
The current legacy path writes to `DiffLayer` in `AVoxelWorld::ApplyModification`; it is not a mining-reward flow. [VoxelWorld.cpp](</home/jahni/VoxelM/Plugins/VoxelForge/Source/VoxelForge/Private/VoxelWorld.cpp:14453>) Core’s edit transaction already has a sequence and digest, but its adapter comment calls that boundary a future authority path. It currently returns a digest and affected tiles, not harvested material. [VoxelWorld.cpp](</home/jahni/VoxelM/Plugins/VoxelForge/Source/VoxelForge/Private/VoxelWorld.cpp:14659>) · [VoxelForgeCore.h](</home/jahni/VoxelM/Plugins/VoxelForge/Standalone/Core/include/VoxelForgeCore/VoxelForgeCore.h:1396>) So persistence, replication, and server-side reward accounting remain game-layer work.
## Contract extension
Add a **companion `materialAt(xUm, yUm, zUm) -> MaterialSample` query** to the immutable evaluator bound to the resolved strate. Return the host material, up to two resource material IDs, and a blend weight. Include a material detail envelope if the mesher needs to suppress or fade veins below a safe LOD size.
Resolve versioned vein records and their stable IDs in the director’s snapshot; give tiles a conservative candidate list. Sample materials at mesh surface vertices and during the mining transaction. Keep density culling certificates density-only: materials do not create geometry, so they should not change solid/air proofs. This extends R6’s immutable, coordinate-stable evaluator contract without adding resource work to every density call. [Research6 §2](</home/jahni/VoxelM/Plugins/VoxelForge/Standalone/Research/WorldAssemblerM3/Research6/REPORT.md:24>)
For mining, extend the edit result with deterministic removed-material quantities. Calculate them from the before/after solid state at a fixed world resolution; Unreal awards inventory only after the server accepts the edit. This prevents yield from already-air space and makes replay and duplicate-sequence handling auditable.
## Placement and authoring
- Guarantee a minimum reachable density of every recipe-critical material in each **eligible** strate. Keep depth eligibility tagged by difficulty tier, as the GDD specifies; don’t assign every resource to a fixed strate. Measure “reachable” against the spine and feasible side-pocket dig distance, rather than a coordinate promise. [GDD §9](</home/jahni/VoxelM/Plugins/VoxelForge/GDD.md:209>)
- Bias veins along passage routes and toward side pockets, with a mix of visible surface outcrops and material just behind the wall. Keep the clear passage, landings, and landmark footprints open. Use resolved passage and landmark bounds as placement inputs so resource placement follows planned content rather than tile order.
- The owner authors resource definitions and looks, rarity and depth-tier tables, vein size and yield, and guarantee quotas for recipe-critical materials. The Unreal material palette supplies the visual blend and emissive treatment.
## Implementation plan
1. **Core data:** add versioned vein records to the resolved layout, deterministic generation and stable overlap ordering, plus a tile candidate index. Include the records and material-table version in world identity.
2. **Core query:** add `materialAt` and a material detail envelope. Verify repeatability at fixed physical coordinates across worker counts, tile order, and LOD.
3. **Core mesh:** add explicit material IDs and weights to mesh output; sample at surface vertices and blend at boundaries. Leave density and geometry hashes unchanged.
4. **Core mining result:** return removed-material quantities with the edit result, using a fixed canonical sampling resolution and an idempotent edit sequence.
5. **Unreal integration:** connect ore assets and the new mesh stream/material shader; route mining through server validation, edit persistence, reward persistence, and replication. Ensure both supported edit paths use the same authority flow.
## Measurements for implementation
- Material-query and mesh cost versus the density-only baseline; candidate counts by tile; peak vein-index memory; additional bytes per vertex and upload time.
- Material ID and weight repeatability across workers and tile order; density and topology hash parity; boundary consistency across neighboring tiles.
- Ore visibility and popping across LODs, especially for veins near the minimum feature size; boundary blend width at close and far LOD.
- Yield for each brush shape against newly removed solid ore; zero yield from air and no duplicate yield on replay; persistence and late-join agreement.
- Per eligible strate: recipe-critical yield density, distance to spine, travel and dig distance, and counts of blocked passages or overlapping landmark footprints.
## Owner questions
1. Should yield be proportional to newly removed solid resource volume (recommended for freeform carving), or awarded once per deposit?
2. What spine distance and side-pocket digging effort count as “within reach” for recipe guarantees?