Start typing to search packages!
netguard
By @zenukopublic
Roblox
Mirrored from Wallynetguard
A declarative, type-safe, rate-limiting networking framework for Roblox with automatic
UnreliableRemoteEventsupport.
Production Origin: This package was extracted and generalized from infrastructure developed for Kabbrawl, a private competitive multiplayer Roblox experience. Kabbrawl itself remains proprietary; this package contains only reusable infrastructure and no proprietary assets or game-specific content.
🛡️ Why NetGuard?
In competitive and commercial Roblox games, the majority of client-server vulnerabilities come from:
- Remote Flooding & DoS: Exploiters spamming remotes 500 times/second to crash server loops.
- Type Confusion & Malformed Payloads: Sending unexpected types (
nil,stringinstead ofnumber) that trigger unhandled server errors. - No Protocol Discipline: Scattering raw
RemoteEventinstances throughoutReplicatedStoragewith inconsistent naming and no rate-limit guarantees. - Under-utilization of UDP: Failing to use
UnreliableRemoteEventfor high-frequency position or visual state updates.
NetGuard solves all four issues with a single declarative API.
✨ Features
- Declarative Schemas: Define your networking contract in one central module.
- Automatic Remote Management: Automatically instantiates and pools
RemoteEvent(reliable/ordered) andUnreliableRemoteEvent(unreliable/fast) based on your config. - Built-in Server Rate Limiting: Per-player, per-packet token-bucket rate limiting rejects remote spam before it reaches your game logic.
- Recursive Payload Type-Checking: Primitives, nested tables,
Vector3,CFrame,Instance, andColor3. - Stateful Predicate Guards: Attach context checks (e.g.
isNotBenched,hasSufficientStamina) that verify game state before invoking listeners. - Rejection Telemetry: Capture security anomalies and exploit attempts with clean
onRejectedcallbacks.
🚀 Installation
Via Wally
Add netguard to your wally.toml:
[dependencies]
NetGuard = "zenukopublic/netguard@1.0.0"
📖 Quickstart
1. Define Your Packet Registry (Shared/Packets.luau)
local NetGuard = require(Packages.NetGuard)
local net = NetGuard.new()
net:registerAll({
-- High-frequency state sync (uses UnreliableRemoteEvent / UDP)
PlayerSync = {
direction = "ClientToServer",
reliable = false,
cooldown = 1 / 30, -- Capped at 30 Hz
schema = {
cframe = "CFrame",
velocity = "Vector3",
},
},
-- Critical action (uses standard RemoteEvent / TCP)
PerformAction = {
direction = "ClientToServer",
reliable = true,
cooldown = 0.5, -- Max 2 actions per second
predicates = { "isAlive", "hasStamina" },
schema = {
actionType = "string",
targetId = "number",
},
},
})
return net
2. Server Implementation (Server/CombatHandler.luau)
local net = require(ReplicatedStorage.Shared.Packets)
net:bindServer("PerformAction", function(player, payload)
print(player.Name, "performed", payload.actionType, "on", payload.targetId)
end, {
getContext = function(player, payload)
return {
isAlive = player.Character ~= nil,
hasStamina = true, -- Check your game's stamina component
}
end,
onRejected = function(player, reason, payload)
warn(`[SECURITY] Rejected {player.Name}: {reason}`)
end,
})
3. Client Implementation (Client/InputController.luau)
local net = require(ReplicatedStorage.Shared.Packets)
-- Send an action
local ok, err = net:fireServer("PerformAction", {
actionType = "Tackle",
targetId = 12345,
})
if not ok then
warn("Failed to fire action:", err)
end
🧪 Testing
Run core unit tests headlessly with Lune:
lune run tests/netguard.test.luau
📄 License
MIT License. Free for personal and commercial use.
Package Details
Install command (Click to copy)
Version
1.0.0
License
MIT
Safe for commercial use
Automated license review — not legal advice.
