Selected work

Case study / 05

Wizball Remake — Legacy C++ Revival

Legacy software recovery and modernisation

Recovered the source of a 2007 C++ game remake and revived it for modern Linux and ARM handhelds, replacing obsolete platform dependencies, hardening runtime behaviour and establishing a modern build and release path with extensive AI-assisted engineering.

Modernisation boundaryPreserve the game · replace the ageing platform layer

The recovered game engine, scripting system and creative content are retained above a modern platform and runtime boundary. That boundary provides SDL2 platform services and feeds an SDL renderer for desktop Linux or a direct OpenGL ES 2.0 renderer for handheld Linux. PhysFS packages shared game data for repeatable desktop, release and PortMaster targets.

Recovered systemGame engine + scripting coreOriginal remake logic · scripts · creative content
Modern platform / runtime boundaryWindow · input · timing · audio · image loading · rendering
SDL2SDL_imageSDL_mixerPhysFS
Desktop LinuxSDL rendererConventional desktop path
ARM handheldsDirect OpenGL ES 2.0PortMaster performance path
data.zipLinux releasesWindows CI packagePortMaster aarch64 + armhf
Modernisation is concentrated around the platform and runtime boundary; the recovered game and scripting core remain the system being carried forward.
Wizball gameplay running through the modern SDL2-based runtime
The recovered 2007 Retrospec remake running through the modern SDL2-based runtime.

01 / Recovery

Recover a codebase from another software era

The original Wizball was released by Sensible Software in 1987. Nearly two decades later, Graham Goring and collaborators created the Retrospec remake for Windows and Mac, with new graphics by Trevor “Smila” Storey and music and arrangements by Infamous, Chris Nunn.

By 2026, the remake’s source appeared to have been lost. After I contacted Graham, he reached out to Peter Hull, who had worked on the Mac conversion. Peter still had a surviving copy, including the Mac-specific project material from that period.

Recovering the files was only the beginning. The archive contained Visual Studio and early Xcode project files, bundled legacy libraries, generated binary data and runtime output. The engine expected Allegro 4, AllegroGL, desktop OpenGL 1.3 and FMOD APIs from the original development period. It also contained Windows, Mac and partial Linux assumptions accumulated across earlier ports.

The first task was therefore investigative: establish what had survived, reconstruct how the engine and data fitted together, and create a working Linux baseline without confusing the 2026 revival with authorship of the original remake.

Preservation included provenance as well as code. The original documentation and contributor credits were retained, and the project history now distinguishes clearly between the 1987 game, the 2006–2007 Retrospec remake and the later recovery work.

02 / Runtime boundary

Replace the platform layer, preserve the game

The modernisation was not approached as a clean-sheet rewrite. The aim was to keep the existing game, scripting system and creative content recognisable while concentrating change around the platform services that had aged out.

Window management, input, timing and rendering were progressively moved behind a new platform boundary. SDL2 replaced the active Allegro runtime, SDL_image took over image loading, and SDL_mixer replaced the legacy FMOD audio path. The old AllegroGL and desktop OpenGL integration was retired from the supported build.

Rendering was split into two targets. A conventional SDL renderer supports the desktop Linux build, while a direct OpenGL ES 2.0 path serves PortMaster and other handheld-style environments. The GLES2 renderer required more than API substitution: draw batching, texture handling, scaling and viewport behaviour had to be adapted until the game reached usable performance on the target hardware.

This boundary also made a later Android experiment possible. The Android branch builds the same native engine through Gradle and the NDK, packages the same game data, uses the GLES2 renderer and adds a touch-control overlay through the SDL activity. It can reach gameplay, but remains prototype work with unresolved lifecycle and memory concerns rather than a completed Android release.

The result is not universal portability, nor a claim of exact behavioural equivalence. It is a substantially more portable runtime architecture that retains the original remake as the system being modernised.

03 / Runtime hardening

Make runtime assumptions visible

A successful compilation did not mean the game was correct.

The recovered code contained assumptions that had been harmless—or at least hidden—on its original platforms. Asset names did not always match their on-disk case. Partial resource loads could leave invalid data for later systems to consume. Tile, collision and scripting paths assumed that indexes and references were valid. Input and simulation behaviour could become coupled to display refresh. A portal failed because its frame-zero state was indistinguishable from an uninitialised value.

Later stages exposed a different class of problem. The first handheld rendering path worked but was too slow to be useful. Release candidates uncovered GLES2 scaling problems. New asset packaging revealed stale-cache behaviour. Save-and-continue required several corrections around restored entities and bonus-stage state. Android testing exposed second-launch crashes, surface lifecycle behaviour and the cost of eagerly decoding long audio streams.

These failures were addressed with more explicit validation, defensive loading, diagnostic logging, a sanitizer-enabled build configuration and repeated testing on the environments that mattered. The purpose was not to suppress every symptom. It was to make enough of the old engine’s implicit contract visible that failures could be understood and corrected.

AI-assisted engineering

Coding agents, including Codex and Claude via GitHub Copilot, were used extensively for scaffolding, migration and repetitive implementation. Their output was treated as a proposed change rather than evidence of correctness. Source review, builds, diagnostics, desktop execution, handheld testing and later release feedback determined whether each change was acceptable.

This distinction matters in legacy work. Agents can move quickly through unfamiliar code, but they cannot replace the engineering judgement required to recognise when a plausible change has altered a load-bearing behaviour.

04 / Delivery

From recovered source to distributable software

Portability extended beyond the executable.

The original project mixed source assets with generated scripts, tile sets, tile maps and historical packfiles. Some release data could only be regenerated by running modes built into the game itself. Those relationships had to become explicit before the project could be built consistently outside its original development environment.

CMake now describes the native build, dependency selection, renderer target and installation layout. The existing data-generation modes can run headlessly, allowing scripts and map data to be rebuilt without opening a game window. Generated output is no longer treated as hand-maintained source.

PhysFS provides a consistent virtual filesystem over a single data.zip. The same package can be mounted by desktop, PortMaster and Android builds, while unpacked files remain available during development. Writable configuration, scores, saves and reports are kept outside the packaged assets.

GitHub Actions builds the game data once and uses it to produce Linux and Windows packages together with PortMaster binaries for both aarch64 and armhf. A separate assembly stage creates the exact launcher, metadata, controller mapping, licence and directory layout expected by PortMaster.

The Windows pipeline demonstrates automated compilation and packaging, but Windows runtime validation has not been established. The strongest completed outcome is the Linux and handheld path: the game runs on modern Linux, reached usable speed on ARM hardware, is available through tagged releases and is now distributed through PortMaster as a ready-to-run port.

What began as an uncertain source-recovery exercise is now a maintained public codebase with an explicit runtime boundary, a defined asset package and a repeatable route from source to release.

05 / Attribution

Provenance and credits

Wizball was originally released in 1987 by Sensible Software, designed by Jon Hare and Chris Yates, with programming by Chris Yates, graphics by Jon Hare and music by Martin Galway.

The 2006–2007 Retrospec remake was programmed by Graham Goring, with graphics by Trevor “Smila” Storey, music and arrangements by Infamous — Chris Nunn — and a Mac conversion by Peter Hull. Scott Wightman contributed the original Linux conversion effort.

This case study covers Craig Chandler’s 2026 recovery and modernisation work. It does not imply authorship of the original game or Retrospec remake.