Skip to content

Ward

Ward is Cluaupp’s server anti-cheat kernel: remote rate limits, packet-size caps, and movement strikes. It does not write Keep data — economy stays on the server. Flare, Net, Keep replication, and Helm call Ward on every inbound client buffer.

Header: #include <clpp/libs/ward.clh>. Runtime: CluauppLibs.Ward.

  • One strike pool. Flooding Flare and teleporting share the same kick counter (Ward.KickAt, default 8).
  • Token bucket per channel. Allow(player, "flare", 60, 120) refills 60 tokens/sec up to a burst of 120.
  • Speed revert. Heartbeat compares HumanoidRootPart distance to MaxTeleport and MaxSpeed; illegal motion is snapped back, then struck.

When not to use: client-side “anti-cheat” (the client is not authority), or treating Ward as a replacement for escrow trades — use Keep.Trade.

#include <clpp/roblox.clh>
#include <clpp/libs/ward.clh>
#include <clpp/libs/keep.clh>
[[server]]
void init() {
Ward.Start();
}
[[server]]
void afterServerTeleport(Player player) {
Ward.Grace(player, 2);
}
[[server]]
void onCustomRemote(Player player, buffer packed) {
if (!Ward.Packet(player, 64)) {
return;
}
if (!Ward.Allow(player, "shop", 8, 16)) {
return;
}
}

The game template already runs this from Guard.server.clpp. After a legitimate server teleport, call Ward.Grace so the next Heartbeat does not look like a speed hack.

Returns: nothing. Starts movement watching (idempotent).

When: Once on the server, typically in a boot/handler script.

Ward.Start();

Returns: nothing. Same as Start without implying “boot the whole anti-cheat”.

When: You already rate-limit remotes yourself and only want speed checks.

Ward.WatchMovement();

Returns: booltrue if the player still has a token for channel.

When: Before handling any client-origin remote. Overloads: channel only (40/s, burst 80), plus maxPerSec, plus burst.

if (!Ward.Allow(player, "shop", 8, 16)) {
return;
}

Returns: booltrue if bytes is a finite number in [0, maxBytes] (default Ward.MaxPacketBytes = 24 KiB).

When: Before buffer unpack. A failed check strikes packet.

if (!Ward.Packet(player, 128)) {
return;
}

Returns: int — strike count after this call. Kicks at Ward.KickAt.

When: Custom detections (impossible inventory, forged ids).

int n = Ward.Strike(player, "shop:forged");

Returns: nothing. Ignores movement deltas until os.clock() + seconds (default 1.5 if you pass a non-positive number).

When: After PivotTo / SetPrimaryPartCFrame from the server.

Ward.Grace(player, 2);

Returns: nothing. Drops the player’s buckets and strikes.

When: Rare admin pardon; leave happens automatically.

Ward.Clear(player);

Returns: int — current strike count (0 if unknown).

When: Admin HUD / logs.

int n = Ward.Strikes(player);
LibraryChannelWhat is rejected
Flareflare / flare:queryoversized buffer, server-bound packet ids from the client, decode errors
Netnet:<name>non-buffer payload, decode errors
Keep replicatorkeepanything except a one-shot ready handshake ≤ 256 bytes
Helmhelmcommand spam; Give amount must be a finite 1…1e9

Keep trades are a separate duplication-proof escrow (Reserve deducts, Commit SaveWaits both sides or rolls back). Ward does not credit currency.