JJ2 Port

Progress Report

A clean-room reimplementation of Jazz Jackrabbit 2 (v1.24, incl. The Secret Files data) in modern C++23 with SDL3 — single player, split-screen, online play and a dedicated headless server, rebuilt from documented behaviour of the original game.

STATUS PLAYABLE DATA AS OF 07 NOV 2026 SIM 70 HZ LANG C++23

How far is it?

Short answer: every visible gameplay feature of the original is implemented and the game is playable from the title screen to the ending. The remaining work is mostly proving that each piece behaves exactly like the original, plus server-side enemy AI for online matches.

95%
feature coverage
(19 of 20 features implemented)
81%
weighted progress toward
full parity
143/157
items closed on the
current open-points list
0
field mismatches vs. the original
in the Jungler13 400-tick trace
Feature coverage (implemented or verified)19/20
Weighted parity progress (verified 1.0 · implemented 0.75 · approx 0.5)81.25%
Work blocks closed (B01–B14)9/14
Features verified against the original (frame / trace / audio / save)6/20

“Implemented” means code plus tests exist. “Verified” means the feature has been checked side by side against the original 1.24 executable. The weights above are an explicit assumption, not a measurement.

What already works

The port reads the original game data that you own and runs it through a re-implemented engine. Highlights of what is in place today:

Game data

  • All 1,403/1,403 levels load, checksums verified
  • 533/534 tilesets decoded (one file is truncated on disk)
  • All 54 animation libraries; 7,086/7,090 sprite frames decode
  • Episodes, data archives, save games, high scores, config, language files, cutscene videos
  • Music: AM plus MOD, S3M, XM, IT, MTM, PTM, STM, 669, FAR, UMX

Gameplay

  • Movement, jumping, slopes, ducking, swimming, poles, vines, springs
  • Character abilities: uppercut, kick, double jump, copter ears, butterfly, stomp
  • All 9 weapons, power-ups, Sugar Rush, airboard, bird & morph monitors
  • 49 enemy and boss types, crates, platforms, bridges, warps, triggers
  • Pickups: gems, coins, food, shields, carrots and secret items

Presentation

  • Parallax layers, animated tiles, lighting, 3D sky, water, particles, weather
  • HUD, all menus, pause, save/load, six languages
  • Intro and ending movies, credits, high-score entry, level-end fade
  • Music and sound effects, ambient sounds, echo zones
  • Pixel-true 320×200 / 640×480 views, scaled up cleanly

Multiplayer

  • Local split-screen: Coop, Battle, Race, Treasure Hunt, Capture the Flag
  • Online client and host, team chat, CTF bases, scores, round end
  • Interop with the original: the port joins original 1.24 hosts and original clients join the port’s server
  • Server list, ban list, chat word filter, LAN timing

Dedicated server

  • Headless jj2_server, deterministic 70 Hz tick
  • Snapshots, client interpolation and prediction
  • Server-side projectiles, damage, shields, boss hosting, freeze effects
  • Docker image prepared

Quality

  • ~186k lines of C++, 278 test sources, 3,600+ unit tests
  • CTest smoke runs, warnings-as-errors lint, ASan/UBSan clean
  • make parity: field-by-field diff against traces captured from the original
  • Every finding traced to an address in the original binary

Measured parity

Since 28 Oct 2026 the original 1.24 executable and the port are run side by side on the same level with the same input. Every tick, every field of the player, the camera, the random number generator and all active objects is compared. The number below is the total count of mismatching fields over 400 ticks of Jungler13 — it went from almost 52,000 to zero.

Other reference levels are still converging (latest idle runs: Castle2 611, Christmas1 1,887, Jungler5 9,245 mismatching fields). Many of these are representation gaps in the trace format rather than gameplay bugs.

Feature register

The port tracks the whole game as a register of features. Each one is either verified against the original, implemented, intentionally approximate, or not applicable to version 1.24.

