API Reference
Channel (Client)

Channel — Client API

When RunService:IsServer() is false at require-time, every Channel exposes the client method set below.

Method Table

MethodSignatureDescription
send(self, data: any) -> ()Sends data to the server.
on(self, callback: (data: any) -> ()) -> ()Registers a listener for packets sent from the server. Runs the middleware chain before invoking callback.

Note the different on signature compared to the server: the client callback only receives data, since there is no ambiguity about the sender (it's always the server).

send

CombatNet.Position:send({ pos = character:GetPivot().Position })

Sends the packet to the server.

on

CombatNet.Damage:on(function(data)
	print("Took damage:", data.amount, "from", data.target)
end)

Registers a client-side handler for packets sent by the server via sendTo, sendToAll, or sendToAllExcept.

⚠️

A Channel only has one method set, decided once when the module is required (based on RunService:IsServer()). Server-only methods (sendTo, sendToAll, sendToAllExcept) simply don't exist on the client's version of the channel, and vice versa for send — attempting to call the wrong one errors immediately rather than doing nothing.

🚫

Reading a channel is what triggers the namespace's build. If your client-side script reads CombatNet.Damage (to call :on(), for example) long before the server does anything with CombatNet, and the namespace relies on automatic build-on-first-access rather than an explicit :build() call in the shared module, the client can end up building the namespace before the server has published its packet IDs. This is one of the most common real-world KravasNet bugs — see Best Practices for how to avoid it.


Continue to Middleware & Reliability to learn how to validate and filter packet data.