Fog of war: wider fades and a grainy edge instead of stepped lines (t17)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-24 12:39:13 -04:00
co-authored by Claude Opus 5.5
parent 1f56d27ded
commit a18dcda8a4
7 changed files with 43 additions and 17 deletions
+12 -7
View File
@@ -1,6 +1,7 @@
// Exploration only: never changes grains or the random stream.
const FOG = 2;
const FOG_SENSE = 20; // Reveal nearby ground through rock, in grains.
const FOG_SENSE = 24; // Reveal nearby ground through rock, in grains.
const FOG_SENSE_FADE = 12;
let fog, FW, FH;
function fogAlloc() { FW = Math.ceil(W / FOG); FH = Math.ceil(H / FOG); fog = new Uint8Array(FW * FH); }
function fogMark(x, y, v) {
@@ -13,7 +14,7 @@ function fogSeen(x, y) {
return fog[Math.floor(y / FOG) * FW + Math.floor(x / FOG)];
}
function fogInit() {
for (let x = 0; x < W; x++) for (let y = 0; y < Math.min(H, surfY[x] + 8); y++) fogMark(x, y, y <= surfY[x] ? 255 : (surfY[x] + 8 - y) * 255 / 8);
for (let x = 0; x < W; x++) for (let y = 0; y < Math.min(H, surfY[x] + 16); y++) fogMark(x, y, y <= surfY[x] ? 255 : (surfY[x] + 16 - y) * 255 / 16);
}
function fogLook(cx, cy) {
for (let a = 0; a < 256; a++) {
@@ -24,23 +25,27 @@ function fogLook(cx, cy) {
if (x < 0 || y < 0 || x >= W || y >= H) break;
const ph = PH[mat[y * W + x]];
if (hit < 0 && (ph === PH_SOLID || ph === PH_POWDER)) hit = d;
const v = Math.min(255, (48 - d) * 255 / 8, hit < 0 ? 255 : (4 - d + hit) * 255 / 4);
const v = Math.min(255, (48 - d) * 255 / 16, hit < 0 ? 255 : (8 - d + hit) * 255 / 8);
if (v <= 0) break;
fogMark(x, y, v);
}
}
// one fog cell at a time, measured from its centre; full inside FOG_SENSE - 4, fading to the edge
const R2 = FOG_SENSE * FOG_SENSE, in2 = (FOG_SENSE - 4) ** 2;
// one fog cell at a time, measured from its centre; full inside 12 grains, fading over the outer 12 grains
const R2 = FOG_SENSE * FOG_SENSE, in2 = (FOG_SENSE - FOG_SENSE_FADE) ** 2;
const fy0 = Math.max(0, Math.floor((cy - FOG_SENSE) / FOG)), fy1 = Math.min(FH - 1, Math.floor((cy + FOG_SENSE) / FOG));
const fx0 = Math.max(0, Math.floor((cx - FOG_SENSE) / FOG)), fx1 = Math.min(FW - 1, Math.floor((cx + FOG_SENSE) / FOG));
for (let fy = fy0; fy <= fy1; fy++) for (let fx = fx0; fx <= fx1; fx++) {
const dx = (fx + 0.5) * FOG - cx, dy = (fy + 0.5) * FOG - cy, d2 = dx * dx + dy * dy, i = fy * FW + fx;
if (d2 >= R2) continue;
const v = d2 <= in2 ? 255 : (FOG_SENSE - Math.sqrt(d2)) * 255 / 4;
const v = d2 <= in2 ? 255 : (FOG_SENSE - Math.sqrt(d2)) * 255 / FOG_SENSE_FADE;
if (v > fog[i]) fog[i] = v;
}
}
function fogRevealAround(x, y, r) {
for (let yy = Math.max(0, Math.floor(y - r)); yy <= Math.min(H - 1, y + r); yy++) for (let xx = Math.max(0, Math.floor(x - r)); xx <= Math.min(W - 1, x + r); xx++) if ((xx - x) ** 2 + (yy - y) ** 2 <= r * r) fogMark(xx, yy, 255);
for (let yy = Math.max(0, Math.floor(y - r)); yy <= Math.min(H - 1, y + r); yy++) for (let xx = Math.max(0, Math.floor(x - r)); xx <= Math.min(W - 1, x + r); xx++) {
const d2 = (xx - x) ** 2 + (yy - y) ** 2;
if (d2 >= r * r) continue;
fogMark(xx, yy, r >= 6 && d2 <= (r - 6) ** 2 ? 255 : Math.min(255, (r - Math.sqrt(d2)) * 255 / 6));
}
}
function fogRevealAll() { fog.fill(255); }