Chat uses the same TCP connection as all other game packets. There is no separate chat server or channel layer — when any authenticated session sends aDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/kenzz55/ue5-iocp-mmo-server/llms.txt
Use this file to discover all available pages before exploring further.
C_ChatReq, the game server validates the message length and immediately broadcasts an S_ChatNtf to every connected session that has completed the EnterGame handshake. Because the broadcast is server-side, the sender also receives its own message back, which is the simplest way for the client to confirm delivery.
Sending a Message: C_ChatReq (0x0221)
Plain UTF-8 text. The server enforces a hard limit of
MaxChatMessageLength = 512 characters (from Common/Config.h). Messages that exceed this limit are silently dropped and no response is sent to the client.C_ChatReq with a dedicated response packet. Delivery confirmation is implicit: the sender will receive the broadcasted S_ChatNtf alongside every other session.
Receiving a Message: S_ChatNtf (0x0222)
account_id of the player who sent the message. Clients can use this to detect their own messages (compare against the locally stored account ID received in S_EnterGameRes).The sender’s nickname as stored in the account record; supplied by the server directly, so clients cannot spoof display names.
The verbatim message text, at most 512 characters.
Full Protobuf Definitions
Both messages are declared inServerSolution/Proto/Packet.proto alongside all other game protocol messages:
Network/Protocol.h:
UE5 Client Integration
The UE5 client wires chat throughUGameClientSubsystem, which owns the TCP connection and exposes a SendChatMessage method and an OnChatMessageReceived delegate:
UChatWidget (defined in UI/ChatWidget.h / UI/ChatWidget.cpp) is a UUserWidget subclass that binds to those hooks:
NativeConstruct — binding the subsystem delegate
When the widget is added to the viewport,
NativeConstruct looks up UGameClientSubsystem via the GameInstance and registers HandleChatMessageReceived as a listener:HandleChatMessageReceived — appending to the log
Each inbound
S_ChatNtf triggers the delegate, which calls AddChatMessage. The widget formats the line as "SenderName : Message", appends it to the ChatMessages array (capped at MaxVisibleMessages = 100), rebuilds the UScrollBox content, and scrolls to the bottom:SubmitChat — sending to the server
When the player presses Enter in the chat input widget, The input widget (either
SubmitChat trims whitespace, calls GameClientSubsystem::SendChatMessage, and closes the input field:UEditableText or UEditableTextBox — resolved at runtime via Cast) commits on ETextCommit::OnEnter, which forwards to SubmitChat through HandleChatTextCommitted.Limitations
The current implementation is intentionally minimal:- Global scope only — every authenticated session receives every chat message regardless of location or zone.
- No message history — the server has no chat log; clients that connect after a message was sent will not see it.
- No profanity or spam filter — the only server-side validation is the 512-character length check.
- No channel support — there is no concept of party, guild, or zone channels.