Skip to main content

Sending raw packets

Three escape hatches for pushing packets onto the wire when no high-level helper exists.

client:send(name, params)

Build a packet from an ID string + key-value table. The runtime sets ID = name and merges params as fields.

client:send("Chat", { text = "hi" })

This is the simplest path — covers most one-off cases.

client:sendRaw(packet)

Send a fully user-defined table. Caller provides every field, including ID. Use when the shape doesn't fit send(name, params) — nested envelopes, replay testing, fields the server expects in a specific order.

client:sendRaw({
ID = "mP",
x = 12.5, y = 9.0,
a = 0, d = 1,
tp = false,
})

client:sendBatch({pkt1, pkt2, …})

Flush multiple packets in a single outbound envelope. Each entry is a full packet table (must contain its own ID). Mirrors the multi-packet bursts the real client emits on world bootstrap.

client:sendBatch({
{ ID = "Gw", W = "PIXELSTATION", WB = 0 },
{ ID = "A", AE = 2 },
{ ID = "A", AE = 6 },
{ ID = "GSb" },
})

Caveats

  • Fields go on the wire as-is, so check the doc shape before sending. Bad fields can trip server-side kicks (see KErr codes).
  • The runtime does no validation — it's your responsibility to match the server's expected schema.
  • Returns (value, err) like every other Lua-facing method. err is non-nil only on transport-layer failures; semantic rejections come back as inbound KErr packets.