De voortgang van frontier-modellen analyseren aan de hand van mijn favoriete spel: Prince of Persia (Apple II, 1989) door Jordan Mechner

In 2012 publiceerde Jordan Mechner de originele Apple II 6502 assembly-broncode, die was hersteld van 3,5" floppy disks die meer dan 20 jaar in een doos hadden gelegen (het herstelproces op zich is al een heel verhaal): github.com/jmechner/Prince-of-Persia-Apple-II.

Omdat C# mijn favoriete taal is, stelde ik mezelf een experiment op. Ik zou deze broncode aan een AI-model geven en het model vragen om het spel te porten naar C#. Ik zou de code niet zelf lezen of bewerken. Mijn enige taak was om het resultaat te spelen en aan te geven wat er mis was. Elk nieuw frontier-model dat uitkwam, kreeg hetzelfde project, waarbij ik enkel prompts gebruikte.

De broncode is te vinden op: https://github.com/priyanr/PrinceOfPersiaC-SharpPortByAI

Dit is hoe het verliep.

Ronde 1 — Claude Opus 4.6 (februari 2026)

Mijn eerste prompt was simpel: "in this original code there 6502 assembly code for prince of persia, use the save level files and try to do it in c# console."

In twee dagen tijd produceerde Opus 4.6 een C# console-game, daarna een level-editor en vervolgens een versie met Raylib-graphics. Het model parseerde de originele level-bestanden correct: kamers, tegels, poorten en posities van bewakers. Het renderde zelfs iets dat leek op het Apple II-spel.

Maar het speelde niet als Prince of Persia. Mijn prompts uit die tijd vertellen het verhaal:

  • "het is slecht, ik kan het niet spelen, de graphics zijn in de war"
  • "nu komt het personage wel, maar de beweging is helemaal fout ... de prins staat niet op de vloer"
  • "nu is hij door de vloer gezakt en de pijltjestoetsen bewegen hem niet"

Het kernprobleem was, zoals ik later leerde, de architectuur. De prins bewoog per tegel, waarbij hij van cel naar cel sprong. Het echte spel gebruikt handgetekende animatieframes met een kleine beweging per frame.

Ronde 2 — OpenAI Codex (maart 2026)

Ik probeerde ook Codex, hoewel ik ben vergeten welk specifiek model dit was. Ik gaf het dezelfde codebase: "this is prince of persia original assembly code to c# port done by claude still graphics not good can you fix it."

Het model voerde zinvolle kleine correcties door: scherpe pixel-filtering zodat de art niet wazig was, transparante achtergronden voor sprites, poorten die openstonden zodat je erdoorheen kon lopen, en pilaren die niet langer als muren fungeerden. De prins belandde echter nog steeds in verkeerde posities en liep nog steeds vast. Het poetste de oppervlakte op, maar de onderliggende engine was nog steeds onjuist.

Ronde 3 — Claude Opus 5 (september 2026)

Hier veranderde ik de regels een beetje. Ik schreef twee 'Claude Code'-skills: één die DOSBox aanstuurt (een programma starten, toetsen verzenden, screenshots maken) en één die elk Windows-programma aanstuurt. Vervolgens richtte ik Opus 5 op mijn originele DOS-kopie van Prince of Persia en zei: "vergelijk dit met het echte werk, en ga door tot je slaagt of tot 6 uur 's ochtends."

Het model werkte de hele nacht door en het eerste wat het deed was het architectuurprobleem diagnosticeren. De oude engine was een tile-grid engine, terwijl het echte spel wordt aangestuurd door frame-sequenties. Daarom herbouwde het model de engine op basis van het originele ontwerp.

Daarna ging het model verder dan ik had verwacht. Het ontcijferde de formaten van de DOS-spelbestanden en las de echte data rechtstreeks uit: elk animatieframe van de prins, de dungeon-art en alle 15 levels. Het vond de originele animatietabellen in PRINCE.EXE door te zoeken naar byte-patronen die het herkende uit de Apple II-broncode, en bevestigde elke tabel aan de hand van een tweede bekende waarde voordat het deze accepteerde. Geen van de auteursrechtelijk beschermde gegevens van het spel kwamen in mijn repository terecht; het C#-programma leest deze live uit mijn eigen DOS-installatie.

