refactor(protocol): cliloc-style message catalog for gameplay cues (#59) #72

Merged
marco merged 2 commits from feat/cliloc-message-catalog into main 2026-07-19 08:25:58 +02:00
Owner

Server sends a message id + args; the client owns the strings and formats them (UO cliloc-style, but a typed SystemMessageId enum, not magic numbers). Closes #59 for the gameplay cues.

What changed

  • SystemMessageId (Shared/Protocol) + a SystemNotice(Id, Args) server→client message.
  • SystemMessageCatalog (Client.Core, unit-tested) maps an id → template and fills the args; GameScreen renders a SystemNotice through it into the journal.
  • Migrated the recurring gameplay cues off literal strings:
    • spell cast cues — SpellCastResult.Message is now a SystemMessageId (CantCastWhileDead, SpellNotImplemented, InvalidTarget, NotEnoughMana, OutOfRange, NoLineOfSight);
    • the skill-gain line — WorldTick + the cast handler build it via GameNotices.SkillIncreased (args: skill, gained, now).
  • Freeform SystemMessage stays for genuinely dynamic/admin text (GM command feedback, targeting errors) — a later pass can catalogue those too.

Presentation copy for gameplay cues now lives in one client table (localization-ready), out of the server game logic — ready for slice 2's many new cues (invalid-combo, timeout, disrupted, …).

just lint → 0 warnings. just test → full suite green (Client.Core 53 incl. 4 new catalog tests, GameServer 145).

Definition of Done

  • Gameplay cues (spell + skill gain) go over the wire as SystemNotice(id, args), not text.
  • The client renders every cue from one catalog table; a Format covers every SystemMessageId (test-enforced).
  • No spell/skill-gain string literal remains in SpellSystem/WorldTick/the cast handler.
  • Localization-ready: a second language is a second table, no server change.
  • Whole solution builds, zero warnings, tests green.

Note: GM command feedback + targeting errors stay freeform for now (admin, dynamic) — cataloguing them is an easy follow-up.

Server sends a **message id + args**; the client owns the strings and formats them (UO cliloc-style, but a **typed `SystemMessageId` enum**, not magic numbers). Closes #59 for the gameplay cues. ## What changed - **`SystemMessageId`** (Shared/Protocol) + a **`SystemNotice(Id, Args)`** server→client message. - **`SystemMessageCatalog`** (Client.Core, unit-tested) maps an id → template and fills the args; `GameScreen` renders a `SystemNotice` through it into the journal. - **Migrated the recurring gameplay cues** off literal strings: - spell cast cues — `SpellCastResult.Message` is now a `SystemMessageId` (CantCastWhileDead, SpellNotImplemented, InvalidTarget, NotEnoughMana, OutOfRange, NoLineOfSight); - the skill-gain line — `WorldTick` + the cast handler build it via `GameNotices.SkillIncreased` (args: skill, gained, now). - Freeform `SystemMessage` **stays** for genuinely dynamic/admin text (GM command feedback, targeting errors) — a later pass can catalogue those too. Presentation copy for gameplay cues now lives in **one client table** (localization-ready), out of the server game logic — ready for slice 2's many new cues (invalid-combo, timeout, disrupted, …). `just lint` → 0 warnings. `just test` → full suite green (**Client.Core 53** incl. 4 new catalog tests, GameServer 145). ## Definition of Done - [x] Gameplay cues (spell + skill gain) go over the wire as `SystemNotice(id, args)`, not text. - [x] The client renders every cue from **one** catalog table; a `Format` covers every `SystemMessageId` (test-enforced). - [x] No spell/skill-gain string literal remains in `SpellSystem`/`WorldTick`/the cast handler. - [x] Localization-ready: a second language is a second table, no server change. - [x] Whole solution builds, zero warnings, tests green. Note: GM command feedback + targeting errors stay freeform for now (admin, dynamic) — cataloguing them is an easy follow-up.
refactor(protocol): cliloc-style message catalog for gameplay cues (#59)
Some checks failed
ci / Lint & Test (pull_request) Has been cancelled
9db130d4fe
The server sends a message id + args; the client owns the strings and formats
them (UO cliloc-style, but a typed SystemMessageId enum, not magic numbers).

- Add SystemMessageId (Shared/Protocol) + a SystemNotice(Id, Args) message.
- Client SystemMessageCatalog (Client.Core, unit-tested) maps id -> template and
  fills args; GameScreen renders a SystemNotice through it into the journal.
- Migrate the recurring gameplay cues off literal strings: the spell cast cues
  (SpellCastResult.Message is now a SystemMessageId) and the skill-gain line
  (WorldTick + the cast handler, via GameNotices.SkillIncreased).
- Freeform SystemMessage stays for genuinely dynamic/admin text (GM command
  feedback, targeting errors) — a later pass can catalogue those too.

Presentation copy for gameplay cues now lives in one client table (localization-
ready), out of the server game logic — ready for slice 2's many new cues.
docs: rule — user-facing text only via the string catalog, never loose literals
All checks were successful
ci / Lint & Test (pull_request) Successful in 1m56s
4764a9ab37
marco merged commit b9fc52dd51 into main 2026-07-19 08:25:58 +02:00
marco deleted branch feat/cliloc-message-catalog 2026-07-19 08:25:58 +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!72
No description provided.