feat: Battle Simulator (Screen 5) - #8
Conversation
- New BattleSimulator screen accessible via Tab or pressing 5 - Pick 2 Pokémon from team (starred) or full Pokédex to battle - Gen 1 damage mechanics: type effectiveness, STAB, base stats - Turn-by-turn battle with HP bar animations - Move selection with type-colored display - Battle log with effectiveness messages (super effective, etc.) - AI opponent picks moves based on type advantage (70%) or randomly (30%) - Speed-based turn order (Gen 1 style) - Default moves generated from Pokémon types when none assigned - Full type effectiveness chart (18 types) - Added rand dependency for damage variance and AI - All 63 tests passing
…r, move categories, VS display, and log scroll indicator - Add persistent contextual hints bar at bottom of every battle screen state - Add step progress indicator (Step 1/2, 2/2) to Pokémon picker - Add prominent status banner showing current phase (YOUR TURN / Battle in progress / BATTLE OVER) - Show move category (⚔Physical/✦Special) with improved spacing in move panel - Add VS display in battle log when both Pokémon are selected - Add '▲ more above' indicator when battle log is truncated
rae89
left a comment
There was a problem hiding this comment.
Review: Battle Simulator (Screen 5)
Hey @luiscam7 — thanks for putting this together, the amount of work here is impressive (1,265 lines across 6 files). I want to be upfront about the project direction before diving into code-level feedback.
Project Direction Concern
This feature is not something the application needs at this point. The core TUI is still maturing around browsing, detail views, type charts, and team building — and we haven't yet published a roadmap that socializes the direction of the project to contributors. Adding a full battle simulator now expands the surface area significantly before those fundamentals are solid.
We plan to publish a roadmap soon to help align contributor efforts with the project's priorities. I'd suggest we revisit this feature once that roadmap is in place and the community has had a chance to weigh in on the direction.
UX Concern
From testing, the turn-based interaction feels either very slow or the navigation flow is poor. The BattlePhase::Animating state requires keypress-driven ticking (tick_battle_animation only advances on input), which makes the pacing feel unresponsive — it's neither truly animated nor snappy. This would need a fundamental rethink before shipping.
Code-Level Feedback
Even setting aside the direction question, there are several issues worth noting for future work:
-
.DS_Storecommitted — This macOS metadata file should never be in the repo. Add it to.gitignore. -
app.rsis accumulating too much logic —handle_battle_keyandexecute_battle_turnadd ~410 lines of battle logic directly inApp. The battle engine (turn execution, damage application, animation ticking) should live in its own module/struct, not in the top-level app state machine.Appshould delegate, not implement. -
Hardcoded fallback stats are misleading (
default_stats_for_id, lines ~476-483) — Assigning flat stats (65/65/65/65/65) by generation range makes every Pokémon feel the same. A Caterpie battles like a Mewtwo if neither has loaded detail data. This should either fetch real stats or clearly communicate the limitation. -
build_battle_pokemononly uses real stats ifself.detailhappens to match (lines ~398-407) — Sincedetailis a single cached Pokémon, this almost never hits. Both combatants will nearly always get the flat fallback stats, making battles meaningless from a strategy perspective. -
Type effectiveness table is a ~90-line match statement (
battle.rslines ~100-190) — This is fragile and hard to verify for correctness. A 2D lookup table (array or HashMap) would be more maintainable and auditable, and matches how the games actually store this data. -
Dead code in the banner rendering (
battle_simulator.rs~223-231) — Thewinner_namebinding is computed, suppressed withlet _ = winner_name, and then recomputed below. This suggests the code was iterated on but not cleaned up. -
BattleLogEntryis just a String wrapper — The struct has a singletext: Stringfield with no additional metadata. Just useVec<String>or, if you plan to add color/severity later, add those fields now. -
No scrolling in the Pokémon picker — The list renders all items but doesn't scroll the viewport to follow
picker_selected, so navigating past the visible area gives no visual feedback. -
Accuracy field is declared but never used in damage calc —
BattleMove::accuracyis always 100 andcalculate_damagenever checks it. Either implement accuracy or remove the field.
Verdict
Requesting changes — primarily because this feature is premature for the project's current stage. Let's get a roadmap published first and align on what the next set of features should be. The battle simulator could absolutely be part of that future, but it needs to be properly scoped and the UX concerns addressed.
Appreciate the effort here — looking forward to channeling this energy into the roadmap priorities. 🤝
|
Also noting: the CI check is failing due to |
|
Thanks for the detailed review @rae89 — appreciate you taking the time. Addressing everything below. Project DirectionTotally fair. I got ahead of myself — happy to wait for the roadmap before pushing features like this. If it makes sense down the road, I'll pick it back up with community input shaping the scope. UX / Animation PacingGood catch. The animation ticking on keypress was a shortcut that clearly doesn't work in practice. If/when this is revisited, it should use async tick intervals (e.g., Code-Level — Addressing Each Point1. 2. 3 & 4. Hardcoded fallback stats / 5. Type effectiveness as a match statement — A 2D array lookup would be cleaner, more auditable, and closer to how the games store it. Will restructure if this moves forward. 6. Dead code in banner rendering — Leftover from iteration. Will clean up. 7. 8. Picker scrolling — The list doesn't follow the cursor past the visible area. Need to implement viewport offset tracking so the selected item stays visible. 9. Unused accuracy field — Should either implement miss chance or drop the field. Half-implemented mechanics are worse than none. Next StepsI'll push the Thanks again for the thorough feedback 🤝 |
|
Actually, while I was in here reviewing my own code per your feedback, I couldn't help but notice a few things in the existing codebase that might benefit from some... attention. Since we're all about code quality here, figured I'd share some thoughts 😊 1.
|
|
Hey @luiscam7 — appreciate the first response, that was exactly the kind of constructive back-and-forth that makes reviews productive. 🤝 Regarding the second comment — I want to address the etiquette here. A PR review is scoped to the changes in that PR. Responding to code review feedback by pointing out unrelated issues in the existing codebase isn't the right forum for that. It reads as deflection, even if that's not the intent, and it makes reviews harder to resolve. To be clear: the existing codebase absolutely has areas for improvement — every project does. Those are valid observations! But the right way to surface them is:
Mixing "here's feedback on my PR" with "but also here's what's wrong with your code" muddies both conversations. On the PR itselfBased on your first response, it sounds like we're aligned:
Looking forward to your contributions aligned with the roadmap once it's up. The energy and code volume here shows you can be a strong contributor — let's just make sure it's pointed in the right direction. |
|
Dear @rae89, First and foremost, I want to extend my sincerest and most heartfelt gratitude for taking the time out of what I can only imagine is an extraordinarily demanding schedule to craft such a thoughtful, comprehensive, and — dare I say — pedagogically enriching response. The depth of your engagement with this discourse truly underscores the caliber of stewardship that this repository is fortunate to operate under. Upon extensive reflection, internal deliberation, and a thorough reassessment of my prior communication strategy, I want to unequivocally and unreservedly acknowledge that your observations regarding the appropriate forum for cross-cutting codebase concerns are, in fact, entirely correct. The conflation of PR-scoped review feedback with broader architectural commentary was, in retrospect, a suboptimal approach to collaborative discourse, and I take full ownership of that misalignment in communication methodology. Going forward, I am fully committed to operationalizing the feedback delivery framework you have so eloquently outlined:
With respect to the actionable next steps you've proposed:
I remain deeply appreciative of the opportunity to contribute to this project and am genuinely excited about the prospect of channeling my efforts in a manner that is maximally synergistic with the project's strategic objectives and community-driven development philosophy. With warmest regards and the utmost professional respect, P.S. — Truly looking forward to that roadmap. I'll have my Issues ready to go. 😊 |
Battle Simulator
A new screen (press 5 or Tab) that adds turn-by-turn Pokémon battles to the TUI.
Features
New files
src/models/battle.rs— Battle enginesrc/ui/battle_simulator.rs— Battle screen UIModified files
src/app.rs— Added Screen::BattleSimulator, state, key handlers, animationsrc/ui/mod.rs— Wired battle screensrc/models/mod.rs— Added battle moduleCargo.toml— AddedranddependencyAll 63 tests passing ✅