Codectionary / Developer documentation / Luau

Server authority, validation and rate limits

A valid-looking remote call can still be an impossible game action. Validate both the shape of a request and whether the sender may perform it now. This example lets a nearby living player request a visual switch; it does not trust a client position, target Instance or reward.

Syntax

-- Validate shape → rate limit → server state → apply action

Examples

Check an action against server state

Create an anchored Part named LessonSwitch in Workspace and a RemoteEvent named ToggleLessonSwitch in ReplicatedStorage. Script in ServerScriptService. Keep the switch anchored so clients cannot move the target through physics ownership.

local Players = game:GetService("Players")
local remote = game:GetService("ReplicatedStorage"):WaitForChild("ToggleLessonSwitch")
local switch = workspace:WaitForChild("LessonSwitch")
assert(switch:IsA("BasePart") and switch.Anchored)
local last = {}
remote.OnServerEvent:Connect(function(player, action)
    if typeof(action) ~= "string" or action ~= "toggle" then return end
    local now = os.clock()
    if now - (last[player] or -math.huge) < 1 then return end
    last[player] = now
    local character = player.Character
    local root = character and character:FindFirstChild("HumanoidRootPart")
    local humanoid = character and character:FindFirstChildOfClass("Humanoid")
    if not root or not root:IsA("BasePart") or not humanoid or humanoid.Health <= 0 then return end
    local distance = (root.Position - switch.Position).Magnitude
    if distance ~= distance or distance > 12 then return end
    switch.Color = if switch.Color == Color3.fromRGB(40, 160, 80)
        then Color3.fromRGB(100, 100, 100) else Color3.fromRGB(40, 160, 80)
end)
Players.PlayerRemoving:Connect(function(player) last[player] = nil end)

Send intent, not a result

LocalScript in StarterPlayerScripts. Press E near the switch in a Studio play test. The client requests an action; the server decides whether the request is possible. This distance check is not a complete movement anti-cheat system.

local UserInputService = game:GetService("UserInputService")
local remote = game:GetService("ReplicatedStorage"):WaitForChild("ToggleLessonSwitch")
UserInputService.InputBegan:Connect(function(input, processed)
    if not processed and input.KeyCode == Enum.KeyCode.E then
        remote:FireServer("toggle")
    end
end)

Best practices

  • For numeric input, reject NaN, infinity, out-of-range and fractional values where only integers make sense.
  • Check ownership, cooldowns and inventory from server state before granting valuable actions; proximity alone is insufficient.
  • Rate limits reduce repeated work but do not make a bad authorization rule safe.

At a glance

Purpose
Typed scripting and Roblox development
File extension
.luau
Runs in
Luau host; Roblox engine examples require Roblox Studio
Usually used with
Roblox APIs and Studio

Specifications & further reading

Related Luau documentation