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.

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
- OmegaSim in Chrome oder Edge öffnen (Link auf der Hauptseite) oder
index.htmlvon der Festplatte starten. - Auf dem Titelbildschirm Starten wählen; Tutorial führt durch die ersten Schritte, Steuerung zeigt die Tastenbelegung.
- FAHREN → Autos: Auto verbinden (für jedes Auto ein Klick im Auswahlfenster des Browsers).
- FAHREN → Strecke: Leseart wählen (Auf der Bahn / Ausdruck), Strecke scannen oder im Editor bauen (siehe Strecke, Strecken- und Raum-Editor).
- FAHREN → Rennoptionen: Renntyp wählen (siehe Rennarten), dann Rennen starten.
- Gefahren wird im Cockpit mit Drehzahl, Gang, Rundenzeiten und Zustand des Autos.
- 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
- Die APK von der Titelseite der Browserfassung herunterladen und installieren („Unbekannte Quellen“ für den Browser erlauben).
- Die App fragt beim Start nach Updates (Optionen → App & Updates); eine neue APK ist nur nötig, wenn die App das meldet.
- Autos verbinden wie im Browser; bekannte Autos verbindet die App beim Start selbst.
- Daten liegen zusätzlich in einer Sicherungsdatei in Dokumente/OmegaSim.
Navigation
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
- Alle Dateien in
src/mit Endung.jsoder.htmlalphabetisch sortieren. - Byte für Byte aneinanderhängen, ohne Trenner: Das Ergebnis ist
index.html. - Prüfen: Klammern zählen (außerhalb von Zeichenketten und Kommentaren), doppelte IDs, lokale Verweise auf fehlende Dateien, Wörterbuch.
sw.jsaustools/sw.js.inschreiben und dabei die Version in den Cachenamen einsetzen; fehlt die Platzhalterzeile, bricht der Bau ab.app-update.jsonschreiben (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
- +1: Die Nummer gilt für den Commit, der gerade entsteht.
- PUSH_VERSATZ: Wurde die Historie zusammengefasst (Force-Push), fehlen Commits; der Versatz gibt sie dem Zähler zurück (Wochen ab 05.10.: 27, ab 12.10.: 23, ab 19.10.: 2).
- Die Woche beginnt am Montag, nicht am Wochentag des ersten Commits; früher sprang die Wochenzahl deshalb an einem Freitag.
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:
- 3 s nach dem Start fragt
97b-app.jsstillpruefen. Ist die Version nicht neuer als die laufende, passiert nichts. Eine Fassung, die schon einmal zurückgerollt wurde, wird nicht erneut angeboten. - 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. - Sonst zeigt die App „Update verfügbar: Version (Größe)“. Ein Tipp auf „Jetzt laden“ startet
laden. ladenlegt einen neuen Ordnerfiles/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.- 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 bleibthttps://localhost, also bleiben alle Einstellungen inlocalStorageerhalten. - 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 dasbeimStart()beim nächsten Öffnen, noch bevor die Seite lädt. - 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 |
- Umfang und Sonderfälle werden vor dem Löschen angezeigt und nochmals bestätigt. Falls durch eine Auto-Löschung keine Teilnehmer übrigbleiben, wird die Sitzung entfernt.
- Beim Löschen von Spieler 1 werden auch seine sitzungsweiten Kilometer, Fahrstil- und Strafdaten entfernt; bei NPC-Löschung bleiben diese Spielerwerte erhalten.
- Beide Ansichten (Statistiken und die Sitzungsliste in Renneinstellungen) sowie CSV-Exports verwenden danach die bereinigte Statistikablage.
- Bereinigung und Undo sind im laufenden Rennen/Training oder virtuellen Fahren gesperrt.
- Zu kurze Runden: Strecke über ihren Code; Drehung und gespiegeltes Layout gehören wie bei den Bestzeiten zur gleichen Strecke. Rundenanzahl und betroffene Fahrzeugrekorde werden korrigiert; Kilometer, Sitzungsanzahl und Kilometerbuchungen bleiben bewusst unverändert. Zusätzlich werden zu kurze lokale Time-Attack-Bestzeiten samt Medaille zurückgesetzt; lokale Telemetrie-Einträge unter dem Grenzwert werden entfernt.
- Nach jeder Bereinigung und nach Rückgängig werden Auswahl- und Statistiklisten sofort neu aufgebaut; der Bereich bleibt aufgeklappt.
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.
- Selbsttest „Statistikbereinigung v1.2.15“ in
src/95-selftest.js.
Sprachen (i18n)
Übersetzt wird mit dem deutschen Text als Schlüssel[7]:
- Zwei Wörterbücher:
I18N_EN(Deutsch → Englisch, rund 3000 Einträge) undI18N_ES(Deutsch → Spanisch, rund 1100 Einträge). - 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 einerWeakMapgemerkt, damit der Weg zurück nach Deutsch exakt ist. - Ein Beobachter (
MutationObserver) übersetzt jeden später eingefügten Knoten. - Text, der im Code entsteht, läuft durch
t(deutsch), dieselbe Tabelle. - 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.
- Nicht übersetzt werden
script,style,code,kbd, alles mitdata-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]:
- Jede Zeile nennt ihr Maß, nicht nur „grün“ oder „rot“, damit man sieht, wie knapp es war.
- „nicht prüfbar“ ist ein eigenes Ergebnis und kein Fehler (etwa Tonschleifen über
file://). - 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
- Heute ist Montag, 26.10.2026; der Montag der laufenden Woche ist also der 26.10.
- Tage seit dem 03.08.2026: 84. Woche = 84 ÷ 7 = 12.
- Woche 12 ≥ 10, also Schema 1.(12 − 10) = 1.2.
- 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).
- Ergebnis: 1.2.9. Der
versionCodeeiner 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
- Web Bluetooth gibt es nur in Chrome und Edge; auf iPhone und iPad kann OmegaSim keine Autos fahren.
- Im Browser verlangt Bluetooth für jedes Auto einen Klick; automatisches Verbinden gibt es nur in der App.
- Ein künftiges Firmware-Update der Autos kann OmegaSim unbrauchbar machen (siehe Firmware).
localStoragekann vom Browser geräumt werden; ohne Sicherungsdatei sind Rundenzeiten und Strecken dann weg.- Die Installation als PWA löst die Mehrspieler-Sperre nicht: Web Bluetooth verlangt einen sicheren Kontext (
https://,localhostoderfile://), und eine Adresse wiehttp://192.168.x.xim WLAN ist keiner (siehe Mehrspieler). - Viele NPCs belasten den Funkadapter; Probleme mit mehreren NPCs sind bisher Funklast (siehe OmegaBle).
- Spanisch ist weniger vollständig als Englisch und fällt dort auf Englisch zurück.
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
- ↑ Kommentar „SINGLE WRITER“,
src/20-protocol.js. - ↑ Kopfkommentar,
tools/build.py. - ↑
version(),tools/bump_version.py. - ↑
tools/sw.js.in;src/91-pwa.js. - ↑
OmegaUpdatePlugin.java;tools/app_update.py;src/97b-app.js. - ↑
SICHERUNG_PRAEFIXE,src/98b-sicherung.js. - ↑ Kommentare zu
I18N_EN,i18nLookup(),t(),src/10-ble-explorer.js. - ↑ Kopfkommentar,
src/95-selftest.js.
Siehe auch
- Aufbau von OmegaSim
- Carrera HYBRID
- Original-App
- OmegaBle
- Firmware
- Fahrverhalten
- Rennarten
- Mehrspieler
- Mitmachen
- Vibe-Coding
- Glossar
Quellen im Code
tools/build.py:pieces(),build(),build_sw(),check_klammern()tools/bump_version.py:version(),PROJEKT_START,PUSH_VERSATZ,VERSION1_WOCHEtools/app_update.py,tools/apk_www.py,tools/sw.js.in,app-update.json.github/workflows/android.ymlandroid-app/…/OmegaUpdatePlugin.java:beimStart(),pruefen(),laden(),wachhund(),bestaetigen(),APK_STUFE,WACHHUND_MSandroid-app/…/OmegaSicherungPlugin.java,MainActivity.javasrc/97b-app.js:appAnbinden(),pruefen()src/98b-sicherung.js:SICHERUNG_PRAEFIXE,SICHERUNG_TYPsrc/98e-statistik.js,src/98ea-statistik-bereinigen.js,src/98eb-statistik-zeiten.js: Statistik, Bereinigung, Zeitbereinigungsrc/15-pause.js,src/98h-pause.js: Rennpausesrc/80c-rennstand.js,src/80d-rennintro.js: Rennstand-Ansage und Rennintrosrc/10-ble-explorer.js:I18N_EN,I18N_ES,i18nApply(),setLang(),t()src/95-selftest.js:stAdd(),ST_TESTS;src/93-testbench.js:OMEGA_TESTsrc/20-protocol.js:controlHeartbeat(),CONTROL_SEND_INTERVAL_MSsrc/91-pwa.js
Weblinks
- Browserfassung, Android-App und Quellcode: Links auf der Hauptseite