Update combat docs to match 3-state machine and correct field names

This commit is contained in:
Jared Miller 2026-02-16 14:48:39 -05:00
parent 13eb6a947b
commit 03d04f0a33
Signed by: shmup
GPG key ID: 22B5C6D66A38B06C

View file

@ -50,29 +50,21 @@ the state machine
:: ::
IDLE → TELEGRAPH → WINDOW → RESOLVE → IDLE IDLE → PENDING → RESOLVE → IDLE
IDLE: IDLE:
no active move. attacker can initiate attack. defender can do nothing no active move. attacker can initiate attack. defender can do nothing
combat-specific. combat-specific.
TELEGRAPH: PENDING:
attacker has declared a move. defender sees the telegraph message. attacker has declared a move. telegraph message sent to defender.
"goku winds up a right hook!" the move is now in flight — defender can queue a defense any time
defender can queue a defense during this phase. during this phase. duration is the attack's hit_time_ms.
duration: brief (implementation decides, not move-defined).
WINDOW:
the timing window opens. defender can still queue defense.
if defender queued correct counter during TELEGRAPH or WINDOW, they succeed.
duration: move.timing_window_ms (defined in TOML).
RESOLVE: RESOLVE:
timing window closes. check if defense counters attack. hit_time_ms elapsed. check if defender's active defense counters the
calculate damage based on attacker PL, damage_pct, and defense success. attack. calculate damage, apply stamina costs, check for knockouts
apply stamina costs. or exhaustion. return to IDLE.
check for knockouts (PL = 0) or exhaustion (stamina = 0).
return to IDLE.
entity stats entity stats
@ -205,7 +197,7 @@ moves live in content/combat/. two formats: simple and variant.
move_type = "attack" move_type = "attack"
stamina_cost = 8.0 stamina_cost = 8.0
telegraph = "{attacker} spins into a roundhouse kick!" telegraph = "{attacker} spins into a roundhouse kick!"
timing_window_ms = 600 hit_time_ms = 600
damage_pct = 0.25 damage_pct = 0.25
countered_by = ["duck", "parry high", "parry low"] countered_by = ["duck", "parry high", "parry low"]
@ -215,7 +207,7 @@ moves live in content/combat/. two formats: simple and variant.
name = "punch" name = "punch"
move_type = "attack" move_type = "attack"
stamina_cost = 5.0 stamina_cost = 5.0
timing_window_ms = 800 hit_time_ms = 800
damage_pct = 0.15 damage_pct = 0.15
[variants.left] [variants.left]
@ -228,7 +220,7 @@ moves live in content/combat/. two formats: simple and variant.
telegraph = "{attacker} winds up a right hook!" telegraph = "{attacker} winds up a right hook!"
countered_by = ["dodge left", "parry high"] countered_by = ["dodge left", "parry high"]
shared properties (stamina_cost, timing_window_ms, damage_pct) are defined at shared properties (stamina_cost, hit_time_ms, damage_pct) are defined at
the top level. variants inherit these and can override them. variant-specific the top level. variants inherit these and can override them. variant-specific
properties (telegraph, countered_by, aliases) live under [variants.<key>]. properties (telegraph, countered_by, aliases) live under [variants.<key>].
@ -236,13 +228,28 @@ each variant produces a CombatMove with a qualified name like "punch left".
the ``command`` field tracks the base command ("punch") and ``variant`` tracks the ``command`` field tracks the base command ("punch") and ``variant`` tracks
the key ("left"). simple moves have command=name and variant="". the key ("left"). simple moves have command=name and variant="".
**defense move** (directional)::
# content/combat/dodge.toml
name = "dodge"
move_type = "defense"
stamina_cost = 3.0
active_ms = 800
recovery_ms = 2700
[variants.left]
[variants.right]
TOML field reference: TOML field reference:
- name: the command name (simple) or base command (variant) - name: the command name (simple) or base command (variant)
- move_type: "attack" or "defense" - move_type: "attack" or "defense"
- stamina_cost: stamina consumed when using this move - stamina_cost: stamina consumed when using this move
- timing_window_ms: how long defender has to respond - hit_time_ms: (attacks) time in ms from initiation to impact
- telegraph: shown to defender during TELEGRAPH phase. {attacker} replaced - active_ms: (defenses) how long defense blocks once activated, in ms
- recovery_ms: (defenses) lockout after active window ends, in ms
- telegraph: shown to defender during PENDING phase. {attacker} replaced
- damage_pct: fraction of attacker's PL dealt as damage - damage_pct: fraction of attacker's PL dealt as damage
- countered_by: list of qualified move names that counter this move - countered_by: list of qualified move names that counter this move
- aliases: short command aliases registered as standalone commands - aliases: short command aliases registered as standalone commands