clone

an endless marble-race generator in the browser; the url is the seed, so every track can be shared

Island wedges respect the surface: full-course openness, lower-side slopes, corner-checked diagonals, one-face waterfalls

Dami committed 5e45ea4
commit
5e45ea46c9b698cc87207e8dc90281608a597ed5
parent
320cf61ec8364f035db5b6e9776f0ef5d37c7b03
author
Dami <dami.etoile@gmail.com>
1 file changed, +32 -8
Msrc/gen/endless/islands.ts40++++++++++++++++++++++++------
M src/gen/endless/islands.ts +32 -8
@@ -252,12 +252,20 @@ export function buildIsland(
252252 [-1, 0],253253 [0, -1],254254 ];255- /** Open at the column's own level: no column there, or one whose top256- * sits a course or more lower. */257- const openAt = (c: Col, dx: number, dz: number): boolean => {255+ /** How far the surface DROPS from this column's top to the neighbor256+ * (Infinity into the void). Shaping decisions read the surface through257+ * this: a wedge face needs a full course of air or it sinks into the258+ * neighbor's block. */259+ const dropAt = (c: Col, dx: number, dz: number): number => {258260 const n = cols.get(key(c.wx + dx, c.wz + dz));259- return !n || n.topWorld < c.topWorld - 0.26;261+ return n ? c.topWorld - n.topWorld : Infinity;260262 };263+ /** Open at the column's own level: no column there, or one whose top264+ * sits a FULL course or more lower (USER RULE: pyramid/wedge blocks265+ * must respect the surface they are on — a side counted "open" at a266+ * half-course drop buried the wedge's low edge in its neighbor). */267+ const openAt = (c: Col, dx: number, dz: number): boolean =>268+ dropAt(c, dx, dz) >= 0.99;261269 const shaped = new Set<string>(); // no caps/decor on these tops262270 263271 // Waterfall pick (per island): one qualifying edge column.
@@ -342,13 +350,17 @@ export function buildIsland(
342350 open.length >= 1 && open.length <= 2 &&343351 cellRng.chance(0.7);344352 353+ // One face per waterfall column — water can't zigzag around the354+ // corner course to course (the old per-course re-pick did).355+ const fallFace = isFall ? cellRng.pick(open) : null;356+345357 let remaining = c.depth;346358 let yTop = c.topWorld;347359 let course = 0;348360 while (remaining >= 1 - 1e-9) {349361 const mat = matAt(yTop, c.topWorld);350362 if (course === 0 && isFall) {351- const [dx, dz] = cellRng.pick(open);363+ const [dx, dz] = fallFace!;352364 placements.push({353365 pieceId: `${NATURE}:cliff_waterfallTop_${mat}`,354366 pos: [c.wx, yTop - 1, c.wz],
@@ -358,7 +370,7 @@ export function buildIsland(
358370 shaped.add(k);359371 } else if (course > 0 && isFall && remaining >= 2 - 1e-9) {360372 // Water continues down the face toward the void.361- const [dx, dz] = cellRng.pick(open);373+ const [dx, dz] = fallFace!;362374 placements.push({363375 pieceId: `${NATURE}:cliff_waterfall_${mat}`,364376 pos: [c.wx, yTop - 1, c.wz],
@@ -367,9 +379,21 @@ export function buildIsland(
367379 });368380 } else if (course === 0 && trim) {369381 // Slope toward the single open side; diagonal across a corner.382+ // USER RULE: the wedge must respect the surrounding surface — the383+ // diagonal cut needs the corner cell BETWEEN its two open sides384+ // open too (else the cut face jams into that block's corner), and385+ // with two open sides the slope descends toward the LOWER one.370386 const dirs = open.map(([dx, dz]) => dirOf(dx, dz));371- const corner = open.length === 2 &&387+ const adjacent = open.length === 2 &&372388 (open[0][0] !== open[1][0] && open[0][1] !== open[1][1]);389+ const corner = adjacent &&390+ dropAt(c, open[0][0] + open[1][0], open[0][1] + open[1][1]) >= 0.99;391+ const slopeDir = open.length === 1392+ ? dirs[0]393+ : dropAt(c, open[1][0], open[1][1]) >394+ dropAt(c, open[0][0], open[0][1])395+ ? dirs[1]396+ : dirs[0];373397 placements.push({374398 pieceId: `${NATURE}:${375399 corner ? "cliff_blockDiagonal" : "cliff_blockSlope"
@@ -380,7 +404,7 @@ export function buildIsland(
380404 ? diagRot(381405 dirs.includes((dirs[0] + 1) % 4) ? dirs[0] : dirs[1],382406 )383- : slopeRot(dirs[0]),407+ : slopeRot(slopeDir),384408 role: "support",385409 });386410 shaped.add(k);