magicciv/.project/objectives/p2-53g-ranged-specifics.md
Natalie f0ddc1669b fix(@projects/@magic-civilization): 🐛 update siege action gaps and statuses
Co-Authored-By: Lilith Autocommit <noreply@atlilith.com>
2026-05-02 20:56:39 -04:00

5.2 KiB

id title priority status scope owner parent blocked_by updated_at evidence
p2-53g Ranged specifics — Volley, Aimed Shot, Fire Arrows p2 done game1 combat-dev p2-53
p2-53a
2026-05-03
ActionKind variants: Volley, AimedShot, FireArrows, StopFireArrows in mc-core/src/action.rs
DisabledReason variants: NotRanged, AlreadyAiming, AlreadyFireArrows, NotFireArrows in mc-core/src/action.rs
UnitCapability state fields: is_aiming, is_fire_arrows in mc-core/src/action.rs
MapUnit state fields: aimed_shot_pending, is_fire_arrows in mc-turn/src/game_state.rs
legal_actions gates: ranged keyword check with toggle logic in mc-core/src/action.rs
Handlers: handle_aimed_shot, handle_fire_arrows, handle_stop_fire_arrows in mc-turn/src/action_handlers.rs
Combat hooks: aimed_shot_defence_reduction (50%), attacker_aimed_shot context field in mc-combat/src/keywords.rs and resolver.rs
JSON keyword wiring: ranged key extended with volley/aimed_shot/fire_arrows in unit_actions.json
Vocabulary keys: action_volley, action_aimed_shot, action_fire_arrows, all tooltip_ and disabled_reason_ keys in vocabulary.json
Tests (legal_actions): 4 tests in mc-core/src/action.rs — ranged_unit_has_volley_aimed_shot_fire_arrows, ranged_aimed_shot_disabled_when_already_aiming, ranged_fire_arrows_toggles, non_ranged_unit_has_no_volley_aimed_shot_fire_arrows, all_new_action_kinds_round_trip_as_str
Tests (combat hooks): aimed_shot_flag_triggers_defence_reduction, aimed_shot_defence_reduction_is_50_pct in mc-combat/src/keywords.rs
AI policy: documented no-hook decision in mc-ai/src/tactical/movement.rs
GDScript: signal/KIND_TO_SIGNAL wiring delegated to ui-wiring2 (sent message 2026-05-01)
Volley AoE queue-drain: pending_volley_requests + process_volley_requests phase + queue_volley bridge implemented — mc-turn/src/game_state.rs (VolleyRequest struct, pending_volley_requests field), mc-turn/src/processor.rs (process_volley_requests fn, step() call), api-gdext/src/lib.rs (queue_volley #[func]). p2-53 closeout 2026-05-03.
DEFERRED (documented): Fire Arrows ignition hook — +damage modifier on is_fire_arrows attacks is shipped (mc-combat/src/keywords.rs). Tile ignition (is_burning flag + 3-turn timer + secondary damage) deferred to a dedicated Fire-system objective once mc-ecology ships a Fire subsystem. This is the authoritative game-design decision for p2-53 scope.

Summary

Three new ActionKind variants gating on keywords: ["ranged"]:

  • Volley — area attack: hits target hex's centre + 2 random edge slots; lower per-target damage, more chances to hit
  • Aimed Shot — skip-turn that ignores 50% of target's defence on next attack; sets aimed_shot_pending = true
  • Fire Arrows — toggle posture; ranged attacks ignite tile (uses Fire system from mc-ecology if available); persistent damage, smoke obscures vision

Acceptance

AimedShot

  • ActionKind::AimedShot + DisabledReason::AlreadyAiming + UnitCapability::is_aiming + MapUnit::aimed_shot_pendingmc-core/src/action.rs, mc-turn/src/game_state.rs
  • handle_aimed_shot handler — mc-turn/src/action_handlers.rs
  • Combat hook: 50% defence reduction when aimed_shot_pendingmc-combat/src/keywords.rs, resolver.rs
  • JSON keyword wiring, vocab keys — unit_actions.json, vocabulary.json
  • Tests: aimed_shot_flag_triggers_defence_reduction, aimed_shot_defence_reduction_is_50_pctmc-combat/src/keywords.rs
  • AI policy: documented no-hook decision — mc-ai/src/tactical/movement.rs

FireArrows

  • ActionKind::FireArrows / StopFireArrows + DisabledReason::AlreadyFireArrows / NotFireArrows + MapUnit::is_fire_arrowsmc-core/src/action.rs, mc-turn/src/game_state.rs
  • handle_fire_arrows, handle_stop_fire_arrows handlers — mc-turn/src/action_handlers.rs
  • Combat hook: is_fire_arrows check adds +damage modifier to ranged attacks — mc-combat/src/keywords.rs
  • JSON keyword wiring, vocab keys — unit_actions.json, vocabulary.json
  • Tile ignition (is_burning: bool, 3-turn timer, secondary damage) DEFERRED to future Fire-system objective. mc-ecology has no Fire subsystem. This is the documented authoritative decision for p2-53 scope.

Volley

  • ActionKind::Volley + DisabledReason::NotRangedmc-core/src/action.rs
  • VolleyRequest struct + pending_volley_requests: Vec<VolleyRequest> on GameStatemc-turn/src/game_state.rs
  • process_volley_requests phase in TurnProcessor::step() (between movement and PvP combat) — mc-turn/src/processor.rs
  • AoE: hits target centre hex + 2 random edge-adjacent hexes; attacker.attack / 2 per hit unit — mc-turn/src/processor.rs
  • GdGameState::queue_volley(player_idx, unit_idx, target_col, target_row) bridge method — api-gdext/src/lib.rs
  • ActionKind::Volley invoke arm pushes VolleyRequest + Ok(())mc-turn/src/action_handlers/mod.rs
  • Test: volley_request_drains_each_turnmc-turn/src/processor.rs

Non-goals

  • Cone-shot AoE attacks (separate work).
  • Indirect ranged (covered by p2-53e Indirect Fire for siege only).
  • Fire Arrows tile ignition (deferred to Fire-system objective; see FireArrows section above).