VERIFIED checked against the original IMPLEMENTED code + tests APPROX close, pixel check pending N/A not in 1.24 · LATER planned stage
IDFEATURESTATUS
F01Walking, running, frictionVERIFIED
F02Jumping, gravity, apex, fallingVERIFIED
F03Ducking and duck-walkingIMPLEMENTED
F04Swimming and waterIMPLEMENTED
F05Slopes and tile collisionVERIFIED
F06Camera, look-ahead, split-screenIMPLEMENTED
F07Player shadowN/A
F08Down-spin, slam, stompVERIFIED
F09Butterfly, glide, double jumpIMPLEMENTED
F10Player contact maskVERIFIED
F11Weapons, muzzle flash, impactsIMPLEMENTED
F12Enemy families and bossesIMPLEMENTED
F13Objects, events, cullingIMPLEMENTED
F14Level and episode flow, endingVERIFIED
F15Save games and file formatsIMPLEMENTED
F16HUD, menus, localisationIMPLEMENTED
F17Layers, parallax, lighting, effectsAPPROX
F18Particles and weatherIMPLEMENTED
F19Audio, music, sound effectsIMPLEMENTED
F20Network and server autonomyIMPLEMENTED
F21Input and trace recordingIMPLEMENTED
F22JJ2+ plugin (plus.dll)LATER
F23Multiplayer modes, local and onlineIMPLEMENTED

Work blocks

B01Player physicsCLOSED
B02Objects and eventsCLOSED
B03Enemies and bossesCLOSED
B04WeaponsIN WORK
B05Level flowCLOSED
B06UI, menus, HUDCLOSED
B07Network and serverIN WORK

 

B08Music (AM player)CLOSED
B09Sound effectsCLOSED
B10Rendering and particlesIN WORK
B11Save formatsCLOSED
B12Input and tracesIN WORK
B13JJ2+ platformLATER
B14Server-side simulationIN WORK

Timeline

From an empty workspace to a playable, online-capable game in about two weeks.

  1. Phase 0: inventory and first analysis

    3,431 original files catalogued and validated. Ghidra set up; the game loop decoded: a fixed 70 Hz simulation with 12 phases per tick. First playable level with collision, camera and parallax; first server prototype.

  2. Engine map and formats

    Events, enemy AI, HUD, menus and audio documented; sprite decoding fixed; player physics measured on the original.

  3. Side-by-side traces

    A supervisor runs the original 1.24 headless and records every field per tick. make parity becomes the single acceptance number: 51,946 mismatches on day one.

  4. Completeness before polish

    Feature-completeness sweep across all areas: 3.6 million events in 4,484 levels analysed to find which features actually matter.

  5. Parity quantified

    95 % feature coverage reached, 6 features verified, Jungler13 player core exact over 400 ticks.

  6. Multiplayer and finishing touches

    Online client, server keep-alive, level cycling, CTF bases, team chat, the port joining original hosts. Level-end fade, high-score entry, power-up weapons, Sugar Rush, shields, Demon, Float-Up.

  7. Open-points list mostly cleared

    143 of 157 tracked items closed across online, level flow, player, enemies, rendering, menus, audio and measurements.

What is used

The engine is written from scratch. Knowledge about the original comes from static analysis of a legitimately owned copy and from measuring its behaviour at run time.

Engine and game

C++23CMake + NinjaGCC 16 / Clang 23SDL3SDL3 GPU → Vulkan / D3D12 / MetalSDL3 audioGLMzliblibpng

Libraries: jj2_core, jj2_formats, jj2_sim, jj2_render, jj2_audio, jj2_net. Binaries: jj2_game (client), jj2_server (headless), jj2tool (inspect, scan, render levels, export tiles and audio).

Reverse engineering

Ghidra 12.1JDK 21REA (Ghidra via MCP)GDBWine + Weston (headless original)strace / tcpdump

Every fact is stored with evidence: a function address, a decompiled excerpt or a run-time measurement. Contradictions are tracked explicitly.

Verification

Unit + integration testsCTestASan / UBSanclang-formatPython 3.14 trace harnessGolden frames / traces / audio / saves

Deterministic input traces replay identically on the original and on the port; the diff is computed field by field.

Workflow and infrastructure

Multi-agent lanesImplementer → verifier → arbiterGitLabDockerLinux x86_64

Work is split into file-disjoint lanes so several AI agents can work in parallel; each change is checked by an independent verifier before it is merged.

Future plans

The roadmap runs in four stages. First the port has to match version 1.24 exactly. Then come the JJ2+ extensions, then every other version and file format. At the end of stage 3 the source code is released as open source. After that the port grows beyond the original.

STAGE 1 Finish 1.24 parity now

Server-side enemy AI

Let the dedicated server simulate object movement and enemy and boss behaviour itself (block B14). Resolve the remaining 50 server-side object types whose hit handling is not yet confirmed.

From “implemented” to “verified”

Work through the 66 open measurement points so the 13 implemented features get a side-by-side check against the original. Bring the other reference levels (Castle2, Christmas1, Jungler5) to zero trace mismatches.

