Schummelschutz im Mobilnetz: Serverautoritative Rennen
7 Min. Lesezeit

BOINGWARD hat einen Teil, den Spieler noch nicht erreichen: ein Online-Rennen für acht Spieler. Server, Protokoll und Tests sind geschrieben; der Menüknopf bleibt verborgen, bis der Server für alle offen ist. Dieser Beitrag erklärt, wie das System aufgebaut wurde, und seinen lehrreichsten Moment: Beim ersten Test in einem echten Mobilfunknetz wurden alle acht ehrlichen Bots gleichzeitig als Betrüger markiert.
Die ganze Geschichte steht im Hauptbeitrag der Serie, die Pogo-Physik, die die Bots nutzen, im Physik-Beitrag.
Wer entscheidet was?
Bei Rennspielen lautet die Grundfrage, wessen Wort man traut. In BOINGWARD ist die Antwort klar: Dem Client wird nicht vertraut.
| Der Server bestimmt | Der Client bestimmt |
|---|---|
| Lobby, Bereitschaft, Countdown, Serveruhr | Die Simulation seines eigenen Pogostabs |
| Reihenfolge und Zeiten der Checkpoints | Eingabe, Kamera, Darstellung |
| Zielreihenfolge, Zeit, nicht beendet, Disqualifikation | Geglättete Anzeige der anderen Fahrer |
| Ob ein Wiedereinsetzen gültig ist | |
| Belohnungen (einmal pro Rennen und Spieler) |
Der Client sagt nie „Ich habe Checkpoint 3 erreicht“ oder „Ich bin im Ziel“. Er sendet nur den Zustand seines Pogostabs (Position, Geschwindigkeit, Zustand), und der Server entscheidet anhand geprüfter Zustände, wann ein Checkpoint oder das Ziel überquert wurde.
Eine weitere Entscheidung fiel von Anfang an: In Ranglistenrennen kollidieren Spieler nicht. Die anderen Fahrer sind reine Anzeigeknoten ohne Kollisionskörper. Man kann nicht erwarten, dass Physik auf verschiedenen Telefonen bitgenau gleich läuft, und Latenz trifft jeden anders. Mit Kollisionen würde die Netzqualität statt des Könnens über Rennen entscheiden.
WebSocket oder ENet?
Godot 4.7 bringt zwei eingebaute Optionen mit, keine braucht ein zusätzliches Plugin. Kurz verglichen:
| WebSocket (TCP) | ENet (UDP) | |
|---|---|---|
| Provider-NAT, Firmen-WLAN | Funktioniert überall, wo HTTPS funktioniert | Meist ja, manchmal blockiert |
| Auf dem bestehenden Server | Ein nginx-Location-Block, vorhandenes TLS; kein neuer Port | Neuer UDP-Port und Firewall-Regel |
| Bei Paketverlust | Reihenfolge garantiert; ein Verlust hält alles dahinter auf | Ein verlorener Schnappschuss wird übersprungen |
Die Wahl fiel auf WebSocket hinter nginx mit TLS. Der Grund: Es läuft auf demselben Server ohne neuen Port und bleibt in Mobilfunknetzen nicht hängen. Der Vorteil von UDP ist real, aber für dieses Spiel klein: Andere Fahrer werden ohnehin 0,3 bis 0,6 Sekunden verzögert gezeichnet, und der eigene Pogostab wartet nie auf das Netz. Der Renncode sieht nur eine kleine Transportschnittstelle; der Wechsel zu ENet ist eine Konfigurationsänderung, und beide Transporte bestehen denselben Test mit acht Bots.
Wie Bewegung geprüft wird
Der Server vergleicht jeden neuen Zustand mit dem zuletzt akzeptierten. Die Grenzen stammen aus der Tuning-Datei des Pogostabs, plus eine Toleranz:
- Geschwindigkeitsgrenzen: horizontal, nach oben und im Fall.
- Strecke und Zeit: Der Weg zwischen zwei Zuständen darf nicht länger sein als das, was in der verstrichenen Zeit möglich ist.
- Bewegungskonsistenz: Zwischen Sprüngen muss die Geschwindigkeit der Schwerkraft und der Luftsteuerung folgen. Der vertikale Fehler summiert sich auf, sodass selbst ein „Schwebe“-Cheat mit in sich stimmigen Geschwindigkeiten langsam abdriftet.
- Impulsbudget: Plötzliche Geschwindigkeitswechsel wie Sprünge, Abpraller und Einfedern zehren von einem kleinen, sich auffüllenden Budget: 4 Marken, alle 0,25 Sekunden eine neue. Ein echter Sprung braucht etwa 2; ein Flug-Cheat, der bei jedem Messpunkt einen Impuls braucht, ist nach etwa einer Sekunde leer.
- Wiedereinsetzen: Ein Teleport darf nur am Start, am bestätigten Checkpoint oder am direkt anschließenden nächsten Checkpoint enden.
Ein Verstoß bedeutet eine Verwarnung und eine Korrektur: Der Spieler wird zum bestätigten Checkpoint zurückgesetzt. Verwarnungen verfallen nach 90 Sekunden; drei gleichzeitig aktive bedeuten Disqualifikation. Die anderen Spieler sehen immer den letzten akzeptierten Zustand, nie eine ungeprüfte Behauptung.
Der erste Test im echten Netz: alle sind Betrüger
Zuerst bestanden die Tests auf einem einzelnen Rechner mit simulierter Latenz und Verlusten. Dann kam ein echtes Netz: Server auf einem entfernten VPS, Verbindung über den Hotspot eines Telefons, acht Bots im Rennen. 34 Sekunden nach dem Start erhielten alle acht Bots im selben Moment einen „Teleport“-Verstoß: 3,8 bis 5,2 Meter in 0,18 Sekunden. Das ist mehr als das Doppelte der horizontalen Höchstgeschwindigkeit des Pogostabs, obwohl alle Bots ehrlich sprangen.
Die Ursache war die Zeit. Im ersten Protokoll bekam jeder Zustand einen Zeitstempel nach der Schätzung des Clients für die Serveruhr. Damit ein betrügender Client nicht in die Zukunft stempeln kann, war der Stempel auf „Ankunft des Pakets + 50 Millisekunden“ begrenzt. Im echten Netz lagen die Uhrschätzungen der Clients etwa 0,35 Sekunden vorn, also stieß jeder Stempel an diese Grenze. Die Bewegung wurde damit faktisch nach der Ankunftszeit der Pakete gemessen. Wenn TCP stockte und dann mehrere wartende Zustände auf einmal freigab, schrumpfte die Zeit zwischen ihnen, und ehrliche Sprünge sahen aus wie Teleports.
Der Satz im Designdokument fasst es gut zusammen: Die Grenze war für Lügner gedacht und erwischte jeden, dessen Uhrschätzung danebenlag. Warum die Schätzungen um 0,35 Sekunden abwichen, wurde nie bewiesen; die Lösung braucht das aber auch nicht.
Die Lösung: zwei Uhren, zwei Aufgaben
Im zweiten Protokoll trägt jeder Zustand zwei getrennte Stempel:
sim: die Simulationsuhr des Zustands, also die Physikzeit des Clients. Bewegung wird nur über Differenzen dieses Werts geprüft. Netzlatenz, gestaute Pakete, Server-Hänger oder Fehler bei der Uhrsynchronisierung können sie weder dehnen noch stauchen.time: die Schätzung des Clients für die Serveruhr. Sie dient nur zur Zeitnahme an Checkpoints und im Ziel und ist begrenzt.
Dass die Simulationsuhr Physikzeit und nicht Wanduhrzeit sein muss, wurde eigens gemessen. Im Spiel wurden erzwungene Hänger von 0,3 Sekunden erzeugt: mit Wanduhr-Stempeln 2 Verstöße, mit Physikzeit null.
Und wenn der Client seine eigene Uhr beschleunigt? Dann sähe die Bewegung plausibel aus. Das fängt ein eigener Uhrwächter ab: Bei einem ehrlichen Client steigt der Abstand „Ankunftszeit minus Simulationsuhr“ mit Hängern und fällt wieder; bei einer beschleunigten Uhr wächst er immer weiter. Die Messungen: Ein ehrlicher Client mit Hängern bis 2,5 Sekunden gewinnt null Sekunden; eine 1,8-fach schnelle Uhr wird nach 3,95 Sekunden erkannt, eine 1,1-fach schnelle nach 20,8 Sekunden. Was ein Betrüger noch herausholen kann, steht ebenfalls fest: höchstens 1,5 Sekunden zusätzliche Bewegung, bevor der Wächter auslöst, und höchstens 0,35 Sekunden bei einer Checkpoint-Zeit.
Ergebnisse
Dasselbe Feldprofil (TCP, Client-Uhr 0,35 Sekunden vorn, Hänger von 150 bis 400 Millisekunden) wurde auf einer simulierten Uhr nachgestellt:
| Verstöße | Korrekturen | Im Ziel | |
|---|---|---|---|
| Protokoll 1 | 24 | 16 | 0 von 8 Bots |
| Protokoll 2 | 0 | 0 | 8 von 8 Bots |
Im selben Profil fuhren auch betrügende Bots mit: Teleport, 1,8-fache Geschwindigkeit, Schweben und eine 1,8-fach schnelle Uhr wurden disqualifiziert, der Bot, der Checkpoints ausließ, bekam „nicht beendet“, und die ehrlichen Bots belegten ohne einen einzigen Verstoß die ersten drei Plätze.
Der zweite Test im echten Netz fand etwas anderes: Bots, die ohne jeden Verstoß nicht ins Ziel kamen. Ursache waren Zustände, die nach Überschreiten der Nachrichtengrenze zusammengefasst wurden. Nach einem langen Verbindungsabbruch wurden gestaute Zustände zu einem einzigen verschmolzen, und ein Checkpoint, der in dieser Lücke überquert wurde, zählte nie. Die Grenze wurde so angehoben, dass etwa 28 Sekunden Rückstau einzeln geprüft werden; im Dokument steht auch, dass viel längere Abbrüche weiterhin eine Überquerung verschlucken können.
Plattformen im selben Takt
Ein Fairness-Problem gab es noch: Jedes Telefon lädt den Parcours zu einem anderen Zeitpunkt, also liefen Kolben und Pendel bei jedem in einer anderen Phase. Andere Fahrer schienen in der Luft zu stehen. Die Lösung: Beim Rennstart wird die Uhr aller beweglichen Teile zurückgesetzt; danach laufen die Teile jedes Clients mit seinen eigenen Physikschritten weiter.
Einige Plattformtypen (Zonen mit geringer Schwerkraft, Windkorridore, Teleporter) verletzen die Annahmen des Prüfers. Bis der Server sie selbst modelliert, verweigert er Online-Rennen auf Parcours, die sie enthalten; in den Einzelspielermodi gibt es sie alle.
Häufig gestellte Fragen
WebSocket oder UDP für ein Handyspiel?
Für einen Shooter mit schnellen Reaktionen ist UDP besser. In einem Spiel wie BOINGWARD, in dem jeder Spieler seine Figur lokal steuert und die anderen ohnehin leicht verzögert sieht, wogen die Zuverlässigkeit von WebSocket im Mobilfunknetz und der fehlende neue Port auf dem bestehenden Server schwerer. Liegt der Transport hinter einer Schnittstelle, lässt sich die Entscheidung später leicht ändern.
Sollte der Client „Ich bin im Ziel“ melden dürfen?
Nein. Der Client sollte nur seinen Zustand senden; Ziel und Checkpoints sollte der Server anhand geprüfter Zustände bestimmen. Sonst gewinnt eine einzige gefälschte Nachricht das Rennen.
Wie erkennt man Speed-Cheats ohne invasiven Schummelschutz?
Indem man Bewegung auf dem Server mit den Grenzen der Physik vergleicht: Geschwindigkeitsgrenzen, Strecke gegen Zeit, Übereinstimmung mit der Schwerkraft und ein Budget für plötzliche Geschwindigkeitswechsel. Messen Sie die Bewegung mit der Simulationsuhr des Clients und prüfen Sie diese Uhr selbst mit einer eigenen Kontrolle.
Verwandte Artikel
Risiko und Belohnung: Lufttricks für ein Pogo-Spiel
Vom Wunsch in einem Satz zum System aus Zahlen: wie die Lufttricks in BOINGWARD eine freiwillige, riskante Belohnung wurden, die nicht von der Bildrate abhängt.
Pogo-Physik in Godot: Eine Figur, die von selbst springt
Die Pogo-Physik von BOINGWARD: Springen mit RigidBody3D, die Abschussformel, eine aufschaukelnde Geschwindigkeit und ein Test für 30, 60 und 144 fps.
Leveldesign mit Messwerten, geprüft von einem Bot
In BOINGWARD entstehen Parcours aus gemessenen Sprungwerten, ein Bot testet jeden Sprung mit echter Physik. Auch die Medaillenzeiten stammen aus seinem Lauf.