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

workbenchthis machine

lanternfall: let the floor talk back

Playing the live floor showed the flat spot: a plain step says nothing, which
is right, but it meant eighteen steps down a corridor left the opening line
sitting there as if nothing had happened.

Two lines, both of which a player actually needs:

- stepping onto a stair says so ('A stair down, here.', and on floor 1 'The
  way out, here. Climb and the gold is yours.') - the way out is the whole
  economy of the game and it was invisible until you guessed at the button.
- something entering your lantern says so ONCE, by comparing what was in
  sight before the step with what is in sight after, so a monster you are
  already fighting does not narrate every turn.

28 tests.
benjivers committed fa8aea7 Browse files
2 files changed +34 −0
src/game.test.ts +23
@@ -112,6 +112,29 @@ test("the stairs are the only way down, and climbing out banks the gold", () =>
112112 db.close();
113113 });
114114
115 test("the floor says what you are standing on", () => {
116 const db = fresh();
117 const delver = delverFor(db, "hand-a");
118 const floor = floorAt(1);
119 db.query("UPDATE delver SET cell = ?2 WHERE id = ?1").run(delver.id, (floor.descent as number) - 1);
120 const onto = act(db, "hand-a", "east");
121 expect(onto.log.join(" ")).toContain("A stair down, here.");
122 const back = act(db, "hand-a", "west");
123 expect(back.log.join(" ")).not.toContain("stair");
124 db.close();
125 });
126
127 test("something coming into the light is worth saying once", () => {
128 const db = fresh();
129 const delver = delverFor(db, "hand-a");
130 db.query(
131 "INSERT INTO monster (depth, spawn, cell, kind, hp) VALUES (1, ?1, ?1, 'rat', 2)",
132 ).run(delver.cell + 2);
133 const first = act(db, "hand-a", "wait");
134 expect(first.log.join(" ")).toContain("still moving");
135 db.close();
136 });
137
115138 test("resting heals, but only when nothing can see you", () => {
116139 const db = fresh();
117140 const delver = delverFor(db, "hand-a");
src/game.ts +11
@@ -204,6 +204,9 @@ export function act(db: Database, hand: string, action: Action): TurnResult {
204204 log.push("There is no stair here.");
205205 }
206206 } else if (action !== "wait") {
207 const watchedBefore = store
208 .monstersOn(db, delver.depth, now)
209 .some((m) => distance(m.cell, delver.cell) <= LANTERN && seesFrom(floor, delver.cell, m.cell));
207210 const here = xy(delver.cell);
208211 const step = DIRECTIONS[action];
209212 const nx = here.x + step.dx;
@@ -250,6 +253,14 @@ export function act(db: Database, hand: string, action: Action): TurnResult {
250253 log.push(`A cache of ${coin} gold, tucked into the wall.`);
251254 }
252255 }
256 const under = floor.tiles[target];
257 if (under === ">") log.push("A stair down, here.");
258 else if (under === "<")
259 log.push(delver.depth === 1 ? "The way out, here. Climb and the gold is yours." : "A stair up, here.");
260 const watchedNow = store
261 .monstersOn(db, delver.depth, now)
262 .some((m) => distance(m.cell, target) <= LANTERN && seesFrom(floor, target, m.cell));
263 if (watchedNow && !watchedBefore) log.push("Something moves at the edge of your lantern.");
253264 const grave = store.graveAt(db, delver.depth, target);
254265 if (grave && grave.looted === 0) {
255266 const share = Math.floor(grave.gold / 2);
↑↓ navigate ↵ open esc close

Keyboard shortcuts