Chat
Chat is a static Lua service for message operations and mute state.
Error Handling Pattern​
- Success:
err == nil - Failure:
erris an error code string
Function List​
| Function | Description | Scope |
|---|---|---|
Chat.Send | Send a chat message. | S |
Chat.EditMessage | Edit an existing message. | S |
Chat.RemoveMessage | Remove a message by id. | S |
Chat.GetMessages | Query messages with filters. | S |
Chat.GetMessageInfo | Read one message by id. | S |
Chat.Clear | Clear message cache and emit clear event. | S |
Chat.MutePlayer | Mute/unmute one player. | S |
Chat.IsPlayerMuted | Read mute state for one player. | S |
Event List​
| Event | Description | Scope |
|---|---|---|
chat:message | Event-bus event emitted after a message send operation. | S |
chat:edited | Event-bus event emitted after a message edit operation. | S |
chat:removed | Event-bus event emitted after a message remove operation. | S |
chat:cleared | Event-bus event emitted after chat clear operation. | S |
chat:mute_changed | Event-bus event emitted after mute/unmute state change. | S |
Event Payload Contract​
Every chat event handler receives the standard event envelope:
event.nameevent.payloadevent.sourceevent.targetevent.timestampevent.correlationIdevent.version
event.payload fields by event:
| Event | Payload Fields |
|---|---|
chat:message | messageId, content, sender, senderId, senderClientId?, senderAccountId?, timestamp, color, showSender, channel |
chat:edited | messageId, content, sender, senderId, senderClientId?, senderAccountId?, timestamp, color, showSender, channel |
chat:removed | messageId (+ optional message fields when available) |
chat:cleared | timestamp |
chat:mute_changed | playerId, clientId, accountId, muted, reason, muteUntil, durationSeconds |
Optional sender identity fields:
senderClientId/senderAccountIdmay benilfor guest/system messages or when identity is not exposed by policy.sendermay include inline color codes (#RRGGBBName) and clients should render them in sender-name UI.
Scope Model​
- Client and server both expose
Chat.*. - Server is authoritative for chat state and moderation.
- Client calls that require authority are either routed to server or denied by policy.
Node Relationship​
Chatis a service API, not a node-domain API.- Chat operations/events are independent from
NodeSimdeterministic state. - Chat UI should be built in
NodeUI(client-only) and driven byChatevents. - For sender-linked visuals, correlate
senderIdwithNodePlayers.
Target selector model:
number->playerId(session target)stringprefixedc_->clientIdstringprefixeda_->accountIdtable-> list of selectors (number,c_*,a_*)targetselector arrays are supported only on server-authoritative operations.
In parameter docs, selector means one of: number, c_*, a_*.
For moderation/persistent workflows, prefer accountId and fallback clientId over session playerId.
Functions​
Chat.Send​
S Shared (Client & Server)
local messageId, err = Chat.Send(content, options)
Parameters:
content(string)options(table, optional):color(string,#RRGGBB)showSender(boolean, defaulttrue)channel(string)broadcast(boolean, server only)target(selector or list of selectors, server only)
Returns:
messageId(string | nil)err(nil| string)
Behavior:
- Client send is routed to server; client-provided
broadcast/targetare not used. - Server send can broadcast or target specific selectors (
playerId,clientId,accountId).
Chat.EditMessage​
S Shared (Client & Server)
local err = Chat.EditMessage(messageId, newText, options)
Parameters:
messageId(string)newText(string)options(table, optional):broadcast(boolean, server only)target(selector or list of selectors, server only)
Returns:
err(nil| string)
Behavior:
- Client edit request is routed to server.
- Client can edit only messages it owns.
Chat.RemoveMessage​
S Shared (Client & Server)
local err = Chat.RemoveMessage(messageId, options)
Parameters:
messageId(string)options(table, optional):broadcast(boolean, server only)target(selector or list of selectors, server only)
Returns:
err(nil| string)
Behavior:
- Client remove request is routed to server.
- Client can remove only messages it owns.
Chat.GetMessages​
S Shared (Client & Server)
local messages, err = Chat.GetMessages(options)
Parameters:
options(table, optional):limit(number, default50, max500)after(number, timestamp ms)before(number, timestamp ms)sender(string)senderId(number)channel(string)
Returns:
messages(table | nil)err(nil| string)
Message fields:
idcontentsendersenderId(sessionplayerId)senderClientId(optionalclientId)senderAccountId(optionalaccountId)timestampcolorshowSenderchannel
Chat.GetMessageInfo​
S Shared (Client & Server)
local message, err = Chat.GetMessageInfo(messageId)
Parameters:
messageId(string)
Returns:
message(table | nil)err(nil| string)
Chat.Clear​
S Shared (Server Authority)
local err = Chat.Clear(options)
Parameters:
options(table, optional):broadcast(boolean, server defaulttrue)target(selector or list of selectors, server only)
Returns:
err(nil| string)
Client behavior:
- Always returns
ERR_PERMISSION_DENIED.
Chat.MutePlayer​
S Shared (Server Authority)
local err = Chat.MutePlayer(target, mutedOrOptions)
Parameters:
target(number|string)mutedOrOptions(boolean | table)- boolean mode:
truemute,falseunmute - table mode fields:
muted(boolean, defaulttrue)durationordurationSeconds(number)reason(string)
Returns:
err(nil| string)
Client behavior:
- Always returns
ERR_PERMISSION_DENIED.
Chat.IsPlayerMuted​
S Shared (Client & Server)
local isMuted, err = Chat.IsPlayerMuted(target)
Parameters:
target(number|string)
Returns:
isMuted(boolean | nil)err(nil| string)
Constants​
| Constant | Value |
|---|---|
Chat.MAX_LENGTH | 512 |
Chat.RATE_LIMIT | 1.5 |
Chat.MAX_CHANNEL_LENGTH | 32 |
Chat.DEFAULT_CHANNEL | "global" |
Events​
chat:message (Event Bus)​
S Shared (Client & Server)
AddEventHandler("chat:message", function(event)
print("msg " .. tostring(event.payload.messageId) .. " from " .. tostring(event.payload.sender))
end)
chat:edited (Event Bus)​
S Shared (Client & Server)
AddEventHandler("chat:edited", function(event)
print("edited " .. tostring(event.payload.messageId) .. " -> " .. tostring(event.payload.content))
end)
chat:removed (Event Bus)​
S Shared (Client & Server)
AddEventHandler("chat:removed", function(event)
print("removed " .. tostring(event.payload.messageId))
end)
chat:cleared (Event Bus)​
S Shared (Client & Server)
AddEventHandler("chat:cleared", function(event)
print("chat cleared at " .. tostring(event.payload.timestamp))
end)
chat:mute_changed (Event Bus)​
S Shared (Client & Server)
AddEventHandler("chat:mute_changed", function(event)
print("mute changed player=" .. tostring(event.payload.playerId) .. " muted=" .. tostring(event.payload.muted))
end)
Function/Event Mapping​
| Function | Emitted Event |
|---|---|
Chat.Send(content, options) | chat:message |
Chat.EditMessage(messageId, newText, options) | chat:edited |
Chat.RemoveMessage(messageId, options) | chat:removed |
Chat.Clear(options) | chat:cleared |
Chat.MutePlayer(target, mutedOrOptions) | chat:mute_changed |
Error Codes​
ERR_RATE_LIMITERR_NOT_FOUNDERR_FILTEREDERR_MSG_TOO_LONGERR_INVALIDERR_NOT_CONNECTEDERR_PERMISSION_DENIEDERR_MUTED
Quick Examples​
Server broadcast message:
local messageId, err = Chat.Send("Server restart in 5 minutes", {
channel = "system",
showSender = false
})
Server message to one player:
local _, err = Chat.Send("You received a reward", {
target = "a_9d4d7c2f",
color = "#7ED957"
})
Client send message:
local messageId, err = Chat.Send("hello world", {
channel = "global"
})
Server mute and state check:
local muteErr = Chat.MutePlayer("a_9d4d7c2f", {
muted = true,
durationSeconds = 300,
reason = "spam"
})
local isMuted, stateErr = Chat.IsPlayerMuted("a_9d4d7c2f")
Correlate sender with NodePlayers read model:
AddEventHandler("chat:message", function(event)
local senderId = event.payload.senderId
local node, err = Node.Get("/NodePlayers/" .. tostring(senderId))
if not err and node then
-- visual-only usage (labels, UI badges, proximity styling)
end
end)