OmegaSim Wiki

OmegaSim Wiki – die Idee dazu stammt von Gnen54. Hier stehen die offenen Artikel von Nutzer Luuke42 unter der Lizenz CC BY-SA 4.0.

OmegaSim

Stand dieses Artikels: OmegaSim 1.2.45 vom 29.10.2026 · Firmware des Autos: nicht bekannt (OmegaSim liest die Firmware-Version nicht aus)
Dieser Text wurde mithilfe von KI erstellt (Claude) und ist nicht in jedem Punkt von Menschen geprüft. Fehler bitte direkt verbessern oder auf der Diskussionsseite melden, siehe Mitmachen. Die öffentliche Fassung auf luuke42.github.io/omegasim kann älter sein als der hier beschriebene Stand.

Titelbildschirm von OmegaSim

OmegaSim ist eine freie, quelloffene App zur Steuerung von Carrera HYBRID-Autos per Bluetooth Low Energy. Sie läuft im Browser (Chrome, Edge) und als Android-App und ergänzt die Autos um ein eigenes Fahrmodell, simulierte Motorgeräusche, computergesteuerte Gegner (NPCs), Rennarten, einen Strecken- und Raum-Editor, Challenges mit Online-Bestenliste und Mehrspieler. OmegaSim ist unabhängig vom Hersteller Carrera; es spricht dieselbe Funkschnittstelle wie die Original-App, deren Protokoll für das Projekt aus Mitschnitten rekonstruiert wurde. Technisch ist OmegaSim eine einzige HTML-Datei mit JavaScript, die ohne Server läuft; die Android-Fassung legt eine dünne Java-Hülle darum. Der Titelbildschirm nennt als Leitsatz „Vollständige Gestaltungsfreiheit für deine Carrera Hybrid Bahn“. In älteren Dateien des Repositorys heißt das Projekt noch „CH Control“.

Auf einen Blick

Merkmal Wert
Autor Luuke (GitHub: Luuke42); weitere Beiträge unter anderem von Playdater1974 (Bambi007)
Lizenz MIT; mitgelieferte Tonaufnahmen und Druckmuster haben eigene Bedingungen (siehe audio/CREDITS.md)
Aktuelle Version 1.2.45 vom 29.10.2026 (Schema 1.<Woche>.<Push>)
Plattformen Browser mit Web Bluetooth (Chrome, Edge) am PC und unter Android; Android-App (APK, ab Android 7); auf iPhone/iPad nur Streckenbau und Doku
Sprachen der Oberfläche Deutsch (Quelle), Englisch, Spanisch
Programmiersprachen JavaScript, HTML, CSS; Java (Android-Hülle); Python (Bau, Werkzeuge, Mehrspieler-Host); Google Apps Script (Bestenliste, Studie); siehe Aufbau von OmegaSim
Umfang 46 JavaScript-Dateien und 2 HTML-Teile in src/, rund 92 500 Zeilen JavaScript; ausgeliefert als index.html mit rund 6,6 MB
Android-Kennung de.lroeseler.omegasim, Capacitor 8.5.2
Selbsttest 522 Prüfungen in src/95-selftest.js
Hauptmenü FAHREN · Challenges · WLAN Mehrspieler · Optionen · (Entwickler)
Status stabil; einzelne Funktionen als WIP oder experimentell gekennzeichnet

Grundlagen

Was eine Web-App ist

