Skip to content

Latest commit

 

History

74 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

jk2-web

Star Wars Jedi Knight II: Jedi Outcast, single-player, running in a browser tab.

▶ Play now · Discord · YouTube · Releases · Issues

A WebAssembly port of Raven Software's original 2002 GPL source release, compiled with Emscripten. It runs entirely on your machine: the engine is WebAssembly, the game data is read from your own disk or from the free demo, and nothing is uploaded or streamed. Ghoul2 skeletal characters, the saber, and Force powers all work; the campaign runs end to end.

The port is deliberately conservative — games/jk2/ is Raven's pristine drop, and every browser adaptation is a separate reviewable commit on top, so git diff <import> -- games/jk2 is the port. No code is copied from OpenJK or iortcw. The engineering log, including theories that turned out to be wrong, is in docs/WASM_ADAPTATIONS.md.

Playing

Open https://jk2.virtastic.app in desktop Chrome, Chromium, Edge or Brave, then pick a route:

  • Play the demo — the official free Kejim Post mission. Nothing to own, nothing to install.
  • Bring your own copy — point the picker at the GameData/base folder of a legal install and select the assets*.pk3 files (assets0, assets1, assets2, assets5). They are read straight from your disk; nothing is uploaded.

Saves and settings persist in the browser (IDBFS), independent of which data you loaded.

Windows tip: copy GameData somewhere outside Program Files first — browsers refuse to grant folder access inside protected system paths, and that is where Steam installs by default.

Single-player only. The multiplayer sources are part of the drop but are not built.

Quick start (Docker)

From a clean clone, with nothing but Docker installed:

docker build -t jk2-web .          # compiles the engine from source
docker run --rm -p 8080:80 jk2-web # http://localhost:8080

or simply:

docker compose up                  # http://localhost:8080

The first build pulls the Emscripten toolchain image and compiles for a few minutes; after that it is layer-cached. See SELF_HOSTING.md for serving it on a real server, and for how to add the free demo pak so the demo route works on your own instance.

What's in this repo

This repo is code only. No game data of any kind is committed.

Path What it is
games/jk2/ Raven's pristine GPL drop + the __EMSCRIPTEN__-guarded port commits
shared/wasm-build/ env.sh (the toolchain pin), the Emscripten platform layer, build scripts, CDP test harnesses
shared/web/ server.py — the COOP/COEP dev server, with HTTP-Range for pk3 streaming
play/jk2/ index.html (the game page) and launcher.html. Built .js/.wasm are gitignored
cloud/ Optional Cloud Locker backend — OAuth sign-in plus S3 storage. Not required to play
infra/ nginx.conf (the serving contract) and the Terraform DNS reference
ci/ A reference Jenkins pipeline

Not included (kept local)

Retail .pk3 archives, the demo pak, build-jk2/, the generated jk2.js/.wasm/qagame.wasm, and node_modules/. The .gitignore and .dockerignore are written so game data cannot be committed or baked into an image by accident.

Running (dev)

source shared/wasm-build/env.sh         # Emscripten 6.0.1 — see env.sh for discovery
shared/wasm-build/build-jk2.sh          # engine   -> play/jk2/{jk2.js,jk2.wasm}
shared/wasm-build/build-jk2-modules.sh  # game DLL -> play/jk2/qagame.wasm
python3 shared/web/server.py jk2        # dev server on :8793

Both build scripts are needed: the engine alone boots to the menu, but loading a map requires the game module (qagame.wasm), which is where single-player keeps game + cgame. They are separate on purpose — qagame.wasm is an Emscripten side module that the engine dlopens per map, mirroring the original's per-map DLL reload.

Building

Emscripten 6.0.1, pinned in shared/wasm-build/env.sh — source it rather than hardcoding flags. No -flto (it miscompiles the boot path). Single-threaded. Pure C++: no Rust, no -pthread, so the toolchain is just emscripten/emsdk:6.0.1 with nothing added.

Testing

The harnesses in shared/wasm-build/*.mjs drive a real headless Chrome over CDP — they boot the actual engine and assert on what it renders and logs, rather than on mocks:

node shared/wasm-build/map-sweep.mjs 8793 "<map1,map2,...>"        # whole campaign, one session
node shared/wasm-build/verify-menu.mjs 8793 <map>                  # menus, incl. same-map reload
node shared/wasm-build/verify-transition.mjs 8793 <mapA> <mapB>    # scripted level transition
node shared/wasm-build/verify-jk-save.mjs jk2 8793 "+devmap <map>" # save round-trip incl. reload

Hosting on a real server

The one hard requirement is the cross-origin isolation header set (COOP/COEP/CORP) plus correct application/wasm and cache headers. infra/nginx.conf is the reference vhost, and SELF_HOSTING.md has worked nginx and Caddy configs.

Browser support

Desktop Chrome / Chromium / Edge / Brave. The folder picker uses the File System Access API, which Firefox and Safari do not implement; mobile is out of scope.

License

jk2-web is licensed under the GNU General Public License, version 2 — see LICENSE and NOTICE.md.

GPLv2, not GPLv3. Raven's drop grants version 2 and does not include the customary "or (at your option) any later version" clause for Raven's own code, so the combined work cannot be relicensed forward.

  • Engine code under games/jk2/ — Copyright (C) 2002 Activision / Raven Software, released by the copyright holder under GPLv2.
  • The port — the Emscripten platform layer, build scripts, the browser shell under play/, the test harnesses, and the optional cloud backend — is likewise GPLv2.
  • Bundled third-party components keep their own licenses; see THIRD-PARTY-LICENSES.md, which also records which of them are actually compiled into the WebAssembly binary.

Game data and trademarks

STAR WARS and JEDI KNIGHT are trademarks of Lucasfilm Ltd. and/or its affiliates. Activision and Raven Software are trademarks of their respective owners. This project is not affiliated with, endorsed by, or sponsored by any of them; the names are used only to identify the software this is derived from.

No retail game data is included in, or distributed by, this repository. The retail archives are commercial content and are not redistributable — you must supply your own legally-obtained copy, or use the official free demo mission.

Contributing

Read CONTRIBUTING.md first — it covers the two rules that matter most here: games/jk2/ stays a pristine import with the port as separate commits, and claims about engine behaviour need a measurement with a positive control, not a plausible story.

Community

Security issues: please follow SECURITY.md rather than opening a public issue.

Credits

Raven Software and Activision, for releasing the engine sources under the GPL in the first place.

WASM port © 2025–2026 Virtastic. Built with the Claude Agent SDK.

About

Star Wars Jedi Knight II: Jedi Outcast ported to WebAssembly — runs in the browser. From the Raven Software GPL source.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages