---
name: roblox-server-authority
description: Use when writing or reviewing any Roblox code that touches RemoteEvents, RemoteFunctions, currency, inventory, damage, rewards or player progress. Keeps the server in charge so exploiters can't cheat.
---

# Server authority for Roblox

Exploiters control everything on their own device. Any LocalScript can be edited, and any RemoteEvent the client
can fire can be fired with any arguments, as often as they like. Write every networked feature so the server decides.

## Rules

1. **The client asks, the server decides.** A remote carries a request ("buy `sword`", "use ability 2"), never a
   result ("add 100 coins", "deal 50 damage").
2. **Validate every argument with `typeof` first.** Reject anything that isn't the exact expected type. Check
   numbers for NaN, infinity and range, and check string length.
3. **Look up prices, rewards, cooldowns and stats on the server.** Never accept them from the client.
4. **Check state.** Is the player alive? Close enough (compare `HumanoidRootPart` distance)? Is the round active?
   Do they own the item?
5. **Rate-limit per player.** Keep the last call time in a table keyed by player and drop calls that come too fast.
6. **Keep secrets on the server.** Item tables, drop rates and admin lists go in `ServerScriptService` or
   `ServerStorage`, not `ReplicatedStorage`.
7. **Avoid `RemoteFunction:InvokeClient`.** A client can hang or error it. If you must use it, wrap it with a
   timeout.

## Pattern

```lua
--!strict
Remotes.BuyItem.OnServerEvent:Connect(function(player: Player, itemId: unknown)
	if typeof(itemId) ~= "string" or #itemId > 50 then return end
	local item = Items[itemId]
	if not item then return end
	if not RateLimit.allow(player, "BuyItem", 0.5) then return end

	local coins = Data.get(player, "Coins")
	if coins < item.Price then return end

	Data.set(player, "Coins", coins - item.Price)
	Inventory.grant(player, itemId)
end)
```

## Before you finish

For every remote you created or changed, list:
- what the client sends
- what the server trusts
- how an exploiter could abuse it

Fix each abuse before saying you're done.