's Ochtends had ik iets dat speelbaar was. De prins viel naar binnen, landde, draaide, rende, sprong, viel door een gat en hurkte bij de landing, allemaal met de echte animaties. In een tweede sessie speelde ik de eerste schermen in DOSBox terwijl het model mijn screenshots bekeek. Het vond een bug in de manier waarop richels werden gedetecteerd: het zocht naar een richel in de verkeerde cel. Dit werd opgelost door terug te grijpen naar de originele assembly-routine.

De levels zagen er echter nog steeds niet goed uit. De bakstenen, de poorten en de decoraties waren allemaal net niet correct. Opus 5 had elk onderdeel geplaatst door het te matchen met screenshots, stuk voor stuk, en alles wat het niet kon verklaren, vulde het in met gissingen.

Ronde 4 — Claude Opus 5.5 (september 2026): één prompt

Toen Opus 5.5 uitkwam, gaf ik het een enkele prompt: "the character moves runs jumps but gate positions bricks all different, you are new model let see anything u can improve."

Het model koos een volledig andere aanpak. In plaats van posities op het oog af te stellen, zocht het naar de originele routine voor het tekenen van kamers, zoals gedocumenteerd in SDLPoP door Dávid Nagy en de princed.org-community (een open-source port van het DOS-spel gereconstrueerd vanuit disassembly). Het portte deze routine. Het resultaat, DosRoomDrawer.cs, is een directe C#-port van de room-drawing code van SDLPoP (src/seg008.c), wat ook in de header van het bestand staat.

De documentatie van SDLPoP legde uit waar eerdere sessies slechts over konden gissen:

  • Het "willekeurige" baksteenpatroon is helemaal niet willekeurig. De originele game seedt de random number generator op basis van de kamer, rij en kolom, waardoor elke muur er bij elk bezoek hetzelfde uitziet.
  • De poort aan het begin van level 1 staat in de level-data eigenlijk open. Het originele spel drukt op een verborgen knop zodra je naar binnen valt, wat verklaart waarom je de poort hoort dichtslaan.

Opus 5.5 ontdekte daarnaast enkele zaken zelf door mijn bestanden en het echte spel te controleren:

  • PRINCE.EXE is eigenlijk gecomprimeerd (Microsoft EXEPACK). De eerdere tabellen hadden alleen gewerkt omdat ze toevallig in een gedeelte zaten dat de packer ongemoeid had gelaten. Het model schreef een unpacker en las de tile-drawing tabellen uit mijn eigen kopie van het executable-bestand.
  • De screenshot-crop die in eerdere sessies werd gebruikt, week één pixelrij af, en een eerdere theorie over "stencil-kleuren" was onjuist. Die kleuren zijn de echte teal-kleur van de uitgangsdeur.

Vervolgens controleerde het zijn werk pixel voor pixel tegen het echte spel in DOSBox. Op het eerste scherm van level 1 ging het aantal pixels dat afweek van het origineel van 8.429 naar 2 (een vlam van een fakkel die op een ander moment werd vastgelegd). De tweede kamer en de uitgangsdeur op level 3 kwamen ook exact overeen.

Het was niet foutloos. Het veranderde ook waar de sprite van de prins wordt getekend op basis van de originele code, maar had dit alleen geverifieerd terwijl hij één kant op keek. Wanneer hij de andere kant op keek, zakte hij een paar pixels in de muren. Ik merkte dat er iets mis was en gaf het model mijn backup van vóór de wijzigingen. Het model bewees dat de beweging zelf identiek was in alle test-ticks, vond het sprite-probleem en draaide alleen dat specifieke deel terug. Deze zelfcontrole is ook een teken van vooruitgang.

Voor het eerst zagen de levels eruit als Prince of Persia.

