Read this before touching anything. It is short on purpose. The long versions are in docs/ARCHITECTURE.md and docs/RULES.md.
REGOLITH — a lunar rover survey game that runs in a browser tab. WebGL2, a vendored copy of three.js, plain ES modules, no build step, no npm dependencies, no asset files. Everything you see and hear is generated by code at load.
src/ is ~6,700 lines. The valuable part is not the rendering — it is that the physics and
the pixels are forced to agree.
The wheels and the shader read the same height field. The GPU never re-derives a height;
it samples the baked field the CPU owns, and the CPU bilinear filter in terrain.js is
written to match GL's. If the two ever disagree where the rover is standing, it floats or
sinks, and no amount of tuning fixes it.
Anything that changes how height is computed must change it on both sides in the same commit.
-
Never replace a uniform wrapper object — only mutate
.value. Every clipmap ring shares the same wrapper objects (buildClipmapdoesObject.assign), andDustholdsuSunDirdirectly. Swapping a wrapper silently unwires them. -
Run
node --checkon every file you changed before you say it works. The browser reports a syntax error as "missing )" with no file, and you will lose an hour. -
Verify in the running game, not by reasoning.
window.REGOLITHexposes the live app andREGOLITH.tick(dt)advances one frame by hand. Claims about behaviour that were not observed are not findings. -
Measure before and after. Put the two numbers in the commit message. "Feels better" is not a result.
-
Never write an absolute you have not checked. "no X", "every Y", "always", "never" — the README has been wrong about this class of claim three times. Check, then write.
npm startThen http://localhost:5173. Any static server works; it must be HTTP, not file://,
because it uses ES modules. Node 18+.
node server.js 5173 --shots adds a POST /__shot endpoint that writes frames into
.shots/ — used to capture screenshots while testing. Off by default.
src/core/ |
engine, input, audio, rng, save |
src/world/ |
terrain, props, sky, dust, textures |
src/game/ |
rover, gameplay, lore, camera |
src/ui/ |
hud, styles |
src/main.js |
boot, menus, settings, the frame loop |
The frame loop in main.js is the thing to read first. Order of operations there matters
and is documented in ARCHITECTURE.md.
docs/ARCHITECTURE.md — how the systems work and the invariants between them. Read the section for whatever you are about to touch. It is written to be read in pieces, not front to back.
Development happens in a private repository, which carries three more files under docs/:
RULES.md (roles, task specs, acceptance, commits), BOARD.md (what is being worked on) and
DECISIONS.md (settled questions, so nobody re-opens one by accident). If those files are
present, read RULES.md before starting work — it defines how a task is picked up and what
counts as done. If they are not, you are in the public release repository.