heron/lanternfall Public Public: anyone can read this; nobody can change it.

One dungeon, many delvers. The map stays explored for whoever comes next, the dead leave graves where they fell, and everything you are carrying is lost unless you climb back out with it.

workbenchthis machine

This repository has no app yet.

README.md

lanternfall

One dungeon, five floors, and everybody who has ever gone down it.

You get a delver, twelve hit points and a lantern that throws about four paces. Below you are rats, then goblins, then things with names you would rather not learn, and caches of coin tucked into the walls. Gold in your pocket is worth nothing: it only counts when you climb back out through the first floor's stair, and if you die on the way it stays where you fell.

What makes it a shared game

  • The map is everyone's. A tile lit by anybody's lantern stays on

everybody's map, forever. A new delver walks into a dungeon already drawn by the people who died in it — rooms in outline, corridors half sketched — and the dark ahead is the part nobody has reached yet.

  • The dead stay where they fell. Dying leaves a grave at that exact tile

with a composed epitaph, and it holds the gold you were carrying. Whoever finds it takes half. The good advice on gravestones is real advice: it was written where somebody actually died.

  • Everyone is in the same rooms at the same time. Other delvers show up

on your floor as a blue @, and the monster hunting you might be hunting them instead — it goes for whoever it can see and is closest to.

  • The floors are permanent. Every floor is a pure function of one seed,

so the dungeon is the same for everyone and always will be. The database stores only what has happened: who is down there, what has been lit, what is dead and where.

Playing

Arrows or wasd (or hjkl) move. Walking into something attacks it. . waits — and waiting is the only way to heal, which works only when nothing can see you, so a cleared room is worth remembering. > goes down a stair, < goes up; < on the first floor is the way out, and the only way to keep what you are carrying.

Every control is a real form button. The keyboard is one small file under static/; with JavaScript off the game plays exactly the same, one click per turn.

In a terminal

ssh -p 2222 lanternfall@<the forge>     # the same dungeon, the same database

The terminal view is the same map drawn in 256 colours, refreshed every few seconds so you can watch somebody else's lantern move. The account at the keyboard is your name, so the gravestone will have it on.

Running it

PORT=8080 FORGE_APP_DATA=./data bun run src/server.ts   # run it here
bun test                                                # 34 tests
FORGE_APP_DATA=./data bun run src/tty.ts                # the terminal client

Shape

filewhat it holds
src/dungeon.tsthe floors: generation, line of sight, the step a monster takes — pure
src/game.tsthe rules: a turn, a blow, a stair, a death, a climb out
src/db.tswhat happened: delvers, the shared map, monsters, graves, the log
src/names.tsnames and epitaphs, composed from a grammar — nobody types into the world
src/pages.tsthe screen
src/server.tsthe door and the cookie
src/tty.tsthe same dungeon in a terminal
static/keys.v1.jskeyboard play, layered over controls that already work without it

Two tests are the ones worth knowing about: one floods every floor from its entrance to prove the stair is actually reachable, and one plays two hands to prove the map they share is really shared.

No dependencies.

↑↓ navigate ↵ open esc close

↑↓ navigate ↵ open esc close

Keyboard shortcuts