Wat ik hiervan heb geleerd

  • Opus 4.6: Kon 6502 lezen en C# schrijven, maar koos de verkeerde architectuur en kon dat zelf niet herkennen.
  • Codex (maart 2026): Goed in kleine correcties, maar stelde de basis niet ter discussie en heeft het spel nooit zelf gedraaid.
  • Opus 5: Met tools om het echte spel te zien, diagnosticeerde het de architectuur, herbouwde deze en haalde de echte data uit de originele bestanden. Dit was de eerste speelbare versie.
  • Opus 5.5: Ging vanuit één prompt op zoek naar hoe het origineel het daadwerkelijk deed in plaats van te approximeren, en bewees het resultaat pixel voor pixel. Eerlijk gezegd was de sleutel tot de laatste sessie kennis die al bestond: de room-drawing routine die Dávid Nagy en de SDLPoP-community hadden gedocumenteerd door jaren van reverse-engineering. Opus 5.5 wist waar het moest zoeken, portte het en verifieerde het.

Ik weet niet zeker of het dit allemaal alleen vanuit het DOS-binary had kunnen uitzoeken. Toen ik het vroeg, antwoordde het model: "Eerlijk gezegd, waarschijnlijk niet in één prompt. Ik heb de drawing-code niet zelf gereversed. Ik heb de reconstructie van SDLPoP gelezen en geport. Ik vond de tabellen in PRINCE.EXE alleen omdat SDLPoP me vertelde wat de inhoud ervan was. Het vorige model zocht in het executable zonder die sleutel en vond niets. Zonder SDLPoP had ik de 16-bit x86 drawing-code zelf moeten disassembleren. Dat is in principe mogelijk, en er waren al aanwijzingen: de observatie dat decoratie één cel naar rechts staat, en dat de random-number constanten van Microsoft C zijn. Maar het is een veel langere klus, en ik verwacht dat het vele sessies van disassembly en controle tegen DOSBox zou kosten, niet één prompt. Wat ik wel meebrengde, was de kennis dat SDLPoP bestond, het correct lezen ervan, het opmerken dat de EXE gecomprimeerd was, en het resultaat pixel voor pixel bewijzen."

De grootste sprong zat hem niet alleen in het feit dat de modellen slimmer werden. Het kwam voort uit het geven van een manier om het origineel te zien en zichzelf daaraan te testen. Vanaf Opus 5 kon het model zijn eigen werk controleren, waardoor ik niet langer de enige tester was.

Er is nog veel te doen: bewakers en zwaardvechten, de palevels en de exacte landingsposities van de prins. Ik zal hetzelfde experiment uitvoeren met het volgende model en kijken hoe ver het komt.

De code, inclusief de volledige geschiedenis van elke sessie, staat op GitHub: github.com/priyanr/PrinceOfPersiaC-SharpPortByAI

Credits

Dit experiment bouwt voort op decennia aan werk van mensen die dit spel net zoveel liefhebben als ik:

  • Jordan Mechner, voor het maken van Prince of Persia en het publiceren van de originele Apple II-broncode: github.com/jmechner/Prince-of-Persia-Apple-II
  • Dávid Nagy en de princed.org-community, voor SDLPoP, de open-source port van het DOS-spel gereconstrueerd vanuit disassembly: github.com/NagyD/SDLPoP.

Het bestand dat mijn kamers pixel-exact maakt, POPGame/Rendering/DosRoomDrawer.cs, is een C#-port van de room-drawing code van SDLPoP (src/seg008.c), en bevat de volgende melding: "This file is a C# port of the room-drawing code of SDLPoP (src/seg008.c), https://github.com/NagyD/SDLPoP — 'SDLPoP, a port/conversion of the DOS game Prince of Persia. Copyright (C) 2013-2025 Dávid Nagy', licensed under the GNU General Public License, version 3 or (at your option) any later version. Modified 2026: translated to C#, restructured to emit placement lists for a framebuffer renderer, and driven by tables read from the player's PRINCE.EXE. This file, like the rest of POPCS, is distributed under the GNU GPL v3 or later."

Vanwege dit feit is mijn gehele project uitgebracht onder dezelfde licentie, GPL-3.0-or-later.

  • Fabien Sanglard, wiens code-review van Prince of Persia de beste begeleide tour is door de originele broncode: fabiensanglard.net/princeofpersia

Er zijn geen originele spelgegevens opgenomen in mijn project. De C#-code leest alles tijdens runtime uit mijn eigen kopie van het DOS-spel. Dit is een non-commercieel fanproject, niet gelieerd aan of onderschreven door Ubisoft of Jordan Mechner. Prince of Persia is een handelsmerk van Ubisoft Entertainment.