Eine Web-App ist ein Programm, das im Browser läuft. Sie besteht aus HTML (dem Gerüst: Knöpfe, Regler, Texte), CSS (dem Aussehen) und JavaScript (der Programmlogik). OmegaSim braucht keinen Server, der für jeden Klick rechnet: Die ganze App wird einmal geladen und läuft dann im Browser des Nutzers, sogar von der Festplatte (file://). Mit Web Bluetooth kann eine solche Seite in Chrome oder Edge direkt mit Bluetooth-Geräten sprechen, nach einem ausdrücklichen Klick des Nutzers für jedes Gerät. Safari und Firefox bieten Web Bluetooth nicht an.

Programmiersprachen in OmegaSim

Sprache Wofür Wo
JavaScript die gesamte App: Fahrphysik, Bluetooth-Protokoll, NPCs, Ton, Editor, Menüs src/*.js
HTML Markup aller Menüs, Optionen mit ⓘ-Texten, Doku, Patchnotes src/00-index.head.html, src/99-index.tail.html
CSS Aussehen, im Kopf der HTML-Datei src/00-index.head.html
Java Android-Hülle: Bluetooth-Schreibweg OmegaBle, Selbstaktualisierung, Mehrspieler-Host, Sicherungsdatei, Gamepad android-app/…/*.java
Python Bau (build.py, bump_version.py, app_update.py), Ton- und Druckvorlagen-Erzeugung, Auswertung von Mitschnitten, WLAN-Host für den PC tools/*.py
Google Apps Script Online-Bestenliste der Challenges und Speicherung der Studie in einem Google Sheet tools/challenges-apps-script.gs
YAML, PowerShell, Batch Bauaufträge für GitHub Actions, Hilfsskripte unter Windows .github/workflows/, tools/*.ps1, *.bat

Wie diese Teile zusammenspielen, wie viel Code auf jede Sprache entfällt und wie die App „aufbereitet“ wird, beschreibt ausführlich der Artikel Aufbau von OmegaSim.

Quelle, Bau und Auslieferung

Der Quelltext ist das, was Entwickler schreiben: hier rund 50 nummerierte Dateien in src/. Ein Bauschritt (build) setzt daraus das aus, was Nutzer bekommen: eine einzige Datei index.html. Bei OmegaSim ist der Bau bewusst einfach: Die Dateien werden in Namensreihenfolge Byte für Byte aneinandergehängt, ohne Bundler und ohne Umwandlung. Die Versionsnummer wird bei jedem Push aus der Git-Historie berechnet. Git ist das Versionsverwaltungssystem, das jede Änderung als Commit speichert; ein Push lädt Commits auf den Server (GitHub).

Gültigkeitsbereich und Ladereihenfolge

Fast alle JavaScript-Dateien bilden zusammen eine Funktion, die sofort ausgeführt wird (IIFE, „immediately invoked function expression“): Sie wird am Anfang von 10-ble-explorer.js geöffnet und in 99-index.tail.html geschlossen. Alles darin sieht sich gegenseitig, nach außen ist nichts sichtbar. Weil JavaScript eine mit let oder const angelegte Variable vor ihrer Zeile nicht lesen darf („temporale Todeszone“), zählt die Reihenfolge: Ein Zugriff zu früh bricht die ganze Funktion ab, und die App bleibt leer. Die Zahlen vor den Dateinamen machen diese Reihenfolge im Verzeichnis sichtbar. 05-app-bruecke.js ist eine eigene Funktion davor, weil sie navigator.bluetooth bereitstellen muss, bevor der Rest es abfragt.

Service Worker und PWA

Eine PWA (Progressive Web App) ist eine Web-App, die sich wie eine installierte App verhält: eigenes Symbol, Vollbild, Start ohne Netz. Dafür sorgt ein Service Worker, ein kleines Hintergrundskript des Browsers, das Dateien zwischenspeichert (Cache).

Lokaler Speicher

Der Browser stellt jeder Seite einen kleinen Schlüssel-Wert-Speicher bereit, localStorage. Er überlebt das Neuladen, gehört aber zum Browser (bzw. zur Installation der App) und kann beim Aufräumen von Websitedaten verloren gehen. Deshalb gibt es eine Sicherungsdatei.

Wie der Quelltext entstanden ist

Viele Kommentare im Code beginnen mit „BESTELLT:“ oder „GEMELDET:“ und zitieren den Wunsch oder Fehlerbericht wörtlich, auf den die Stelle zurückgeht; Messungen stehen mit Zahlen daneben. Wie diese Arbeitsweise mit KI-Werkzeugen funktioniert, beschreibt Vibe-Coding; Hinweise für KI-gestützte Beiträge stehen in Anleitung für KIs.

Bedienung

Im Browser

  1. OmegaSim in Chrome oder Edge öffnen (Link auf der Hauptseite) oder index.html von der Festplatte starten.
  2. Auf dem Titelbildschirm Starten wählen; Tutorial führt durch die ersten Schritte, Steuerung zeigt die Tastenbelegung.
  3. FAHREN → Autos: Auto verbinden (für jedes Auto ein Klick im Auswahlfenster des Browsers).
  4. FAHREN → Strecke: Leseart wählen (Auf der Bahn / Ausdruck), Strecke scannen oder im Editor bauen (siehe Strecke, Strecken- und Raum-Editor).
  5. FAHREN → Rennoptionen: Renntyp wählen (siehe Rennarten), dann Rennen starten.
  6. Gefahren wird im Cockpit mit Drehzahl, Gang, Rundenzeiten und Zustand des Autos.
  7. Optional: Über das Symbol in der Adresszeile oder den Knopf Als App installieren als PWA installieren; dann startet OmegaSim auch ohne Netz.

In der Android-App

  1. Die APK von der Titelseite der Browserfassung herunterladen und installieren („Unbekannte Quellen“ für den Browser erlauben).
  2. Die App fragt beim Start nach Updates (Optionen → App & Updates); eine neue APK ist nur nötig, wenn die App das meldet.
  3. Autos verbinden wie im Browser; bekannte Autos verbindet die App beim Start selbst.
  4. Daten liegen zusätzlich in einer Sicherungsdatei in Dokumente/OmegaSim.

Mit dem Gamepad wechseln L1/R1 die Reiter, das Steuerkreuz wählt, Kreuz bestätigt, Kreis geht zurück. Die Zurück-Taste des Handys führt zum Titelbildschirm.

Reiter Inhalt
FAHREN Kacheln Autos (Garage), Strecke (Leseart, Scan, Editor, Laden, Raum, Druckvorlagen), Rennoptionen, Meisterschaft, Rennen starten
Challenges feste Strecken und Wochenstrecken mit Online-Bestenliste (siehe Challenges)
WLAN Mehrspieler gemeinsame Rennen mehrerer Geräte, Host am PC oder in der Android-App (siehe Mehrspieler)
Optionen Allgemein, Fahrgefühl, Renneinstellungen, Ton, Ansagen, Vibration, NPCs, Safety Car, Controller, System, Daten sichern, Mehrspieler, Statistiken, Telemetrie (WIP), OmegaLab (WIP), Tutorials, Info-Seiten mit Patchnotes
Entwickler nur mit Optionen → System → Entwicklertools zeigen: Doku, Programmierschule, BLE-Werkbank, Selbsttest, Code-Sonde, Zahlensysteme, Aufnahme-Modus

Einstellungen

Hier stehen nur die Einstellungen, die OmegaSim als Ganzes betreffen; die übrigen stehen in den Fachartikeln.

Name in der App Bereich/Werte Standard Wirkung (aus dem Code) Interner Schlüssel/ID
Sprache (Optionen → System, auch auf dem Titelbildschirm) Deutsch, English, Español Deutsch übersetzt alle Texte der Oberfläche; der Knopf auf dem Titelbildschirm schaltet reihum setting-sprache, gespeichert in omegasim-lang
Entwicklertools zeigen (System) an/aus aus blendet den Reiter Entwickler ein; auch mit ?dev in der Adresse setting-dev
Bekannte Autos beim Start verbinden (System, nur App) an/aus an verbindet gemerkte Autos über die MAC-Adresse setting-autoverbinden
Beim Start nach Updates suchen (App & Updates, nur App) an/aus an fragt 3 s nach dem Start einmal die Projektseite; geladen wird erst nach Tipp auf „Jetzt laden“ app-auto, gespeichert in chc.app.v1
Mitgelieferte Fassung verwenden (App & Updates) Knopf – schaltet auf die in der APK eingebaute Web-Fassung zurück OmegaUpdate.eingebaut()
Sicherung speichern / einlesen (Optionen → Daten sichern) Knöpfe – eine Datei mit allem, was die App sich merkt src/98b-sicherung.js
Profil (System) benannte Profile – vollständiger Stand aller Menüs und der Tastenbelegung je Person chc.profile.v1

Funktionsweise

Architektur: Module in Ladereihenfolge

tools/build.py hängt alle Dateien in src/ alphabetisch aneinander. Die Reihenfolge ist damit die Ladereihenfolge.

Datei Zweck
00-index.head.html Kopf der Seite: CSS, alle Menüs und Optionen mit ⓘ-Texten, Doku-Seiten, Patchnotes, Startdiagnose.
05-app-bruecke.js Eigene Funktion, nur in der Android-App aktiv: baut Web Bluetooth auf dem Community-Plugin nach und bindet OmegaBle an.
10-ble-explorer.js Öffnet den gemeinsamen Gültigkeitsbereich; BLE-Werkbank, crc8(), Wörterbücher Englisch/Spanisch und Übersetzungsmechanik.
15-pause.js Lokale Rennpause: eigene Uhr, Wiederanlauf-Ampel, pausierbare Renn-Timeouts.
20-protocol.js Das 20-Byte-Befehlspaket, der 45-ms-Herzschlag, das Schreibschloss je Merkmal und der RC-Gasverlauf.
30-input.js Eingabe: wer darf steuern (Tastatur, Gamepad, Touch, Neigung), Tempo-Skalen, Mitschrift.
40-physics.js Die Fahrphysik als Klasse: Gänge, Reifen, Reibkreis, Gewichtsverlagerung, Einspurmodell (siehe Fahrverhalten).
49-spieler.js Spielerplätze 2 und 3 für Mehrspieler an einem Gerät.
50-drive.js Fahren: Regler, Kalibrierung, Autopilot, Abseits-Erkennung, Aufnahme und Wiedergabe von Fahrten.
50b-menu-nav.js Menüführung mit Steuerkreuz und Pfeiltasten im Cockpit und in den Optionen.
51-konsole.js Menü im Konsolenstil mit Kacheln, Titelbildschirm und PS5-Tastenlogik.
51b-tutorial.js Geführte Einführung vom Titelbildschirm aus.
59-lade.js Ladeanimation: ein sich drehendes Streckenteil.
60-track.js Strecke: Modell, Geometrie, Codes, Editor, Ideallinie, Scan (siehe Strecke).
60b-raum.js Raumdesigner und Platzierung der Strecke im Raum (siehe Strecken- und Raum-Editor).
60c-streckenbild.js Export der Strecke als PNG-Bild.
60d-virtuell.js Virtuelles Fahren: ein Auto ohne Bluetooth in 3D auf der Editor-Strecke.
61-simlinie.js SIMULATOR-Ideallinie: Suche über Linien und Tempopläne mit derselben Physik.
70-race.js Rennen: Cockpit, Meldungsauswertung, Rundenzählung, Renntypen, Boxenstopp, Wetter, Akku (siehe Rennarten).
70b-telemetrie.js Zwischenzeiten je Streckenteil für jede Runde (WIP).
71-rammen.js Crash-Arten, Rammen und Rammer-Strafen.
72-challenges.js Challenges mit Online-Bestenliste.
72b-spuren.js Telemetrie-Spuren der Bestenlisten (WIP).
73-meisterschaft.js Meisterschaft aus mehreren Rennen.
80-sound.js Der Ton: Motorklang aus Aufnahmen, Effekte, Reifenquietschen.
80b-dualsense.js Trigger-Effekt des DualSense-Controllers bei ABS (WIP, WebHID).
80c-rennstand.js Ansagen zum Rennstand aus vorproduzierten Sprachclips (siehe Rennarten#Rennstand-Ansage).
80d-rennintro.js Rennintro vor der Startampel (siehe Rennarten#Rennintro).
90-ghosts.js Garage und Verbindungen, NPCs, Ortung auf der Strecke, Gamepad-Belegung (siehe NPC-Fahrverhalten, Safety Car und Reinigungswagen).
90b-sim.js „Rennen simulieren“: ein Rennen ohne Autos im Modell.
90c-macro-track.js Strecke aus einer Aufnahme lernen (WIP).
90d-challenger.js Challenger: ein echtes Auto fährt eine Bestzeit gegen dich (experimentell).
91-pwa.js Installierbarkeit als PWA, Anmeldung des Service Workers.
92-coding-school.js Programmierschule: Kurven ziehen statt Code schreiben.
92b-num-trainer.js Binär- und Hex-Trainer (siehe Hexadezimalsystem).
93-testbench.js Messstände für Selbsttest und Konsole (OMEGA_TEST).
94-engine-workshop.js Motorwerkstatt: elf Größen des Motormodells zum Drehen.
95-selftest.js Der Selbsttest mit 522 Prüfungen.
96-home.js Gezählte Angaben für die Info-Seite (Zahl der Einstellungen).
97-sessions.js Sitzungsdaten: Rundenzeiten aller Rennen, am Rennende gespeichert.
97b-app.js Nur in der App: Selbstaktualisierung (OmegaUpdate) und Host ohne PC (OmegaHost).
97b-fahrstil.js Fahrstil-Kennwerte der letzten Sitzung (WIP).
98-presets.js Voreinstellungen (Presets) der Abstimmung.
98b-sicherung.js Sicherung: alles Gemerkte in einer Datei.
98c-opt-info.js ⓘ-Knöpfe: Hilfetexte der Optionen im Pop-up.
98d-profile.js Profile und Presets je Menü.
98e-statistik.js Statistiken (Kilometer, Ranglisten); 98ea-statistik-bereinigen.js und 98eb-statistik-zeiten.js zur Statistikbereinigung.
98f-studie.js OmegaLab: Studie mit Fragebogen und Fahr-Challenge (WIP).
98g-telemetrie-seite.js Seite Optionen → Telemetrie (WIP).
98h-pause.js Rennpause: Anzeige und Bedienung im Cockpit (siehe Rennarten#Rennpause).
99-index.tail.html Schließt den gemeinsamen Gültigkeitsbereich und das Skript-Element.

Der Herzschlag

Das zentrale Bauprinzip: Eingaben senden nicht selbst. Tastatur, Gamepad, Touch und Neigung setzen nur Zustand; ein einziger Zeitgeber, controlHeartbeat(), läuft alle 45 ms (CONTROL_SEND_INTERVAL_MS, dem beobachteten Takt der Original-App) und erledigt in fester Reihenfolge: Gamepad frisch lesen, Ort der Spielerautos bestimmen, Physik rechnen, Boxengasse, Paket von Spieler 1 senden, Spieler 2 und 3 senden, NPC-Takte, zuletzt das Cockpit zeichnen („erst senden, dann malen“). Vor 0.5.8 schrieben fünf Quellen ungeordnet ans Auto; überlappende Schreibvorgänge gingen verloren, und das Auto stotterte[1]. Gemessen kostet der ganze Takt im Median 0,3 ms (mit zwei NPCs 0,4 ms), unter 2 % des Budgets.

Bau: tools/build.py

  1. Alle Dateien in src/ mit Endung .js oder .html alphabetisch sortieren.
  2. Byte für Byte aneinanderhängen, ohne Trenner: Das Ergebnis ist index.html.
  3. Prüfen: Klammern zählen (außerhalb von Zeichenketten und Kommentaren), doppelte IDs, lokale Verweise auf fehlende Dateien, Wörterbuch.
  4. sw.js aus tools/sw.js.in schreiben und dabei die Version in den Cachenamen einsetzen; fehlt die Platzhalterzeile, bricht der Bau ab.
  5. app-update.json schreiben (tools/app_update.py): Version, APK-Stufe und für jede Datei Pfad, SHA-256 und Größe.

python tools/build.py --check baut nichts, sondern prüft, ob index.html dem Bau entspricht. Die Auslieferung bleibt bewusst eine Datei: Sie soll per file:// laufen, ohne Installation, ohne Bundler, ohne Netz[2].

Versionsschema: tools/bump_version.py

Vor jedem Commit berechnet bump_version.py die Nummer aus der Git-Historie, schreibt sie in <span id="app-version"> der Quelle und baut index.html, sw.js und app-update.json neu[3]:

Start   = 03.08.2026 (PROJEKT_START, Woche 0)
Montag  = Montag der laufenden Woche
Woche   = (Montag − Start) in Tagen ÷ 7  (ganzzahlig)
Push    = Commits seit Montag 00:00 + 1 + PUSH_VERSATZ[Montag]
Version = 1.(Woche − 10).Push     ab Woche 10 (12.10.2026)
          0.Woche.Push            davor

Die Patchnotes haben je Nebenversion (1.2, 1.1, …) einen Abschnitt. Für die APK wird daraus ein streng steigender Android-versionCode: Haupt × 100 000 + Neben × 1000 + Push.

Service Worker: sw.js

Im Browser hält ein Service Worker die Hülle bereit (index.html, Manifest, Symbole). Er holt Netz zuerst: online immer die neueste Fassung, offline die zuletzt gesehene. Der übliche Rat „Cache zuerst“ wäre hier falsch, weil mehrmals am Tag neu gebaut wird; ein Cache-zuerst-Arbeiter lieferte dann eine alte Fassung aus. Der Cachename trägt die Version (omegasim-1.2.9), alte Caches werden beim Aktivieren gelöscht. Nicht gecacht werden Anfragen, die nicht GET sind, und fremde Herkünfte (etwa der Mehrspieler-Host). Die Tonschleifen werden nicht vorab geladen, sondern beim ersten Hören. In der Android-App wird kein Service Worker angemeldet, weil OmegaUpdate die Dateien selbst verwaltet[4].

Android-App und APK

Die APK ist dieselbe index.html in einer Capacitor-Hülle. Was die App nativ anders macht, steht in index.html hinter window.Capacitor und schläft im Browser. Eigene Plugins der Hülle:

Plugin Aufgabe
OmegaBle schneller Schreibweg und Aufräumen von Verbindungen, siehe OmegaBle
OmegaUpdate Selbstaktualisierung der Web-Fassung
OmegaHost Mehrspieler-Host auf dem Telefon, Vollbild
OmegaSicherung Sicherungsdatei in Dokumente/OmegaSim
OmegaPadNativ (kein Plugin, JavascriptInterface) Gamepad direkt lesen

Bau der APK. Ein Git-Tag apk-v<Version> (oder ein Start von Hand) löst den Bauauftrag .github/workflows/android.yml aus: build.py baut index.html, tools/apk_www.py kopiert genau die Dateien aus app-update.json nach android-app/www, npx cap sync android überträgt sie, Gradle baut eine signierte Release-APK (Schlüssel aus Repository-Secrets, nie im Repository), und sie wird als OmegaSim-<Version>.apk und unter dem festen Namen OmegaSim.apk an ein GitHub-Release gehängt. Eine neue APK ist nur nötig, wenn sich die native Schicht ändert.

Update-Mechanismus der App (OmegaUpdate)

Die APK trägt eine eingebaute Web-Fassung. Neuere Fassungen kommen von der Projektseite auf GitHub Pages; app-update.json nennt Version, APK-Stufe und Dateien (Fassung 1.2.9: 638 Einträge mit Pfad p, SHA-256 h, Größe g)[5].

Methode Wirkung
stand APK-Version, APK-Stufe, aktive Web-Fassung, ob eingebaut oder geladen, offene oder zurückgerollte Fassung
pruefen lädt app-update.json und zählt, welche Dateien sich nach Prüfsumme unterscheiden; meldet Version, Zahl, Bytes und apkNoetig
laden lädt die neue Fassung in einen eigenen Ordner und schaltet um
bestaetigen die neue Fassung meldet sich; alte Ordner außer der aktiven und der vorigen werden gelöscht
eingebaut zurück zur Fassung in der APK
abbrechen laufenden Download abbrechen
vergessen Merker „zurückgerollt“ löschen

Ablauf einer Aktualisierung:

  1. 3 s nach dem Start fragt 97b-app.js still pruefen. Ist die Version nicht neuer als die laufende, passiert nichts. Eine Fassung, die schon einmal zurückgerollt wurde, wird nicht erneut angeboten.
  2. Ist die APK-Stufe der neuen Fassung (apk) größer als die der installierten APK (APK_STUFE = 2), heißt das Angebot „Neue APK nötig“ und führt zum Download der APK.
  3. Sonst zeigt die App „Update verfügbar: Version (Größe)“. Ein Tipp auf „Jetzt laden“ startet laden.
  4. laden legt einen neuen Ordner files/www/<Version>-<Zeit> an. Für jede Datei: Ist die Prüfsumme gleich der laufenden Fassung, wird kopiert; sonst geladen und nachgeprüft. Eine falsche Prüfsumme bricht ab, der Ordner wird gelöscht. Pfade mit .. oder führendem / sind verboten. Fortschritt geht als Ereignis an den Ladebalken.
  5. Danach merkt sich die App die vorige Fassung und die neue als „offen“, setzt den Pfad und schaltet die WebView nach 400 ms um (setServerBasePath). Die Herkunft bleibt https://localhost, also bleiben alle Einstellungen in localStorage erhalten.
  6. Die neue Fassung ruft beim Hochkommen bestaetigen. Kommt diese Bestätigung nicht binnen 25 s (WACHHUND_MS), schaltet der Wachhund zurück. Wurde die App vorher beendet, erledigt das beimStart() beim nächsten Öffnen, noch bevor die Seite lädt.
  7. Eine neue APK setzt alles zurück: Capacitor erkennt die neue Binärfassung und nimmt wieder die eingebaute Web-Fassung.

Textdateien werden für die Prüfsumme mit LF-Zeilenenden gerechnet, weil GitHub Pages sie so ausliefert; sonst passte keine Prüfsumme.

Speicherorte

Alles liegt im localStorage des Browsers bzw. der App-WebView, unter Schlüsseln mit drei Präfixen[6]:

Präfix / Schlüssel Inhalt (Auswahl)
chc.cars.v1 Name und Farbe je Auto (nach Gerätekennung)
chc.rollen.v1 gemerkte Rolle, NPC-Stufe, NPC-Motor, Selbstlenkung je Auto
chc.sessions.v1 Sitzungshistorie: Rennen mit allen Rundenzeiten (bis 200 Rennen)
chc.statistics.undo.v1 Sicherung des vorherigen Statistikstands für „Letzte Bereinigung rückgängig“ (seit einem Folgepatch in IndexedDB)
chc.auto.v1 Selbstsicherung aller Regler
chc.presets.v1, chc.menupresets.v1, chc.profile.v1 Presets und Profile
chc.layout.v1, chc.gearbox.v1, chc.cockpit.v1, chc.motorwerkstatt.v1 Fahrzeuglayout, Getriebe, Cockpit, Motorwerkstatt
chc.mp.v1, chc.app.v1 Mehrspieler, App-Update-Einstellung
chc.migrate.* Merker für einmalige Umstellungen alter Werte
carrera-hybrid-tracks gespeicherte Strecken
carrera-hybrid-macros aufgenommene Fahrten
carrera-hybrid-gamepad-bindings-v2 (und -p2, -p…, …-pad:) Tastenbelegung je Spieler und Controller
omegasim-lang Sprache
omegasim-raum…, omegasim-editor-… Raum und Editor
omegasim-challenges, omegasim-ch-…, omegasim-bestzeiten Challenges, Zwischenspeicher der Bestenliste, eigene Bestzeiten
omegasim-meisterschaft, omegasim-studie, omegasim-telemetrie, omegasim-vf-… Meisterschaft, Studie, Telemetrie, virtuelles Fahren

Sicherungsdatei. Optionen → Daten sichern schreibt alle Schlüssel mit diesen Präfixen in eine JSON-Datei vom Typ omegasim-sicherung (Version 1), dazu den Stand der Regler aus Optionen und Steuerung. Eine Präfixregel statt einer Schlüsselliste ist Absicht: Beim Sammeln fanden sich zwölf Schlüssel im Quelltext und ein dreizehnter (die Tastenbelegung, 1223 Byte Handarbeit) erst im laufenden Browser; eine Liste hätte ihn vergessen. Ein Selbsttest prüft, dass jede bekannte Schlüsselkonstante unter die Regel fällt. In der App schreibt OmegaSicherung die Datei zusätzlich nach Dokumente/OmegaSim/OmegaSim-Sicherung.json; sie überlebt eine Deinstallation, und eine neue Installation öffnet sie über den Dateiwähler. Seit 0.8.96 bittet die App den Browser außerdem, den Speicher dauerhaft zu halten (navigator.storage.persist()).

Statistikbereinigung

Die Statistikbereinigung (Optionen → Statistiken → „Statistiken bereinigen“, übernommen aus dem PR von Playdater1974; als WIP gekennzeichnet) entfernt gezielt Teile der Statistikablage, mit Vorschau, Rückfrage und Rückgängig. Sie liegt in src/98ea-statistik-bereinigen.js und src/98eb-statistik-zeiten.js.

Löschart Was entfernt wird
Auto (Name und Kennung) seine Lebenszeit-Statistik und seine Anteile aus gespeicherten Sitzungen; Mitfahrer und Garagenkonfiguration (Foto, Name, Farbe) bleiben erhalten
Einzelne Sitzung (Datum/ISO-Zeit, Modus, Autos, Runden, Bestzeit, Streckencode) nur diese Sitzung
Zu kurze Zeiten je Strecke alle gespeicherten Sitzungsrunden mit Zeiten strikt unter dem Grenzwert in Sekunden, samt ihrer indexbezogenen Boxen-/Crash-Ereignisse

Sicherung und Rückgängig: Vor jeder Löschung wird der vorherige Statistikstand automatisch und bytegetreu unter chc.statistics.undo.v1 gesichert (seit einem Folgepatch asynchron in IndexedDB, Datenbank omegasim-statistics-backups). Schlägt die Sicherung fehl, wird nicht gelöscht. „Letzte Bereinigung rückgängig“ funktioniert auch nach Neuladen, solange die Ablagen seit der Löschung unverändert sind. „Statistik-Sicherung als JSON“ exportiert den VORHERIGEN Stand im Format des Sicherungsimports.

Altdaten: Die Lebenszeit-Summen sind unabhängig von den letzten maximal 200 Sitzungen und werden bewusst nicht aus diesem begrenzten Archiv neu aufgebaut. Neu gespeicherte Sitzungen erhalten pro Auto statistikBuchung mit dem exakt gebuchten Schlüssel und den km-/Runden-/Sitzungsbeiträgen; beim Löschen werden nur diese exakten Beiträge abgezogen. Alte Sitzungen ohne diese Buchung: Runden und Sitzungsanzahl werden abgezogen, soweit die Zuordnung eindeutig ist, die Lebenszeit-Kilometer bleiben unverändert (Vorschau und Rückfrage weisen darauf hin). Gerätekennungen haben Vorrang vor Namen; mehrdeutige Altdaten erscheinen als eigene name:…-Gruppe.

Sprachen (i18n)

Übersetzt wird mit dem deutschen Text als Schlüssel[7]:

  1. Zwei Wörterbücher: I18N_EN (Deutsch → Englisch, rund 3000 Einträge) und I18N_ES (Deutsch → Spanisch, rund 1100 Einträge).
  2. Beim Umschalten läuft ein Baumdurchlauf über Kopfzeile, Hauptteil und Lightbox: Jeder Textknoten wird normalisiert (Leerraum zusammengefasst) und nachgeschlagen; dazu die Attribute title, aria-label, placeholder. Der Originaltext wird in einer WeakMap gemerkt, damit der Weg zurück nach Deutsch exakt ist.
  3. Ein Beobachter (MutationObserver) übersetzt jeden später eingefügten Knoten.
  4. Text, der im Code entsteht, läuft durch t(deutsch), dieselbe Tabelle.
  5. Spanisch fällt auf Englisch zurück, wo noch keine spanische Übersetzung steht; fehlt beides, bleibt der deutsche Text stehen. Ein fehlender Eintrag fällt so auf, ein leerer Text nicht.
  6. Nicht übersetzt werden script, style, code, kbd, alles mit data-i18n-skip, Log-Zeilen und Bytewerte der Protokoll-Doku.

Der Preis dieser Bauform: Zwei gleiche deutsche Sätze bekommen immer dieselbe Übersetzung; kurze mehrdeutige Wörter stehen deshalb nur mit Zusammenhang im Wörterbuch. Der Vorteil: Am Markup muss nichts ausgezeichnet werden, bei rund 1460 Textstellen.

Selbsttest

Entwickler → Selbsttest → Selbsttest starten führt alle mit stAdd(name, fn) angemeldeten Prüfungen der Reihe nach aus (Fassung 1.2.9: 522). Drei Grundsätze stehen im Kopf der Datei[8]:

  1. Jede Zeile nennt ihr Maß, nicht nur „grün“ oder „rot“, damit man sieht, wie knapp es war.
  2. „nicht prüfbar“ ist ein eigenes Ergebnis und kein Fehler (etwa Tonschleifen über file://).
  3. Die Prüfungen benutzen dieselben Funktionen wie die App, keine nachgebauten.

Zwischen zwei Prüfungen gibt der Test dem Browser über einen MessageChannel (oder scheduler.yield()) kurz Luft, ohne Zeitgeber, die in einem verborgenen Tab gedrosselt würden. Beispiele: „Aufbau durchgelaufen“ (mehr als 30 Regler, mehr als 400 Wörterbucheinträge), „Protokoll: CRC-8“ (Leerlaufpaket ergibt 0x33). Messstände für die Konsole liegen unter OMEGA_TEST (src/93-testbench.js), etwa taktKosten(), sendeUnterLast(), ghostDriveProbe().

Meilensteine

Zeit / Version Meilenstein
03.08.2026 Projektbeginn (Woche 0 des Versionsschemas)
13.–26.08.2026 Mitschnitte der Original-App; Rahmen, CRC-8, Licht- und Bremsbit, Leitplanken-Modus, Streckencodes, die zwei Lesearten
0.4 Autopilot bei gelber Flagge, ab 0.4.54 auch in der Einführungsrunde; drei Getriebe
0.5 fünf Fahrzeuglayouts, Einspurmodell als Instrument; 0.5.8 ein einziger Sender mit „neuestes Paket merken“
0.6 Leseart als eigener Schalter (0.6.14); Zwei-Spieler-Modus auf einem Gerät (ab 0.6.44)
0.7 Garage, Menüs komplett mit Gamepad, Druckmuster, Strecke aus einer Aufnahme lernen, Binär-/Hex-Trainer
0.8 Menü im Konsolenstil; Android-App (experimentell) mit Bluetooth-Brücke, Host ohne PC und Updates ohne Neuinstallation; Challenges mit Online-Bestenliste; erste Fassung von OmegaBle (0.8.124)
0.9 OmegaBle neu gebaut (0.9.2), Sicherungsdatei (0.9.6), Drei-Spieler-Modus (0.9.17), Ziellinie aus Byte 15 (0.9.37), Tempo nachgemessen (0.9.39)
0.10 Direktweg in der App und Gamepad direkt (0.10.4), RC-Modus (0.10.5)
1.0 (ab 12.10.2026) neues Versionsschema; Ghosts heißen NPCs; Meisterschaft; Fahrgefühle Omega und RC; „Bestzeit“ heißt Time Attack
1.1 (ab 19.10.2026) Virtuelles Fahren (WIP), Studie (heute OmegaLab), NPC-Stufe MAX, automatische Aufstellung, Funklast mit mehreren NPCs verringert, stabiler Funkweg-Rückfall
1.2 (ab 26.10.2026) sauberes Trennen von Bluetooth-Verbindungen (1.2.3), Renntypen je Leseart und Fahrgefühl je Spieler (1.2.4), schnellerer Streckenscan (1.2.5), Karten-Autos als Silhouetten (1.2.9)

Beispiele

Die Versionsnummer 1.2.9

  1. Heute ist Montag, 26.10.2026; der Montag der laufenden Woche ist also der 26.10.
  2. Tage seit dem 03.08.2026: 84. Woche = 84 ÷ 7 = 12.
  3. Woche 12 ≥ 10, also Schema 1.(12 − 10) = 1.2.
  4. Push = Zahl der Commits seit Montag 00:00 plus eins (für den 26.10. ist kein Versatz eingetragen). 1.2.9 ist damit die neunte Nummer dieser Woche; welche Commits genau mitgezählt wurden, hängt an der Historie zum Zeitpunkt des Pushs (zusammengefasste oder automatisch erzeugte Commits zählen mit).
  5. Ergebnis: 1.2.9. Der versionCode einer APK dieser Fassung wäre 1 × 100 000 + 2 × 1000 + 9 = 102 009.

Was eine Aktualisierung lädt

Angenommen, zwischen zwei Fassungen hat sich nur index.html (rund 6,6 MB) geändert und alle übrigen 637 Dateien (Klänge, Bilder, Symbole) haben dieselbe Prüfsumme. pruefen meldet dann „1 Datei, 6,6 MB“, und laden kopiert 637 Dateien aus der laufenden Fassung und lädt nur eine. Startet die neue Fassung nicht (etwa wegen eines Syntaxfehlers), fehlt nach 25 s die Bestätigung, und die App schaltet auf die vorige zurück; diese Version wird danach nicht mehr angeboten.

Ein Text in drei Sprachen

Der Optionsname „Funk-Rundlauf“ steht nur deutsch im HTML. In Englisch findet i18nLookup() den Eintrag „Radio round trip“, in Spanisch „Ronda de radio“. Ein neuer Satz ohne Eintrag bleibt in beiden Sprachen deutsch stehen, bis jemand ihn ins Wörterbuch aufnimmt.

Wie viele Pakete im Herzschlag

Ein Rennen mit Spieler 1 und vier NPCs: Spieler 1 sendet alle 45 ms, also 22,2 Pakete je Sekunde. Die NPCs teilen sich ein Budget von rund 30 Paketen je Sekunde (jeder etwa alle 128 ms). Zusammen gehen rund 52 Pakete je Sekunde über den Funkadapter, statt rund 110 wie vor 1.1.24 (siehe OmegaBle#Funklast mit mehreren Autos).

Grenzen und bekannte Probleme

Versionsgeschichte

Version Änderung (Auswahl aus den Patchnotes)
0.7 Navigation aufgeräumt, Auto-Verwaltung in der Garage, Info-Seiten als Kacheln
0.8 Android-App (experimentell); Titelseite verlinkt die neueste APK
0.9 alles bleibt gespeichert, Sicherungsdatei in der App; Auswahlfelder als „◀ Wert ▶“
0.9.30 Versionsschema mit festem Projektstart nach Zusammenfassen der Historie
1.0 Versionsschema 1.<Woche>.<Push>; Ghosts heißen NPCs, auch auf Englisch und Spanisch
1.1 Tastatur mit WASD, Testtasten nur im Entwicklermodus; Studie für alle sichtbar
1.2 Studie heißt OmegaLab; Bluetooth sauber trennen; Renntypen je Leseart

Einzelnachweise

  1. ↑ Kommentar „SINGLE WRITER“, src/20-protocol.js.
  2. ↑ Kopfkommentar, tools/build.py.
  3. ↑ version(), tools/bump_version.py.
  4. ↑ tools/sw.js.in; src/91-pwa.js.
  5. ↑ OmegaUpdatePlugin.java; tools/app_update.py; src/97b-app.js.
  6. ↑ SICHERUNG_PRAEFIXE, src/98b-sicherung.js.
  7. ↑ Kommentare zu I18N_EN, i18nLookup(), t(), src/10-ble-explorer.js.
  8. ↑ Kopfkommentar, src/95-selftest.js.

Siehe auch

Quellen im Code