Commit Graph

32 Commits

Author SHA1 Message Date
Steven Wroblewski d986f2a5db Test: Startzeitpunkt einer dekodierten Aufzeichnung ist festgeschrieben
Recording::from_bytes leitet start_tick aus der gespeicherten Startwelt
ab. Kein Test prüfte das: Setzte ein Fehler start_tick beim Dekodieren
auf 0, blieb er unbemerkt, und eine so dekodierte Aufzeichnung würde
beim erneuten Kodieren oder Verlängern abstürzen.

Der Test a_recording_can_start_in_the_middle_of_a_session kodiert die
Aufzeichnung jetzt, dekodiert sie wieder und prüft, dass sie beim
selben Takt endet und der ursprünglichen gleicht. Mit start_tick = 0
beim Dekodieren schlägt er fehl (Endtakt 70 statt 120).

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-01 13:20:22 +02:00
Steven Wroblewski 8aaeae5cf7 Test: volle Spielerliste mit vielen Offline-Spielern wird geladen
Eine Welt kennt bis zu 16 Spieler, von denen höchstens vier online sind.
Kein Test lud eine Welt mit mehr als vier bekannten Spielern; ein Fehler,
der in check_restorable alle bekannten statt der Online-Spieler zählt,
hätte gültige Spielstände zurückgewiesen und blieb unbemerkt. Mit dem
Koop-Spiel in M1c sind mehr als vier bekannte Spieler der Normalfall.

Der neue Test baut die Welt über Befehle auf: 16 Schlüssel treten in
Vierergruppen bei, jede Gruppe außer der letzten geht wieder, bevor die
nächste kommt. from_snapshot muss dieselbe Welt liefern, load alle Spieler
offline. Mit dem Fehler (alle Spieler gezählt) schlägt der Test mit
Invalid("online players") fehl.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-01 13:19:23 +02:00
Steven Wroblewski fc8d5cb164 Textwächter erkennt gruppierte std-Importe und globale Sperren
Mit `use std::{fs, process};` und anschließendem `fs::remove_file(…)`
kam bisher beides durch: Der Textwächter suchte `std::fs` wörtlich, und
Clippy kennt nur die aufgelisteten Funktionen. Globaler veränderlicher
Zustand über `static` mit Mutex, RwLock, OnceLock oder LazyLock wurde
auch nicht erkannt.

Neu in FORBIDDEN: `std::{` (gruppierte Importe verbergen dem Text die
Modulnamen) sowie Mutex, RwLock, OnceLock und LazyLock. Der Kern in
core/src nutzt nichts davon. Der Kommentar in core/clippy.toml behauptet
jetzt nur noch, was Clippy leistet, und CLAUDE.md nennt die Regel, dass
jeder std-Pfad in einer eigenen use-Zeile steht.

Der bestehende Selbsttest every_forbidden_term_is_detected deckt die
neuen Einträge ab.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-01 13:18:26 +02:00
Steven Wroblewski 842213c574 Spielstand bleibt erhalten, wenn das letzte Umbenennen scheitert
SaveStore.write_save verschob die geprüfte Temporärdatei direkt auf
world.grw. Godot löscht unter Windows ein vorhandenes Ziel, bevor es die
Datei verschiebt. Scheiterte die Verschiebung, zum Beispiel weil ein
Virenscanner world.grw.tmp festhielt, war der vorige Spielstand schon weg.

Jetzt wird der vorige Stand zuerst nach world.grw.bak verschoben, dann
rückt die Temporärdatei nach. Scheitert das, kommt der Stand aus der
Sicherung zurück; nach Erfolg wird die Sicherung gelöscht. Bleibt nach
einem Absturz zwischen den beiden Verschiebungen nur world.grw.bak übrig,
holt SaveStore sie beim Öffnen des Ordners zurück.

Neue Tests: ein offenes Handle auf world.grw.tmp, eine blockierte
Sicherung, die Wiederherstellung aus der Sicherung und dass eine
Sicherung einen vorhandenen Stand nie ersetzt.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-01 13:16:02 +02:00
Steven Wroblewski 68d063209c Startskript, Regeln und Probelauf für M1b
play.bat baut die Brücke und startet das Spiel. CLAUDE.md beschreibt
jetzt Kern, Brücke und Hülle mit allen Prüfbefehlen, die Versionsregel
für festgeschriebene Werte und die Zuschreibung in Commits. Ein
Fragebogen begleitet den ersten Probelauf.

