feat(pacing): soft floor-readiness guidance — answer "how much Tetris?" - #21
Merged
Conversation
Players had no signal for how long to build a floor before descending. Add
advisory (never gating) guidance that scales with depth.
- Each non-boss floor has a readiness target: baseTarget + (level-1)*perLevel
blocks (all knobs in balance.json's new floorReadiness block). Later floors
ask for more Tetris, so play naturally lengthens as the run deepens.
- The HUD floor dial leads with readiness: "building 6/15" → a glowing "ripe"
once the floor is built out → "linger" past target*lingerMult. One-time
toasts fire at ripe ("descend when you are ready") and lingering ("the rift
grows restless").
- Descent stays entirely player-driven — the stairs are never locked.
- Each descent banks a pieces/target pacing sample (non-boss floors only,
stack-collapses count as staying to the limit). The seanchai in the mound
reads the run's average and comments: leaving too soon, lingering too long,
or judging it well (seanchaiEarlyRatio / seanchaiLateRatio).
- balance.json + schema + balance.ts: floorReadiness block
- types.ts: UIState.floorProgress.readiness
- game.ts: readiness target/ceiling, ripe/linger detection, dial state,
recordFloorPacing on both descent paths, pacingAdvice, per-floor reset
- ui.ts + style.css: readiness dial segment (build/ripe/linger)
- npcEncounters.ts: seanchai pacing line in the "your tale" recount
- tests: target scaling, dial states, gating, ripe toast once, pacing tally,
seanchai verdict bands
- README: new "Floor readiness" system row
Pacing state (pacingRatioSum/Samples) round-trips through save/resume via the
generic scalar sweep. Verified live: the dial renders building/ripe/lingering
with no page errors.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01V6kP5vUAcNbxLK5EnPKAhv
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.
Players had no signal for how long to build a floor before descending. Add
advisory (never gating) guidance that scales with depth.
Each non-boss floor has a readiness target: baseTarget + (level-1)*perLevel
blocks (all knobs in balance.json's new floorReadiness block). Later floors
ask for more Tetris, so play naturally lengthens as the run deepens.
The HUD floor dial leads with readiness: "building 6/15" → a glowing "ripe"
once the floor is built out → "linger" past target*lingerMult. One-time
toasts fire at ripe ("descend when you are ready") and lingering ("the rift
grows restless").
Descent stays entirely player-driven — the stairs are never locked.
Each descent banks a pieces/target pacing sample (non-boss floors only,
stack-collapses count as staying to the limit). The seanchai in the mound
reads the run's average and comments: leaving too soon, lingering too long,
or judging it well (seanchaiEarlyRatio / seanchaiLateRatio).
balance.json + schema + balance.ts: floorReadiness block
types.ts: UIState.floorProgress.readiness
game.ts: readiness target/ceiling, ripe/linger detection, dial state,
recordFloorPacing on both descent paths, pacingAdvice, per-floor reset
ui.ts + style.css: readiness dial segment (build/ripe/linger)
npcEncounters.ts: seanchai pacing line in the "your tale" recount
tests: target scaling, dial states, gating, ripe toast once, pacing tally,
seanchai verdict bands
README: new "Floor readiness" system row
Pacing state (pacingRatioSum/Samples) round-trips through save/resume via the
generic scalar sweep. Verified live: the dial renders building/ripe/lingering
with no page errors.
Co-Authored-By: Claude Opus 4.8 noreply@anthropic.com
Claude-Session: https://claude.ai/code/session_01V6kP5vUAcNbxLK5EnPKAhv