UI parity for the restart frame, a speed-boost HUD line, and setup docs - #118
Conversation
|
Self-review (posted as a comment — the reviews API isn't available in this environment; inline findings are folded in below as OverallThe three changes hang together: two of them are the recurring text-vs-graphical drift problem, and the third is the setup gap a new contributor hits before they can run either UI. Behaviour of the sentinel is now stated once ( Three findings, two of which are being fixed. Findings
Checked and clear
This comment was drafted during a Gardener session (Stephenson-Software/gardener). |
- drawHud/renderHud now check `is not None and > 0` instead of relying on truthiness, so suppressing the line for an expired-but-not-yet-cleared boost reads as deliberate rather than accidental; both are pinned by a test now. - README states the version the project is actually exercised on alongside the 3.8 floor, which nothing verifies. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Summary
handleKeyDownEvent's"restart"return was acted on withcontinuein both game loops, but inrunPygameUIthatcontinuesat inside thefor event in ...drain, so it only advanced to the next event and the snake still moved in the very frame a run restarted. Both loops now track arestartedflag and skip only that iteration's movement step, so the freshly initialized board is presented before it advances. The pygame loop still finishes draining its event queue, so a key pressed behind the restart key isn't dropped.moveSelectedSnakePart(). The per-loopif direction == 0: ... elif direction == 3:chains were byte-for-byte duplicates — the exact shape of drift PRs Add text-based UI option for terminal gameplay #92/Add text-based UI option with clean architecture, comprehensive testing, CI/CD verification, and performance optimizations #95/Add cross-run progression: obituaries, cosmetics, currency/shop, naming/lore, ascension #99 kept having to repair. One method, called from both loops.UiBanner.durationSeconds(2s) while the boost runs forconfig.speedBoostDuration(5s), so the snake spent the tail of every boost moving faster for no visible reason. NewOphidian.getSpeedBoostRemainingSeconds()returns a plain number (orNone); each renderer formats it itself — pygame gets a third HUD line, the text UI gets aSpeed boost: 3sline — so no display strings leak into gameplay code. The optional pygame HUD lines flow upwards, so a run owning no upgrades doesn't render the boost line under a blank row.requirements.txt(pygame) andrequirements-dev.txt(pytest, pytest-cov, black, autoflake), plus "Requirements" and "Installation" sections inREADME.mdabove "Usage". Notes explicitly that--text-uiruns without pygame.Test plan
python -m pytest— 161 passed (was 150; 11 new tests)python -m compileall srccleantests/test_ophidian_run_lifecycle.py)tests/rendering/test_pygame_run_loop.py)getSpeedBoostRemainingSeconds()—Nonewhen idle, counts down while active, clamped at 0 once expired (tests/test_ophidian_food_types.py)tests/rendering/test_hud_and_banner.py,tests/textui/test_textrenderer.py)handleKeyDownEvent;--text-uiis still the only argparse flagCloses #117
Closes #114
Closes #115
This PR description was drafted during a Gardener session (Stephenson-Software/gardener).