optimize markdown files
Signed-off-by: Peter Siegmund <mars3142@noreply.mars3142.dev>
This commit is contained in:
@@ -1,64 +1,64 @@
|
||||
# Lua State Persistence / Spielstand-Speicherung
|
||||
# Lua State Persistence / Save Game System
|
||||
|
||||
## Übersicht
|
||||
## Overview
|
||||
|
||||
Der Wherigo Player kann den Lua-State speichern und wiederherstellen, um Spielfortschritte zu sichern.
|
||||
The Wherigo Player can save and restore the Lua state to preserve game progress.
|
||||
|
||||
## Funktionsweise
|
||||
## How It Works
|
||||
|
||||
### Automatisches Speichern
|
||||
### Automatic Save Locations
|
||||
|
||||
Der Spielstand wird automatisch gespeichert unter:
|
||||
Game saves are automatically stored at:
|
||||
- **macOS**: `~/Library/Application Support/wxWherigo/<CartridgeName>.save`
|
||||
- **Windows**: `%APPDATA%\wxWherigo\<CartridgeName>.save`
|
||||
- **Linux**: `~/.wxWherigo/<CartridgeName>.save`
|
||||
|
||||
### Was wird gespeichert?
|
||||
### What is Saved?
|
||||
|
||||
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)
|
||||
Persistence saves:
|
||||
- ✅ **All Wherigo Objects**: ZCartridge, Zone, ZItem, ZCharacter, ZTask, ZTimer, ZInput, ZMedia
|
||||
- ✅ **Object Properties**: Name, Description, Active, Visible, Container, etc.
|
||||
- ✅ **Global Variables**: All simple variables (Strings, Numbers, Booleans)
|
||||
- ✅ **Player Object**: Position, inventory, etc.
|
||||
- ✅ **Nested Tables**: Recursive serialization (up to depth 10)
|
||||
|
||||
### Was wird NICHT gespeichert?
|
||||
### What is NOT Saved?
|
||||
|
||||
- ❌ **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
|
||||
- ❌ **Functions**: Lua functions cannot be serialized
|
||||
- ❌ **Userdata**: C objects remain in original state
|
||||
- ❌ **Threads/Coroutines**: Saved as `nil`
|
||||
- ❌ **Metatables**: Not persisted
|
||||
|
||||
## Verwendung im Code
|
||||
## Usage in Code
|
||||
|
||||
### Spielstand speichern
|
||||
### Save Game State
|
||||
|
||||
```cpp
|
||||
// Automatischer Pfad (empfohlen)
|
||||
// Automatic path (recommended)
|
||||
wxGetApp().saveGameState("");
|
||||
|
||||
// Eigener Pfad
|
||||
// Custom path
|
||||
wxGetApp().saveGameState("/path/to/save.lua");
|
||||
```
|
||||
|
||||
### Spielstand laden
|
||||
### Load Game State
|
||||
|
||||
```cpp
|
||||
// Automatischer Pfad
|
||||
// Automatic path
|
||||
wxGetApp().loadGameState("");
|
||||
|
||||
// Eigener Pfad
|
||||
// Custom path
|
||||
wxGetApp().loadGameState("/path/to/save.lua");
|
||||
```
|
||||
|
||||
### Im Spiel
|
||||
### In-Game
|
||||
|
||||
- **Menü → Spielstand speichern** (Strg+S)
|
||||
- **Menü → Spielstand laden** (Strg+L)
|
||||
- **Menu → Save Game** (Ctrl+S)
|
||||
- **Menu → Load Game** (Ctrl+L)
|
||||
|
||||
## Save-Datei-Format
|
||||
## Save File Format
|
||||
|
||||
Die Save-Datei ist eine lesbare Lua-Datei:
|
||||
The save file is a readable Lua file:
|
||||
|
||||
```lua
|
||||
-- Wherigo Save State
|
||||
@@ -79,51 +79,51 @@ return {
|
||||
["Visible"] = true,
|
||||
["Container"] = <reference to Player>
|
||||
},
|
||||
-- ... weitere Objekte
|
||||
-- ... more objects
|
||||
}
|
||||
```
|
||||
|
||||
## Technische Details
|
||||
## Technical Details
|
||||
|
||||
### Serialisierung
|
||||
### Serialization
|
||||
|
||||
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
|
||||
The implementation uses:
|
||||
1. **Recursive traversal** of Lua tables
|
||||
2. **Type detection** for different Lua types
|
||||
3. **Escaping** of special characters in strings
|
||||
4. **Reference handling** by Lua itself when loading
|
||||
|
||||
### Deserialisierung
|
||||
### Deserialization
|
||||
|
||||
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
|
||||
1. Save file is loaded as Lua code (`luaL_loadstring`)
|
||||
2. Execution returns a table (`lua_pcall`)
|
||||
3. Table entries are restored as globals
|
||||
4. UI is updated via `notifyStateChanged()`
|
||||
|
||||
## Performance
|
||||
|
||||
- **Speichern**: ~10-100ms für typische Cartridges
|
||||
- **Laden**: ~20-200ms (inkl. Lua-Parsing)
|
||||
- **Dateigröße**: ~10-500KB (abhängig von Cartridge-Komplexität)
|
||||
- **Saving**: ~10-100ms for typical cartridges
|
||||
- **Loading**: ~20-200ms (including Lua parsing)
|
||||
- **File size**: ~10-500KB (depends on cartridge complexity)
|
||||
|
||||
## Erweiterungen
|
||||
## Extensions
|
||||
|
||||
### Eigene Filter
|
||||
### Custom Filters
|
||||
|
||||
```cpp
|
||||
// Nur bestimmte Globals speichern
|
||||
// Save only specific globals
|
||||
std::vector<std::string> myGlobals = {"Player", "zitemKey", "ztaskMain"};
|
||||
wherigo::LuaPersistence::saveGlobals(L, "custom.save", myGlobals);
|
||||
```
|
||||
|
||||
### Auto-Save beim Beenden
|
||||
### Auto-Save on Exit
|
||||
|
||||
```cpp
|
||||
// In cGame::OnClose()
|
||||
wxGetApp().saveGameState(""); // Auto-Save
|
||||
wxGetApp().saveGameState(""); // Auto-save
|
||||
```
|
||||
|
||||
### Mehrere Save-Slots
|
||||
### Multiple Save Slots
|
||||
|
||||
```cpp
|
||||
std::string slot1 = wxGetApp().getAutoSavePath() + ".slot1";
|
||||
@@ -131,34 +131,34 @@ std::string slot2 = wxGetApp().getAutoSavePath() + ".slot2";
|
||||
std::string slot3 = wxGetApp().getAutoSavePath() + ".slot3";
|
||||
```
|
||||
|
||||
## Bekannte Limitierungen
|
||||
## Known Limitations
|
||||
|
||||
1. **Funktions-Callbacks** werden nicht gespeichert (OnClick, OnEnter, etc.)
|
||||
- Diese bleiben im Cartridge-Code definiert
|
||||
1. **Function Callbacks** are not saved (OnClick, OnEnter, etc.)
|
||||
- These remain defined in cartridge code
|
||||
|
||||
2. **Zirkuläre Referenzen** werden bei der Rekursion abgebrochen
|
||||
- Max. Tiefe: 10 Ebenen
|
||||
2. **Circular References** are cut off during recursion
|
||||
- Max depth: 10 levels
|
||||
|
||||
3. **Metatables** gehen verloren
|
||||
- Nach dem Laden müssen ggf. Metatables neu gesetzt werden
|
||||
3. **Metatables** are lost
|
||||
- May need to be reset after loading
|
||||
|
||||
4. **Timer-Status** wird gespeichert, aber `Remaining` muss ggf. neu berechnet werden
|
||||
4. **Timer Status** is saved, but `Remaining` may need recalculation
|
||||
|
||||
## Debugging
|
||||
|
||||
Aktiviere Logging um Save/Load zu tracken:
|
||||
Enable logging to trace save/load:
|
||||
|
||||
```cpp
|
||||
wxLogDebug("Saved %zu globals to %s", globals.size(), filePath);
|
||||
wxLogDebug("Restored %d globals from %s", count, filePath);
|
||||
```
|
||||
|
||||
## Zukünftige Erweiterungen
|
||||
## Future Enhancements
|
||||
|
||||
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)
|
||||
Possible improvements:
|
||||
- [ ] Compression of save files (zlib)
|
||||
- [ ] Encryption (prevent cheating)
|
||||
- [ ] Delta saves (only save changes)
|
||||
- [ ] Cloud sync integration
|
||||
- [ ] Automatic backups (keep 3 most recent saves)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user