heron/lanternfall Public Public: anyone can read this; nobody can change it.
workbenchthis machine
Files a80ad1c2e997ef7cb60c1375df4ad23cf52f6553
| 1 | # lanternfall |
| 2 | |
| 3 | One dungeon, five floors, and everybody who has ever gone down it. |
| 4 | |
| 5 | You get a delver, twelve hit points and a lantern that throws about four |
| 6 | paces. Below you are rats, then goblins, then things with names you would |
| 7 | rather not learn, and caches of coin tucked into the walls. Gold in your |
| 8 | pocket is worth nothing: it only counts when you climb back out through the |
| 9 | first floor's stair, and if you die on the way it stays where you fell. |
| 10 | |
| 11 | ## What makes it a shared game |
| 12 | |
| 13 | - **The map is everyone's.** A tile lit by anybody's lantern stays on |
| 14 | everybody's map, forever. A new delver walks into a dungeon already drawn |
| 15 | by the people who died in it — rooms in outline, corridors half sketched — |
| 16 | and the dark ahead is the part nobody has reached yet. |
| 17 | - **The dead stay where they fell.** Dying leaves a grave at that exact tile |
| 18 | with a composed epitaph, and it holds the gold you were carrying. Whoever |
| 19 | finds it takes half. The good advice on gravestones is real advice: it was |
| 20 | written where somebody actually died. |
| 21 | - **Everyone is in the same rooms at the same time.** Other delvers show up |
| 22 | on your floor as a blue `@`, and the monster hunting you might be hunting |
| 23 | them instead — it goes for whoever it can see and is closest to. |
| 24 | - **The floors are permanent.** Every floor is a pure function of one seed, |
| 25 | so the dungeon is the same for everyone and always will be. The database |
| 26 | stores only what has *happened*: who is down there, what has been lit, what |
| 27 | is dead and where. |
| 28 | |
| 29 | ## Playing |
| 30 | |
| 31 | Arrows or `wasd` (or `hjkl`) move. Walking into something attacks it. `.` |
| 32 | waits — and waiting is the only way to heal, which works only when nothing |
| 33 | can see you, so a cleared room is worth remembering. `>` goes down a stair, |
| 34 | `<` goes up; `<` on the first floor is the way out, and the only way to keep |
| 35 | what you are carrying. |
| 36 | |
| 37 | Every control is a real form button. The keyboard is one small file under |
| 38 | `static/`; with JavaScript off the game plays exactly the same, one click per |
| 39 | turn. |
| 40 | |
| 41 | ## In a terminal |
| 42 | |
| 43 | sh |
| 44 | ssh -p 2222 lanternfall@<the forge> # the same dungeon, the same database |
| 45 | |
| 46 | |
| 47 | The terminal view is the same map drawn in 256 colours, refreshed every few |
| 48 | seconds so you can watch somebody else's lantern move. The account at the |
| 49 | keyboard is your name, so the gravestone will have it on. |
| 50 | |
| 51 | ## Running it |
| 52 | |
| 53 | sh |
| 54 | PORT=8080 FORGE_APP_DATA=./data bun run src/server.ts # run it here |
| 55 | bun test # 34 tests |
| 56 | FORGE_APP_DATA=./data bun run src/tty.ts # the terminal client |
| 57 | |
| 58 | |
| 59 | ## Shape |
| 60 | |
| 61 | | file | what it holds | |
| 62 | | ------------------ | ------------------------------------------------------------------------ | |
| 63 | | `src/dungeon.ts` | the floors: generation, line of sight, the step a monster takes — pure | |
| 64 | | `src/game.ts` | the rules: a turn, a blow, a stair, a death, a climb out | |
| 65 | | `src/db.ts` | what happened: delvers, the shared map, monsters, graves, the log | |
| 66 | | `src/names.ts` | names and epitaphs, composed from a grammar — nobody types into the world | |
| 67 | | `src/pages.ts` | the screen | |
| 68 | | `src/server.ts` | the door and the cookie | |
| 69 | | `src/tty.ts` | the same dungeon in a terminal | |
| 70 | | `static/keys.v1.js`| keyboard play, layered over controls that already work without it | |
| 71 | |
| 72 | Two tests are the ones worth knowing about: one floods every floor from its |
| 73 | entrance to prove the stair is actually reachable, and one plays two hands to |
| 74 | prove the map they share is really shared. |
| 75 | |
| 76 | No dependencies. |