Cliloc-style message catalog: server sends id + args, client owns strings #59
Labels
No labels
alpha:wave-0
alpha:wave-1
alpha:wave-2
alpha:wave-3
area:assets
area:combat
area:ecology
area:infra
area:render
area:scripting
area:ui
area:world
enhancement
epic
migration
post-alpha
roadmap
tech-debt
type:bug
type:chore
type:design
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
marco/IsoMmo#59
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Problem. User-facing strings are scattered across the server: spell cues ("Not enough mana", "No line of sight", "Out of range", "Invalid target", "You can't cast while dead") in
SpellSystem/SpellCastResult, the skill-gain line ("{Skill} increased … — now …") inWorldTickandGameSessionHandler, GM-command feedback in the command classes. As the spell system grows (invalid-combo, timeout, disrupted, fizzle variants…) this surface explodes, and presentation strings live inside authoritative game logic.Proposal (UO cliloc-style). The server sends a message id + parameters; the client owns the string table and formats it. Decouples wire from presentation, keeps gameplay logic free of copy, and is localization-ready. Aligns with "server = authoritative logic, client = presentation" and with ModernUO/UO (our reference).
Our variant (type-safe, not magic numbers). UO uses numeric cliloc ids because its client is closed + the table huge. We should instead use a typed
SystemMessageIdenum inIsoMmo.Shared/Protocol(compile-time safe, both sides reference it), a newSystemNotice(SystemMessageId Id, IReadOnlyList<string> Args)protocol message, and a client-side formatter mapping id → template (a single file, e.g.en.json/a static table). Call sites becomenew SystemNotice(SystemMessageId.NotEnoughMana)/SystemNotice(SystemMessageId.SkillIncreased, [skill, gained, now]).Keep freeform
SystemMessage(string)only where the text is genuinely dynamic and not worth cataloguing (or drop it entirely). Migrate incrementally.Why now-ish (not urgent). Do it as its own pass before the spell-system string surface grows much further (slices 2–4 add many cues). Owner flagged it as "later".
Scope
SystemMessageIdenum +SystemNoticemessage toShared/Protocol.SystemMessagegameplay cues (spell cues, skill-gain, GM feedback) toSystemNotice.Definition of Done
SpellSystem,WorldTick, command classes) — all go throughSystemMessageId.SystemNotice(id, args)and render correctly (integration-tested for at least one of each).