Overlays yield to the body standing in front of them

The warp veil painted over a wizard standing before the mouth — the
overlay passes ran after the sprites with no knowledge of their depth.
Each column now remembers its nearest sprite, and every overlay family
(veils, ghost walls, doorway lintels, rising conjurations) skips the
columns where a body stands closer, while still washing translucently
over anything beyond.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Eric Wagoner
2026-08-23 21:46:27 -04:00
co-authored by Claude Fable 5
parent 7a32370ccb
commit b235a7a9cd
+9
View File
@@ -363,6 +363,10 @@
if (s) sprites.push({ ...s, alpha: f.kind === "impact" ? 1 - p : 1, fallback: f.art });
}
sprites.sort((a, b) => b.sort - a.sort);
// The nearest sprite each column carries: the overlay passes (veils,
// ghosts, lintels, risings) must not paint over a body standing in
// front of them.
const spriteZ = new Float64Array(W).fill(Infinity);
for (const s of sprites) {
const img = imageFor(s.src) ??
(s.fallback
@@ -381,6 +385,7 @@
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;
if (s.depth < spriteZ[col]!) spriteZ[col] = s.depth;
const texX = ((col - s.left) / (s.right - s.left));
if (img) {
ctx.drawImage(
@@ -406,6 +411,7 @@
// translucent, swirling — the doorway between rooms that are not
// neighbors announces itself.
for (const vl of veils) {
if (vl.depth >= spriteZ[vl.col]!) continue;
const vh = Math.min(H * 2.5, H / Math.max(vl.depth, 0.05));
const vTop = half - vh / 2;
const wt = textures.warp!;
@@ -421,6 +427,7 @@
// 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) {
if (ri.depth >= spriteZ[ri.col]!) continue;
const full = Math.min(H * 2.5, H / Math.max(ri.depth, 0.05));
const top0 = half + full / 2 - full * ri.g;
const tex = textures[ri.kind] ?? textures.wall!;
@@ -436,6 +443,7 @@
// Doorway lintels: the frame's top rows hung across each opening.
for (const li of lintels) {
if (li.depth >= spriteZ[li.col]!) continue;
const lh = Math.min(H * 2.5, H / Math.max(li.depth, 0.05));
const lTop = half - lh / 2;
const ft = textures.doorframe!;
@@ -451,6 +459,7 @@
// The ghosts of walls you know are lies: drawn over everything at
// their columns, thin as breath, rippling.
for (const gh of ghosts) {
if (gh.depth >= spriteZ[gh.col]!) continue;
const gHft = Math.min(H * 2.5, H / Math.max(gh.depth, 0.05));
const gTop = half - gHft / 2;
const tex = textures.wall!;