Der erste Godot-Import in einem frischen Checkout stürzt beim Beenden
ab; play.bat wiederholt ihn deshalb einmal.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-10-01 12:26:28 +02:00
Steven Wroblewski 754d7f1e92 Speichern meldet Fehler und schützt unbrauchbare Stände
Lässt sich ein unbrauchbarer Spielstand nicht beiseitelegen, bleibt das
Speichern gesperrt, bis ein Stand erfolgreich geladen wird; so wird er
nie überschrieben. Ein gescheitertes automatisches Speichern zeigt
SAVE_FAILED, und jedes gescheiterte Speichern wird protokolliert.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-10-01 12:15:05 +02:00
Steven Wroblewski 68483c648e Darstellung und Hauptszene
Die Hauptszene verbindet Kern, Karte, Figur, Anzeige und Dateien:
fester Takt, Laufen, Stein schlagen in Reichweite, Speichern mit F5,
Laden mit F9, Pause mit Esc, automatisches Speichern alle zwei Minuten
und beim Schließen. Die Karte erscheint in Platzhalterfarben, bis in
M1d ein Stil gewählt ist. Ein Werkzeug macht Bildschirmfotos ohne
Handarbeit.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-10-01 11:53:51 +02:00
Steven Wroblewski 3761966303 SaveStore prüft jeden Schreibvorgang
Ein Speicherstand ersetzt den vorigen nur noch, wenn er vollständig
geschrieben und zurückgelesen wurde. Ein nicht gespeicherter
Spielerschlüssel wird gemeldet, und set_aside_save meldet, wenn nichts
verschoben wurde.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-10-01 11:42:31 +02:00
Steven Wroblewski ccf9813c80 Texte, Tasten und Dateien
Alle Texte stehen in einer Tabelle mit Deutsch und Englisch, die das
Spiel zur Laufzeit liest. Die Tasten werden in Code angelegt, nach
physischer Position. SaveStore verwaltet den Spielerschlüssel dieser
Installation, schreibt den Speicherstand über eine temporäre Datei,
legt unbrauchbare Stände beiseite und behält die zehn neuesten
Aufzeichnungen.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-10-01 11:26:12 +02:00
Steven Wroblewski 2607df8a97 Takt und Bewegung der Figur
TickClock rechnet Bildzeit in Takte um und holt nach einem Ruckler
höchstens fünf Takte auf. GridMotion bewegt einen Körper über das
Kachelraster und lässt ihn an Wänden entlanggleiten. Die Figur läuft
fünf Felder pro Sekunde, außerhalb des Gleichschritts.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-10-01 11:11:52 +02:00
Steven Wroblewski bd0f588714 Brücke zu Godot und Godot-Projekt
Die GDExtension grovewright-bridge gibt den Kern als Klasse GwSession
an GDScript weiter: Befehle einreihen, einen Takt ausführen, Karte und
Inventar lesen, speichern, laden, aufzeichnen. Eine Panik im Kern macht
die Sitzung defekt, statt einen guten Speicherstand zu überschreiben.
Das Godot-Projekt bekommt einen Testläufer, der auch Laufzeitfehler als
Fehlschlag zählt.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-10-01 10:46:23 +02:00
Steven Wroblewski 5dacbf2222 Aufzeichnung an den Weltschritt koppeln
Recording::step führt einen Takt aus und zeichnet ihn auf. Andere
Befehle als die ausgeführten können so nicht in eine Aufzeichnung
geraten. Aufzeichnung und Welt prüfen gegenseitig ihren Takt, und ein
beschädigter Startzustand fällt schon beim Einlesen auf.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-10-01 10:34:30 +02:00
Steven Wroblewski ef728cd100 Speicherstand mit Prüfsumme und Prüfung beim Laden
Snapshots tragen jetzt eine Prüfsumme (Format 2). Beim Wiederherstellen
werden Zustände abgelehnt, die die Regeln nie erzeugen: zu große Takte,
mehr als vier Spieler online, doppelte Schlüssel, unmögliche
Wartezeiten. World::load ersetzt den öffentlichen Aufruf von
set_all_offline. Die festgeschriebenen Werte sind bewusst angepasst und
um einen Offline-Spieler und das Kartenformat ergänzt.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-10-01 10:17:03 +02:00
Steven Wroblewski 8573a68901 Wächter für den Kern schärfen
Clippy sperrt im Kern Hash-Tabellen, Uhr, Dateien, Threads und
Umgebung über aufgelöste Pfade, auch bei Aliasen und gruppierten
Importen. Der Textwächter kennt globalen veränderlichen Zustand und
Prozesse, prüft sich selbst, und ein neuer Test hält die Abhängigkeiten
des Kerns leer.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-10-01 10:01:11 +02:00
Steven Wroblewski 5be2764276 Umsetzungsplan M1b: Brücke und Hülle
Zweiter von vier Plänen für Meilenstein 1. Acht Tasks härten den Kern
(Wächter, Speicherstand mit Prüfsumme und Prüfung beim Laden,
Aufzeichnung am Weltschritt) und bauen die GDExtension-Brücke sowie die
Godot-Hülle mit Takt, Figur, Karte, Anzeige, Texten, Dateien und
Startskript. Der Code im Plan ist vorab geprüft, jede Task-Grenze
einzeln.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 09:55:14 +02:00
steven f66fbcdfc0 M1a: deterministischer Rust-Kern (#3)
Deterministischer Rust-Kern mit Karte, Spielern, Inventar, Befehlen,
Speicherstand, Prüfsumme sowie Aufzeichnung und Wiederholung. 91 Tests
in Debug und Release, jede Task und der ganze Branch geprüft.

Closes #1

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 06:03:36 +00:00
Steven Wroblewski c75b629dfd Regeln und Konzept an den Stand angleichen
CLAUDE.md: Die Regeln für den Kern gelten für den Quelltext in
core/src/, nicht für die Tests. World::set_all_offline ist als einzige
Ausnahme von der Regel genannt, dass sich die Welt nur durch Befehle
ändert. Die Überlaufregel sagt jetzt, dass Taktzähler normal addiert
werden und Werte aus geladenen Dateien beim Laden geprüft werden. Ein
neuer Absatz erklärt, was bei einem Fehler in golden.rs zu tun ist.

KONZEPT.md: Das Konzept ist bestätigt. Hochladen, Branches, Issues und
Pull Requests sind freigegeben, und die veraltete Angabe, das Archiv
sei noch leer, ist entfernt. Die Reihenfolge der Rückkehrer steht
jetzt bei den Festlegungen statt bei den offenen Punkten.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-09-30 22:18:45 +02:00
Steven Wroblewski 3857fe99a6 Festgeschriebene Werte und Test für überlange Namen
Die neuen Tests in golden.rs vergleichen gegen einmal aufgezeichnete
Werte statt gegen eine zweite Berechnung im selben Build. So fällt
über Builds hinweg auf, wenn sich Regeln oder Formate unbeabsichtigt
ändern: der Startzustand der Welt, das Ende einer festen Befehlsfolge
und die Prüfsumme der Aufzeichnung. Die Fehlermeldung nennt die
Versionskonstante, die dann erhöht werden muss.

Der neue Test in world.rs deckt ab, dass überlange Namen auf beiden
Beitrittswegen gekürzt gespeichert werden: beim ersten Beitritt und
bei der Rückkehr.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-09-30 22:18:35 +02:00
Steven Wroblewski d84c338291 Abnahmetest prüft, dass die Startzahl die Karte formt
Der Vergleich der Prüfsummen allein konnte nicht fehlschlagen, weil die
Startzahl selbst in die Prüfsumme eingeht. Jetzt vergleicht der Test
auch die Karten beider Welten.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-09-30 21:48:42 +02:00
Steven Wroblewski 7aae093f82 Abnahmetests für den Gleichschritt
Fünf Tests prüfen über tausende Takte mit vier Spielern, dass gleiche
Befehle dieselbe Welt ergeben: im direkten Vergleich, nach einem
Snapshot mitten in der Sitzung, beim Wiederholen einer Aufzeichnung
und nach dem Weg über die Kodierung.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-09-30 21:35:44 +02:00
Steven Wroblewski 40bef858f3 Aufzeichnung und Wiederholung von Sitzungen
Eine Aufzeichnung hält den Startzustand und die Befehle jedes Takts
fest. Wiederholen ergibt exakt dieselbe Welt; verify meldet, wenn das
Ende von der aufgezeichneten Prüfsumme abweicht.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-09-30 21:27:36 +02:00
Steven Wroblewski 311516dd0a Snapshot und Zustandsprüfsumme
Der Snapshot enthält den vollständigen Zustand der Welt hinter einem
Kopf mit Format und Version. Er dient als Speicherstand und als
Grundlage der Prüfsumme. Das Konzept ist entsprechend korrigiert: Der
Speicherstand ist der vollständige Zustand, nicht Startzahl plus
Änderungen.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-09-30 21:18:09 +02:00
Steven Wroblewski afc6d9ca77 Welt und ihre Regeln
World::step wendet die Befehle eines Takts der Reihe nach an: Spieler
treten bei und verlassen die Welt, drei Schläge brechen weichen Fels
und bringen einen Stein. Abgelehnte Befehle ändern nichts.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-09-30 21:05:46 +02:00
Steven Wroblewski 7f904b5e1d Spieler und Befehle
Ein Spieler hat eine dauerhafte Kennung, einen Namen, eine
Werkzeugstufe und ein Inventar. Befehle (Beitreten, Verlassen, Graben)
sind der einzige Weg, die Welt zu ändern, und lassen sich kodieren.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-09-30 20:56:51 +02:00
Steven Wroblewski 1a0be06c3b Inventar mit Stapeln
24 Plätze mit je bis zu 99 Gegenständen. Hinzufügen füllt zuerst
vorhandene Stapel und meldet, was nicht passt; Entfernen nimmt alles
oder nichts.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-09-30 20:49:27 +02:00
Steven Wroblewski aae0eccc8b Generator für die Testkarte
Baut aus einer Startzahl eine 64 × 64 Felder große Karte mit Rand aus
Grundgestein, Lichtung am Startpunkt, Felsblock daneben, weichem Fels
innen und hartem Fels außen. Die Regeln sind für 300 Startzahlen geprüft.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-09-30 20:39:47 +02:00
Steven Wroblewski 88d8069f8e Karte aus Kacheln
Gelände mit Grabregeln, Kacheln mit Schaden und eine rechteckige Karte,
die sich kodieren lässt und unmögliche Eingaben ablehnt.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-09-30 20:32:06 +02:00
Steven Wroblewski 4df328243c Prüfsumme und wiederholbarer Zufall
FNV-1a für Zustandsprüfsummen und SplitMix64 als einzige Zufallsquelle
des Kerns. Beide sind gegen veröffentlichte Referenzwerte geprüft.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-09-30 20:24:15 +02:00
Steven Wroblewski 4eed8efed0 Binäre Kodierung für den Kern
Writer und Reader für Befehle, Snapshots und Aufzeichnungen. Beschädigte
Eingaben führen zu einem Fehler statt zu einem Absturz.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 20:17:02 +02:00
Steven Wroblewski 477b9a41dd Gerüst für den Rust-Kern anlegen
Workspace, leeres Crate grovewright-core und ein Wächter-Test, der den
Quelltext des Kerns auf Verstöße gegen die Gleichschritt-Regeln prüft.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 20:08:01 +02:00
Steven Wroblewski fc909f963d Umsetzungsplan M1a: Rust-Kern
Erster von vier Plänen für Meilenstein 1. Elf Tasks bauen den
deterministischen Kern: Kodierung, Prüfsumme, Zufall, Karte, Generator,
Inventar, Spieler, Befehle, Welt, Snapshot, Aufzeichnung und die
Abnahmetests für den Gleichschritt. Der Code im Plan ist vorab geprüft.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 16:10:40 +02:00
Steven Wroblewski 2aad6fd3c3 Spielkonzept hinzufügen
Ergebnis des Konzeptgesprächs vom 30.09.2026: lebendige Fabrik,
Koop im Gleichschritt, Rust-Kern mit GDScript-Hülle, sechs Meilensteine.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 15:47:16 +02:00