Skip to content

Raise the game's level once on each floor that says so, and heal to full - #97

Merged
calebl merged 3 commits into
mainfrom
fm/ta-floors-s5-engine
Oct 30, 2026
Merged

calebl merged 3 commits into
mainfrom
fm/ta-floors-s5-engine

Conversation

@calebl

@calebl calebl commented Oct 30, 2026

Copy link
Copy Markdown
Contributor

Stage 5 of the dungeon plan, engine half: levelling stage 1, one level per floor reached, healed to full (D8 b, X1 a, X2, X3, X5).

  • A floor that says levels_up raises the game's level by one the first time that game stands on it, and heals the player to full on the same turn. This applies to this game only: the world's characters.level is never written.
  • The arrival is recorded on every floor, whether or not it raises a level. A new per-game table, playthrough_floors, gets one row per game and floor, written once. Stage 6's countdown will read its arrived_at.
  • The game's level is its highest row's level. Every max-HP reader now asks the game.
  • The level-up notice is engine copy, for the player only. No model is told of it: no request changes, and no prompt template changed.

A world without levels_up plays byte for byte as before. No model was called.

The notice

Exact wording (Game::floor_to_s, the plan's §4.3 draft as written):

Reaching {floor} raised {fullname} to level {level}: {max} hit points, and healed to full.

For example: Reaching The First Floor raised Odile to level 4: 23 hit points, and healed to full.

Where it shows:

  • Engine alone (no model): as a report note, the game: Reaching …, beside the tolls' the world: … notes.
  • On the told path: the turn's scene claims the row (playthrough_floors.scene_id), the way it claims a toll. The server's log entry shows it from there (below).
  • Never in a request. tests/floor_levels.rs checks every request of a levelling move, and the new script's records file holds the requests themselves.

What changed

  • turn.rs reach_floor, called first in on_arrival, on both the engine-alone and the told path. When the room stood in is a floor, or a room of one (playthrough::floor_of, now shared with stage 3's monster level), and this game has no row for that floor yet:

    • it writes playthrough_id, location_id, arrived_at (story now) and level;
    • level is the game's level plus one when floors.levels_up is true and the player has a stat block, capped at Character::LEVELS.max (20); otherwise it is null;
    • when a level was written, it mends the player by the new maximum (mend, so the dead are never raised).

    It writes nothing when the game is over, or when the database has no playthrough_floors table. It runs before the doorway's toll and the room's own hazard, and before the riposte. So every toll and blow of that turn is paid, and described, at the new maximum. A hazard on the way in still costs hit points after the heal (the_way_onto_a_floor_takes_its_toll_after_the_floor_has_healed_the_player).

  • playthrough.rs.

    • Game::level_at(character, at) and Game::max_hp_at(character, at), with level/max_hp for now. For the player, the level is the highest non-null playthrough_floors.level among this game's rows with arrived_at <= at. Anybody else, and a player no floor has raised, has the world's level.
    • hit_points(level, die) is the one formula. max_hp(row) keeps the world's figure for the fight simulator.
    • Game::floors_reached and Game::floor_to_s (the notice).
  • Every max-HP reader the plan lists now asks the game, re-checked at this main:

    • vitals_for (playthrough.rs), so the glance's condition, the moment's "is hurt (H of M)", arrival, revisit and outcome::State follow;
    • toll_to_s, at the toll's story_timestamp;
    • turn.rs: the thrown-thing blow, a new vitals row at full, the mend cap, and blow_to_s, which now takes the maximum from its caller: strike (now), and close_fight and the narrated facts card (narrates.rs) at the blow's story_timestamp;
    • the glance's sheet line (level {level}, d{die}), which reads the game's level.

    The fight simulator's arena.rs keeps the world's max_hp, because a simulated fight is never on a floor.

  • told.rs claim_floors, a journal step (told_floors) after told_tolls. The turn's scene claims this game's unclaimed floor rows. No paragraph tells them.

  • Notes. Mechanics remembers the last floor row at the start of the line (floors_before, as it does tolls_before). answered_by_the_world adds the game: {notice} for each new row that raised a level.

  • Store.

    • store::PLAYTHROUGH_FLOORS joins OPTIONAL_LOADED, which now also covers the one optional table the engine writes. Its whole shape is in OPTIONAL_SHAPES.
    • floors.levels_up is in OPTIONAL_COLUMNS.
    • Store::has(table) reports whether the table is there.

    SCHEMA_VERSION and shape.txt do not move, so the game at its current pin still opens and plays. There levels_up reads as false and nothing is written.

  • Migration 20261031090000 (AddLevelsUpAndCreatePlaythroughFloors), applied to all 33 world dumps in parity/worlds/:

    • How it was applied. Each dump re-dumped byte-identically first. Then bin/rails db:migrate ran on a copy of each world, in a scratch checkout of the game at SERVER_COMMIT holding only this migration.
    • Dumps lacking 20261029154235. 29 dumps lack it (refused_lines, optional to the engine). Its version row was added before the run and deleted after, as in stage 3.
    • Byte check. two-floors-and-a-key already had that migration, so its dump is Rails' own.
    • What moved in each dump: floors gains "levels_up" boolean DEFAULT FALSE NOT NULL (each row a trailing 0); there is a new playthrough_floors table with its four indexes; and the version row is added.
  • README. The playthrough row of the module table.

What did not move

  • No existing golden or records file. parity --check parity: AGREED 106 of 110. The other four are runner-only, as before.
  • The floor scripts (a-floor-laid-out-to-its-count, a-guard-waits-at-the-stairs, a-keyed-stair-onto-a-place-stays-keyed, a-deeper-floor-births-stronger-people) now write a playthrough_floors row with a null level on each first arrival. playthrough_floors is not in parity::WRITTEN_TABLES, so no records file moved, and no floor in those worlds raises a level.
  • fight --check sim: AGREED, 10 fight goldens, unchanged. Nothing was re-blessed. The reference fights are fought in the simulator's own worlds, which have no floors, so no game level ever differs from the world's.

Sweep

New world three-floors-that-raise-you and script a-floor-raises-a-level-once (11 steps), in PASSING with a golden and a records file.

How the world was made. It is the game's loader at SERVER_COMMIT (b2a4523) loading the world file below without levels_up:, which that loader refuses. Then the migration ran, and UPDATE floors SET levels_up = 1 wrote what the new loader will write. As with stages 2 and 3, rebuild the dump from the pin branch's own loader once it reads levels_up:.

The world. Odile is level 3 on a d8 (18 hit points). Under the landing are three floors of two rooms each, every one with levels_up: true. The walk goes floor 1 → 2 → 1 → 2:

  1. harm 5 on the landing: Odile unhurt -> hurt (13 of 18).
  2. Walking into The First Floor lays it out and raises her to level 4, healed to full: hp 23.
  3. harm 3: unhurt -> hurt (20 of 23), so the maximum is the game's.
  4. Room 2, the way down, is another room of the same floor: hp stays 20.
  5. The Second Floor raises her to level 5, healed: hp 28.
  6. harm 4: unhurt -> hurt (24 of 28).
  7. Back up onto The First Floor room 2: hp stays 24. Nothing is healed or raised.
  8. harm 1: hurt (24 of 28) -> hurt (23 of 28). She keeps level 5 on floor 1.
  9. Down onto The Second Floor again: hp stays 23.
  10. mend 99: hurt (23 of 28) -> unhurt. It stops at level 5's 28, not a level 6.
  11. A second game walks onto the laid-out First Floor with no model. Its note reads the game: Reaching The First Floor raised Odile to level 4: 23 hit points, and healed to full., and its hp is 23. The level is the game's, raised from the world's 3.

The sweep has no expectation key for a level or a maximum. So the script asserts them through hp (the heal is to the new maximum) and through harm/mend's change, which reads (H of MAX). The notice shows only on an engine-alone move: a browser step's note is its token. I checked every expect: against the engine's dumps: 24 expectations, 0 mismatches.

Tests

  • tests/floor_levels.rs (new; live path with a scripted model, plus the engine alone):
    • Raised once, healed to full. Floors 1 and 2 write level 4 and 5, each claimed by its scene. The heal is to 23 and 28, the sheet reads level 4, d8 and then level 5, d8, and the world's characters.level stays 3. A second room of floor 1, and walking back and down again, write no row and heal nothing. harm and mend say (H of 23) and (H of 28).
    • No model is told. No request of a levelling move mentions the level or the heal. A second game's engine-alone move carries the exact notice, and only on its first arrival.
    • The level is the game's. One game at level 5 and another at 4 hold their own levels side by side.
    • A floor with levels_up false writes a row with a null level and heals nobody.
    • Capped. A protagonist at level 20 stays at 20, at 103 HP.
    • The toll comes after the heal. An undertow on the way in is paid after the heal: hp and the toll's hp_after are 23 less the damage.
    • A database from before the migration (no table, no column) plays, and raises nobody.
    • Game over records. A toll before the arrival is said at (15 of 18) and one at it at (20 of 23). max_hp_at gives 18 then 23. A non-player keeps the world's level. floor_to_s gives the exact notice.
  • Store (tests/engine.rs).
    • A database from before the migration opens and plays.
    • A floors.levels_up declared nullable is refused (found column floors.levels_up boolean pk=0).
    • A playthrough_floors missing its unique index is not whole, so it is refused.
    • every_world_has_the_shape_the_engine_is_written_against holds for all 34 dumps.

Local runs, all with both provider keys unset:

  • cargo fmt --check, cargo clippy --workspace --all-targets --locked -- -D warnings and cargo test --workspace --locked: all pass.
  • parity --check parity: 106 of 110 agree (the four runner-only, as before).
  • fight --check sim: AGREED, 10 fight goldens.
  • I also ran CI's runner job locally against the game at SERVER_COMMIT (b2a4523), on its own schema (no new table or column), with the extension built from this checkout:
    • parity/runner.sh: 109 of 110 agree; the new script is "not in the checkout yet";
    • engine:rust_gates: PASSED for 109 scripts (goldens, invariants, doctor and audit).

SERVER_COMMIT does not move. At its pin (b2a4523) the game has neither the table nor the column, and the engine opens it and plays as before.

What the server pin PR must change

Line numbers are at b2a4523.

  1. Migration db/migrate/20261031090000_add_levels_up_and_create_playthrough_floors.rb. Use exactly this version and declaration, so the dumps here stay byte-true. store::OPTIONAL_COLUMNS and store::OPTIONAL_SHAPES hold every fact of it. db/schema.rb moves to 2026_10_31_090000. No later migration was on main (86b9764) when this was written.
    class AddLevelsUpAndCreatePlaythroughFloors < ActiveRecord::Migration[8.1]
      def change
        add_column :floors, :levels_up, :boolean, default: false, null: false
        create_table :playthrough_floors do |t|
          t.references :playthrough, null: false, foreign_key: true
          t.references :location, null: false, foreign_key: true
          t.datetime :arrived_at, null: false
          t.integer :level
          t.references :scene, foreign_key: true
          t.timestamps
        end
        add_index :playthrough_floors, [ :playthrough_id, :location_id ], unique: true,
          name: "index_playthrough_floors_on_playthrough_and_location"
      end
    end
    fell_at (plan §1.2) is left to stage 6, which adds its own migration for minutes anyway.
  2. Models, each with a model test and a dice-free factory.
    • Playthrough::Floor (table playthrough_floors; any name).
      • belongs_to :playthrough, :location and :scene, optional: true.
      • Validates level in Character::LEVELS, allowing nil, and location unique per playthrough.
      • #to_s is the notice, word for word as Game::floor_to_s: "Reaching #{location.name} raised #{playthrough.character.fullname} to level #{level}: #{max} hit points, and healed to full.", where max is hit_die + (level - 1) * (hit_die / 2 + 1) on the player's hit die. It is nil for a row with no level.
    • The associations:
      • Playthrough has_many …, dependent: :destroy;
      • Scene has_many …, dependent: :nullify (as :tolls, scene.rb:193);
      • Location has_many …, dependent: :destroy (as :tolls, location.rb:65). The foreign keys are NO ACTION.
    • Floor validates levels_up as a boolean.
  3. One game-aware reader, mirroring Game::level_at / Game::max_hp_at exactly: Playthrough#level_for(character, at: nil) and #max_hp_for(character, at: nil).
    • For the playthrough's own character, the level is the highest non-nil level of its playthrough_floors rows with arrived_at <= at (every row when at is nil). With no such row, and for anybody else, it is character.level.
    • Then every reader of Character#max_hp on a game asks it:
      • Playthrough::Vitals: .instantiate! (vitals.rb:65), Condition.for (:80), #max (:129), and so the hp_within_the_stat_block validation (:139-144). Without the validation change, any Ruby save of a levelled player's row is refused.
      • Playthrough::Turn#mend! (turn.rb:1334), the cap.
      • Blow#condition (blow.rb:63), at the blow's story_timestamp.
      • Toll#condition (toll.rb:134), at the toll's story_timestamp.
      • Playthrough::Mechanics::State#sheet (mechanics.rb:127-134): "level #{playthrough.level_for(character)}, d#{character.hit_die}". That is what engine:rust_gates holds to the engine's glance.
    • Character#advance! (character.rb:840) stays uncalled. Its comment should say why: it writes the world, and a level is the game's.
  4. Story::Doctor#hp_above_maximum (doctor.rb:3390) and Story::Repair#repair_hp_above_maximum (repair.rb:465) in this same PR. Both read row.playthrough.max_hp_for(row.character) instead of row.character.max_hp.
    • Otherwise the doctor reports every levelled player as "past the … their stat block allows", and because that finding is :safe, a routine rake game:repair clamps them back down to the world's maximum.
    • The finding's words should name the game's level.
    • Test: a game raised to level 5 at 28 hp is neither reported nor clamped, and one at 29 still is (and is clamped to 28, not to 18).
  5. Loader (lib/world_seed/loader.rb). The floor: keys gain levels_up.
    • Refuse anything but true or false.
    • Write it in both directions on every load (absent writes false).
    • Tests: it seeds; it refuses levels_up: "yes".
  6. Exporter. Emit levels_up: true under floor: when it is set. Round-trip test.
  7. Protocol. Protocol::V1#entry (protocol/v1.rb:71-77) appends this game's floor rows the scene claimed that raised a level, by id, after its tolls (filtered to the playthrough as the tolls are): … + floors.filter_map(&:to_s). Update the notices description in docs/protocol/v1/openapi.json if it names what a notice is. Test it with a scene that claimed a levelling row.
  8. Copies of a game. Add playthrough_floors to Playthrough::SqlitePackage's packaged tables (PLAYTHROUGH_TABLES, sqlite_package.rb:27-43). Story::Fork and Story::Snapshot copy no playthroughs, so they need nothing.
  9. Doctor finding (report, never repair), with a test: a playthrough_floors row whose location has no floors row. A re-seed that removes floor: leaves exactly this, and the game keeps its level.
  10. Sweep.
    • Copy lib/engine_sweep/worlds/three-floors-that-raise-you.yml and lib/engine_sweep/scripts/a-floor-raises-a-level-once.yml, with their comments and why: notes (below).
    • Vendor this commit's script, golden and records file. Write test/engine_parity/a-floor-raises-a-level-once.checks.json.
    • Update test/ruby_loop_coverage.yml if it must list the script.
    • Then rebuild parity/worlds/three-floors-that-raise-you.sql here from that branch's loader.
  11. Move the pin to this commit.

Out of scope, as the brief says: the countdown, healing items, safe rooms, rest, the front end, wardens, and any prompt change.

lib/engine_sweep/worlds/three-floors-that-raise-you.yml
# Three floors, one under another, and each of them raises a level. They are
# FLOORS, laid out by the engine the first time anybody walks into them, and
# each says `levels_up: true`: the first time a game stands on one, the engine
# writes that game's row for it (`playthrough_floors`) at one level past the
# level the game had, and heals the player to full before anybody there
# strikes. It is the game's level, not the world's: Odile's own row stays at
# level 3, and a second game starts from there. A floor raises a level once a
# game; walking back onto it raises nothing.
format: 2
universe:
  physics: Ordinary physics.
  technology: Lanterns, iron keys and hand tools.
  weapons: Short blades and cudgels.
  geographies: A dungeon cut down into black stone under a lantern-lit landing.
  civilizations: Delvers who sell what they bring up.
  history: The dungeon was cut long ago by people nobody remembers.
  economics: Coin for what comes up from below.
  politics: Nobody governs the dungeon.
  religion: Delvers leave a coin on the landing for luck.
  races:
  - name: Delvers
    description: People who go down into the dungeon for a living.
story:
  title: Three Floors That Raise You
  genre: dungeon crawl
  start_time: '2026-10-31T08:00:00Z'
  preface: Every floor a delver reaches leaves them harder to kill.
  summary: Odile goes down two floors and climbs back up one.
opening_scene:
  location: The Landing
  characters: [Odile]
  description: You stand on the lantern-lit landing above the first floor.
  summary: Odile reaches the landing.
characters:
- fullname: Odile
  nickname: Odile
  race: Delvers
  age: 29
  sex: female
  is_protagonist: true
  is_companion: false
  backstory: A delver who has never been below the first floor.
  personality: Careful and stubborn.
  appearance: A lantern on a pole and a short blade.
  likes: A clear way back.
  dislikes: Doors she cannot open.
  fears: The dark below the first floor.
  stats: {level: 3, hit_die: 8, strength: 14, dexterity: 12, will: 12}
locations:
- name: The Landing
  detail_level: realized
  population: nobody
  opening: true
  description: A square landing of black stone lit by one lantern, a stair going down from it.
  teaser: A lantern-lit landing.
  lore: Delvers gather here before they go down.
- name: The First Floor
  detail_level: stub
  kind: warren
  teaser: The first level of the dungeon, with a stair somewhere that goes further down.
  floor:
    rooms: 2
    danger: safe
    hazard: none
    down: The Second Floor
    levels_up: true
- name: The Second Floor
  detail_level: stub
  kind: warren
  teaser: The second level of the dungeon, colder than the first.
  floor:
    rooms: 2
    danger: safe
    hazard: none
    down: The Third Floor
    levels_up: true
- name: The Third Floor
  detail_level: stub
  kind: warren
  teaser: The third level of the dungeon, where the stair ends.
  floor:
    rooms: 2
    danger: safe
    hazard: none
    levels_up: true
connections:
- between: [The Landing, The First Floor]
  distance: adjacent
  travel_method: taking stairs
- between: [The First Floor, The Second Floor]
  distance: adjacent
  travel_method: taking stairs
- between: [The Second Floor, The Third Floor]
  distance: adjacent
  travel_method: taking stairs
lib/engine_sweep/scripts/a-floor-raises-a-level-once.yml
# A FLOOR RAISES A LEVEL ONCE A GAME. Every floor of the world says
# `levels_up: true`. The first time a game stands on one, the engine writes
# that game's row for the floor (`playthrough_floors`) at one level past the
# level the game had, and heals the player to full before anybody in the room
# strikes. Odile starts at level 3 on a d8: 18 hit points. Reaching The First
# Floor raises her to level 4 (23), and The Second Floor to level 5 (28).
#
# She is hurt before each first arrival, so the hit points she arrives with
# are the new maximum, and `harm`'s read-out says what that maximum is. Then
# she walks back up onto The First Floor and down onto The Second again: each
# floor was reached already, so neither heals her nor raises her, and she
# keeps level 5, not the level the floor she stands on gave. A second game
# reaches The First Floor from the world's level 3 and is raised to 4: the
# level is the game's, never the world's.
story: Three Floors That Raise You
steps:
- id: hurt-on-the-landing
  why: >-
    At the world's level 3 on a d8, Odile can take 18 hit points.
  type: harm 5
  expect:
    change: Odile unhurt -> hurt (13 of 18)
    hp: 13
- id: the-first-floor-raises-her-to-level-four
  why: >-
    The floor is laid out on this turn, and reaching it raises her to level 4
    and heals her to full: 23 hit points, the most a level 4 body on a d8 can
    take.
  type: "/move The First Floor"
  browser:
    token: into-the-first-floor
    realizes: The First Floor
    replies:
    - purpose: location
      content:
        description: A level of black stone passages lit by nothing you can see.
        lore: The first floor was cut by people nobody remembers.
        place_kind: warren
    - purpose: location
      content:
        description: A low chamber at the foot of the stair.
        lore: Delvers rest here before going on.
        items: []
        people: []
    - purpose: arrival
      unavailable: true
  expect:
    location: The First Floor room 1 (realized)
    hp: 23
- id: level-four-takes-twenty-three
  why: >-
    The read-out says it against the game's maximum, not the world's 18.
  type: harm 3
  expect:
    change: Odile unhurt -> hurt (20 of 23)
    hp: 20
- id: to-the-way-down
  why: >-
    The other room of the same floor: reaching a room of a floor already
    reached raises nothing and heals nothing.
  type: "/move The First Floor room 2"
  browser:
    token: first-floor-room-2
    realizes: The First Floor room 2
    replies:
    - purpose: location
      content:
        description: A bare chamber with a stair cut down into its floor.
        lore: The stair down is older than the rest.
        items: []
        people: []
    - purpose: arrival
      unavailable: true
  expect:
    location: The First Floor room 2 (realized)
    exits_include:
    - The Second Floor (stub)
    hp: 20
- id: the-second-floor-raises-her-to-level-five
  why: >-
    One past the level this game had: level 5, healed to full at 28.
  type: "/move The Second Floor"
  browser:
    token: into-the-second-floor
    realizes: The Second Floor
    replies:
    - purpose: location
      content:
        description: A colder level, the air still and the dark close.
        lore: Few delvers come this far.
        place_kind: warren
    - purpose: location
      content:
        description: The foot of the stair, cold and quiet.
        lore: The stair comes down here from the floor above.
        items: []
        people: []
    - purpose: arrival
      unavailable: true
  expect:
    location: The Second Floor room 1 (realized)
    hp: 28
- id: level-five-takes-twenty-eight
  type: harm 4
  expect:
    change: Odile unhurt -> hurt (24 of 28)
    hp: 24
- id: back-up-onto-the-first-floor
  why: >-
    The First Floor was reached already in this game, so walking back onto it
    heals nothing.
  type: "/move The First Floor room 2"
  expect:
    location: The First Floor room 2 (realized)
    hp: 24
- id: she-keeps-level-five-on-the-first-floor
  why: >-
    The level is the highest this game has reached, wherever she stands: 28,
    not the first floor's 23.
  type: harm 1
  expect:
    change: Odile hurt (24 of 28) -> hurt (23 of 28)
    hp: 23
- id: down-onto-the-second-floor-again
  why: >-
    Reaching The Second Floor a second time raises nothing and heals nothing.
  type: "/move The Second Floor room 1"
  expect:
    location: The Second Floor room 1 (realized)
    hp: 23
- id: still-level-five
  why: >-
    A mend stops at level 5's 28, not at a level 6 nobody reached.
  type: mend 99
  expect:
    change: Odile hurt (23 of 28) -> unhurt
    hp: 28
- id: a-second-game-is-raised-from-the-worlds-level
  why: >-
    Another game reaches The First Floor, already laid out, for the first time:
    it is raised from the world's level 3 to 4, and the engine says so in its
    own words.
  player: second
  type: "/move The First Floor"
  expect:
    location: The First Floor room 1 (realized)
    hp: 23
    note: 'the game: Reaching The First Floor raised Odile to level 4: 23 hit
      points, and healed to full.'

The first time a game stands on a floor (a place with a floors row, or a
room of one), the engine writes that game's row of playthrough_floors:
when it arrived, and on a floor whose row says levels_up, the level it
raised the player to, one past the level the game had (capped at 20).
The player is mended to the new maximum on the same turn, before the way
in or the room takes a toll and before anybody strikes. A floor is
reached once a game; walking back onto it writes and heals nothing. The
world's characters.level is never written.

The game's level is the highest such row's level; every max-HP reader
asks the game (Game::level_at, Game::max_hp_at): vitals_for, a toll's
and a blow's condition at its own story time, a new vitals row, the mend
cap, and the glance's sheet line. The turn's scene claims the row, as it
claims a toll, and the engine-alone report notes it in the engine's own
words: "Reaching {floor} raised {fullname} to level {level}: {max} hit
points, and healed to full." No request carries it.

Migration 20261031090000 adds floors.levels_up and playthrough_floors,
applied to every world dump as Rails' SQLite adapter applies it.
store::OPTIONAL_COLUMNS and OPTIONAL_SHAPES hold its facts, so the game
at its current pin still opens and plays; SCHEMA_VERSION and shape.txt do
not move. No golden or records file moved, and the fight simulator's
reference fights are unchanged.

New world three-floors-that-raise-you (the game's loader at server
b2a4523, then the migration and levels_up set) and script
a-floor-raises-a-level-once, in PASSING with a golden and records.
…dstep/server 132b475

The game's pin PR (renderedstep/server#373) reads levels_up:, so the dump
is now the one its own loader writes from a schema load: levels_up is
written by the loader rather than by hand. The rows are the same; only
timestamps, the order playthrough_floors and its indexes are dumped in,
and the walk's id pin on its sequence moved. No golden or records file
moves.
@calebl
calebl merged commit 9bbff37 into main Oct 30, 2026
4 checks passed
calebl added a commit to renderedstep/server that referenced this pull request Oct 30, 2026
9bbff37 adds to the head pinned before only the engine's CI and
parity/worlds/three-floors-that-raise-you.sql rebuilt from this branch's
loader (132b475). No golden, script or vector portion changed: bin/rails
engine:vendored passes, engine:rust_gates passes all 110 scripts.
calebl added a commit to renderedstep/server that referenced this pull request Oct 30, 2026
Pin renderedstep/engine#97's head (e8a28d2): raise the game's level once on each floor that says so, and heal to full
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant