09 — Save-Schema #10
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Teil der Map #1 · Type:
wayfinder:grilling· Blocked by: #8Was steht in einem Speicherstand, und wie ueberlebt er geaenderte Mods?
Volle Fragestellung (kanonisch):
.scratch/rustkeep-1.0/issues/09-save-schema.mdAufgeloest in
bed9ef5. Kanonische Fassung:.scratch/rustkeep-1.0/issues/09-save-schema.mdDie Etage wird gespeichert, nicht gewuerfelt
#15 hat einen seedbaren Generator geliefert, Regenerieren waere also moeglich. Drei Dinge sprechen dagegen:
cleared, gefallene Gegner, genommene Beute) laesst sich nicht regenerieren und muss ohnehin mit. Der Seed spart also nur das Kachelgitter.Der Seed bleibt im Save, aber fuer kuenftige Wuerfe (#15), nicht zum Regenerieren.
Ein Slot, Permadeath
Autosave beim Betreten einer Etage und beim Beenden. Kein manuelles Speichern: es braechte nur die Wahl des Zeitpunkts, und die hat #15 mit dem Seed bereits abgeraeumt. Mehrere Slots waeren eine Verwaltungsansicht fuer ein Spiel mit einem Helden.
Speichern im Kampf erlaubt (passiert beim Beenden ohnehin, Kampfzustand faellt bei serde-Ableitung gratis mit ab). Bei Tod wird geloescht — aber erst beim Erscheinen des
GameOver-Screens, nicht beim Fallen der Lebenspunkte. Stuerzt das Spiel dazwischen ab, ist der letzte Autosave noch da.Der Save ist der
Game-Baum#[derive(Serialize, Deserialize)]durchgehend, mit einer handgeschriebenen Ausnahme: dem Kachelgitter als ASCII-Zeilen statt eines Arrays mit 3200 Eintraegen. Eigene Save-Structs hiessen, jede Struktur zweimal zu pflegen — das Duplikat, das genau dann auseinanderlaeuft, wenn es niemand merkt.Bewusst kein
floor/turnim Header — der Baum serialisiert beide ein paar Zeilen weiter unten, und einen Speicherstand-Browser gibt es bei einem Slot nicht.Bei abweichender
schema: ablehnen mit Klartextmeldung, Datei bleibt liegen. Migration zu schreiben, bevor ein einziger Speicherstand ausgeliefert wurde, ist Code fuer ein Problem, das niemand hat; Best-Effort auf strukturell anderem Schema erzeugt stille Verfaelschung statt eines Fehlers. Und eine Datei zu loeschen, weil man sie nicht lesen kann, waere die schlechteste aller Reaktionen.Fehlende Mods: verwerfen, nie ablehnen
Ein Spieler soll nicht seinen ganzen Lauf verlieren, weil er einen Mod deinstalliert hat.
Die Mod-Version wird verglichen und protokolliert, mehr nicht. Verschwundene IDs fangen die Regeln oben ab, geaenderte Werte gelten einfach. Der Vergleich leistet reine Diagnose — eine Zeile "
meinmod1.0.0 -> 1.2.0 seit dem Speichern", die genau dann Gold wert ist, wenn jemand meldet "mein Spielstand ist seit dem Update kaputt". Das ist die ehrliche Bilanz desversion-Felds aus #4.Warnungen gehen in dieselbe Sitzungsdatei wie der Mod-Ladelauf (zwei Dateinamensmuster hiessen zwei Rotationsregeln), plus eine Rueckfrage vor dem Betreten des Spiels: "12 Eintraege fehlen. Fortfahren?" Das weicht bewusst von #5s Regel "eine Zeile, kein Screen" ab — der Spieler will an dieser Stelle vielleicht den fehlenden Mod nachinstallieren statt weiterzuspielen, und diese Wahl hat er nur vorher.
Atomar schreiben
data_dir()/rustkeep/save.toml, geschrieben nachsave.toml.tmpund perfs::renamedarueberzogen — das ersetzt die Zieldatei auf Windows 10 1607+ wie auf Unix (gegen die std-Doku geprueft).Die eine Stelle in diesem Ticket, an der bewusst nicht lazy entschieden wurde. Der Autosave ueberschreibt den einzigen Speicherstand, den es gibt; bricht das Schreiben ab, ist ein Lauf von einer Stunde weg. Zwei Zeilen, und es liegt entweder die alte Datei da oder die neue, nie eine halbe.
Gold braucht kein eigenes Feld — es ist seit #2 ein stapelbarer Gegenstand und liegt im Inventar.
Zwei Nachtraege
core:attackundcore:fleesind jedem Wesen implizit gewaehrt. Faehigkeiten kamen bisher ausschliesslich von Charakteroptionen und Gegenstaenden — ein Held ohne Klasse und ohne Waffe haette gar keine und koennte nicht einmal angreifen. Keine Sonderregel fuer den Ladefall: es trifft auch jeden Gegner ohneabilities-Eintrag, vor dessen leerer Liste die KI aus #15 stuende.Confirm { text, on_yes: Box<Response> }statton_yes: Command. Die Rueckfrage beim Laden braucht keinen Command, sondern einen Screen-Wechsel;Response::Commandist bereits eine Variante, der Sonderfall entfaellt ersatzlos und die Struktur wird dabei kleiner.