Report the run's own score on the obituary screen - #138
Conversation
formatObituaryLines() read name, level, length, ticksSurvived and causeOfDeath off the obituary record but never score, even though SaveManager.recordRun() stores it and the function's own docstring lists it. The only score anywhere on the end-of-run screen was the chronicle's "Highest score ever", which is the lifetime maximum from lifetimeStats - so a player was shown their all-time best at the exact moment a run was summarised, with no way to see what the run just played scored, including when that run was the one that set the best. The narrative line now carries the run's score, read with a default of 0 so obituaries written before score was recorded still render. Both UIs render through this one formatter, so the graphical and text interfaces pick the change up together. README's Scoring section says where the run's score is reported once the run is over. Closes #136 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The new end-to-end test was inserted between two restart tests, splitting a group that otherwise reads top to bottom. It belongs after them, since it is about what an ended run reports rather than about restarting one. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Self-review rubric
Out-of-diff observationThe graphical UI clips this line — including before this change. Wrapping was deliberately left out of this PR: it is a rendering concern in
This review was drafted during a Gardener session (https://github.com/Stephenson-Software/gardener). drafted by Claude on behalf of Daniel Stephenson |
Summary
formatObituaryLines()(src/progression/obituary.py) now reads thescorekey off the obituary record and reports it in the narrative line, so the end-of-run screen names the score of the run that just ended.0, so obituaries written before score was recorded still render rather than raising.Before this change, the only score anywhere on the screen was the chronicle's
Highest score ever, which is the lifetime maximum held inlifetimeStats— the all-time best was shown at the exact moment a run was summarised, with no way to see what the run just played had scored.Rendered output, taken from the text UI after a run was ended with
q:Test plan
./test.sh— 310 passed (306 before this branch); coverage forsrc/progression/obituary.pystays at 100%, and no touched module regressed.src/progression/obituary.pystashed, the four new tests plus the two updated ones fail (6 failed); with it restored, all 26 pass. Sentinel data is used so the run's score (4242) cannot be satisfied by the chronicle's lifetime best (9999).python3 src/ophidian.pylaunched — no startup crash.python3 src/ophidian.py --text-uilaunched under a pty and driven to a run end — obituary renders as shown above.python3 -m compileall srcclean;blackreports the three changed Python files unchanged.New coverage:
test_format_obituary_lines_reports_the_score_of_the_run_that_just_endedtest_format_obituary_lines_defaults_score_for_records_predating_ittest_format_obituary_screen_distinguishes_run_score_from_lifetime_besttest_ending_a_run_shows_that_run_s_score_on_the_obituary_screen— end-to-end, fromOphidian.recordCurrentRun()through to the formatted screenCloses #136
Issues deferred this cycle
Skip reasons are recorded here rather than as comments on each issue:
This PR description was drafted during a Gardener session (https://github.com/Stephenson-Software/gardener).
drafted by Claude on behalf of Daniel Stephenson