Source-Portierung von Forgotten Saga (koreanisches DOS-RPG von 1997)
Motivation
- Vor 30 Jahren war das erste Paketspiel, das ich in der Grundschule gekauft habe, Forgotten Saga
- Mein erstes RPG überhaupt, in das ich ganz natürlich tief eingetaucht bin
- Nach mehr als 20 Jahren hatte ich es schon fast vergessen und erfuhr dann, dass es noch immer von vielen Leuten gespielt wird
- „Lässt sich daraus nicht ein Multiplattform-Spiel machen?“
- Übrig waren nur die PE32-Executable von 1997 und die Datendateien (natürlich ohne Sourcecode)
Vorgehensweise
- Es gibt im Wesentlichen zwei Wege, das Originalspiel zu reproduzieren
- Spezifikationsbasierte Neuinterpretation — das Gameplay beobachten und etwas Ähnliches neu erstellen
- Originalgetreue Wiederherstellung auf Funktionsebene — den dekompilierten Code direkt portieren
- Ich habe mich für Letzteres entschieden, um nicht auf Vermutungen, sondern auf verifiziertem Originalverhalten aufzubauen
- Das Original basiert auf MSVC für Windows von 1997
Was analysiert wurde
Dekompilierung des Original-Binarys
- Verarbeitung der PE32-Datei mit Ghidra 12. 937 Funktionen wurden zu 100 % erfolgreich dekompiliert
- 51.799 Zeilen Pseudocode in C
Reverse Engineering der Datenformate (48 Typen, alle verifiziert)
- LZSS — Standard + FAM-Variante (ring init
0x00, andere Bit-Anordnung von ref_offset)
- SPB — 256 Farben + RLE, 1.155 Bilder
- MOB — Charakter-/NPC-Animationen mit 2.699 Frames.
0xA4-Header + RLE-Pixel + Frame-Stride 20B
- SCP — Bytecode-VM, 128+ Opcodes, 6.026 Einträge, 43.036 Dialogzeilen
- FAM — 292 Karten, 5 Layer (base / overlay / collision / ...)
- DAT — CHAR / ITEM 290 Typen / MAGIC / ABILITY / MONSTER
- SAV — Actor-Struct
0x2A4 (676B), Party + Inventar + globale Variablen
Direkte Verifikation von Nutzereingaben
- Save-Dateien direkt geparst, um die Offsets der Actor-Struct zu verifizieren
- Frühere fehlerhafte Zuordnungen korrigiert (
0x3C ATK→STR, 0x40 INT→TLT usw.)
Was erstellt wurde
- 263 Lua-Dateien, 157.277 Zeilen
- 3.760 Assets
- Desktop-Build mit LÖVE 2D 11.5 + Web-Build mit love.js (emscripten)
- Virtueller Joystick für Mobilgeräte + koreanische IME selbst implementiert
- SharedArrayBuffer aktiviert (COOP/COEP via coi-serviceworker)
- Persistente Speicherung von
sav in IndexedDB (Browser-Umgebung)
- 5 Distributionskanäle — Web / iOS / Android / Windows / macOS
Umfang der Reproduktion
- Titelbildschirm / Charaktererstellung / Feld / Dialog / Shop / Inventar / Ausrüstung / Fallen / DETECT·UNLOCK / Speichern — abgeschlossen
- Kampfsystem — in Arbeit
Einsatz von AI-Tools
- Vor allem die
/goal-Funktion von GPT 5.5, Claude Code als Unterstützung + für Echtzeit-Debugging
Rolle von GPT 5.5 /goal — Analyse der Dekompilierung / fortlaufende Korrekturen
- Automatisierte Analyse von Original-Funktionsclustern / Call Graph / Opcode-Referenzen
- Deep Dives in Datenformate (sav-Format, Actor-Offsets, FAM-Struktur usw.)
- Fortlaufende Korrektur von Mislabels in der anfänglich automatisch dekodierten Fassung (korrigierte Version mit 51.799 Zeilen)
Rolle von Claude Code — Lua-Portierung + sofortiger Verifikationszyklus
- Originalfunktion lesen → nach Lua portieren →
verify.sh-Tests ausführen (100+ Testmodi, 1.000+ Assertions)
- Debugging in der Browser-Umgebung (IDBFS / IME / SharedArrayBuffer usw.)
- Bei Nutzerberichten: Debuggen → Fix → Dev-Deployment → Verifikation → Live-Deployment-Zyklus
Arbeitszeit
Was für ein Ergebnis daraus geworden ist
- Play (Browser): https://forgottensaga-classic.blogspot.com/2026/05/…
- Läuft sowohl auf PC als auch mobil. Auf Mobilgeräten mit selbst implementiertem virtuellem Joystick + koreanischer IME
- Originalgetreue Reproduktion des Gameplays — Z-Sortierung, Palette Cycling, NPC-State-Machine, SCP-VM und anderes Originalverhalten 1:1
Noch keine Kommentare.