Here's a truth that many indie multiplayer developers learn the hard way: the moment your game has 100 concurrent players, someone will try to cheat. By 1,000, cheating will be organized. By 10,000, it will be automated. If you don't design security into your multiplayer game from day one, you'll be fighting a losing battle against players who have more time, skill, and motivation to break your game than you have to fix it.
This guide covers practical anti-cheat strategies, not kernel-level drivers or ML-based detection (those are for AAA studios with dedicated security teams). These are the fundamentals that every multiplayer game should implement regardless of scale.
The Cardinal Rule: Never Trust the Client
The single most important principle in multiplayer security is this: the client is compromised. Always. Assume every message from a client could be fabricated, modified, or replayed. The client isn't your ally, it's a potential adversary running on hardware you don't control.
This means:
- Don't let the client decide damage amounts. The client says "I did 999 damage", so what? The server calculates damage.
- Don't let the client set its own position arbitrarily. The client says "I teleported to x:500, y:300", the server validates whether that movement is physically possible given the client's last known position and movement speed.
- Don't let the client award itself items, currency, or progression. Server-side only.
- Don't send the client information it shouldn't have. Don't send enemy positions to a client that can't see them (wallhack prevention).
Server Authority: The Foundation of Security
Server authority means the server owns the game state. Clients send inputs (I pressed W, I clicked at position X), and the server decides the outcome. This is the strongest anti-cheat architecture because cheaters can't modify what they don't control.
// BAD: Client-authoritative (cheatable)
// Client sends: { action: "attack", damage: 500, target: "player2" }
// Server blindly applies it
// GOOD: Server-authoritative (secure)
// Client sends: { action: "attack", target: "player2" }
// Server calculates:
function processAttack(attacker, target) {
const distance = getDistance(attacker.pos, target.pos);
if (distance > attacker.weapon.range) return; // Too far, rejected
const damage = attacker.weapon.baseDamage;
const isHeadshot = checkHeadshot(attacker.aimDirection, target.hitboxes);
const finalDamage = isHeadshot ? damage * 2 : damage;
target.hp -= finalDamage;
broadcastDamageEvent(attacker.id, target.id, finalDamage);
}
The cost of server authority is latency, every action round-trips to the server. Client-side prediction mitigates this but adds complexity. The tradeoff is worth it: a slightly higher-latency game that's fair beats a low-latency game ruined by cheaters.
Input Validation: The First Line of Defense
Even with server authority, you need to validate client inputs. A cheater might send impossible inputs, movement faster than allowed, actions more frequent than the game allows, or inputs that reference game objects they shouldn't know about.
Implement validation for:
- Movement speed: Calculate the maximum distance a player could have moved since their last input. Reject movements that exceed this. Account for speed boosts, dashes, and other modifiers.
- Action rate: Cap the number of actions per second. If a player fires faster than their weapon allows, reject the excess inputs.
- Line of sight: Before processing an attack, verify the attacker has line of sight to the target. This prevents shooting through walls.
- Resource validation: If a player tries to use an item they don't have, reject it. Validate resource counts on every transaction.
- Timing validation: Track the timestamp of inputs. Flag inputs that arrive impossibly fast or in suspicious patterns.
Information Security: Preventing Wallhacks and Map Hacks
One of the most common cheats in competitive games is a wallhack, seeing enemies through walls. This is made possible when the server sends all player positions to all clients, regardless of visibility. If the data is on the client, it can be read, no matter how you try to hide it.
The solution: interest management (also called relevancy filtering or area-of-interest). Only send entity data to clients that should be able to see those entities. If Player A is on the opposite side of the map from Player B, Player A doesn't need to know Player B's position.
This is harder than it sounds. You need to calculate visibility for every entity pair on every tick. Spatial hashing, BSP trees, and pre-computed visibility sets (PVS) make this tractable. The performance cost is real but the security benefit is absolute, you can't hack data that never arrived.
Behavioral Detection: Catching Smart Cheaters
Server authority and input validation catch crude cheats. Smart cheaters use subtle advantages, soft aimbots that slightly improve accuracy, ESP overlays that use publicly available data creatively, or movement scripts that stay within validation bounds but optimize pathing inhumanly.
Behavioral detection analyzes player behavior statistically:
- Accuracy anomalies: Human accuracy follows a distribution. A player with 95% headshot rate over 100 games is almost certainly cheating.
- Reaction time: Humans can't react in under ~150ms to a visual stimulus. If a player consistently reacts in 50ms, flag them.
- Movement patterns: Humans make suboptimal movements. Perfectly optimized pathing, pixel-perfect strafing, or inhuman snap-aiming patterns suggest automation.
- Statistical outliers: Compare every player's metrics against the population. Flag anyone who's consistently 3+ standard deviations from the mean.
Behavioral detection is powerful but requires data. You need thousands of matches to establish baselines and tune thresholds. Start collecting behavioral data from day one, even if you don't analyze it immediately.
Practical Security for Indie Developers
You don't need to build the next Easy Anti-Cheat. Here's a prioritized list for indie multiplayer games:
- Server authority for all critical game logic. Non-negotiable. This prevents 80% of cheats.
- Input validation. Reject impossible inputs. Simple to implement, high impact.
- Interest management. Don't send data clients shouldn't see. Prevents wallhacks completely.
- Rate limiting. Cap input frequency. Prevents speed hacks and rapid-fire exploits.
- Reporting system. Let players report cheaters. Community detection catches what automation misses.
- Replay system. Record matches server-side. Lets you investigate reports efficiently.
- Behavioral logging. Track accuracy, reaction times, and action patterns. Build the dataset for future detection.
Perfect security doesn't exist in multiplayer games. The goal is to make cheating hard enough that most people don't bother, and detectable enough that the ones who do get caught. Every layer of security you add raises the skill bar for cheaters and protects the experience for legitimate players.
Your players chose your game because they want fair, competitive fun. Protecting that experience is one of the most important things you can do as a multiplayer developer.
