Chat is not one surface. Lobby chat, battle chat, Gameface entry fields, BigWorld chat helpers, and XMPP-backed services can all participate in message delivery. A mod should document which layer it observes or changes and leave every other layer alone.

Chat layer map

Layer Typical owner Safe use Risk
System message Notification or formatter subsystem Local feedback, warnings, confirmations. Using the wrong formatter can hide fields or mutate payload dictionaries.
Lobby messenger Messenger service and account session Lobby conversations, contact state, private-message surfaces. Unavailable during account transitions or reconnect.
Battle channel Battle messenger and arena context Team/channel messages after the arena and channel are ready. Sending before channel initialization can fail silently or target the wrong context.
Gameface chat UI Visible view, route, and model owner Presentation, field visibility, current view behavior. Blocking only the visible field does not control lower-level message paths.
Transport/service layer Client messenger/XMPP infrastructure Understanding the final delivery path and lifecycle. Too deep for most UI features; signatures and permissions are version-sensitive.

Readiness and channel ownership

A battle message can require more than an avatar. The arena may exist before the team channel is ready, and a lobby view may exist while its messenger service is still reconnecting.

  • Resolve the current account, avatar, arena, and messenger service at the moment of use.
  • Use the arena period or view route as a gate only when that is the layer you actually target.
  • Retry channel lookup only with a bounded callback budget.
  • Cancel pending send or display work on battle leave, disconnect, replay seek, and account switch.
  • Do not cache channel objects across lobby/battle transitions.

Outgoing message boundary

If a feature intentionally filters, blocks, formats, or delays outgoing text, define the exact paths it covers. The visible input field, Gameface model, battle action handler, BigWorld helper, and messenger transport can be separate paths.

  • Make the feature explicit and user-controlled when it changes outgoing communication.
  • Never capture or persist unrelated private messages.
  • Prefer a narrow wrapper around the owned message path instead of broad transport interception.
  • Return the failure state expected by the caller if a send action is intentionally blocked.
  • Log only the action and context, not the full private message body.

Diagnostics

Symptom Likely cause Check
Message works in hangar but not battle The feature used a lobby messenger path. Trace the battle channel owner and readiness event.
Message sends twice after reconnect Duplicate subscription or retry callback survived teardown. Log subscription identity and cancel callback IDs on context change.
UI says blocked but text still sends Only the visible input layer was intercepted. Map all outgoing paths used by the current view and helper layer.
Battle-start message is dropped The arena period was ready before the chat channel. Boundedly wait for the channel and reject stale attempts.

How to verify chat behavior

Search for the visible view handler, then follow the value to the service call that actually submits or displays the message. Confirm the channel type, sender identity, callback result expectations, and teardown path before wrapping anything.