Stopping cheaters

Play this lesson

Never trust the client

Every web browser has developer tools that let anyone look inside a web game and change it: its saves, its scores, even its code. A player can turn a score of 10 into 99999 with a few clicks, and then send it to our server.

Moving saves to the cloud doesn't stop that by itself, because the game on the device (the client) is in the player's hands. So servers follow a golden rule: never trust the client. Check everything it sends.

Security Rules: the bouncer

Firebase Security Rules live on Firebase's servers and check every read and write in Firestore, the database, before it happens. A cheater can change the game, but not the rules.

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /players/{userId} { ... }
  }
}

{userId} stands for the save card's name, which is the player's UID (user ID). request.auth.uid is the UID of the player asking. Anything no rule allows is denied.

Bolt says: Firebase offers a "test mode" that lets anyone read and write for 30 days. Fine for a first try, never for launch.

Fix the rule

firestore.rules
match /players/{userId} {  allow read: if request.auth.uid == userId;  allow write: if ???;}

Which condition should replace ??? so players can change only their own save?

  1. request.auth != null
  2. request.auth.uid == userId
  3. true
Show the answer

request.auth.uid == userId

"request.auth != null" only checks that someone is logged in, so any player could change any save. "true" lets anyone at all write. Matching the UID to the card's name means you can only change your own.

Rules can check the data too

A cheater can still change their own save, from wave 3 to wave 99. So rules can also check what is being written.

Comparing the two lets a rule say: wave must be a whole number, it can only go up by one at a time, and seeds can't jump by a million.

Fix the rule

firestore.rules
match /players/{userId} {  allow update: if request.auth.uid == userId    && request.resource.data.wave is int    && request.resource.data.wave         <= resource.data.wave + 1;}

A cheater edits their own save from wave 3 to wave 99. Which part of the rule blocks it?

  1. Line 2
  2. Line 3
  3. Lines 4 and 5
Show the answer

Lines 4 and 5

Line 2 passes because it is the cheater's own save, and line 3 passes because 99 is a whole number. Lines 4 and 5 only allow the wave to grow by one, so 99 is refused.

Replays: proof of a record

Some checks are too big for rules. For record runs, Hyper Shards saves every input: which buttons were pressed on each frame. At 60 FPS, a 3-minute run is 10,800 frames. It also saves the random seed, the starting number that decides where aliens appear.

Code on the server (a Cloud Function) replays the run. If it ends with the same score, the record is real. This only works if the game is deterministic: same inputs, same result. So the game must use the seeded random, never Math.random().

Quick check

If the server replays a run with the same random seed and the same inputs, it should end with the same score.

Show the answer

True

The seed fixes where every alien appears, and the inputs fix what the pilot did. Same inputs, same result. A different score means the claimed run never happened.

Save scumming in Garden Defense

Here's a sneaky trick. A player is about to lose a wave, so they quickly close the app and reload the save from before the wave. Then they try again until they get lucky. This is called save scumming.

The fix: save the moment a wave starts, and keep the random seed in the save. Quitting can't undo a loss, and the same pests come back every time.

Bolt says: In a game just for you, save scumming mostly hurts your own fun. It matters when it wins leaderboard spots or rewards.

Quick check

What is save scumming?

  1. Quitting and reloading an old save to undo a bad result
  2. Saving your game to the cloud
  3. Sharing your save with a friend
Show the answer

Quitting and reloading an old save to undo a bad result

Save scumming means reloading an older save to escape a loss. Saving at the start of each wave, with the seed, stops it from working.

Fair play is on

Security Rules guard every save and check the data. Replays prove the big records. Saving at wave start stops save scumming.

The strongest checks need our own code running on Google's servers, where players can't touch it: Cloud Functions, from the Code on the server lesson. Next, we look at the data itself: what we should collect from players at all, and what the law says about it.

Bolt says: Never trust the client. Real game studios live by it.

Fact-checked 9 October 2026