DEV Community

emick
emick

Posted on • Edited on

Cloning a 90s DOS Game with AI

Since I've been running a lot of AI-agent experiments lately, I wanted to see how far I could get building a game just by using prompts alone (aka vibe coding). For this experiment I used OpenAI Codex CLI with the GPT-5.2 Codex model (high thinking mode).

I didn't have a fresh game idea ready, so I decided to clone something small and nostalgic: Paddlers, a 1996 indie DOS game that mixes Arkanoid-like gameplay with four-player chaos. The goal wasn't a perfect 1:1 remake—just something close enough to feel like the original.

Starting Point: Treat the .exe as a Data Container

I wanted to use the original game's levels so I pulled a trick I have used in the past. I gave Codex the original DOS executable (only 80 kB) and let it dig through the executable to find the level data.

Finding the Level Data

AI seems to have a great eye for patterns. I gave a couple of observations as a starting point:

  • There are 10 stages in the game
  • The first stage is a 5×5 grid, centered
  • The full game grid seems to be 11×11 blocks
  • Most stages include sparse patterns (not fully filled)

After ~40 seconds, Codex had already found the level data. Codex’s reasoning summary revealed that the breakthrough came by looking for a contiguous region of low-value bytes that resemble tile IDs. Needless to say, I was already impressed. A likely level region showed up around offset 0x15FEB, and decoding it produced a perfect match for stage 1:

00000000000
00000000000
00000000000
00011111000
00017331000
00013131000
00013371000
00011111000
00000000000
00000000000
00000000000
Enter fullscreen mode Exit fullscreen mode

Level 1 image:

Level 1 screenshot

I was still a little puzzled, since both special blocks had code 7 in the level data. That seemed strange. Nevertheless, I asked Codex to export the levels to files.

Extracting Graphics: AI Being Lazy AND Creative

Next were the block graphics. From observation:

  • blocks appear about 30×30 pixels
  • there's a small 2 px margin between blocks in the grid
  • code 1 is bluish, 3 turquoise/cyan

Codex had some trouble with extracting the graphics and I did not push it much. But it found a creative workaround: it copied the common block graphic from a screenshot I had given to it and figured out that the block colors are exactly the same as EGA color codes (blue = 1, cyan = 3, ...). I would not have noticed that!

So Codex extracted one block and produced recolorings using the EGA palette. It wasn't the "purest" method, but it let me go forward with the game implementation.

Quest for the Game Logic

To replicate mechanics properly, I needed rules: scoring, special blocks, level progression, ball behavior. Since figuring out that by myself sounded like a lot of work I thought I could try to see if I could extract at least some of the logic through decompiling the binary to C code.

