feat: combat vertical slice (melee, timed swings, damage numbers) #25

Merged
marco merged 3 commits from feat/combat-slice into main 2026-07-17 14:21:53 +02:00
Owner

Summary

Combat vertical slice ("first blood"): player melee vs creatures, server-authoritative, deliberately NOT instant-kill.

  • Swing is timed and resolves at the end (CombatSystem, owned by World under its lock): a swing starts on an Attack intent and lands after the swing duration, re-checking range — step away during the swing and you dodge. HP >> damage-per-hit + a swing cooldown → a rat (~20 HP) takes ~4 hits over a few seconds.
  • HP is server-only, never on the wire. No health bar — you don't know the mob's (or your) HP. Only damage numbers are shown.
  • Creature death → removed + respawns after a delay.
  • Client: click a creature to engage (auto-attack; Esc/click-away disengages); the human plays a real one-shot attack animation (extracted into the pack) facing the target; a floating red damage number rises and fades over the target on each hit.
  • Damage/swing are per-attacker (fixed from config in v1) so weapons can later change both damage and swing time.
  • Deferred (noted): creature aggro / two-way combat, PvP, weapon-driven stats.

Screenshots / recording

How it was tested

CombatSystem via World: swing resolves to a hit when the target stays in range, misses when the attacker steps out of range before it resolves, respects the swing cooldown, and kills-after-enough-hits then respawns (deterministic stationary test creature). Protocol round-trips (Attack/Swing/Attacked). Full suite green (175), just lint clean, zero warnings.

Needs your eyes

I can't verify the GUI: please confirm in-game that the attack animation looks right (I used UO people action 9 for the 1H swing — if the pose is wrong, tell me and I'll pick another action), and that the swing/dodge/damage-number feel is good.

Checklist

  • just lint passes
  • just test green
  • Whole solution builds
  • Multi-platform preserved
  • Tests added
## Summary Combat vertical slice ("first blood"): player melee vs creatures, server-authoritative, deliberately NOT instant-kill. - **Swing is timed and resolves at the end** (CombatSystem, owned by World under its lock): a swing starts on an Attack intent and lands after the swing duration, **re-checking range** — step away during the swing and you dodge. HP >> damage-per-hit + a swing cooldown → a rat (~20 HP) takes ~4 hits over a few seconds. - **HP is server-only, never on the wire.** No health bar — you don't know the mob's (or your) HP. Only **damage numbers** are shown. - Creature death → removed + respawns after a delay. - **Client**: click a creature to engage (auto-attack; Esc/click-away disengages); the human plays a real one-shot **attack animation** (extracted into the pack) facing the target; a **floating red damage number** rises and fades over the target on each hit. - Damage/swing are **per-attacker** (fixed from config in v1) so weapons can later change both damage and swing time. - Deferred (noted): creature aggro / two-way combat, PvP, weapon-driven stats. ## Screenshots / recording <!-- VISIBLE feature — please attach a short screen recording of engaging a rat: the swing animation, the "-5" damage numbers, and the rat dying + respawning. --> ## How it was tested CombatSystem via World: swing resolves to a hit when the target stays in range, **misses when the attacker steps out of range before it resolves**, respects the swing cooldown, and kills-after-enough-hits then respawns (deterministic stationary test creature). Protocol round-trips (Attack/Swing/Attacked). Full suite green (175), `just lint` clean, zero warnings. ## Needs your eyes I can't verify the GUI: please confirm in-game that the **attack animation** looks right (I used UO people action 9 for the 1H swing — if the pose is wrong, tell me and I'll pick another action), and that the swing/dodge/damage-number feel is good. ## Checklist - [x] `just lint` passes - [x] `just test` green - [x] Whole solution builds - [x] Multi-platform preserved - [x] Tests added
New CombatSystem (owned by World under its single lock, like ItemRegistry): a swing
starts on an Attack intent and RESOLVES after the swing duration, re-checking range so
a target that steps away dodges. Damage/HP/swing are per-mobile (weapons override
later); HP is server-only, never on the wire. On a kill the creature is removed and
respawns after a delay. Protocol: Attack intent + Swing (animation) + Attacked (damage
number, hit only). World stays a thin facade; broadcasts flow via the tick loop.
feat(combat): client — click-to-attack, swing animation, floating damage numbers
All checks were successful
ci / Lint & Test (pull_request) Successful in 1m45s
22d7876a3e
Extract the human attack action into the pack (human/attack_<dir>); SpriteAnimator
gains a one-shot mode and Player a transient swing state driven by the server's Swing
event (plays the attack clip once facing the target, then idles). Click a creature to
engage (auto-attack resends Attack while it's in view; Esc/click away disengages);
the Attacked event pops a rising, fading red damage number over the target (no health
bar — HP stays hidden). GameLoopService broadcasts hits before the reconcile so a
killing blow's number shows before MobileRemoved.
marco force-pushed feat/combat-slice from f2f4785d09
Some checks failed
ci / Lint & Test (pull_request) Has been cancelled
to 8f8f1ea6bd
All checks were successful
ci / Lint & Test (pull_request) Successful in 1m34s
2026-07-17 14:15:18 +02:00
Compare
marco merged commit 83bf62a5e8 into main 2026-07-17 14:21:53 +02:00
marco deleted branch feat/combat-slice 2026-07-17 14:21:53 +02:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
marco/IsoMmo!25
No description provided.