Give somebody the turn, and let them spend it #39
No reviewers
Labels
No labels
area/ai
area/build
area/character
area/combat
area/data
area/docs
area/game
area/net
area/ui
area/world
size
l
size
m
size
s
type
bug
type
design
type
feature
type
refactor
type
test
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
icub3d/terra-redux-org!39
Loading…
Reference in a new issue
No description provided.
Delete branch "8-mission-phases"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Declares the mission loop rather than leaving it implied, and closes the last gap between
"an action can be resolved" and "a player can take one".
The phases
MissionPhaseis a sub-state ofGameState::Mission—PlayerTurn,EnemyTurn,Resolving,Animating— followingMenuScreen, so leaving a mission tears it down forfree and systems are gated on a phase rather than asking "is it my turn?" in their bodies.
Turnnames the acting unit and is absent between turns, which is the signalbegin_turnwaits for: it advances the scheduler exactly once per turn and refills whatthat unit has to spend. Advancing merely to look at who is next would spend a turn
nobody took.
Nothing is driven by a timer. A turn ends when its allowance is gone;
Animatingpassesstraight through until playback (#9) gives it something to wait for.
The ordering block earned its keep immediately
CombatSetdeclares the whole order in one place:Reconcile, thenTurn, thenAct.Worth recording: adding
CombatSet::Turnto the enum without adding it toconfigure_setsgave it no run condition at all, so combat systems ran duringLoadingand panicked looking for a
Schedulerthat does not exist yet. The single block is whatmakes that kind of mistake visible — which is the argument this issue was making.
The third stage of the two-stage commit
Pressing a chosen destination again raises
Confirmedfrom the map. That says only thatthe player asked; whether it is that unit's turn is combat's question and is answered
there. The dependency stays one-way — combat already reads the map, and the map still
knows nothing about turns.
Hostiles give up their turn immediately. A placeholder, and the loop does not turn without
it: the opening turn belongs to the fastest unit, which in the shipped deployment is a
hostile, so without this a mission stalls before the player has moved once. #11 replaces
the body rather than the shape.
The two-representation fix you asked for
ADR 0008 flagged the snapshot and the components as two representations that could drift.
The write-back now destructures
Combatantexhaustively, so adding a field stops itcompiling until somebody decides whether the world needs to hear about it — a silent bug
turned into a build error. The ignored fields (
unit,team,movement,attack) areignored on purpose and say why.
Only changed units are written back, because writing every one marks every
GridPoschanged and the movement preview rebuilds on exactly that signal — an attack across the
map would have quietly redrawn an overlay that never moved.
Acceptance criteria
MissionPhasedoes not exist outsideGameState::Mission— asserted in thestyle of
menu_screen_exists_only_inside_main_menu, including that it is absent inthe menu and torn down on leaving.
begin_turnpulls from the scheduler,
finish_animatingends or continues the turn. NoTimeranywhere.
Verification
cargo fmt --check,cargo clippy --all-targets -- -D warnings(and--features perf),cargo test— 171 passing, up from 163.Ran on a Pixel Tablet: a unit selects, a destination holds, confirming walks it — but
only for the unit whose turn it is, and nothing on screen says which that is. I spent
several attempts tapping the wrong unit before testing the path headlessly. The loop is
sound; the game is hard to play by eye until the HUD lands. That makes #10 blocking in
practice, not just desirable.
Closes #8
🤖 Generated with Claude Code
https://claude.ai/code/session_01TA4hJHkRSU3XBxZYtMKXdh