← hex_place · API reference · version 0.1.3
6 file(s), 674 lines. This is the source the published version ships, and it is loft — the library is written in the same language you call it from.
Public items
A worked example is a call site the author chose as the thing to read first. Call sites are every line naming the item, found mechanically over the source with comments excluded — so an item with no worked example is not an item nobody uses.
| Item | Defined | Worked example | Call sites |
|---|---|---|---|
field_union fn | 34 | — | 58 |
combine_cut fn | 57 | HXP-002 | 42 53 54 61 85 86 … (7 total) |
combine_cut_level fn | 106 | HXP-003 | 119 |
kappa_at_level fn | 147 | HXP-003 | 125 126 129 |
shared_marked fn | 160 | HXP-001 | 43 56 62 |
Pose struct | 25 | — | 34 35 40 44 49 54 … (8 total) |
pose_new fn | 34 | — | 25 180 |
pose_inv_x fn | 40 | — | 67 82 30 |
pose_inv_y fn | 44 | — | 68 83 31 |
pose_fwd_x fn | 49 | — | 69 28 196 |
pose_fwd_y fn | 54 | — | 70 29 197 |
pose_residual fn | 66 | HXP-005 | 183 187 192 |
disk_hit fn | 81 | — | 198 |
arb_solid fn | 98 | HXP-006 | 49 50 51 213 214 215 |
arb_owner fn | 105 | HXP-006 | 218 219 222 223 226 |
SEAT_LOW const | 31 | — | 56 149 |
SEAT_MEAN const | 32 | — | 150 |
SEAT_HIGH const | 33 | — | 57 151 |
seat_height fn | 38 | HXP-004 | 149 150 151 |
seat_residual fn | 66 | HXP-004 | 154 155 |
seat_write fn | 85 | HXP-004 | 159 |
src/hex_place.loft
// Copyright (c) 2026 Jurjen Stellingwerff
// SPDX-License-Identifier: LGPL-3.0-or-later
// hex_place — place, seat and combine — the operations a model survives.
//
// A body carries a POSE and is never stamped into the world lattice; two stencils are combined
// by "mark all, then cut once", which is order-free and fuses their shared edge; and a stencil
// is SEATED on terrain by writing the height slot alone, so its footprint is untouched.
//
// Entry point: re-exports `hexframe`, `hexseat`, `hexcombine`.
pub use hexframe::*;
pub use hexseat::*;
pub use hexcombine::*;
src/hexcombine.loft
// Copyright (c) 2026 Jurjen Stellingwerff
// SPDX-License-Identifier: LGPL-3.0-or-later
// hexcombine — TWO STENCILS ADJACENT: WHO OWNS THE SHARED EDGE? (rung A8, the combination rung).
//
// Where things that work ALONE stop working TOGETHER. The mechanism is crawler's `cut_arb`,
// float-free. The design in one line:
//
// "MARK EVERY PART, THEN CUT ONCE."
//
// Do NOT draw each stencil's walls and overlay them. Union the footprints first, then cut the
// boundary of the UNION once, tagging each boundary edge with the material of the source stencil
// its cell came from. Two consequences, both the point of the rung:
//
// ORDER-FREE BY CONSTRUCTION. The result reads only the finished union and the fixed source
// map — never which stencil was stamped when — so `combine_cut(a, b) == combine_cut(b, a)`. The
// naive per-body overlay is last-writer, hence order-DEPENDENT: it works for one stencil and
// breaks for two. (This is `X4` / law K₂: same-level overlap arbitrates deterministically and
// order-freely.)
//
// THE SHARED EDGE FUSES. Between two adjacent stencils the shared edge is INTERIOR to the union,
// so cutting the union's boundary never marks it — nobody owns it, and there is no seam wall.
// Two adjacent stencils become one fabric (crawler's FORMS.md, DESIGN §8.0.1: "seated fabric may
// merge"). Which two parts were authored is not recoverable from the fabric, and by law P1 need
// not be — `rebuild` returns the canonical representative.
//
// Exact and float-free: the "nearest source" of a boundary edge is simply its own bordering cell's
// stencil, so no distance and no float enter. This is the κ ≤ 2 case; N stencils are the same
// construction (union all, cut once, nearest source). Different LEVELS never contend at all
// (crawler's bridge guarantee) — that axis waits on the layer machinery and is not gated here.
use hex_field::*;
use hex_form::*;
// The union footprint of two stencils sharing `a`'s chunk — a fresh HexSet, `a ∪ b`.
pub fn field_union(a: HexSet, b: HexSet) -> HexSet {
u = hexset_chunk(hexset_q0(a), hexset_r0(a), hexset_w(a), hexset_h(a));
for r in hexset_r0(a)..hexset_r0(a) + hexset_h(a) {
for q in hexset_q0(a)..hexset_q0(a) + hexset_w(a) {
if hexset_get(a, q, r) || hexset_get(b, q, r) { hexset_set(u, q, r, true); }
}
}
u
}
// Combine two same-level stencils: union the footprints, cut the boundary of the union ONCE, and
// tag each boundary edge with the material of the source stencil its bordering cell came from.
// Order-free by construction (reads the finished union + source map, never stamp order); the shared
// interior edge is never cut, so adjacent stencils fuse. Returns the number of edges cut.
//
// The tie-break is INTRINSIC, not positional: a cell in BOTH stencils (an overlap) takes the LOWER
// material id, so `combine_cut(a,b) == combine_cut(b,a)` for overlapping stencils too, not only
// disjoint ones — otherwise "order-free" would quietly hold only for the adjacency case gated here.
// (crawler's full `cut_arb` breaks the same tie by nearest SURFACE then lower id; with no surfaces
// in play the lower id is the whole rule. Overlap itself is a separate, ungated A8 axis.)
//
// Example: @HXP-001
// Example: @HXP-002
pub fn combine_cut(a: HexSet, ma: integer, b: HexSet, mb: integer, e: EdgeSet) -> integer {
u = field_union(a, b);
n = 0;
for r in hexset_r0(u)..hexset_r0(u) + hexset_h(u) {
for q in hexset_q0(u)..hexset_q0(u) + hexset_w(u) {
if hexset_get(u, q, r) {
for d in 0..6 {
nq = nb_q(q, r, d);
nr = nb_r(q, r, d);
if !hexset_get(u, nq, nr) {
ina = hexset_get(a, q, r);
inb = hexset_get(b, q, r);
m = ma;
if inb && !ina { m = mb; }
if ina && inb && mb < ma { m = mb; } // overlap: lower id, order-free
edge_set_mat(e, q, r, nq, nr, m);
n = n + 1;
}
}
}
}
}
n
}
// ── LEVELS — THE BRIDGE GUARANTEE ──────────────────────────────────────────
//
// A **level** is the topological *sheet* a thing sits on — exactly OSM's `layer` tag, and the
// `layer*` axis the foxel already has at the top of its schema (`ROUNDTRIP` §2.4; moros's `cy`).
// crawler settled what it buys (`bridgetest.loft`), and the sharpest statement of it is a contrast:
//
// > the SAME two ways, at the same level, are a level crossing; at different levels, a bridge.
// > Nothing about the ways changes — only the sheet.
//
// **A LEVEL IS NOT A HEIGHT.** The actual `z` comes from the surface/feature interval; the level is
// a discrete sheet index and nothing else. Two things can share a `z` on different levels, or sit
// at different `z` on the same one.
//
// The load-bearing consequence, and why this is not just bookkeeping: **different levels never
// contend.** So the level is a **filter applied BEFORE the cut**, not an arbitration rule after it —
// it does work the contention degree `κ` would otherwise have to do (`X4`, and `DESIGN` §6.1). Most
// of a world exists only at level 0, where this costs exactly nothing.
// Combine two stencils **as seen at level `at`**: only those whose own level matches take part, and
// the survivors are then cut exactly as `combine_cut` does. Two stencils on different levels can
// therefore never fuse, never arbitrate and never contend — at either level, one of them simply is
// not there. Returns the number of edges cut at this level.
//
// Example: @HXP-003
pub fn combine_cut_level(a: HexSet, la: integer, ma: integer,
b: HexSet, lb: integer, mb: integer,
at: integer, e: EdgeSet) -> integer {
ina = la == at;
inb = lb == at;
u = hexset_chunk(hexset_q0(a), hexset_r0(a), hexset_w(a), hexset_h(a));
for r in hexset_r0(a)..hexset_r0(a) + hexset_h(a) {
for q in hexset_q0(a)..hexset_q0(a) + hexset_w(a) {
if (ina && hexset_get(a, q, r)) || (inb && hexset_get(b, q, r)) {
hexset_set(u, q, r, true);
}
}
}
n = 0;
for r2 in hexset_r0(u)..hexset_r0(u) + hexset_h(u) {
for q2 in hexset_q0(u)..hexset_q0(u) + hexset_w(u) {
if hexset_get(u, q2, r2) {
for d in 0..6 {
nq = nb_q(q2, r2, d);
nr = nb_r(q2, r2, d);
if !hexset_get(u, nq, nr) {
inaa = ina && hexset_get(a, q2, r2);
inbb = inb && hexset_get(b, q2, r2);
m = ma;
if inbb && !inaa { m = mb; }
if inaa && inbb && mb < ma { m = mb; } // overlap: lower id, order-free (X52)
edge_set_mat(e, q2, r2, nq, nr, m);
n = n + 1;
}
}
}
}
}
n
}
// The contention degree at one cell, counted **per level**: how many of the two stencils claim it
// *at level `at`*. This is `κ` (`X53`) made level-aware — two stencils that overlap in `(q,r)` but
// sit on different sheets give `κ = 1` at each level, never `κ = 2` at either.
//
// Example: @HXP-003
pub fn kappa_at_level(a: HexSet, la: integer, b: HexSet, lb: integer,
at: integer, q: integer, r: integer) -> integer {
k = 0;
if la == at && hexset_get(a, q, r) { k = k + 1; }
if lb == at && hexset_get(b, q, r) { k = k + 1; }
k
}
// How many marked edges separate an `a`-cell from a `b`-cell — the "shared wall" run. Zero after
// `combine_cut` (the seam fuses); non-zero after a per-body overlay (a spurious seam wall). This
// is the measurable form of "who owns the shared edge?": nobody, if the parts were combined right.
//
// Example: @HXP-001
pub fn shared_marked(a: HexSet, b: HexSet, e: EdgeSet) -> integer {
n = 0;
for r in hexset_r0(a)..hexset_r0(a) + hexset_h(a) {
for q in hexset_q0(a)..hexset_q0(a) + hexset_w(a) {
if hexset_get(a, q, r) {
for d in 0..6 {
nq = nb_q(q, r, d);
nr = nb_r(q, r, d);
if hexset_get(b, nq, nr) && edge_mat(e, q, r, nq, nr) != 0 { n = n + 1; }
}
}
}
}
n
}
src/hexframe.loft
// Copyright (c) 2026 Jurjen Stellingwerff
// SPDX-License-Identifier: LGPL-3.0-or-later
// hexframe — THE FRAME SEAM: a POSED body against the world (DESIGN §6; laws K₁, K₂).
//
// Collision reads several presentations at once — the world (identity frame) plus every posed body.
// Inside a frame geometry is exact; ACROSS frames it cannot be, because a pose is continuous. The
// whole discipline of this module is to make the error live in exactly ONE place:
//
// THE POSE TRANSFORM IS THE SOLE FLOATING-POINT STEP. Every cross-frame query routes through it
// once — world → p⁻¹ → exact local test → (p) → world — so ε > 0 is permitted ONLY on the seam
// (`ε_seam`), and is a DETERMINISTIC function of its inputs (`L7`/`I9`: byte-identical replay).
// Inside a frame the error is exactly 0. (crawler's chunk seam is a different thing, and exact.)
//
// The FORBIDDEN fix is closing a crack by moving geometry — snapping a body's wall onto the world
// lattice. That relocates the machine-ε seam error into a frame INTERIOR, where it becomes a real
// displacement, and voids law D for that body. `tests/seam.loft` §3 measures both.
//
// This is the one place `hexframe` is float, on purpose. Everything the pose acts on is otherwise
// integer/exact (X1–X52), so `ε_seam` is the entire error budget of the stack.
use hex_form::*;
// A pose: a rotation (given as its cos/sin, so a Pythagorean angle can be represented EXACTLY) then
// a translation. Stored as cos/sin rather than θ so a gate can build a rational rotation and check
// the float pipeline against an exact integer oracle.
pub struct Pose {
ps_cs: float,
ps_sn: float,
ps_tx: float,
ps_ty: float,
}
// A placement: a rotation given as cos/sin and a translation. Storing the pair rather than
// an angle keeps `pose_fwd` and `pose_inv` exact inverses with no trig at use time.
pub fn pose_new(cs: float, sn: float, tx: float, ty: float) -> Pose {
Pose { ps_cs: cs, ps_sn: sn, ps_tx: tx, ps_ty: ty }
}
// world → local. THE sole float step (with `pose_fwd_*`). A cross-frame query calls this once and
// then tests in the body's own exact frame.
pub fn pose_inv_x(p: Pose, wx: float, wy: float) -> float {
p.ps_cs * (wx - p.ps_tx) + p.ps_sn * (wy - p.ps_ty)
}
// A world point's y in the pose's frame — the companion of `pose_inv_x`.
pub fn pose_inv_y(p: Pose, wx: float, wy: float) -> float {
0.0 - p.ps_sn * (wx - p.ps_tx) + p.ps_cs * (wy - p.ps_ty)
}
// local → world.
pub fn pose_fwd_x(p: Pose, lx: float, ly: float) -> float {
p.ps_cs * lx - p.ps_sn * ly + p.ps_tx
}
// A local point's y in the world — the companion of `pose_fwd_x`, and the inverse of
// `pose_inv_y`.
pub fn pose_fwd_y(p: Pose, lx: float, ly: float) -> float {
p.ps_sn * lx + p.ps_cs * ly + p.ps_ty
}
// The round-trip residual |p(p⁻¹(W)) − W|∞ at one world point — the transform's numerical error,
// which is what `ε_seam` bounds. Exactly 0 in exact arithmetic; ~machine ε in float.
//
// AT ONE WORLD POINT is the load-bearing half: this is a jagged, deterministic function of the
// point, not a constant. Near the frame origin it commonly reads exactly 0, and reading it there
// and adopting that as ε_seam is the mistake the number exists to prevent.
//
// Example: @HXP-005
pub fn pose_residual(p: Pose, wx: float, wy: float) -> float {
lx = pose_inv_x(p, wx, wy);
ly = pose_inv_y(p, wx, wy);
bx = pose_fwd_x(p, lx, ly);
by = pose_fwd_y(p, lx, ly);
ex = bx - wx; if ex < 0.0 { ex = 0.0 - ex; }
ey = by - wy; if ey < 0.0 { ey = 0.0 - ey; }
if ey > ex { return ey; }
ex
}
// Is world point (wx,wy) inside the disk body posed by `p`? The body is a disk of squared-radius
// `rr` about its LOCAL centre (cx,cy) — a posed tower (its radius is a shell, `X49`). Routes through
// the transform, then the exact local test |l − c|² ≤ rr. This is the general body test in
// miniature: transform once, then decide in the body's own frame.
pub fn disk_hit(p: Pose, cx: float, cy: float, rr: float, wx: float, wy: float) -> boolean {
lx = pose_inv_x(p, wx, wy) - cx;
ly = pose_inv_y(p, wx, wy) - cy;
lx * lx + ly * ly <= rr
}
// ── ARBITRATION WHERE FRAMES DISAGREE (law K₂) ─────────────────────────────
//
// Two requirements the design flags as easy to omit silently: a TOTAL ORDER on frames (a
// "whichever is nearer" tie broken by iteration order breaks replay), and a FAIL-SAFE DIRECTION —
// prefer *solid* over *gap*, so a crack yields a spurious contact rather than a body falling through
// the world (composes with `I4`). Both are captured below and are order-free by construction.
// The fail-safe verdict at a point claimed by two frames: solid if EITHER is solid. Order-free
// (symmetric) and conservative — a gap only where both agree it is a gap.
//
// Example: @HXP-006
pub fn arb_solid(a_solid: boolean, b_solid: boolean) -> boolean { a_solid || b_solid }
// Which frame OWNS a contested point — its material/surface wins. The lowest id among the frames
// claiming *solid* (a total order on frames), or -1 if none is solid. Intrinsic, so it does not
// depend on the order the frames are visited.
//
// Example: @HXP-006
pub fn arb_owner(a_solid: boolean, a_id: integer, b_solid: boolean, b_id: integer) -> integer {
if a_solid && b_solid {
if a_id < b_id { return a_id; }
return b_id;
}
if a_solid { return a_id; }
if b_solid { return b_id; }
-1
}
src/hexseat.loft
// Copyright (c) 2026 Jurjen Stellingwerff
// SPDX-License-Identifier: LGPL-3.0-or-later
// hexseat — SEATING A STENCIL ON TERRAIN.
//
// Terrain is stored in the `height` slot, the same slot as roofs. Seating is the question of
// where a stencil goes on it: a stencil is authored flat in its own local frame, and the ground
// it is placed on is not flat. The answer is *"a building … **seated on terrain**, residual
// flagged"* (`SPEC` **G5**).
//
// THE CONSTRUCTION, AND WHY IT COSTS THE ROUND TRIP NOTHING:
//
// **Seating writes the `height` slot. It does not touch cells or edges.**
//
// So a stencil's footprint is byte-identical on flat ground and on a slope, and `rebuild` — which
// reads the CELLS — recovers the same text either way. Terrain and stencil occupy **orthogonal
// slots** in the foxel, so they compose without interacting at all.
//
// The same shape of answer recurs across the family: a **door** is a
// material, not a hole (`X51`); a **level** is a filter before the cut, not an arbitration after it
// (`X58`); **terrain** is a height, not a change of footprint. Each time the round trip survives
// because the new thing lands in a slot the recovery does not read.
//
// WHAT THE SLOPE DOES COST is a **residual**: a stencil seated at ONE height cannot match ground
// that varies under it. That residual is real, it is a function of the seat policy, and by `G5` it
// must be **returned and flagged — never silently absorbed**. Which height to seat at (lowest,
// mean, highest) is a **policy**; it changes the residual and changes nothing about recoverability —
// the same split `A6` found between `Sep` (recoverability) and `X7` (a choice policy).
use hex_field::*;
use hex_form::*;
pub const SEAT_LOW = 0; // seat at the lowest ground under the footprint — the building perches
pub const SEAT_MEAN = 1; // seat at the mean — the residual is smallest, split above and below
pub const SEAT_HIGH = 2; // seat at the highest — the building is buried into the slope
// The height to seat at, under `policy`. A pure read of the terrain under the footprint.
//
// Example: @HXP-004
pub fn seat_height(cells: HexSet, terr: Heights, policy: integer) -> float {
lo = 0.0;
hi = 0.0;
sum = 0.0;
n = 0;
for r in hexset_r0(cells)..hexset_r0(cells) + hexset_h(cells) {
for q in hexset_q0(cells)..hexset_q0(cells) + hexset_w(cells) {
if hexset_get(cells, q, r) {
z = height_get(terr, q, r);
if n == 0 { lo = z; hi = z; }
if z < lo { lo = z; }
if z > hi { hi = z; }
sum = sum + z;
n = n + 1;
}
}
}
if n == 0 { return 0.0; }
if policy == SEAT_LOW { return lo; }
if policy == SEAT_HIGH { return hi; }
(sum / (n as float)) ?? 0.0
}
// THE RESIDUAL, and it is returned rather than swallowed (`G5`): the largest gap between the seat
// height and the ground under any footprint cell. Zero on flat ground; on a slope it is the
// cut-and-fill the placement owes, and the editor must show it.
//
// Example: @HXP-004
pub fn seat_residual(cells: HexSet, terr: Heights, z: float) -> float {
worst = 0.0;
for r in hexset_r0(cells)..hexset_r0(cells) + hexset_h(cells) {
for q in hexset_q0(cells)..hexset_q0(cells) + hexset_w(cells) {
if hexset_get(cells, q, r) {
d = height_get(terr, q, r) - z;
if d < 0.0 { d = 0.0 - d; }
if d > worst { worst = d; }
}
}
}
worst
}
// SEAT THE STENCIL: write the seat height into the `height` slot for every footprint cell. Cells
// and edges are untouched — that is the whole point, and it is what keeps `rebuild` exact. Returns
// the number of cells whose height was written.
//
// Example: @HXP-004
pub fn seat_write(cells: HexSet, terr: Heights, z: float) -> integer {
n = 0;
for r in hexset_r0(cells)..hexset_r0(cells) + hexset_h(cells) {
for q in hexset_q0(cells)..hexset_q0(cells) + hexset_w(cells) {
if hexset_get(cells, q, r) {
height_set(terr, q, r, z);
n = n + 1;
}
}
}
n
}
tests/01-hex-place.loft
// Copyright (c) 2026 Jurjen Stellingwerff
// SPDX-License-Identifier: LGPL-3.0-or-later
// hex_place — the conformance tests: a pose is exact in its own frame, and two stencils combine
// order-free with their shared edge fused.
//
// Contract only; the exhaustive measurement is hexbody's `tests/seam.loft`, `tests/combine.loft`
// and `tests/level.loft`.
use hex_place::*;
use hex_field::*;
fn twobox(off: integer) -> HexSet {
s = hexset_chunk(-10, -10, 21, 21);
for r in 0..3 { for q in 0..3 { hexset_set(s, q + off, r, true); } }
s
}
fn main() {
a = twobox(0);
assert(hexset_count(a) == 9, "a 3x3 block has 9 cells");
}
fn test_a_pose_inverts_exactly() {
// A pose maps local<->world; the inverse of the forward map returns the original point. This
// is I6 in miniature: the map is a pure function, exact in its own frame.
p = pose_new(0.8, 0.6, 3.0, 4.0); // cos/sin 4/5-3/5, a Pythagorean pose
lx = 2.0;
ly = 5.0;
wx = pose_fwd_x(p, lx, ly);
wy = pose_fwd_y(p, lx, ly);
bx = pose_inv_x(p, wx, wy);
by = pose_inv_y(p, wx, wy);
assert(bx > 1.999 && bx < 2.001, "x survives the round trip, got {bx}");
assert(by > 4.999 && by < 5.001, "y survives the round trip, got {by}");
}
fn test_two_adjacent_stencils_fuse_at_the_shared_edge() {
// "mark all, then cut once": the edge shared by two touching stencils is interior to the union,
// so it is never cut -- the two fuse rather than growing a wall between them.
a = twobox(0);
b = twobox(2); // overlaps a's last column
e = edgeset_new(-10, -10, 21, 21);
combine_cut(a, 1, b, 2, e);
shared = shared_marked(a, b, e);
assert(shared == 0, "no wall is marked on the shared interior, got {shared}");
}
fn test_arbitration_is_fail_safe_toward_solid() {
// A world gap under a body solid reads solid -- collision never falls through. I4.
assert(arb_solid(true, false), "solid over gap is solid");
assert(arb_solid(false, true), "gap over solid is solid");
assert(!arb_solid(false, false), "gap over gap is gap");
}
tests/02-worked-examples.loft
// Copyright (c) 2026 Jurjen Stellingwerff
// SPDX-License-Identifier: LGPL-3.0-or-later
//
// Worked examples for `hex_place` (@PLN141). Each `test_*` below is a REAL,
// run-every-CI demonstration of a contract the signature cannot state; the
// function documents itself by CITING the tag with `// Example: @HXP-00N`, and
// `check_doc_drift.sh examples` fails if a citation goes dangling. These are
// teaching examples, distinct from the conformance suite in `01-hex-place.loft`.
//
// WHAT THIS PACKAGE IS ABOUT. Everything here answers one question — what
// happens where two things MEET — and the answers all have the same shape: the
// contention is removed by CONSTRUCTION rather than settled by a rule applied
// afterwards. Two stencils fuse because the seam is interior to the union that
// was cut. Two levels never contend because the level filters before the cut.
// Terrain never moves a footprint because seating writes a different slot.
//
// That shape is exactly what a signature cannot carry: every one of these is a
// call that quietly does the right thing, and a NEARBY call that quietly does
// the wrong one. The nearby call is what each example shows beside the right
// one, because a demonstration of only the good half teaches nothing about
// which half you are in.
use hex_place::*;
use hex_field::*;
// A 3x3 block of cells, its left column at `off`, in a chunk with room around it.
fn box3(off: integer) -> HexSet {
s = hexset_chunk(-10, -10, 21, 21);
for r in 0..3 { for q in 0..3 { hexset_set(s, q + off, r, true); } }
s
}
// @HXP-001 — TWO ADJACENT STENCILS: WHO OWNS THE SHARED EDGE? Nobody — and
// that is a property of HOW you cut, not of the stencils. Union the footprints
// first and cut the boundary of the union once ("mark all, then cut once"), and
// the shared edge is interior to that union, so it is never cut: the two become
// one fabric with no seam wall between them.
//
// Draw each stencil's own walls instead and overlay them, and both sides mark
// the seam — a wall appears down the middle of what the author drew as one
// building, and every cell of it is reachable, so nothing downstream complains.
//
// This is the same question `hex_grid`'s @HXG-003 answers one level down: there,
// ONE wall between two hexes must resolve to one stored slot, or it becomes two
// half-walls that disagree. Here it is one seam between two STENCILS, and the
// answer is that it should not be stored at all.
fn test_the_shared_edge_belongs_to_nobody_if_you_cut_once() {
a = box3(0); // cells q 0..2
b = box3(3); // cells q 3..5 — adjacent, not overlapping
// THE WRONG WAY, shown first: cut each stencil's own boundary into one edge
// set. `combine_cut(a, 1, a, 1, e)` is exactly "a's own walls".
naive = edgeset_new(-10, -10, 21, 21);
na = combine_cut(a, 1, a, 1, naive);
nb = combine_cut(b, 2, b, 2, naive);
assert(na == 22 && nb == 22, "each 3x3 block alone has 22 boundary edges");
seam = shared_marked(a, b, naive);
assert(seam == 5, "and a wall now runs between them: {seam} marked edges");
// THE RIGHT WAY: one call, one cut, over the union.
fused = edgeset_new(-10, -10, 21, 21);
ng = combine_cut(a, 1, b, 2, fused);
assert(shared_marked(a, b, fused) == 0, "no wall on the shared interior");
// And the arithmetic says exactly where the difference went: the five seam
// edges were each cut twice by the overlay and not at all by the union.
assert(ng == na + nb - 2 * seam, "{ng} = {na} + {nb} - 2 * {seam}");
}
// @HXP-002 — ORDER-FREE BY CONSTRUCTION, including where the stencils OVERLAP.
// The result reads the finished union and a fixed source map, never which
// stencil was stamped when, so swapping the arguments cannot change a single
// edge. Where two stencils claim the same cell the tie goes to the LOWER
// MATERIAL ID — an intrinsic property of the pair, not a positional one.
//
// The distinction matters because "last writer wins" is the natural way to
// build this and is indistinguishable from correct on ONE stencil. It only
// diverges on two, and then only sometimes, which is the worst way for a bug
// to present.
fn test_swapping_the_two_stencils_changes_nothing() {
c = box3(0); // q 0..2
d = box3(2); // q 2..4 — the q=2 column is in BOTH
one = edgeset_new(-10, -10, 21, 21);
two = edgeset_new(-10, -10, 21, 21);
n1 = combine_cut(c, 1, d, 2, one);
n2 = combine_cut(d, 2, c, 1, two);
assert(n1 == 30 && n2 == 30, "the same {n1} edges either way round");
// Not just the same count — the same material on every edge.
same = true;
for r in -10..11 {
for q in -10..11 {
for dir in 0..6 {
nq = nb_q(q, r, dir);
nr = nb_r(q, r, dir);
if edge_mat(one, q, r, nq, nr) != edge_mat(two, q, r, nq, nr) { same = false; }
}
}
}
assert(same, "and the same material on every one of them");
}
// @HXP-003 — A LEVEL IS A FILTER APPLIED BEFORE THE CUT, not an arbitration
// rule applied after it. Two stencils on different levels do not fuse, do not
// arbitrate and do not contend: at either level, one of them simply is not
// there. So the contention degree is 1 at each level even where the two
// overlap in (q,r) — a bridge over a road contends with nothing.
//
// A LEVEL IS NOT A HEIGHT. It is a discrete sheet index; the actual z comes
// from the height slot (@HXP-004). Two things can share a z on different
// levels, or sit at different z on the same one.
fn test_two_levels_never_contend_however_much_they_overlap() {
c = box3(0); // q 0..2
d = box3(2); // q 2..4 — overlaps c at q=2
// Seen at level 0, with c on level 0 and d on level 1, only c is there —
// so the cut is c's own boundary, exactly as if d did not exist.
lv = edgeset_new(-10, -10, 21, 21);
n0 = combine_cut_level(c, 0, 1, d, 1, 2, 0, lv);
solo = edgeset_new(-10, -10, 21, 21);
nsolo = combine_cut(c, 1, c, 1, solo);
assert(n0 == nsolo, "at level 0 the cut is c alone: {n0} edges");
// The overlap cell is claimed once at each level, never twice at either.
assert(kappa_at_level(c, 0, d, 1, 0, 2, 0) == 1, "one claim at level 0");
assert(kappa_at_level(c, 0, d, 1, 1, 2, 0) == 1, "one claim at level 1");
// Put them on the SAME level and that same cell is contended by two.
assert(kappa_at_level(c, 0, d, 0, 0, 2, 0) == 2, "same level: two claims, one cell");
}
// @HXP-004 — SEATING WRITES THE HEIGHT SLOT AND NOTHING ELSE. A stencil is
// authored flat and the ground under it is not, so seating has to give somewhere
// — and where it gives is a number RETURNED to you, never a change to the
// footprint. The cells are byte-identical on flat ground and on a slope, which
// is what lets the model be recovered from the cells either way.
//
// The policy (low / mean / high) chooses the residual, not the shape: a building
// perches, splits the difference, or is buried, and the footprint is the same
// three by three cells in all three cases. Read `seat_residual` and show it —
// it is the cut and fill the placement owes, and swallowing it is the one thing
// this design refuses to do for you.
fn test_seating_moves_the_height_never_the_footprint() {
a = box3(0);
terr = heights_new(-10, -10, 21, 21);
for r in 0..3 { for q in 0..3 { height_set(terr, q, r, q as float); } } // a slope, 0..2
// Three policies, three seat heights, over the same nine cells.
assert(seat_height(a, terr, SEAT_LOW) == 0.0, "perch on the lowest ground");
assert(seat_height(a, terr, SEAT_MEAN) == 1.0, "or split the difference");
assert(seat_height(a, terr, SEAT_HIGH) == 2.0, "or bury into the slope");
// The residual is the choice's cost, and it is handed back rather than absorbed.
assert(seat_residual(a, terr, 1.0) == 1.0, "seated at the mean, the worst gap is 1.0");
assert(seat_residual(a, terr, 0.0) == 2.0, "perched, it is 2.0 — the same slope, a worse fit");
// Seating writes heights. The footprint does not move.
before = hexset_count(a);
wrote = seat_write(a, terr, 1.0);
assert(wrote == 9, "nine cells got a height");
assert(hexset_count(a) == before, "and the footprint is the same {before} cells");
assert(height_get(terr, 0, 0) == 1.0, "the ground under the stencil now reads the seat height");
}
// @HXP-005 — THE POSE TRANSFORM IS THE ONLY PLACE FLOAT ERROR LIVES, and ONE
// MEASUREMENT OF IT IS NOT A BOUND. Inside a frame every test is exact
// integer work; across frames it cannot be, because a pose is continuous. The
// design confines that error to the transform so the whole stack has one error
// budget — but the size of it depends on WHERE you evaluate it.
//
// Measure the residual near the frame origin and you will very reasonably read
// exactly zero, and conclude the transform is exact. The same pose, at a point
// a hundred times further out, is not zero. It is deterministic — the same
// inputs always give the same answer, which is what replay needs — but it is a
// jagged function of the point, not a constant you can sample once.
//
// So: never compare cross-frame coordinates with `==`, and never take a
// tolerance from a measurement made next to the origin.
fn test_one_sample_of_the_seam_error_is_not_a_bound() {
g = pose_new(0.8660254037844386, 0.5, 3.0, 4.0); // a 30-degree pose
// Near the origin: exactly zero, and that is a true measurement.
near = pose_residual(g, 10.0, 7.0);
assert(near == 0.0, "at (10,7) the round trip is exact");
// The same pose, further out: not zero.
far = pose_residual(g, 1000.0, 700.0);
assert(far > 0.0, "at (1000,700) it is not, though nothing about the pose changed");
assert(far < 0.000001, "it is still tiny — the seam is tight, it is simply not zero");
// Deterministic, which is what byte-identical replay rests on.
assert(pose_residual(g, 1000.0, 700.0) == far, "the same inputs give the same answer");
// Inside the frame there is no such caveat: the forward map lands a local
// point exactly on the boundary of a local disk test, radius 5 about (0,0).
wx = pose_fwd_x(g, 3.0, 4.0);
wy = pose_fwd_y(g, 3.0, 4.0);
assert(disk_hit(g, 0.0, 0.0, 25.0, wx, wy), "the local test is exact in its own frame");
}
// @HXP-006 — ARBITRATION FAILS SAFE TOWARD SOLID, and the owner is INTRINSIC.
// Where two frames disagree about a point, `arb_solid` answers solid if either
// does: a crack between presentations yields a spurious contact rather than a
// body falling through the world. It is symmetric, so it cannot depend on which
// frame you happened to visit first.
//
// `arb_owner` breaks the tie by LOWEST ID — a total order on frames, not
// "whichever is nearer" and not iteration order, either of which would make a
// replay diverge. Its no-owner answer is **-1**, and -1 is a sentinel, not an
// id: in loft a negative index reads from the END of a vector rather than
// failing, so handing it on unchecked finds a frame, just not the right one.
fn test_arbitration_prefers_solid_and_names_an_owner_intrinsically() {
assert(arb_solid(true, false), "solid over gap is solid");
assert(arb_solid(false, true), "and so is gap over solid — it is symmetric");
assert(!arb_solid(false, false), "only where both agree is it a gap");
// Both solid: the lower id owns it, whichever way round you ask.
assert(arb_owner(true, 7, true, 3) == 3, "lowest id wins");
assert(arb_owner(true, 3, true, 7) == 3, "and the answer does not depend on the order");
// One solid: that one owns it, high id or not.
assert(arb_owner(false, 7, true, 3) == 3, "the solid frame owns it");
assert(arb_owner(true, 7, false, 3) == 7, "even when its id is the larger");
// Neither: -1, which is not a frame.
assert(arb_owner(false, 7, false, 3) == -1, "no owner is -1, and -1 is not an id");
}