Fog of war: underground is black until the bot has seen it (t8)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-24 01:37:34 -04:00
co-authored by Claude Opus 5.5
parent a730a7d73c
commit 152a2af6df
20 changed files with 222 additions and 22 deletions
+17 -10
View File
@@ -75,6 +75,7 @@ dist/, shots/ build output and screenshots (not committed)
only those are simulated. `setCell` wakes what it touches; after writing arrays directly, call
`wakeXY` / `wakeHeatXY`.
- **Other state:**
- `fog`: exploration at one cell per 2×2 grains; see [fog](systems/fog.md);
- `machines`: index = machine id; removed ones are `null`. Each is
`{ type, x, y, w, h, dir, on, ... }`. Its footprint is hull cells (solid) and void cells
(open inside).
@@ -215,11 +216,16 @@ Starter furnace designs and the milestone list shown in the notebook.
- functions: smelterBlueprint
- variables: STARTER_DESIGNS, MILESTONES
### src/sim/world.js (96 lines)
### src/sim/world.js (97 lines)
World state: the per-cell typed arrays, alloc(), ambient temperature by depth, waking.
- functions: emit, bagCap, discover, alloc, depthU, depthY, computeAmbient, fillNoise, wakeXY, wakeHeatXY, wakeIdx, wakeHeatIdx
- variables: W, H, N, CW, CH, NCH, mat, temp, life, flags, stamp, part, mach, digp, noiseB, airS, netId, isPow, occ, surfY, dirtY, graniteY, basaltY, magmaY, roofY, AMB, worldSeed, surfBase, underD, shallowD, lapse, BW, BH, NB, blockP, blockV, ents, bgm, flyers, ghostBlocks, ghostMolds, awake, hot, hotLvl, tick, tickStamp, machines, molds, nets, pcells, powerDirty, beltL, beltR, tubeLists, brokenMachines, ghostMachines, ghostBlocked, EV, bot, bag, bagTotal, player, seen, ledger, stats
### src/sim/fog.js (35 lines)
Exploration only: never changes grains or the random stream.
- functions: fogAlloc, fogMark, fogSeen, fogInit, fogLook, fogRevealAround, fogRevealAll
- variables: FOG, fog, FW, FH
### src/sim/cells.js (176 lines)
Cell helpers (setCell, move, enter) and the falling-sand movement of powders, liquids and gases (simMove).
- functions: setCell, swapCells, move, enter, powder, passable, liquid, gas, simMove
@@ -314,16 +320,16 @@ Weather: clouds from steam, rain and snow, and the world water count.
- functions: wrnd, resetWeather, rainGap, worldWater, absorbSteam, spawnRain, rainAt, weatherTick
- variables: WBAND, WS, weather
### src/sim/tick.js (25 lines)
### src/sim/tick.js (26 lines)
simTick: one simulation step, in order.
- functions: simTick
### src/sim/worldgen.js (315 lines)
### src/sim/worldgen.js (316 lines)
World generation: noise, layers, ores, caves, water, trees, and clearing tiny hard specks.
- functions: makeNoise, fbm, clearHardSpecks, generateWorld
- variables: SPECK_MIN
### src/sim/save.js (112 lines)
### src/sim/save.js (120 lines)
Saving and loading a world (serializeWorld / deserializeWorld) and old-save migration.
- functions: serializeWorld, deserializeWorld
- variables: SAVE_VERSION, TOFF
@@ -337,16 +343,16 @@ Drawing (src/render/): browser only. This file: the renderer state R, colour tab
Propagated coloured light from glowing and burning cells.
- functions: computeLight
### src/render/world.js (277 lines)
drawWorld: the per-grain pixel buffer (pixel look), also the input of the smooth look.
- functions: drawWorld
### src/render/world.js (297 lines)
Scale colour without changing the smooth-look class.
- functions: fogColor, drawWorld
- variables: TUBE_CLASS
### src/render/machines.js (197 lines)
Machine overlays: fans, engines, refiner, cutter, silo and the rest, drawn on top of the world.
- functions: cellRect, drawHazardRims, drawMachines, drawSilo, drawSiloPixel
### src/render/overlays.js (228 lines)
### src/render/overlays.js (229 lines)
Other overlays: floating text, rain and snow, flow arrows, filter tags, molds, the bot, particles.
- functions: spawnFloater, drawRain, drawFlowArrows, drawRunOutline, drawFilterTags, drawFloaters, moldLabel, drawMolds, drawBot, spawnDebris, spawnSpark, spawnSuck, drawParticles
@@ -379,7 +385,7 @@ Saves in IndexedDB, world files (export / import) and the blueprint library.
Starting, loading and quitting a game; modal dialogs; the pause menu.
- functions: showLoading, enterGame, startNewWorld, startFromSave, quitToTitle, refreshContinue, anyModal, openModal, closeModal, closeAllModals, topModal, dialog, openPause, renderWorlds
### src/ui/settings.js (123 lines)
### src/ui/settings.js (124 lines)
The settings screen.
- functions: openSettings, renderSettings, applySettings, toggleFullscreen, confirmWipe
- variables: SET_TABS, setTab
@@ -403,7 +409,7 @@ The selected tool and piece: R / Q / E, drill width, filter picker, the selectio
- functions: pieceUsesWall, setDrillWidth, tuneUnderCursor, cycleItem, cycleWall, rotate, toggleCollect, pickFilterUnderCursor, toggleFilterMat, toggleCollectUnderCursor, setBrush, pieceV, pieceExtra, filterChoices, matList, filterParts, filterSentence, applyFilterRun, openFilterPicker, openWallPicker, filterBlockAt, chipCost, pieceCostNow, renderSelCard, renderBag
- variables: lastBagKey
### src/ui/info.js (170 lines)
### src/ui/info.js (171 lines)
Discovery cards, hover info (I) and the cursor label.
- functions: showCard, howText, discoveryCard, reactionsOf, hoverInfo, renderInfo, drawCursorLabel
@@ -447,6 +453,7 @@ The frame loop and boot.
- `test/t_conveyors.js`: Screw tubes that never carry liquid (it flows through), tube and belt throughput, filters.
- `test/t_drill.js`: The resonance drill: pulses from the bot shake rock until it shatters. Widths trade area for speed, tuning shatters only one material and drains it out of the wall, built blocks are left alone, and the drill says why when nothing breaks.
- `test/t_econ.js`: Economy: the dock (instant sale), orders, prices, the market dip, money for machines, alloys.
- `test/t_fog.js`: Fog: surface, sight, range, saves and simulation independence.
- `test/t_furnace_repeat.js`: The starter furnaces keep working when fired again and again without cleaning, however the charge goes in: mixed, ore first with coal on top, or blown in through the vent. Each case plays furnace_play.js, which builds the design and fires it like a player.
- `test/t_molds.js`: Molds and furnaces stay usable: ingots drop below and keep their stubs, plugs over molds are cleared, spoiled castings can be knocked out, grains never drop through a grate by teleporting, and slag lets the fire breathe.
- `test/t_pipes.js`: Pipes, pumps and outlets move liquids; the Refiner grinds waste rock for trace ore.
+16
View File
@@ -4,6 +4,22 @@ What agents have done, newest first. Add an entry for every piece of work: the d
note or request it was for, what changed, the files touched, the tests run, and anything left
open or not verified. Keep each entry short; the git history has the details.
## 2026-10-24: t8 Fog of war for unexplored areas (Claude Code, Codex)
- Decided with the owner: revealed by line of sight; unseen is black with a soft edge.
- New `src/sim/fog.js` (2×2-grain cells, 0-255, only ever rises): `fogInit` (sky and surface
seen), `fogLook` (256 rays, 48 grains, through air, gas and liquid, 4 grains into rock), called
every 4 ticks from `simTick`. Never read by the simulation.
- `src/sim/save.js`: fog saved; saves without it rebuild it (surface, 12 grains around built
things, the bot's view). `src/sim/world.js`, `worldgen.js`: allocate and initialize.
- `src/render/world.js`: grains scaled by a bilinear fog value; fully unseen grains drawn like
out-of-world grains; no glow from fog; thermal lens fogged too. `overlays.js`: rain and
particles hidden in fog. `src/ui/info.js`: "Unexplored". Setting `fog` (Game tab).
- Browser tests and tools turn fog off (`play.py`, `t_smooth.py`, `shot.py`, `perf.py`,
`playthrough.py`) except the fog checks. New `test/t_fog.js`; `docs/systems/fog.md`.
- Tests: all 12 headless suites, `play.py` (185 checks), `t_smooth` pass. Screenshots checked in
both looks. `tools/perf.py`: drawWorld 0.34 → 0.43 ms with fog on (no change with light off).
## 2026-10-24: t5 Material selection menu (Claude Code, Codex)
- Decided with the owner: F opens it for walls and molds, R keeps cycling.
+33
View File
@@ -0,0 +1,33 @@
# Fog of war
Unexplored ground is black with a soft edge. The sky and the first few grains of the
surface start seen. Exploration never changes the simulation.
## Data and revealing
`src/sim/fog.js` keeps a `Uint8Array` at half the grain resolution (`FOG = 2`).
Values run from 0 (unseen) to 255 (seen) and only increase. `alloc` allocates it with
the other world arrays. `fogInit` reveals above `surfY` and fades eight grains below it.
Every four ticks, 256 rays from the bot's centre reveal up to 48 grains. The last eight
grains fade out. Solid and powder stop sight after a four-grain fade into their face;
air, gas and liquid pass sight. Bars and machine voids do not block it.
## Saving
The fog buffer is saved and exported with the other typed arrays, without a save version
change. Older saves rebuild the surface, reveal a radius of 12 grains around built blocks,
machine footprints and molds, then look from the bot. Loading and generating also look
immediately from the bot.
## Drawing and setting
Both looks and the thermal lens sample fog bilinearly. Seen grains use the usual drawing;
unseen grains use the out-of-world colour and smooth-look buffers, hiding their shapes.
Partial values dim foreground, background and trees. Bloom sources need at least 128;
bars, flyers, rain and particles need at least 64. Hover info and the cursor label say
only “Unexplored” below 64.
Game settings → Fog of war is on by default. Turning it off shows the whole world while
exploration continues to be recorded and saved. Browser scenes and performance tools turn
it off in their shared setup; dedicated fog checks enable it explicitly.