Files
wx_wherigo/LUA_PERSISTENCE.md
2026-02-14 09:47:26 +01:00

165 lines
4.2 KiB
Markdown

# Lua State Persistence / Spielstand-Speicherung
## Übersicht
Der Wherigo Player kann den Lua-State speichern und wiederherstellen, um Spielfortschritte zu sichern.
## Funktionsweise
### Automatisches Speichern
Der Spielstand wird automatisch gespeichert unter:
- **macOS**: `~/Library/Application Support/wxWherigo/<CartridgeName>.save`
- **Windows**: `%APPDATA%\wxWherigo\<CartridgeName>.save`
- **Linux**: `~/.wxWherigo/<CartridgeName>.save`
### Was wird gespeichert?
Die Persistierung speichert:
-**Alle Wherigo-Objekte**: ZCartridge, Zone, ZItem, ZCharacter, ZTask, ZTimer, ZInput, ZMedia
-**Objekt-Properties**: Name, Description, Active, Visible, Container, etc.
-**Globale Variablen**: Alle einfachen Variablen (Strings, Numbers, Booleans)
-**Player-Objekt**: Position, Inventar, etc.
-**Verschachtelte Tabellen**: Rekursive Serialisierung (bis Tiefe 10)
### Was wird NICHT gespeichert?
-**Funktionen**: Lua-Funktionen können nicht serialisiert werden
-**Userdata**: C-Objekte bleiben im Originalzustand
-**Threads/Coroutines**: Werden als `nil` gespeichert
-**Metatables**: Werden nicht persistent gespeichert
## Verwendung im Code
### Spielstand speichern
```cpp
// Automatischer Pfad (empfohlen)
wxGetApp().saveGameState("");
// Eigener Pfad
wxGetApp().saveGameState("/path/to/save.lua");
```
### Spielstand laden
```cpp
// Automatischer Pfad
wxGetApp().loadGameState("");
// Eigener Pfad
wxGetApp().loadGameState("/path/to/save.lua");
```
### Im Spiel
- **Menü → Spielstand speichern** (Strg+S)
- **Menü → Spielstand laden** (Strg+L)
## Save-Datei-Format
Die Save-Datei ist eine lesbare Lua-Datei:
```lua
-- Wherigo Save State
return {
["Player"] = {
["ClassName"] = "Player",
["Name"] = "Player",
["ObjectLocation"] = {
["latitude"] = 51.5074,
["longitude"] = -0.1278,
["altitude"] = 0
}
},
["zitemLetter"] = {
["ClassName"] = "ZItem",
["Name"] = "Letter from Professor",
["Active"] = true,
["Visible"] = true,
["Container"] = <reference to Player>
},
-- ... weitere Objekte
}
```
## Technische Details
### Serialisierung
Die Implementierung verwendet:
1. **Rekursives Traversieren** der Lua-Tabellen
2. **Type-Detection** für verschiedene Lua-Typen
3. **Escaping** von Sonderzeichen in Strings
4. **Referenz-Handling** durch Lua selbst beim Laden
### Deserialisierung
1. Save-Datei wird als Lua-Code geladen (`luaL_loadstring`)
2. Ausführung gibt eine Tabelle zurück (`lua_pcall`)
3. Tabellen-Einträge werden als Globals wiederhergestellt
4. UI wird über `notifyStateChanged()` aktualisiert
## Performance
- **Speichern**: ~10-100ms für typische Cartridges
- **Laden**: ~20-200ms (inkl. Lua-Parsing)
- **Dateigröße**: ~10-500KB (abhängig von Cartridge-Komplexität)
## Erweiterungen
### Eigene Filter
```cpp
// Nur bestimmte Globals speichern
std::vector<std::string> myGlobals = {"Player", "zitemKey", "ztaskMain"};
wherigo::LuaPersistence::saveGlobals(L, "custom.save", myGlobals);
```
### Auto-Save beim Beenden
```cpp
// In cGame::OnClose()
wxGetApp().saveGameState(""); // Auto-Save
```
### Mehrere Save-Slots
```cpp
std::string slot1 = wxGetApp().getAutoSavePath() + ".slot1";
std::string slot2 = wxGetApp().getAutoSavePath() + ".slot2";
std::string slot3 = wxGetApp().getAutoSavePath() + ".slot3";
```
## Bekannte Limitierungen
1. **Funktions-Callbacks** werden nicht gespeichert (OnClick, OnEnter, etc.)
- Diese bleiben im Cartridge-Code definiert
2. **Zirkuläre Referenzen** werden bei der Rekursion abgebrochen
- Max. Tiefe: 10 Ebenen
3. **Metatables** gehen verloren
- Nach dem Laden müssen ggf. Metatables neu gesetzt werden
4. **Timer-Status** wird gespeichert, aber `Remaining` muss ggf. neu berechnet werden
## Debugging
Aktiviere Logging um Save/Load zu tracken:
```cpp
wxLogDebug("Saved %zu globals to %s", globals.size(), filePath);
wxLogDebug("Restored %d globals from %s", count, filePath);
```
## Zukünftige Erweiterungen
Mögliche Verbesserungen:
- [ ] Kompression der Save-Dateien (zlib)
- [ ] Verschlüsselung (verhindert Cheating)
- [ ] Delta-Saves (nur Änderungen speichern)
- [ ] Cloud-Sync Integration
- [ ] Automatisches Backup (3 neueste Saves)