Fix food spawning on occupied cells; surface notifications in the text UI - #111
Conversation
spawnFood() searched for an empty location and then discarded it, letting Environment.addEntity()'s independent random draw place the food - so food routinely landed under a snake part, on a cell that ends the run instead of feeding the player. The discarded while-loop also hung forever on a full grid. Placement now picks from the set of empty locations directly. notify() only printed in text mode, and renderGrid()'s clearScreen() wipes that print later in the same tick, so every notification was invisible there. Messages are now queued on the shared banner in both modes, and the text loop renders the current one via TextRenderer.renderMessage() - which takes a plain string, so textui stays independent of the pygame ui package. Closes #109 Closes #110 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Self-reviewThe fix is correct on both counts and well covered by tests — Verified against source (not from the diff alone):
Non-blocking notes
(Posted as a PR comment rather than a formal review: the review-submission API call is not available to this session.) This comment was drafted during a Gardener session (Stephenson-Software/gardener). |
- spawnFood() iterates grid.getLocations().values() instead of resolving each location ID twice (once in the filter, once in the result) - notify()'s docstring now says explicitly that in text mode the console print only survives in redirected output; the banner is the player- facing channel Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
Both self-review notes applied in 284a0bb:
Re-verified after the change: Documentation pass (Phase 7) found nothing to fix: This PR is ready for a human to review and merge — this session is not authorized to merge. This comment was drafted during a Gardener session (Stephenson-Software/gardener). |
Summary
spawnFood()now places food on an empty location. It previously searched for an empty location and then threw the result away, handing placement toEnvironment.addEntity()'s independent random draw. Food therefore landed under snake parts regularly — andmoveEntity()checks the destination for aSnakePartbefore it ever looks for food, so those cells end the run (or burn thesecond_windcharge) instead of feeding the player. Placement now picks from the set of empty locations directly, and falls back to the old behaviour only when the grid is completely full.while notFoundloop is gone. Wired up as written it hung forever on a full grid; the new test for that case reproduced the hang against the pre-fix source (pytest had to be killed at the 2-minute mark).notify()onlyprint()ed in text mode, andTextRenderer.renderGrid()'sclearScreen()wipes that print later in the same tick — so speed boosts,second_windsaves, skin unlocks, ascensions and biome-arrival flavor text were all silently dropped for text-UI players. Messages are now queued on the shareduiBannerin both modes, andrunTextUI()renders the current one through a newTextRenderer.renderMessage().renderMessage()takes an already-resolved plain string, sosrc/textuinever imports fromsrc/ui, and gameplay code still only ever callsnotify().Notes
test_notify_is_console_only_in_text_ui_modeasserted the now-reversed behaviour and was replaced bytest_notify_queues_the_message_in_text_ui_mode../format.shwas not run: the repo is not currently black-clean (9 files, including the vendoredsrc/lib/pyenvlib/environment.py, would be reformatted).black --diffconfirms it would not touch any line added here, so the diff is left focused on the actual change.Test plan
python3 -m pytest— 138 passed (was 132)python3 -m compileall src— cleanrenderMessage()prints a message, and prints nothing forNone/""notify()queues in text mode, andrunTextUI()hands the queued message to the rendererCloses #109
Closes #110
This PR description was drafted during a Gardener session (Stephenson-Software/gardener).