Skip to main content

Chat

Chat is a static Lua service for message operations and mute state.

Error Handling Pattern​

  • Success: err == nil
  • Failure: err is an error code string

Function List​

FunctionDescriptionScope
Chat.SendSend a chat message.S
Chat.EditMessageEdit an existing message.S
Chat.RemoveMessageRemove a message by id.S
Chat.GetMessagesQuery messages with filters.S
Chat.GetMessageInfoRead one message by id.S
Chat.ClearClear message cache and emit clear event.S
Chat.MutePlayerMute/unmute one player.S
Chat.IsPlayerMutedRead mute state for one player.S

Event List​

EventDescriptionScope
chat:messageEvent-bus event emitted after a message send operation.S
chat:editedEvent-bus event emitted after a message edit operation.S
chat:removedEvent-bus event emitted after a message remove operation.S
chat:clearedEvent-bus event emitted after chat clear operation.S
chat:mute_changedEvent-bus event emitted after mute/unmute state change.S

Event Payload Contract​

Every chat event handler receives the standard event envelope:

  • event.name
  • event.payload
  • event.source
  • event.target
  • event.timestamp
  • event.correlationId
  • event.version

event.payload fields by event:

EventPayload Fields
chat:messagemessageId, content, sender, senderId, senderClientId?, senderAccountId?, timestamp, color, showSender, channel
chat:editedmessageId, content, sender, senderId, senderClientId?, senderAccountId?, timestamp, color, showSender, channel
chat:removedmessageId (+ optional message fields when available)
chat:clearedtimestamp
chat:mute_changedplayerId, clientId, accountId, muted, reason, muteUntil, durationSeconds

Optional sender identity fields:

  • senderClientId / senderAccountId may be nil for guest/system messages or when identity is not exposed by policy.
  • sender may 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​

  • Chat is a service API, not a node-domain API.
  • Chat operations/events are independent from NodeSim deterministic state.
  • Chat UI should be built in NodeUI (client-only) and driven by Chat events.
  • For sender-linked visuals, correlate senderId with NodePlayers.

Target selector model:

  • number -> playerId (session target)
  • string prefixed c_ -> clientId
  • string prefixed a_ -> accountId
  • table -> list of selectors (number, c_*, a_*)
  • target selector 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, default true)
  • 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/target are 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, default 50, max 500)
  • after (number, timestamp ms)
  • before (number, timestamp ms)
  • sender (string)
  • senderId (number)
  • channel (string)

Returns:

  • messages (table | nil)
  • err (nil | string)

Message fields:

  • id
  • content
  • sender
  • senderId (session playerId)
  • senderClientId (optional clientId)
  • senderAccountId (optional accountId)
  • timestamp
  • color
  • showSender
  • channel

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 default true)
  • 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: true mute, false unmute
  • table mode fields:
  • muted (boolean, default true)
  • duration or durationSeconds (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​

ConstantValue
Chat.MAX_LENGTH512
Chat.RATE_LIMIT1.5
Chat.MAX_CHANNEL_LENGTH32
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​

FunctionEmitted 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_LIMIT
  • ERR_NOT_FOUND
  • ERR_FILTERED
  • ERR_MSG_TOO_LONG
  • ERR_INVALID
  • ERR_NOT_CONNECTED
  • ERR_PERMISSION_DENIED
  • ERR_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)