Credibility pass: the reel's scars sanded, the veil finally hung
Three blind reviews over the first-person arc, every finding verified against the source. History-narrating comments made timeless or cut; the stacked BUDDY comment collapsed to one voice. Dead code out: the orphaned FACE copy, the DIR_ANGLE duplicate, the dead loop-counter poke, the impossible-state sentinel. The never-produced "warp" hit kind resolved the right way — warp mouths now hang a translucent veil of the painted warp texture, so art that never rendered finally does. Types tightened (SlabStrike named once, ShareData rides CatchUpStep, botTier loses its casts), the gallery reads MATERIALS instead of a hand-copied list, the chronicle resets through one helper, a superseded share mint rejects instead of stranding, and the conjured safe gains the growth key its siblings had. Tests lose a triple assignment, a tautology, and two self-swallowing regex alternatives. The sprite spec — which still told the artist to paint for additive compositing the renderer no longer uses — now describes the renderer that exists. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
88994f18a2
commit
7a32370ccb
@@ -55,16 +55,6 @@
|
||||
return img.complete && img.naturalWidth > 0 ? img : null;
|
||||
}
|
||||
|
||||
/** Base colors per face (fallback + tinting basis). */
|
||||
const FACE: Record<string, [number, number, number]> = {
|
||||
wall: [126, 118, 100],
|
||||
stone: [96, 96, 104],
|
||||
door: [130, 92, 48],
|
||||
rim: [82, 76, 66],
|
||||
firewall: [214, 92, 28],
|
||||
warp: [96, 60, 160],
|
||||
};
|
||||
|
||||
// Materials come from /textures/*.png when those files exist — the
|
||||
// independently paintable set — with the baked procedurals underneath
|
||||
// so a missing or still-loading file never leaves a wall naked.
|
||||
@@ -253,6 +243,9 @@
|
||||
// VIRTUAL one only through its OWN warp's columns, beyond the mouth.
|
||||
const warpIdCol = new Int32Array(W).fill(-1);
|
||||
const warpDistCol = new Float64Array(W).fill(Infinity);
|
||||
// Each mouth a ray passed through hangs a translucent veil of the
|
||||
// warp texture at its own depth, drawn with the other overlays.
|
||||
const veils: { col: number; depth: number; u: number }[] = [];
|
||||
// Known illusions: the ray passes, but a translucent ghost of a wall
|
||||
// stands at the crossing — drawn after the sprites so bodies show
|
||||
// through it, shimmering so nobody mistakes it for stone.
|
||||
@@ -269,6 +262,7 @@
|
||||
if (hit.warpId !== undefined) {
|
||||
warpIdCol[col] = hit.warpId;
|
||||
warpDistCol[col] = (hit.warpDist ?? 0) * Math.cos(rayAngle - facing);
|
||||
veils.push({ col, depth: warpDistCol[col]!, u: hit.warpU ?? 0 });
|
||||
}
|
||||
if (hit.ghost) {
|
||||
ghosts.push({
|
||||
@@ -289,9 +283,9 @@
|
||||
const top = half - wallH / 2;
|
||||
const tex = hit.frame ? textures.doorframe! : textures[hit.kind] ?? textures.wall!;
|
||||
// Sample by the texture's own size: painted files may be any scale.
|
||||
// Fire and warps shift their slice per world cell, so a blaze
|
||||
// spanning edges reads as one long fire, not a repeated flame.
|
||||
const texU = hit.kind === "firewall" || hit.kind === "warp"
|
||||
// Fire shifts its slice per world cell, so a blaze spanning edges
|
||||
// reads as one long fire, not a repeated flame.
|
||||
const texU = hit.kind === "firewall"
|
||||
? (hit.u + Math.floor(hit.worldU) * 0.37) % 1
|
||||
: hit.u;
|
||||
ctx.drawImage(tex, Math.min(tex.width - 1, texU * tex.width), 0,
|
||||
@@ -316,11 +310,6 @@
|
||||
ctx.fillRect(col, top, 1, wallH);
|
||||
dark *= 0.5; // the fire lights itself
|
||||
}
|
||||
if (hit.kind === "warp") {
|
||||
const swirl = 0.12 + 0.12 * Math.sin(time / 240 + hit.worldU * 9);
|
||||
ctx.fillStyle = `rgba(190,150,255,${Math.max(0, swirl)})`;
|
||||
ctx.fillRect(col, top, 1, wallH);
|
||||
}
|
||||
if (hit.kind === "wall" && hit.edge && view.illusionEdges[hit.edge] === "untested") {
|
||||
// The same tell the board gives: an untested illusion's face
|
||||
// shimmers faintly — maybe stone, maybe not.
|
||||
@@ -389,7 +378,7 @@
|
||||
for (let col = Math.max(0, s.left | 0); col < Math.min(W, s.right); col++) {
|
||||
if (s.depth >= zbuf[col]!) continue;
|
||||
if (s.warped) {
|
||||
if (warpIdCol[col] !== (s.warpId ?? -2) || s.depth <= warpDistCol[col]!) continue;
|
||||
if (warpIdCol[col] !== s.warpId || s.depth <= warpDistCol[col]!) continue;
|
||||
} else if (s.depth >= warpDistCol[col]!) continue;
|
||||
if (s.clampL !== undefined && (col < s.clampL || col > s.clampR!)) continue;
|
||||
const texX = ((col - s.left) / (s.right - s.left));
|
||||
@@ -413,6 +402,22 @@
|
||||
if (s.alpha !== undefined || s.glow) ctx.globalAlpha = 1;
|
||||
}
|
||||
|
||||
// Warp mouths wear their veil: the warp texture at the opening,
|
||||
// translucent, swirling — the doorway between rooms that are not
|
||||
// neighbors announces itself.
|
||||
for (const vl of veils) {
|
||||
const vh = Math.min(H * 2.5, H / Math.max(vl.depth, 0.05));
|
||||
const vTop = half - vh / 2;
|
||||
const wt = textures.warp!;
|
||||
ctx.globalAlpha = 0.3;
|
||||
ctx.drawImage(wt, Math.min(wt.width - 1, vl.u * wt.width), 0,
|
||||
Math.max(1, wt.width / 96), wt.height, vl.col, vTop, 1, vh);
|
||||
ctx.globalAlpha = 1;
|
||||
const swirl = 0.1 + 0.1 * Math.sin(time / 240 + vl.u * 9 + vl.col * 0.02);
|
||||
ctx.fillStyle = `rgba(190,150,255,${Math.max(0, swirl)})`;
|
||||
ctx.fillRect(vl.col, vTop, 1, vh);
|
||||
}
|
||||
|
||||
// Conjurations rising: the wall (or stone) grows bottom-up where it
|
||||
// will stand, glowing swirls running over the young face.
|
||||
for (const ri of risings) {
|
||||
@@ -521,7 +526,7 @@
|
||||
const bottom = half + wallH / 2 - b.rise * wallH;
|
||||
// A cell-bound volume is windowed to its own square: the billboard's
|
||||
// camera-facing plane is intersected with the cell, and only that
|
||||
// lateral segment may paint — an obliquely-viewed hedge can no longer
|
||||
// lateral segment may paint, so an obliquely-viewed hedge cannot
|
||||
// poke its ends through the neighboring walls. (Virtual warp copies
|
||||
// skip this — their clip cell lives in another frame.)
|
||||
let clampL: number | undefined;
|
||||
|
||||
Reference in New Issue
Block a user