blog

Getting Mercenaries Building and Running on Windows

Mar 4, 2026 | gamedev, porting

I first played—and loved—Mercenaries: Playground of Destruction when I was eight years old. As a fan, I kept following the game and held out hope that it might eventually receive a native Windows release or a remaster. That release never came: Pandemic Studios closed, and LucasArts later stopped developing games in-house. Eventually, as seems to happen with so many projects in the modern era, a source-code and asset leak surfaced online and offered an unexpected look inside the game I had grown up with.

Mercenaries: Playground of Destruction was built around the original Xbox, its SDK, and a Visual Studio 2003-era toolchain. The recovered source was valuable, but it was not something that could simply be opened in a current version of Visual Studio and compiled. The first goal of my Windows work was deliberately narrower than a complete port: produce a native executable, enter the original game loop, render the real frontend, and accept input on a modern Windows machine.

The Mercenaries main menu running on the original Xbox version
The original Xbox frontend—the destination for the first native Windows bring-up.

Building a modern project around an old codebase

The original project files were kept as useful documentation, but CMake became the authoritative build system. I set up a Win32/x86 build for Visual Studio 2022 and divided the source into the same broad layers used by the game: Pebble for low-level platform services, RedEngine for rendering and resources, and RetroStrike for the game itself. Keeping those layers separate made it possible to bring up and test one part of the stack at a time instead of confronting one enormous linker failure.

The earliest target was intentionally tiny. It proved that the compiler, architecture, include paths, and runtime flags were correct before any original engine code was introduced. From there, small smoke programs were added for Pebble, Havok, and RedEngine. Each one had to compile and exit cleanly in both Debug and Release before the next layer was connected.

Replacing the Xbox platform layer

Much of the game code was portable C++, but its foundations assumed Xbox APIs and an older Microsoft compiler. The Windows build needed native replacements for file access, logging, timing, controller polling, rumble, and several math and memory helpers. It also needed conservative compiler settings for Windows-1252 source, old language behavior, and code that predates modern MSVC.

Input was routed through XInput so the original controller-facing game code could remain in place, with keyboard and mouse added as a fallback for development. File requests were adapted in a similar way: the Windows runtime identifies itself as a PC build, while a compatibility layer resolves the unchanged Xbox-era data names when there is no PC-named equivalent.

Getting the dependencies across

The largest external dependency was Havok 2.3. The licensed Win32 libraries were staged separately for Debug and Release, then exposed to CMake as imported targets. A few pieces had to be built from source with the same ABI as the new executable, and small compatibility shims covered CRT and key-code differences between the old libraries and Visual Studio 2022. Lua and the other bundled libraries were then linked into the same native build graph.

This part of the setup is important: the source tree, licensed middleware, and original game data are all kept local. The build process does not download or redistribute proprietary assets.

Opening a real Windows window

The first renderer was intentionally modest. A Win32 window and message pump handed an HWND to a D3D11 backend, which created a swap chain, render target, and present loop using only the modern Windows SDK. A small HLSL shader, compiled by fxc.exe, drew a textured quad and proved that textures and GPU buffers could cross the new RedEngine boundary. Hardware rendering was preferred, with WARP available as a fallback for diagnostic runs.

That did not make the game visually complete, and it was never meant to. It established the essential path from the original engine's render calls to a native Windows display so the actual game could be brought online incrementally.

Reconnecting the original game bootstrap

Once the lower layers were stable, the executable was switched from its renderer test loop to the original RsMain::Main bootstrap. Temporary bridges stood in for subsystems that were not required to reach the frontend, while missing PC-specific configuration names fell back to their shipped equivalents. The game could then load shell2, enter the real frontend state, and process menu input through its original code rather than a replacement test menu.

The Mercenaries main menu rendered inside a native Windows application window
The original frontend running inside the first native Windows executable.

Moving beyond the menu required the original generated virtual disks to be present alongside the loose data. Those contain the level lists, textures, and global definitions that the game expects at runtime. With the data mounted, basic terrain parsing and the Havok heightfield path were enough to enter the first world, create the player, and keep the process alive for a sustained test.

The first input test: the original frontend responding inside the native Windows build.

What the first working build required

  • Windows 10 or 11.
  • Visual Studio 2022 with Desktop development with C++, MSVC v143, CMake tools, and a Windows SDK.
  • The original source/data directory layout and local junctions expected by the tools.
  • The licensed Havok Win32 libraries, staged locally for both build configurations.
  • The generated game-data disks required by the original streaming system.

From a Visual Studio Developer PowerShell, the current Debug build is configured and compiled with:

cd C:\projects
cmake --preset windows-debug
cmake --build build\out\windows-debug --config Debug --target mercenaries -- /m:1

The executable can then be started directly from build\out\windows-debug\build\cmake\Debug\mercenaries.exe. A serial MSBuild invocation is used for the full game target because some legacy projects can otherwise compete for shared program-database files.

The milestone

At this point, “running on Windows” meant something specific: a native x86 executable built with a current Microsoft toolchain, using Win32, D3D11, and XInput to boot the original game code, display the authentic frontend, and respond to player input. It was still a bring-up build, with incomplete subsystems and plenty of work left beyond that boundary, but the most important uncertainty had been removed. The recovered code was no longer only an archival console project; it was a living Windows program that could be tested and improved one system at a time, which is fully what I intend to do.

Remi Teeple