FORTO: Ein Managerspiel für Formel 1 Enthusiasten (Entwicklertagebuch)

There are 25 replies in this Thread which has previously been viewed 1,542 times. The latest Post (November 18, 2025 at 2:39 AM) was by Yhoko.

  • in der Formel-1 treten immer nur 10 Teams gegeneinander an.

    10 Teams mit jeweils 2 Fahrern, also 20 Fahrer.

    Und... ab 2026 werden es 11 Teams sein, und bis... 2014 oder sowas... gab es ebenfalls 11.

    :D

  • Entwicklertagebuch, Woche 6

    Es mag bereits aufgefallen sein, dass bis zu diesem Zeitpunkt das ganze Projekt nur aus Verwaltungsfunktionen (Registrierung, Team-Auswahl, Trainingseinstellungen, Serverauswahl) und Vorbereitung (Ländertabelle, Fahrerwerte, Streckendaten) bestand. Nun ging's langsam an's Eingemacht, aber der Reihe nach.

    Nach besagten Funktionen war für mich der nächste logische Schritt, den Rennsimulator einzubauen, denn dieser stellt die einfachste Form des Rennens dar -- ganz ohne Gegner, Siegerehrung, bleibenden Folgen oder sonstigen Verbindlichkeiten. Er sollte aber eine solide Grundlage bildern, auf der sich später weitere Details und Spielmodi (Trainingsrunden, Qualifikation und Grand Prix) implementieren liessen. Am Ende wäre also eine Fahrt im Simulator nichts anderes als ein Rennen ohne Mitstreiter und mit ein paar deaktivierten Simulationseinstellungen.

    Rudimentäre Einstellungen des Simulators

    Nun stellte sich also die grosse Frage der Umsetzung. Erneut kam mir das erste Konzept in den Sinn, pro Rennwagen einfach nur eine Rundenzeit zu berechnen und daraus die Platzierungen abzuleiten. Eine besonders raffinierte Formel könnte dabei Reifenabrieb, Fahrerwerte, Motorleistung, Wetterbedingungen und sogar Überholmanöver uvm. berücksichtigen. Für ein rein tabellenbasiertes Spiel wäre völig ausreichend, wenngleich sehr mager, aber die Serverlast wäre dabei lächerlich gering (ein nicht zu vernachlässigender Faktor bei einem Browsergame): Ausgehend von 20 Fahrern wären das, vereinfacht gesagt, 20 Berechnungen.

    Darauf aufbauend sondierte ich verschiedene Lösungen, wie etwa die rundenbasierte Variante. Statt pro Rennen wird dabei pro Runde ein Zeitwert berechnet und die Reihenfolge dementsprechend nach jeder Runde neu sortiert (was quasi auch Überholmanöver darstellt). Der Aufwand hierbei wären 20 Fahrer * 20 Runden = 400 Berechnungen, also immer noch sehr wenig.

    Ein Wert pro Runde war immer noch zu wenig, also bot sich eine weitere Option an: Ein Wert pro Streckenabschnitt. Schliesslich sollte man auf langen geraden eine höhere Geschwindigkeit erreichen und das Überholen auf engen Abschnitten unwahrscheinlich bis unmöglich werden. Bei durchschnittlich 20 Abschnitten wären das 20 Fahrer * 20 Runden * 20 Abschnitte = 8000 Berechnungen, immer noch völlig akzeptabel.

    Dann wurde mir bewusst, dass das grafisch nicht funktionieren konnte. Angenommen, ein Fahrer wäre im ersten Abschnitt letzter, und im nächsten Abschnitt erster, dann würde er plötzlich extrem beschleunigen -- nur um vermutlich im nächsten Abschnitt wieder zurückzufallen. Ausserdem wären alle Wagen immer maximal 1 Abschnitt voneinander entfernt, was unplausibel wirkte. Diese Zeitberechnung war also insgesamt eine Sackgasse.

    Stattdessen erdachte ich mir ein ereignisbasiertes Simulationssystem und betrat damit völliges Neuland, was mitunter den Wert solcher Projekte offenbart -- jedes stellt eine Gelegenheit dar, Altbackenes zu überdenken, neue Wege zu gehen, neue Werkzeuge zu erschaffen und insgesamt dazuzulernen.

    Der neue Plan war also, ab dem Startschuss vorauszuberechnen, wann ein Ereignis stattfinden würde, und die Simulation dann zu diesem Zeitpunkt springen zu lassen. Ereignisse wären dabei, dass ein Wagen beschleunigt, bremst, einen anderen überholt, die Ziellinie durchfährt, einen Boxenstopp einlegt, die Box wieder verlässt, etc. Die Implementierung selbst hatte einige Stolperfallen zu bieten und stellte sich daher als knifflig aber machbar heraus (mitunter führten Ungenauigkeiten beim Umgang des Computers mit Fliesskommazahlen die Simulation in eine Endloschleife).

    Am Ende kam etwas heraus, das vermutlich nur Entwicklerherzen höher schlagen lassen kann: Ein Text-Log mit Ereignissen:

    A attackiert D kurz vor der 7. Runde und wird dann direkt von C überholt! -- was für ein Rennen

    Zumindest in der Theorie war damit das Rennen "im Kasten", denn aus diesen Ereignissen liess sich nun der grafisch relevante Teil (wer ist wann wo?) durch einfache Interpolation ableiten. Damit stellte sich nur noch die grosse Frage: Passt das alles? Anhand des Logs liess sich das zwar abschätzen, aber ultimativ würde nur die grafische Darstellung offenbaren, ob in den Daten noch Sprünge, Rückwärtsbewegungen oder sonstige Stotterer verborgen wären.


    Das Ganze liess sich glücklicherweise mit den Streckendaten kombinieren, so dass die Woche mit einem grafischen Player endete:

    Orange Ereignisse auf der Timeline sind Überholmanöver, pinke die Zieleinfahrten

    Wie sich zeigte, war die Simulation korrekt und plausibel -- Wagen fuhren los, überholten sich, machten ihre Runden und endeten mit der Zieleinfahrt. Ein voller Erfolg! Mit den Buttons lassen sich Geschwindigkeit und Abspielrichtung durchschalten und in der Timeline sieht man die Events.


    Damit war die Grundlage für die Simulation gelegt. Bis dato waren das alles aber nur ganz simple Beispieldaten, die lediglich Geschwindigkeit und Reifenabrieb berücksichtigten. In den kommenden Woche wird also die Ausarbeitung dieser Simulation im Fokus stehen, und so werden die SPRINT-Werte endlich ihre Anwendung finden.

    Yhoko

    PS: Herzlichen Dank, Kentaro -- ich werde dich auch gerne beim Betatest berücksichtigen, sofern du das möchtest.

    Edited 2 times, last by Yhoko (September 22, 2025 at 7:58 PM).

  • Entwicklertagebuch, Woche 7

    Diese Woche verlieft nicht ganz so wie geplant. Im letzten Beitrag sprach ich noch von 8000 Berechnungen pro Rennen und das war völlig in Ordnung. Doch wie sich dann zeigte, erforderte die ereignisbasierte Simulation nochmal deutlich mehr als das - konkret kam ich auf rund 50'000 Events bei 20 Fahrern und 80 Runden (das klingt zunächst nach immens viel, aber runtergerechnet sind das bloss ca. 30 Events pro Fahrer und Runde, wobei ein Event nicht 1:1 mit einer Berechnung vergleichbar ist; da steckt noch mehr Verwaltungsaufwand dahinter). Am Ende dauerte es über 60 Sekunden, ein Rennen zu berechnen. Untragbar.

    Also steckte ich einige Mühe in die Performance-Optimierung (ein grundlegendes und ewiges Thema bei der Spielentwicklung). Konkret implementierte ich: Heap, Lookup Tables, Binary Search und sogar einen Bubble Sort -- normalerweise verpönt, doch aufgrund der besonderen Situation tatsächlich spürbar schneller als der PHP-interne usort(). Das alles brach die Berechnungszeit um Faktor 20 auf ca. 3 Sekunden runter. Ein hervorragendes Ergebnis, aber aus Nutzersicht bedeutete das noch immer: nach einem Klick auf "Simulation starten" würde der Browser sekundenlang "nichts tun" bzw. auf den Server warten und erst dann würde die Seite sich aktualisieren. Und das unter optimalen Bedinungen, also nachts um vier ohne zusätzliche Serverlast.

    Deswegen, und auch in Gedanken an spätere Skalierung, beschloss ich, die Berechnung in eine asynchrone Warteschlange zu verlagern (soll heissen: nach Klick auf "Start" wird die Seite sofort neu geladen und ein Ladebalken vertröstet den Nutzer, bis die Ergebnisse vorliegen). Spätestens bei 100+ Nutzern würden diese Rundenberechnungen sonst den ganzen Server in die Knie zwingen.


    Nach diesem eher trockenen Thema noch etwas für's Auge: Zum besseren Verständnis des Rennablaufs färbte ich die Strecke anhand der Abschnitte ein (hier: gelb für Kurven und blau für DRS-Geraden) und beschränkte die Timeline auf Überholmanöver (orange) sowie Zieleinfahrten (grün). Neu kam auch die Tabelle mit den Fahrzeiten dazu, deren Reihenfolge sich "live" anpasste:

    Streckenabschnitte und Rundenzeiten

    Damit endete dieser kleine Ausflug in den Kern des Spielablaufs -- denn eigentlich ging es ja um den Rennsimulator, mit dem die Spieler ihre Setups testen und Einstellungen optimieren sollten. Aber ohne effektiv ein komplettes Rennen zu berechnen (egal ob mit 1 oder 20 Teilnehmern / 1 oder 80 Runden) liessen sich auch keine Rundenzeiten ausgeben.

    Diese Vorarbeit würde sich später auf jeden Fall noch lohnen. ;)

    Yhoko

  • Sehr cooler Fortschritt :)

    Am Ende dauerte es über 60 Sekunden, ein Rennen zu berechnen. Untragbar.

    Deswegen, und auch in Gedanken an spätere Skalierung, beschloss ich, die Berechnung in eine asynchrone Warteschlange zu verlagern (soll heissen: nach Klick auf "Start" wird die Seite sofort neu geladen und ein Ladebalken vertröstet den Nutzer, bis die Ergebnisse vorliegen).

    Genau das wäre auch mein Vorschlag gewesen. Es spricht ja nichts dagegen, den Spieler mit einem kurzen Ladebalken oder irgendeiner anderen grafischen Nachricht auf dem Laufenden zu halten.

  • Tatsächlich dachte ich recht lange, ohne Wartezeit auskommen zu können, da die Berechnungen ohne Mitfahrer kaum messbar waren, und selbst mit 10 Fahrern und 80 Runden noch unter 500 ms pro Rennen lagen... aber durch die Interaktionen der Wagen untereinander wächst die Anzahl Ereignisse exponentiell und 20 waren dann einfach zu viele.

    Diese Einschränkungen webe ich nun in die Spielmechanik ein; also statt Klick und Ergebnisse liegen sofort vor (das war der ursprüngliche Plan), startet man jetzt die Simulation und das dauert eben ein paar Minuten, in denen der Fahrer quasi den Simulator benutzt (ganz in Echtzeit wollte ich es dann doch nicht machen, da so ein Rennen gerne über eine Stunde dauert). Entsprechend ist die Funktion auch solange gesperrt; man könnte aber weitere Simulatoren dazukaufen... Screenshots folgen. ;)

    Edited once, last by Yhoko (October 3, 2025 at 1:45 AM).

  • Entwicklertagebuch, Woche 8

    So, wo waren wir? Leider kam seit dem letzen Beitrag etwas dazwischen -- nein, nicht der Jam, sondern mein Portfolio-Projekt, für dessen Umsetzung ich endlich einen Anlass hatte (Jobsuche). Neben der Website-Entwicklung selbst dauerte es seine Zeit, all die Daten, Texte und Bilder zusammenzutragen, aber IMHO war es notwendig unt hat sich auch gelohnt. Nach diesem kleinen Exkurs geht es hier nun weiter.


    Also nochmal, wo waren wir? Richtig, der Simulator. Genauer: Die Simulatoren, denn man soll ja auch mehrere gleichzeitig betreiben können -- zumindest so viele, wie man Fahrer unter Vertrag hat. Damit das auch nach 'was aussieht habe ich sie als Server gestaltet und mit ein paar dynamischen Zahlen und blinkenden Lämpchen in der Übersichtsseite integriert:

    Die Zahlen haben (noch?) keine Bedeutung

    Die nächste Herausforderung stand auch bereits in den Startlöchern, oder besser gesagt, wartete auf der Ziellinie auf mich, nämlich die Auswertung dieser Rennen. Die Tabelle sollte gleichzeitig kompakt sein, damit sich die Rundenzeiten auf einen Blick vergleichen liessen, aber auch möglichst detailliert, um ggf. Problemen auf den Grund gehen zu können. Auch hier sollte wieder etwas für's Auge hin, also investierte ich einen Moment in die Gestaltung der Zeitstempel. Oh, und natürlich sollte sich die Tabelle sortieren lassen, also schüttelte ich dafür noch ein Skript aus dem Ärmel:

    Ergebnistabelle mit sortierbare Spalten

    Die Zeilen sollen sich später noch anklicken lassen und zur Detailauswertung der Rennen führen -- mehr dazu später. Das war's nämlich bereits für diese Woche, denn jeder Wechsel bzw. Wiedereinstieg kostet mich übermässig Zeit. Aber das Portfolio war's wert, also schaut da gerne mal rein (FORTO ist natürlich auch mit aufgeführt).

    Yhoko

    PS: Wofür steht eigentlich FORTO? Die Antwort lautet: "Fun-Oriented Racing Tournament Onlinegame" oder alternativ auf Deutsch: "Fahrer-Orientiertes Renn-Taktik-Onlinespiel", was euch lieber ist.

Participate now!

Don’t have an account yet? Register yourself now and be a part of our community!