refactor(gameserver): Spell hierarchy + SpellCatalog #79

Merged
marco merged 2 commits from refactor/spell-catalog into main 2026-07-19 09:32:35 +02:00
Owner

Pulls spell resolution out of the incantation FSM into a small class hierarchy, as agreed ("una classe per Spell, come per i mobiles"). Zero behaviour change — the existing IncantationTests + TrainingDummyTests are the regression net and stay green.

Before

SpellSystem.Resolve switched on the form, hard-coded the bolt (target/LOS/range/damage) and held the BoltDamage formula.

After

  • Gameplay/Spells/ (new namespace, one type per file): Spell (abstract: Element, Form, Resolve), BoltSpell (the shared bolt logic), FireBolt / WaterBolt (element + base damage only), SpellCatalog ((element,form) -> Spell), SpellContext (resolution inputs bundled).
  • SpellSystem.Resolve now: train Magery → catalog.TryGet(element, form) → miss ⇒ SpellNotImplemented fizzle (identical to before), hit ⇒ spell.Resolve(ctx). No per-form switch, no bolt formula in the FSM.

This is the seam for slice 2b: shield (KOR) and heal (REN) become a new Spell subclass + one catalog entry each, and invalid pairings (e.g. fire+heal) fall out of the TryGet miss.

No protocol / client / persistence change.

Definition of Done

  • SpellSystem contains no bolt damage/target/LOS/range logic — it delegates to a Spell from the catalog.
  • Adding a spell requires only a new Spell subclass + one SpellCatalog entry (no edit to the FSM resolve path).
  • IncantationTests + TrainingDummyTests pass unchanged (fire & water bolt still land with the same damage; unknown forms still fizzle as not-implemented).
Pulls spell resolution out of the incantation FSM into a small class hierarchy, as agreed ("una classe per Spell, come per i mobiles"). **Zero behaviour change** — the existing `IncantationTests` + `TrainingDummyTests` are the regression net and stay green. ### Before `SpellSystem.Resolve` switched on the form, hard-coded the bolt (target/LOS/range/damage) and held the `BoltDamage` formula. ### After - `Gameplay/Spells/` (new namespace, one type per file): `Spell` (abstract: `Element`, `Form`, `Resolve`), `BoltSpell` (the shared bolt logic), `FireBolt` / `WaterBolt` (element + base damage only), `SpellCatalog` (`(element,form) -> Spell`), `SpellContext` (resolution inputs bundled). - `SpellSystem.Resolve` now: train Magery → `catalog.TryGet(element, form)` → miss ⇒ `SpellNotImplemented` fizzle (identical to before), hit ⇒ `spell.Resolve(ctx)`. No per-form switch, no bolt formula in the FSM. This is the seam for slice 2b: **shield (KOR)** and **heal (REN)** become a new `Spell` subclass + one catalog entry each, and invalid pairings (e.g. fire+heal) fall out of the `TryGet` miss. No protocol / client / persistence change. ## Definition of Done - [ ] `SpellSystem` contains no bolt damage/target/LOS/range logic — it delegates to a `Spell` from the catalog. - [ ] Adding a spell requires only a new `Spell` subclass + one `SpellCatalog` entry (no edit to the FSM resolve path). - [ ] `IncantationTests` + `TrainingDummyTests` pass unchanged (fire & water bolt still land with the same damage; unknown forms still fizzle as not-implemented).
refactor(gameserver): extract Spell hierarchy + SpellCatalog from the FSM
Some checks failed
ci / Lint & Test (pull_request) Has been cancelled
06e17d69a6
The incantation FSM hard-coded bolt resolution and switched on form. Move each
spell into its own Spell subclass (FireBolt/WaterBolt over a shared BoltSpell),
looked up by (element, form) in a SpellCatalog. SpellSystem.Resolve now trains
Magery, resolves the spell from the catalog and delegates — no per-form branch,
no bolt formula in the FSM. SpellContext bundles the resolution inputs.

Behaviour is unchanged: an unknown combination still fizzles as not-implemented.
Adding shield/heal is now a new subclass + one catalog entry.
marco force-pushed refactor/spell-catalog from 7e44741c97
Some checks failed
ci / Lint & Test (pull_request) Has been cancelled
to 6a77dbf385
All checks were successful
ci / Lint & Test (pull_request) Successful in 1m30s
2026-07-19 09:30:48 +02:00
Compare
marco merged commit 4146e0902a into main 2026-07-19 09:32:35 +02:00
marco deleted branch refactor/spell-catalog 2026-07-19 09:32:35 +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!79
No description provided.