I decompiled with both Ghidra and Reko, which resulted in vastly different outputs: one contained "recognizable gameplay logic" (in AI's words, not mine); the other "mostly looked like runtime glue".

To give an impression of what decompiled DOS code feels like:

void FUN_1000_010a(void)

{
  code *pcVar1;
  char cVar2;
  undefined2 in_CX;
  undefined2 extraout_DX;
  undefined1 in_CF;

  pcVar1 = (code *)swi(0x21);
  (*pcVar1)();
  if (!(bool)in_CF) {
    pcVar1 = (code *)swi(0x21);
    (*pcVar1)();
    if (!(bool)in_CF) {
      pcVar1 = (code *)swi(0x1a);
      cVar2 = (*pcVar1)();
      if (cVar2 != '\0') {
        DAT_0000_0470 = 1;
      }
      DAT_256b_0096 = extraout_DX;
      DAT_256b_0098 = in_CX;
      FUN_1000_021c();
      FUN_1000_4881();
      FUN_1000_c388();
      FUN_1000_0260(0x1934);
      return;
    }
  }
  FUN_1000_02a9();
  return;
}
Enter fullscreen mode Exit fullscreen mode

And the rest of it looks just as incomprehensible: unnamed variables, interrupt calls, anonymous functions, and artifacts of 16-bit DOS conventions.

The First Clear Signal: Scoring and Special Blocks

But luckily that "incomprehensible mess" was not so hard for Codex. It managed to cut through and find some of the game logic I was looking for:

I dug through the decompiles; the Ghidra output has the useful gameplay bits. Here's what I can confidently extract from the Ghidra C:

  • Score updates + cap: FUN_1000_5751 adds points to a player and caps the score at 30000, then updates the HUD. paddlers-ghidra.c:4576
  • Block hit scoring: When a block is removed, it always awards +10 points; special blocks can award +100. The block grid is indexed with row * 0xb + col → 11 columns, matching the 11×11 level size. paddlers-ghidra.c:3342 paddlers-ghidra.c:3368
  • Special block IDs: If a block value is > 7, it triggers special behavior; cases 8, 9, 10, 0xb branch to different handlers, with 0xb explicitly giving +100 points. paddlers-ghidra.c:3344 paddlers-ghidra.c:3349
  • Bonus per survivor: Stage-clear bonus is computed as 300 / survivors and awarded to each surviving player. That yields 75/100/150/300 for 4/3/2/1 survivors, matching the readme. paddlers-ghidra.c:3496 paddlers-ghidra.c:3511 paddlers-ghidra.c:3518
  • Stage block counter: DAT_256b_19f0 is decremented on each block removal (likely remaining block count). paddlers-ghidra.c:3363

The Mystery of Block Code 7 Solved

When I extracted the levels, one thing baffled me. Every special block showed up as a 7. That seemed wrong until the decompile and discussion with Codex clarified the design:

  • the level data stores only 0–7
  • 7 is a placeholder that is replaced during level initialization with a random special block

Building the Clone

I initially considered Pygame, but a quick discussion with ChatGPT convinced me that Godot would be a better, more portable option for my case.

Godot Reality Check: Parse Errors and Type Inference

The initial implementation by Codex threw parse errors that stopped scripts from loading:

  • a custom get_rect() collided with Sprite2D native method naming (warnings treated as errors)
  • type inference failed for locals like prev_pos, target, rect, offset, angle, plus later geometry variables like half_len, min_x/max_x, min_y/max_y
  • some inferred values became Variant, which also triggered warnings-as-errors

Codex was able to fix those in one pass. Now the game starts in Godot, but the result was a minor letdown: most of the original game logic was not implemented.

Reconstructing Missing Mechanics

Apparently some of the mechanics were hard to locate in the decompile. So I just asked the Codex to implement those:

  • ball spawns in corners/corner-ish positions aimed toward center
  • players have distinct colors
  • balls spawn neutral gray and don't award points to anyone
  • only after a paddle touch do balls become "owned" and adopt player color
  • lives reset to 3 each level
  • the level ends when all players are dead
  • icon overlays for all specials

Codex got all of it right on the first try.

Result: A Playable Clone

And here's a link to the original Paddlers, which is playable in the browser.

What This Experiment Demonstrated

In one evening and 16 prompts, I extracted all 10 levels, reproduced the core scoring rules, rebuilt several mechanics, approximated the block art, and ended up with a playable clone that feels surprisingly close.

During the process, Codex surprised me three times:

  1. It managed to scrape the levels from raw binary data.
  2. It figured out the blocks were colored using EGA color codes.
  3. It reconstructed the entire scoring logic from decompiled code.

Overall, this suggests that:

  • developing simple games by vibe coding (without looking at the resulting code) is clearly possible, even easy.
  • AI is highly effective at finding structures even inside binaries.
  • Although decompiled code is messy, AI can still pinpoint and extract a lot of game logic from it.

Conclusion

At this point, I felt the experiment was complete. I wasn’t interested in finishing the game further or publishing it, since that would raise obvious copyright issues—and the original is already playable in DosBox and in the browser.

Top comments (1)

Collapse
 
fithappensml profile image
Fit Happens ML

Very nice game! Great job Emick!

Some comments may only be visible to logged-in visitors. Sign in to view all comments.