Kuiper Ranger: a familiar game and an AI experiment

While I was at Carnegie Mellon in 1988, two friends and I collaborated on writing an AsteroŃ–ds arcade game knock-off. The game, called aster, was written in C and tried to adhere to strict object-oriented rules where every object, even simple ones such as 2D points, had to be accessed exclusively through accessor functions and macros. Back then, math was slow and floating point was unthinkable. It used exclusively fixed-point integer math (16.16), including trig that was implemented using the CORDIC algorithm.

It ran initially on Sun 2 workstations by memory mapping the sunbw black and white bitmap graphics frame buffer and drawing lines using the Bresenham algorithm. Then it ran on the suncg6 color-mapped monitor (8 bits/pixel = “bytemap”), although it still used only black and white, as it still does today. It had some primitive sound effects even at this early stage. Graphics were also very slow, so to move an object the game erased it by redrawing it in black, then redrew it at its new position. Flickering was not visible, as objects were moved quickly enough, one at a time.

Next it was ported to the DECstation 3100 with bytemap. Its MIPS CPU was really fast and the game played very smoothly in real time. It was like night and day. If I recall correctly, Zalman Stern did that.

When I worked at IBM after college, it was ported to a few IBM displays including the IBM RT/PC (AIWS), Megapixel, APA16 on the HFT (“high function terminal”). Some of the platforms even had rudimentary sound, supported by a simple sound API.

By 1993 it had been ported to the X Window system. At that point, all the other raw display implementations were dropped, along with sound support. The X11 support allowed it to run on virtually every relevant Unix-based platform at the time. It was renamed to xaster. Various work continued at random intervals through 1999 when version xaster-1.17 was done. After that, it sat untouched for a quarter century.

In 2025, I decided it would be a good project to use as a vehicle for learning AI technology for software development, with the ultimate goal as having it run in a web browser in an HTML5 canvas. That seemed like a big task, so I broke it down carefully into several steps:

  • Converted to C++17 so it could remain object-oriented while removing the verbose macro accessors and beautifying the code. AI was actually not very helpful for this at all. It couldn’t do seemingly simple tasks like converting function prototypes from K&R style to ANSI. This ended up being a largely manual process, by which time I was questioning the wisdom of doing it. Ultimately, the result was pleasing. While I love C and have used it since I was a teenager, after 40 years of malloc’ing blocks of memory to implement and re-implement basic data structures ad infinitum, I’ll gladly take things like std::vector and std::map.
  • The Plot module and the Input modules always had strictly-defined APIs to abstract graphic drawing and keyboard input. But they really assumed a fixed 4:3 display with static resolution (X11 full screen mode only). I knew it eventually needed to run in a variable-sized window with dynamic resizing. At that point I replaced all the fixed-point arithmetic with floating point, and replaced CORDIC with libm. All object positions are now done assuming a fixed “virtual” window size of 1280.0 x 960.0. Objects are scaled to the actual window size at drawing time. In order to maintain a 4:3 aspect ratio, the drawing area is letterboxed with gray horizontal or vertical borders when needed.
  • Next, I considered sound. The legacy code still had calls to the Sound API spread throughout, so that API just needed to be implemented. AI suggested using the SDL2 library for that. Then something quite incredible happened. I wrote sound.hpp, a header file declaring API function definitions like init(), term(), play a sound specified by an enum (fire, explode, etc), start a continuous sound (thrust, alien) and stop it. Each function had a comment specifying in detail exactly what the API should do. I believe it was Anthropic Claude 4.5 that I was using from vscode when I asked that the API be implemented. Boom! It wrote sound.cpp, complete with waveform generators and a waveform mixer, which compiled without error and the damn thing suddenly had sound! This can’t be what “vibe coding” is, can it? It seems more significant than that.
  • Now, the sounds were kind of crappy. I used AI further to generate better kinds of sounds. For example, I had it create a band-pass filter that I could apply to the output of its noise generator. I had it improve the decaying sinewave sounds and the alien siren sound. The sound was getting pretty respectable!
  • I’m embarrassed to say it was only at this point that I realized SDL2 was actually a complete and popular cross-platform graphics library for gaming, and not just a sound interface. The path became clear instantly. I’d replace all X11 graphics with SDL2, and then the application would run on any Linux, whether X11 or Wayland, plus Windows, macOS, and probably other platforms for almost no effort. Moreover, since SDL2 is fully supported for compilation under the Emscripten tool chain for Web Assembly (WASM), it would theoretically run in an HTML5 canvas in a web browser!
  • But before undertaking all of this, I knew I needed to reorganize the code structure into a typical event-driven game loop. It required refactoring mainly the top level of code into a couple levels of nested state machines. Finally I had an outer loop that looked like:
    while(1) { UpdateGameState; UpdateDisplay; ProcessInputs; }
    where the UpdateDisplay code is expected to regulate the frames-per-second rate.
  • I had AI do most of the conversion to SDL2. It ripped out the X11 code and replaced it with SDL2 code, which unbelievably worked the first time. I’m still reeling over that actually happening. Next, I spent a considerable amount of extra time getting the window resizing and full screen mode that had worked under X11 to work seamlessly under SDL2. I used AI often for hints (RIP StackOverflow). I was delighted to replace that Imakefile with a Makefile, removing the last vestige of the X11 legacy. SDL2 under X11 actually worked better than raw X11 under X11, because SDL2 has vertical sync support. Under X11, there had been some tearing during graphics updates, but SDL2 did not have this problem.
  • Finally, I used hints from AI to get Emscripten working. I had it running in a web browser within maybe an hour. Yet again I was blown away by the existence of such technologies (SDL2 and Emscripten among them) that just work, and the ease of following AI instructions to download it and get it all working.

In vscode, I experienced seeing this: AI ran the build command in the terminal, saw that the Makefile it had generated went into an infinite loop spewing output, recognized the problem, fixed the Makefile, ran the build command again and had it succeed with a binary. The only thing I was doing was pressing an OK button to allow it to run each command. At the rate technology is progressing, it won’t be but a few months before the programmer can be out of the loop entirely. And once it’s able to learn dynamically, it’ll be a full-on programmer. Then it’ll be writing code we can’t even understand, and that’s probably the cusp of the Singularity.

At this point I had visions of publishing these results and decided it might be advisable to rename it so it would be less likely to get a take-down request from the trademark holder. Roid Ranger sounded good to me, but AI advised rather insistently that Roid is too similar. Plus there are already games called that anyway. I had it list 20 possible names, but they were meh. I suggested to it my second idea Kuiper Ranger, and it wrote a two-page essay about how much it loved that and why. So that’s how it got its current name.

I’ll need to update this page as I complete additional phases of this project. These are basically more learning projects below. Then I can wash my hands of this project and maybe use AI for something useful.

  • Packaging it as an RPM for Debian based installers, including desktop icons (done!)
  • Contributing install package to distros like Ubuntu.
  • Testing on Windows & macOS and creating installers for those too. Why not? AI will do the grunt work!
  • Keeping secure high scores for the on-line version. Anti-cheat is quite an undertaking for games that run entirely on client machines. It’s doable, but the only secure method I know of is to have the game log every detail of play (RNG seed, what buttons were down each frame) for the entire game, then send that history up to the server, which then “replays” the game internally at hyperspeed to verify the score. But we know what comes next: someone uses AI to write a super Kuiper Ranger player.

Ok, without further ado, here is as link to the on-line browser version. Be sure to press S to turn on the sound! Also, be sure to use a large window or just press F to go full screen!

Curt
Author

Curt

Leave a Reply

Your email address will not be published. Required fields are marked *