Pixel and audio exactness

Build a golden set of frames, traces, audio and save files. That lets rendering (F17) move from approximate to verified, and audio be compared sample by sample.

Remaining polish

The last player-animation and trace items, boss-death edge cases, and how menu clicks feed the random numbers that place players in multiplayer.

STAGE 2 JJ2+ reimplementation

Clean-room JJ2+

Analyse plus.dll under the same clean-room rules and rebuild its behaviour in original code: bug fixes, new game modes, extended networking and server features.

AngelScript and modding

A compatible AngelScript API, so existing JJ2+ level scripts and mutators run unchanged. This is also the port’s modding system: new enemies, weapons, game modes and HUDs, all written in script.

Extended formats

32-bit tilesets (v0x300), extra layers, MLLE level data and JJ2+ packages, so community content made since 2013 plays as intended.

STAGE 3 Every version, every file format

The same evidence-based method is applied to every release in the reference collection. The port should load each version’s data and behave like that version, as far as the binaries allow.

VERSIONWHAT IT ISTARGET
1.24Final retail release (The Secret Files engine), current baselineBASELINE
1.24 Plus1.24 install with the JJ2+ loader patch (stage 2)FULL
1.24 TSFThe Secret Files edition: extra episode, its own Anims.j2a and level variantsFULL
1.24 CHChristmas edition on the 1.24 engine, with its own animation setFULL
1.23The most widely played multiplayer version (1.25 is the same engine)FULL
1.23 CHChristmas edition on the 1.23 engineFULL
1.20Early patch with older animation and data formatsBEST EFFORT
1.00Original 1998 release, the oldest data formatsBEST EFFORT

All file formats

  • Levels (J2L), tilesets (J2T), animations (J2A), data archives (J2D), episodes (J2E), music (J2B), cutscenes (J2V)
  • Saves, high scores, config and language files
  • All format revisions of every release, documented with evidence

Version-specific behaviour

  • Physics, weapons, enemies and events per version
  • A version switch in the menu and on the command line
  • Version detection from the game data you own

Network compatibility

  • Join and host original 1.23 and 1.24 servers
  • Protocol differences between versions mapped and tested
  • Mixed-version lobbies where the originals allow it

★ Milestone: open-source release

When stage 3 is complete, the engine, server, tools, tests and format documentation from stages 1–3 will be published under a permissive open-source license. Anyone may use, modify and redistribute the code, as long as they credit the project. As before, no original game data is included: you still need your own copy of Jazz Jackrabbit 2.

STAGE 4 Beyond the original

MCP server for LLMs

An MCP interface to the engine. AI assistants could load a level, step the simulation, read game state, render frames, run parity checks, search the evidence base and help test levels.

Level editor based on MLLE

Build on MLLE, the community’s Multi-Layer Level Editor (by Violet CLM, source on GitHub), with live play-testing in the port. This happens in agreement with its author. It gets its own MCP interface too, so an assistant can inspect, build and fix levels.

Replays and spectating

The trace system already records every input. Turn it into replay files, a ghost mode for races, a spectator view for online matches and frame-by-frame playback.

Speedrun and TAS tools

An in-game timer with splits, plus deterministic frame stepping, save states and input editing for tool-assisted runs.

Better online play

A modern server browser with matchmaking, optional rollback netcode for smoother games, server admin tools and a web dashboard for the dedicated server.

Bots

AI opponents and partners for Battle, CTF and Coop, so multiplayer modes can be played alone or with an incomplete team.

More platforms

Native builds for Windows, macOS and Linux, Steam Deck support, a WebAssembly build that runs in the browser, and touch controls for tablets.

Achievements and stats

Optional local achievements, per-level statistics (gems, secrets, time) and coin and gem collection tracking.

Public dedicated server

Ship jj2_server as a Docker container that hosts games for original clients and for the port.

Clean-room rules

  • Only a legitimately owned copy of the game is analysed, for interoperability purposes.
  • No original game data is distributed. Levels, tilesets, sprites, music, sounds and executables stay with the owner; the port needs your own copy to run.
  • No decompiled code is published. Specifications and facts (offsets, formats, behaviour) are re-implemented in original code.
  • No code is copied from other ports such as Jazz² Resurrection or OpenJazz.
  • JJ2+ (plus.dll) is analysed later under the same rules, as stage 2 of the roadmap.
  • Third-party code (for example MLLE for the editor) is used only in separate tools, under its author’s terms, and never mixed into the clean-room engine.