Anticheat Internals¶
QS-Bridge's anticheat system is observation-only — it never auto-bans. All detections are logged to
SecurityEventfor human review in the admin panel.
Design Philosophy¶
- Never auto-ban — false positives destroy trust. All detections are flagged for human review.
- Observation-only — the anticheat observes and records. Admins decide enforcement.
- Cross-server correlation — patterns across multiple servers increase confidence.
- Layered detection — 7 tiers from simple heuristics to ML-based analysis.
Architecture¶
graph TD
GS[Game Server — bridge]
subgraph Tier 1-4: Per-server detection
POS[Position validation]
KILL[Kill validation]
ITEM[Item validation]
STAT[Stat anomaly detection]
end
subgraph STDB SecurityEvent table
LOG[All detections logged with:]
LOG --> PID[player_id, server_id]
LOG --> EVT[event_type, severity]
LOG --> EVI[evidence — JSON blob]
LOG --> TS[timestamp]
end
GS --> POS
GS --> KILL
GS --> ITEM
GS --> STAT
GS --> LOG
GS --> T5[Tier 5: Session integrity — per-server]
GS --> T6[Tier 6: Cross-server correlation — STDB query]
GS --> T7[Tier 7: ML on historical data — offline]
The Seven Tiers¶
Tier 1 — Position Validation¶
Detect teleportation, noclip, and speed hacks by comparing consecutive position updates:
| Check | Method | Threshold |
|---|---|---|
| Teleport | Distance between updates > max possible | distance / delta_time > max_speed * 2 |
| Speed hack | Sustained speed above maximum | Moving speed > max run speed for > 3 seconds |
| Noclip | Position inside solid geometry | Compare Z coordinate with terrain heightmap |
| Fly hack | Airborne without valid jump/fall | Time airborne > max jump duration + grace |
Evidence payload:
{
"positions": [prev, current],
"delta_time": 0.5,
"calculated_speed": 450.0,
"max_allowed_speed": 300.0,
"terrain_z_at_position": 100.0,
"player_z": 500.0
}
Tier 2 — Kill Validation¶
Detect impossible kills:
| Check | Method |
|---|---|
| Impossible distance | Kill distance > weapon max range |
| Rapid kills | More kills than fire rate allows in time window |
| Impossible damage | Single hit exceeds weapon max damage |
| Through-wall kills | No line-of-sight between attacker and target |
| Self-damage immunity | Player takes no damage from any source |
Tier 3 — Item Validation¶
Detect impossible inventory states:
| Check | Method |
|---|---|
| Impossible stack size | Item count > max stack size |
| Unknown item IDs | Item ID not in valid item table |
| Spawn rate anomaly | Acquiring items faster than loot respawn allows |
| Duplicate unique items | Multiple copies of items flagged as unique |
Tier 4 — Stat Anomaly¶
Detect impossible progression:
| Check | Method |
|---|---|
| XP rate | XP gain per hour > theoretical maximum |
| Invincibility | Zero damage taken over extended combat period |
| Infinite resources | Resource count never decreases despite usage |
| Skill unlock rate | Skills unlocked faster than XP allows |
Tier 5 — Session Integrity¶
Detect connection-level manipulation:
| Check | Method |
|---|---|
| Reconnect spam | Rapid disconnect/reconnect cycles (rate > 5/minute) |
| Multi-connection | Same Steam ID connected from multiple IPs simultaneously |
| Session length anomaly | Connected for impossibly long periods without heartbeat gaps |
| Modified client | Client version mismatch or unexpected handshake |
Tier 6 — Cross-Server Correlation¶
Leverage the multi-server architecture to detect patterns invisible on a single server:
-- Find players flagged on multiple servers
SELECT player_id, COUNT(DISTINCT server_id) as server_count,
COUNT(*) as total_flags
FROM security_event
WHERE timestamp > NOW() - INTERVAL '7 days'
GROUP BY player_id
HAVING COUNT(DISTINCT server_id) >= 2
ORDER BY total_flags DESC;
| Pattern | Signal |
|---|---|
| Same player flagged on 3+ servers | High confidence cheater |
| Flags always within 1 hour of joining | Likely using hack tool at startup |
| Flags only on specific server | Could be server-specific bug (lower confidence) |
| Flags cluster by time-of-day | Possible shared account or hack tool schedule |
Tier 7 — ML on Historical Data (Planned)¶
Offline analysis of SecurityEvent data using machine learning:
- Training data: Confirmed bans (positive) vs. reviewed-and-cleared flags (negative)
- Features: Position delta distributions, kill patterns, session timing, server hop patterns
- Output: Suspicion score (0.0–1.0) per player, updated daily
- Integration: High-score players surfaced in panel's "Flagged Players" queue
SecurityEvent Schema¶
#[spacetimedb::table(name = security_event, public)]
pub struct SecurityEvent {
#[primary_key]
#[auto_inc]
pub event_id: u64,
pub player_id: String,
pub server_id: String,
pub event_type: String, // "position_teleport", "kill_impossible", etc.
pub severity: u8, // 1=low, 2=medium, 3=high, 4=critical
pub evidence: String, // JSON blob with detection-specific data
pub timestamp: Timestamp,
pub reviewed: bool, // Has an admin reviewed this flag?
pub reviewed_by: String, // Admin who reviewed
pub verdict: String, // "confirmed", "false_positive", "inconclusive"
}
Panel Integration¶
The admin panel provides a "Flagged Players" queue:
- Queue view — sorted by severity and recency
- Evidence viewer — expand each flag to see detection details
- Player context — full dossier (play history, other flags, ban history)
- One-click ban — ban directly from the flag review screen
- Mark false positive — remove from queue, feeds ML negative training data
Related Pages¶
- Bridge Internals — detection runs inside the bridge
- Memory Offsets — position reading for validation
- Roadmap — anticheat is Phase 8