Keeping the leaderboard honest
What a cheater can and can't do, how names are kept clean, and how a friend gets the same luck.
A public leaderboard attracts cheaters and trolls. This chapter is about the game's defenses, and about being honest on what they can't do.
The honest limit
The game runs in each player's browser. Anything running on someone's own computer can be tampered with, so a determined person could always fake a score. The goal is to stop the easy kinds of cheating.
A ticket for every run
When you start a shared tour, the server gives your run a ticket. When you post a score, it checks the ticket: that it exists, that it hasn't been used, that the run took a believable amount of time, and that the numbers fit the tour:
79def check_run(store, run_id: str, rec: dict, legend_pts: int, ip: str) -> tuple[dict | None, str | None]: 80 """Validate a submission against its run ticket. Returns (ticket, None) or (None, reason).""" 81 if ip and store.incr("rl:" + ip, ttl=RATE_WINDOW) > RATE_MAX: 82 return None, "Too many scores from here in the last hour. Try again later." 83 ticket = store.get("run:" + str(run_id)) if run_id else None 84 if not ticket: 85 return None, "That run is already on the board, or it wasn't started from a shared tour." 86 stops, years = ticket["stops"], ticket["years"] 87 if time.time() - ticket["t0"] < MIN_SECONDS_PER_STOP * stops * years: 88 return None, "That run finished faster than the road allows." 89 limits = { 90 "shows": stops * years, "legendary": years, "tapes": 40 * stops * years, 91 "miles": 12000 * years, "day": 400 * years, 92 } 93 for k, cap in limits.items(): 94 v = rec.get(k, 0) 95 if not isinstance(v, int) or v < 0 or v > cap: 96 return None, "Those numbers don't fit this tour." 97 if not isinstance(rec.get("score"), int) or not 0 <= rec["score"] <= score_cap(rec, stops, years, legend_pts): 98 return None, "That score doesn't fit this tour." 99 store.delete("run:" + str(run_id)) # each ticket counts once 100 return ticket, None
Concept: "validation". Validation means checking that incoming data makes sense before using it. A server never trusts what it's sent; it checks.
Keeping names clean
Names on the board go through a filter. It catches tricks like using 0 for o or adding spaces, but it's careful not to block innocent names. Matching 'rape' anywhere would block 'grape', so short words only count when they're a whole word:
43def clean_name(raw: str) -> tuple[str | None, str | None]: 44 """Return (name, None) if usable, or (None, reason) if not.""" 45 swapped = str(raw or "").lower().translate(_SWAPS) 46 name = re.sub(r"\s+", " ", str(raw or "")).strip() 47 name = re.sub(r"[^A-Za-z0-9 _.'\-]", "", name)[:24].strip() 48 if len(name) < 2: 49 return None, "Pick a name with at least 2 letters." 50 letters = _squash(re.sub(r"[^a-z]", "", swapped)) 51 words = {_squash(w) for w in re.split(r"[^a-z]+", swapped) if w} 52 bad = any(_squash(w) in letters for w in _BLOCKED_ANYWHERE) or any(_squash(w) in words for w in _BLOCKED_WORDS) 53 if bad: 54 return None, "That name can't go on a public board. Pick another." 55 return name, None
The same luck
Every random event in the game (a flat tire, a cop, which crew you get) comes from one random-number function. A run can be given a seed, a starting number that makes the random numbers come out the same every time:
19 if (typeof window !== "undefined" && window.__TT_SEED__) { 20 var luckSeed = window.__TT_SEED__ >>> 0; 21 rand = function () { 22 luckSeed = (luckSeed + 0x6D2B79F5) >>> 0; 23 var t = luckSeed; 24 t = Math.imul(t ^ (t >>> 15), t | 1); 25 t ^= t + Math.imul(t ^ (t >>> 7), t | 61); 26 return ((t ^ (t >>> 14)) >>> 0) / 4294967296; 27 }; 28 }
Concept: "seeded randomness". Computers fake randomness with math. Start the math from the same number (the seed) and you get the same 'random' sequence. A challenge link carries your seed, so your friend starts with the same luck. Once they make different choices, the games drift apart.
- A determined cheater can't be stopped when the game runs in their browser; casual cheating can be.
- Every score needs a one-time ticket and has to pass validation.
- A seed lets a friend replay your tour with the same starting luck.