Repository navigation
Pin renderedstep/engine#97's head (e8a28d2): raise the game's level once on each floor that says so, and heal to full - #373
Merged
Merged
Conversation
…nce on each floor that says so, and heal to full
Stage 5 of the dungeon plan, server half ("Levelling stage 1"). A floor that
says `levels_up: true` raises a game's level by one the first time that game
stands on it, and the engine heals the player to full on the same turn. The
level is the game's: `characters.level` never moves. A world without
`levels_up` plays as before; no checked-in story world turns it on.
- Migration 20261031090000 AddLevelsUpAndCreatePlaythroughFloors, the
engine's version and declaration. schema.rb moves to 2026_10_31_090000.
- Playthrough::FloorReached (table playthrough_floors), written by the engine
only: level in Character::LEVELS or nil, one row per game and floor. #to_s
is the engine's notice word for word. Playthrough destroys, Location
destroys, Scene nullifies. Floor validates levels_up as a boolean.
- Playthrough#level_for / #max_hp_for mirror Game::level_at / max_hp_at, and
every max-HP reader on a game asks them: Vitals (.instantiate!,
Condition.for, #max and so its validation), Turn#mend!, Blow#condition
and Toll#condition at their story_timestamp, and Mechanics::State#sheet.
Character.hit_points is the one formula; Character#advance! stays uncalled
and says why.
- Story::Doctor#hp_above_maximum and Story::Repair#repair_hp_above_maximum
read the game's maximum, so a routine repair never clamps a levelled
player back to the world's. New finding floor_reached_that_is_no_floor
(manual, never repaired).
- Loader reads floor `levels_up` (true or false only, absent writes false);
the exporter writes it when true.
- Protocol::V1#entry and the browser log show this game's claimed levelling
rows after its tolls. turn_log preloads what they read.
- SqlitePackage carries playthrough_floors; OneRoomFold moves its location.
- Sweep: world three-floors-that-raise-you and script
a-floor-raises-a-level-once, golden vendored and checks file written.
calebl
added a commit
to renderedstep/engine
that referenced
this pull request
Oct 30, 2026
…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.
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Stage 5 of the dungeon plan, server half: levelling stage 1. This PR pins renderedstep/engine#97 at its head (
e8a28d27cc2308e3378103194c13db57fe0973ff) and does every item in that PR's "What the server pin PR must change" list.levels_up: trueraises a game's level by one the first time that game stands on it. The engine heals the player to full on the same turn.characters.levelnever moves.A world without
levels_upplays exactly as before. No checked-in story world turns it on, no prompt changed, and no model was called.What changed
Migration
20261031090000_add_levels_up_and_create_playthrough_floors.rbuses the engine's version and declaration exactly.db/schema.rbmoves to2026_10_31_090000. I placed the lines by hand so the existing column order stays as it was. No later migration is onorigin/main(86b9764).Models
Playthrough::FloorReached(tableplaythrough_floors) is written by the engine only.levelmust be inCharacter::LEVELSor nil, and a game has one row per floor.#to_sisGame::floor_to_sword for word, and nil for a row with no level.Playthrough has_many :floors_reached(destroy),Scene(nullify),Location(destroy).Floorvalidateslevels_upas a boolean.One game-aware reader.
Playthrough#level_for(character, at: nil)and#max_hp_for(character, at: nil)mirrorGame::level_at/Game::max_hp_at.Character.hit_pointsis the one formula. Every reader of a maximum on a game now asks the game:Playthrough::Vitals:.instantiate!,Condition.for, and#max, so thehp_within_the_stat_blockvalidation uses it too;Playthrough::Turn#mend!, the cap;Blow#conditionandToll#condition, at theirstory_timestamp;Mechanics::State#sheet, which prints the game's level, as the engine's glance does.Character#advance!is still never called, and its comment now says why: it writes the world, and a level belongs to the game.Story::Doctor#hp_above_maximumandStory::Repair#repair_hp_above_maximumnow readrow.playthrough.max_hp_for(row.character), and the finding's words name the game's level.Loader.
floor:gainslevels_up.trueorfalseis refused (test with"yes").Exporter. Writes
levels_up: truewhen it is set. Round-trip test.Protocol.
Protocol::V1#entryappends this game's claimed floor rows that raised a level, after its tolls. The browser log (turns/_turn) shows the same notice after the tolls.turn_logpreloads what both read, so the "preloaded log reads no more rows" test still holds.openapi.jsondoes not describe what a notice is, so it is unchanged.Copies of a game.
Playthrough::SqlitePackage::PLAYTHROUGH_TABLESgainsplaythrough_floors(test).Location::OneRoomFold::REFERENCESgainsplaythrough_floors.location_id, which its schema-walking test requires.New doctor finding
floor_reached_that_is_no_floor(warning/manual, never repaired): a game's row for a place that has nofloorsrow. Test: the game keeps its level after a repair.Sweep
three-floors-that-raise-youand scripta-floor-raises-a-level-onceare copied from the engine PR body, with their comments andwhy:notes.test/engine_parity/a-floor-raises-a-level-once.checks.jsonis written. The doctor finds nohp_above_maximumafter the walk.test/ruby_loop_coverage.ymllists no scripts, so neither changes.bin/rails engine:vectorsre-exports with no change.Pin:
ext/renderedstep/Cargo.tomlandCargo.locknow point ate8a28d2.Gates (both provider keys unset)
bin/rails test: 5466 runs, 0 failures, 0 errors. This includes the game sweep.bin/rails engine:rust_gates: PASSED, 110 scripts: goldens, invariants, doctor and audit.bin/rails engine:vendored: VENDORED, byte for byte againste8a28d2.bin/rails engine:kept_requests: the engine reproduces every golden vector and kept request.bundle exec rubocop: no offenses.bin/rails zeitwerk:check: all good.bin/brakeman: no warnings.Follow-up on the engine side
The engine PR asks for
parity/worlds/three-floors-that-raise-you.sqlto be rebuilt from this branch's loader. That file lives in the engine repository and is not changed here.I built it following
parity/README.md, in a scratch copy of this commit:db:schema:load, then theload_world.rbrunner. Its rows are identical to the engine PR's dump. The differences are:schema_sha1;sqlite_sequencerow forplaythrough_floors.After engine#97 merges, this PR re-pins to the merge commit.