Underground 2 Revived
Play Need for Speed: Underground 2 (2004) in Chrome and Firefox with WebGPU graphics, Web Audio, up to 120 fps widescreen, controller support, free roam and Online races with friends. Fan project, not
翻译准备中
尚未检测到更新。GitHub 发布版本后会显示在这里。
个人 GitHub 账号下公开仓库的所有者可以登录并验证所有权,自行管理介绍,无需管理员批准。
登录并生成验证文件,在 30 分钟内将其提交到此仓库的默认分支。其他分支或分叉仓库中的文件无效。然后在下方检查文件,即可无需管理员批准直接管理项目。请保留文件以维持管理权限。
如需登录,将前往登录页面。登录后请回到此处,再次点击所选的验证按钮。
在项目文件夹中运行 /nomorevibe verify,即可验证所有权并自行管理介绍。
一分钟完成验证SHADOW SIX — an unofficial fan tribute: a realistic three.js remake of Commandos: Behind Enemy Lines (1998). Not affiliated with Pyro Studios, Eidos, Square Enix or Kalypso.
翻译准备中
取自仓库 README
正在加载完整 README。 以下为已保存的摘录。
A real-time stealth tactics game in your browser: a fan remake of Commandos: Behind Enemy Lines (1998) built
with three.js. Six specialists, enemy vision cones, a fixed 3/4 camera and WWII missions behind enemy lines.
▶ Play now in your browser (nothing to install):查看完整 README ↗A real-time stealth tactics game in your browser: a fan remake of Commandos: Behind Enemy Lines (1998) built with three.js. Six specialists, enemy vision cones, a fixed 3/4 camera and WWII missions behind enemy lines.
▶ Play now in your browser (nothing to install): https://jaher.github.io/shadow-six/
Fan tribute, not an official game. SHADOW SIX is an unofficial, non-commercial fan tribute to Commandos: Behind Enemy Lines (Pyro Studios / Eidos Interactive, 1998). It is not affiliated with, endorsed by or connected to Pyro Studios, Eidos, Square Enix or Kalypso Media. 'Commandos' is a trademark of its owner. No assets from the original game are used; all art, audio and code are original or CC0/redistributable (see CREDITS.md).
A mission with a scripted solution can be filmed: the art opening (the title card over a slow pan of the map, from the objective to the team's start), then the whole solution played in the real game with player orders only and captioned step by step, down to the Mission complete card. Each sheet below is a 4 × 4 contact sheet of one film, in film order (click it for the full-size image); the numbers are the film's own: game time, detections, enemies killed, commandos alive. More films are on the way. How to make one: Film a mission; the films themselves are not in the repository.
The Sniper shoots the officer, the compound patrol and the bridge sentry; the Sapper's bear trap takes the road patrol and his time bomb the fuel depot; the Green Beret knifes the depot guard. Game time 6:08 (film 1:36), 0 detections, 5 kills, all 3 commandos alive.
The Green Beret knifes the road sentry; the Marine swims round the peninsula, harpoons a second guard and rafts the Green Beret up the fjord; the Green Beret carries a fuel drum to the relay station and sets it off with one pistol shot. The Driver takes no part. Game time 18:10 (film 2:20), 0 detections, 2 kills, all 3 commandos alive.
The Sapper's bear trap takes two guards, the Marine's speargun one, the Sniper two shots across the river and the Green Beret's knife two more inside the camp; the Marine rafts the team over, the Sapper blows the fuel depot and the Driver drives the truck out. Game time 20:00 (film 3:34), 0 detections, 7 kills, all 5 commandos alive.
The Marine harpoons three guards, the Green Beret knifes four and works a decoy, the Sapper's trap takes the sergeant, the Spy takes a uniform and switches the fence off; the Sapper's charges destroy the bunker (and its gunner) and the dam, and all four leave in the truck. Game time 45:03 (film 8:19), 0 detections, 9 kills, all 4 commandos alive.
The Spy rides the cable car in a German uniform and injects five guards; the Green Beret knifes one, climbs the east cliff and puts a fuel drum by the radar; the Spy's pistol shots set off the drums that destroy the barracks (with a three-man patrol) and the radar, and both fly out in the autogyro. Game time 14:59 (film 3:05), 0 detections, 9 kills, both commandos alive.
The Green Beret knifes one guard and lays a decoy; the Sniper shoots one guard on the way in and two after the blast; the Sapper's charge destroys the Leopold railway gun and a guard beside it; all three board the truck. Game time 36:04 (film 4:47), 0 detections, 5 kills, all 3 commandos alive.
The Green Beret knifes sixteen guards from behind, several drawn in by a decoy, and carries three barrels into place in and beside the oil store; the Sniper shoots five guards, and his sixth round sets off a chain of barrels that destroys the oil store, the reservoir and both fuel tanks (and three more guards); both leave in the jeep. Game time 111:28 (film 10:10), 0 detections, 24 kills, both commandos alive.
The Green Beret knifes twelve guards (the four sentries in the ruins, Patrol 4's three men, the guard on the compound's west wall and the compound's four, five of them drawn to a decoy first) and frees McRae from the cage; the Sapper's time bomb destroys the bomb store; the Sniper shoots two machine-gunners covering the road up to the airfield and the Sapper's two grenades kill the nine men in the dugout at the ramp head; McRae flies the Junkers out with the team aboard. Game time 21:14 (film 4:53), 0 detections, 23 kills, all 4 commandos alive.
The Spy, in uniform, injects the gate sentry and four valley guards; the Sapper plants three remote bombs; the Driver takes the half-track through the yard and fires its gun at the quarry's fuel truck, which takes both quarry rigs, and the Sapper's detonator takes the yard and valley rigs; all five drive out in the half-track. Game time 17:11 (film 4:26), 0 detections, 5 kills, all 5 commandos alive.
The Spy, in uniform, injects eleven guards from behind and holds others in talk with their backs turned; the Green Beret knifes eight and opens the cell door to free the Informer; the Sniper shoots five roof guards one after another; the Green Beret, the Sniper and the Informer crawl over the roofs to the mosque platform, and all four drive off in the car on the quay. Game time 16:22 (film 4:08), 0 detections, 24 kills, all 3 commandos alive.
The Marine spears eleven guards from the water, opens both lock gates and rafts the team in; the Green Beret knifes six, the Sniper shoots four and the Sapper's bear trap takes one; the Driver blocks the garage door with a truck; the Marine's mini-sub torpedo sinks the battleship by the bow, the Sapper's remote charge blows the fuel tanks and the Driver sinks a patrol boat with the pier gun; all five row out to the red buoy. Game time 53:19 (film 9:29), 0 detections, 22 kills, all 5 commandos alive.
The Marine rows the boat and spears ten guards; the Sniper shoots seven; the Green Beret knifes one, holds a guard's eyes with a decoy and stands a fuel barrel by gun 4; the Sapper sets remote charges on guns 1, 2 and 3; the Sniper's shot into the barrel destroys gun 4 and the Sapper fires the other three from the sea (four guards die with them); all five row out to the red buoy. Game time 46:07 (film 7:05), 0 detections, 22 kills, all 5 commandos alive.
The Spy takes a German uniform from a balcony, injects seven guards and holds a patrol in talk; the Marine spears one guard from under the water; the Driver parks the fuel tanker on the tram line and drives the tram into it, which destroys the headquarters as an accident, with no alarm; the Sniper shoots General Schleper with one round at the corner of his garden; all four leave in the van. Game time 92:29 (film 9:10), 0 detections, 9 kills, all 4 commandos alive.
The Spy takes the German uniform from the clothesline and drives the lorry onto the bridge with the Sniper and the Marine aboard; the Spy holds one engineer in talk while the Sniper shoots the four bridge engineers and a sentry; the passing train runs down three more guards; all three drive off in the lorry by the south road. Game time 20:04 (film 3:15), 0 detections, 8 kills, all 3 commandos alive.
The Marine dives to the moored rowboat and ferries the team across the river; the Sniper shoots three guards and a guard dog from outside the palisade; the Green Beret climbs in, knifes one guard, lays a decoy and sets three barrels by the V2 rockets; the Sniper's fifth and sixth rounds into the barrels destroy all three rockets, and the Marine lets the current carry the boat out with all four aboard. Game time 33:43 (film 4:25), 0 detections, 5 kills, all 4 commandos alive.
The storyboard of each of these missions comes when its film is done (a film needs the mission's scripted solution first, see Status); until then it keeps its single in-game frame.
The earlier reference set, an action frame and two scene frames for each of missions 1 to 20, is catalogued in verify/reference/README.md.
?debug, see Debug mode); tools/solutions/film-mission.mjs films it
(see the storyboards).Work in progress. All twenty missions of the Behind Enemy Lines campaign are in the build and playable (in
campaign order, or any of them at once with ?debug), with art (terrain, water, buildings, vehicles, animated
soldiers and commandos), vision cones, alarms, the knapsack, stealth kills, carrying bodies, explosives, briefings,
debriefings, and saving and loading. They are at different stages of finish:
For development there is no build step: the repository root is the web root.
npm install # dev tools only (esbuild for the web build, playwright-core for the tests)
npm run serve # http://localhost:8080/ (node tools/serve.mjs [port])
The web build that GitHub Pages serves bundles and minifies the code and copies only the runtime assets:
npm run build # → dist/ (size report; fails over 950 MB or on a non-relative URL)
npm run serve:dist # http://localhost:8080/shadow-six/, served like GitHub Pages
node tools/perf/measure-web-start.mjs # first-visit start-up on a throttled 20 Mbit/s link
Any static file server also works, for example npx serve . or python3 -m http.server 8080. Use a desktop
browser with WebGL 2 (Chrome, Edge or Firefox; a discrete GPU is recommended for the higher presets).
URL parameters:
| Parameter | Effect |
|---|---|
?mission=m01 | Skip the title screen and load a mission (m01–m20; m00 is the sandbox). |
?preset=low|medium|high|ultra | Rendering quality preset. |
?test=1 | Test mode: the simulation only advances through window.__game.advance(s). |
?debug | Debug mode: the DEBUG LEVEL SELECT instead of the title (see Debug mode). ?debug=cones also shows every vision cone. |
Add ?debug to the URL (?debug=1, ?debug=cones and any other value work too; ?debug=0 is off), for example
http://localhost:8080/?debug or https://jaher.github.io/shadow-six/?debug. The game skips the title splash and
opens DEBUG LEVEL SELECT: every mission in the mission list, grouped as Behind Enemy Lines (by mission number),
Beyond the Call of Duty and Sandbox / test maps, each with its number, name, theater colour and icon, and a
thumbnail once you have played it in debug mode (a small capture cached in the browser). New missions appear by
themselves. Click or tap a level, or use the arrow keys and Enter. Esc (or Main menu) goes to the normal title.
Options in the overlay, remembered in localStorage (those marked * apply on the next launch):
| Option | Effect |
|---|---|
| Skip briefing (default on) | The level starts at once. |
| All commandos * | Adds every missing commando of the campaign beside the first one. |
| Invulnerable | Commandos take no damage. |
| Enemies blind & deaf | Inspection mode: enemies see and hear nothing, so they never react. |
| All vision cones | Every enemy cone stays drawn. |
| Free camera | No scroll clamp at the map edge and zoom from 0.125× to 4×. |
| Time ×0.5 / ×1 / ×2 / ×4 | Simulation speed. |
| Time of day * / Wind * | Dawn, noon, dusk or overcast lighting; any wind preset. |
| Info HUD | The corner readout of latency, triangles and memory (also F11). |
Keys while ?debug is on: F10 level select (also the small DEBUG button, bottom left), PageDown / PageUp
next / previous level, Ctrl+R instant restart, F11 info HUD (below). The URL follows the level you are in, so
?debug&mission=m05 reloads or shares that level directly, with the remembered options. Without the parameter none
of this exists, and nothing in the normal menus leads to it.
The info HUD sits in the bottom-left corner above the DEBUG buttons (with a finger: right of the MENU / TURN buttons, or above them on a phone held upright). Frame numbers are the average, 95th percentile and worst of the last 2 seconds, so a single hitch stays readable for 2 s:
| Row | What it measures |
|---|---|
| frame, FPS | Time between two displayed frames (one requestAnimationFrame to the next). |
| main cpu | Main-thread ms of each frame: simulation ticks, render, texture uploads (Game.frame). |
| render cpu | The Game.render part of it: scene updates and the WebGL calls (not the GPU's own time). |
| input→frame | From a click, tap, key or wheel (the event's timestamp) to the end of the next frame drawn after it, over the last 32 inputs, plus the last one. GPU, compositor and display time come on top. |
| draws, tris | Draw calls and triangles of the whole frame, including the offscreen passes (water mirror, ocean / ripple / trail maps) drawn before the main view, whose share is shown as offscreen. |
| GPU MB | Live GPU allocations counted as they happen (src/debug/gpu-mem-counter.js, same rules as tools/perf/mem-probe.js): textures with every mip / face / layer, vertex and index buffers, renderbuffers, plus the canvas (estimated). |
| three.js, JS heap | The renderer's live texture and geometry counts; the JS heap in use (Chrome / Edge only). |
Below the table, a perf graph shows the last 15 seconds: each frame's time as a bar (green up to 16.7 ms, amber up to 33.3 ms, red above; one column per pixel keeps the worst frame in it, so a single hitch stays visible), the main-thread CPU as a blue line, dashed 16.7 / 33.3 ms guides, and the GPU memory as a violet line on its own scale. The − button shrinks the HUD to one line (FPS · frame ms · GPU MB) and + brings it back; the choice is remembered. Sampling runs only while the HUD is shown. In video mode the HUD starts minimized in the corner, with the caption moved clear of it; F11 hides or shows it there. Capture runs (?test=1, or ?debug=clean) keep it hidden in video mode, so films stay clean.
Missions with a saved full solution (tools/solutions/<id>.solution.mjs: so far the sandbox and missions 1, 2, 3, 5,
6, 8, 11 to 16, 19 and 20; the script is the one the mission's <id>-solution regression test plays) can be watched
being solved inside the game. In DEBUG LEVEL SELECT pick ▶ … — play the solution under Solution replays; in a
mission press F9 or the small ▶ SOL button beside DEBUG. The mission is loaded fresh, as authored (the select's
All commandos, Invulnerable, Enemies blind & deaf, time of day and wind are ignored while it plays), and the
solution's player orders are issued live in the real game loop, starting at 1× (real time). The bar at the top has:
| Control | Effect |
|---|---|
| ■ STOP (or Esc, or F9 again) | Stops the replay; you take over the mission where it stands. |
| ❚❚ / ▶ | The game's own pause (P works too). |
| 1× 2× 4× 8× | Replay speed. |
| STEPS ▾ | Skip to a step (stage) of the solution: a later one fast-forwards to it, an earlier one reloads the mission and fast-forwards. |
| CAM | The camera follows the commando the last order went to (on), or is yours to scroll (off). |
A caption shows the current step, each checkpoint as it is reached and the latest order. Your own orders are held
while it plays. Adding a solution for another mission: write tools/solutions/<id>.solution.mjs (exports solve(D, ctx) and STAGES; driver API in tools/solutions/driver.mjs). Nothing to register: the debug menu lists the folder
(the dev server answers tools/solutions/?ls; the web build bakes the list in and bundles every solution as a lazy
chunk).
A guided film of a mission's solution, played live in the game. In DEBUG LEVEL SELECT pick ▶ … — watch the
walkthrough under Watch walkthrough · video mode; in a mission press F8 or the small ▶ VIDEO button; or
open ?debug&walkthrough=m03 directly (&speed=auto, &speed=4, … picks the speed; no speed is AUTO). Missions without a solution are listed under No walkthrough yet (their
button says so). The mission loads fresh, as authored, on a title card (Start, Chapters, Exit); then:
tools/solutions/<id>.walkthrough.mjs, format in docs/walkthrough-format.md).| Control | Keys | Effect |
|---|---|---|
| ✕ | Esc | Back to the debug menu. |
| ⏮ / ⏭ | B / N | Previous / next step. Ahead fast-forwards from where you are; back reloads the mission and fast-forwards (the run is deterministic). ⏮ restarts the current step, or goes to the previous one in its first 4 s. |
| ❚❚ / ▶ | Space | Pause / play. |
| ☰ | L | Chapters and steps: jump to any of them. |
| ½× 1× 2× 4× | 1–4 | A fixed speed. |
| AUTO | 5 / A | The default: the speed follows the action, as the solution films did. Fast through walks and long crawls (4×, up to 8× while the frame rate holds); a true wait (the solution waits for a guard, a gap in the cones, a timer, and nobody acts) is skipped like a jump — about a second of wall time per 30–60 s of game — under a "⏩ waiting: " tag; while the step's men wait their moment the camera shows what moves (another commando at work, the guard they wait for); eased down to 1× ahead of what matters (a knife, a shot, a charge, the uniform, a switch, the raft, a near miss, a man closing in on the guard the step is about) and held there until the action has visibly finished; ½× for blasts and the escape; never above 2.5× while a new caption is read. The button shows the speed it plays at; a fixed speed leaves AUTO. |
| ⏩ | W | Skip waits (fixed speeds; on by default): while every commando waits, the pace rises up to 4× faster; it drops back the moment anything happens. |
| CC | C | Captions on / off. |
| CAM | F | Director on / off. Off is a free camera: scroll, drag and zoom as in the game; a drag or the wheel over the map also switches to it. CAM gives the camera back to the director. |
The walkthrough never changes the simulation: it wins exactly like the scripted run, checkpoint for checkpoint
(tests/debug-walkthrough-sim.test.mjs) — opened from a cold link too, however slow the connection: the load waits for
everything the gameplay world measures on the art, never racing it against a clock, so the run is the tested one tick
for tick (tests/debug-walkthrough-cold.test.mjs: M2 and M3 cold, M2 through a 4 Mbit/s link).
Any mission with a solution can be filmed: the art opening (the title card over a slow pan of the map, from the objective to the team's start), then the whole solution played in the real game with player orders only and captioned step by step, with a soundtrack mixed from the game's own music, ambience and effects. One command makes the MP4 and a 4 × 4 contact sheet of its key frames (the storyboards are those sheets):
# writes ../commandos-shots/videos/m01.mp4 and m01-sheet.jpg
node tools/solutions/film-mission.mjs m01 --sheet
It needs npm install (playwright-core) and a GPU, and takes from a few minutes to half an hour or more, depending on
the mission: it plays the solution twice, first without drawing to learn when things happen (kills, blasts,
checkpoints), then frame by frame, so run it in the background and read its progress lines. It also needs an ffmpeg
with libx264 and AAC (--ffmpeg <bin>, $FFMPEG, or the PATH). It checks the run (both passes won with identical
checkpoints, the file decodes with video and audio, its length matches the frames, it is audible and not clipping)
and ends with one FILM_RESULT {json} line; the exit code is 0 only when every check passed. Options:
--videos <dir> (or $FILM_VIDEOS; default ../commandos-shots/videos), --no-opening, --keep-frames,
--mix-only, --bitrate 1400k or --crf 26. An optional tools/solutions/<id>.cut.mjs words the captions and sets
fixed shots and speeds for one mission; the details are in docs/mission-videos.md. Films are
never committed to the repository.
The controls follow the original game.
| Mouse / keyboard | Touch (phone, tablet) | Action |
|---|---|---|
Left click a commando or portrait, 1–6 | Tap a commando or his portrait; long-press a commando adds / removes him | Select (Shift adds to the selection); 0 deselects, 8 selects all |
| Left drag | — | Box select |
| Left click on the ground | Tap the ground; double-tap runs | Walk there; double-click runs |
| Right click | CANCEL button (shown while something is armed) | Cancel the armed item, else deselect |
| Click (Shift+click) an enemy | Long-press an enemy, or the eye button then tap | Show its vision cone |
C / S | Posture button | Lie down and crawl / stand up |
X knife, G pistol, R sniper rifle, J harpoon or trap, B bomb, A detonator, E grenade, L injection, W wire cutters, K first aid, U uniform, Q decoy, T boat, D diving gear, F shovel | Tap the item in the knapsack, then tap the target | Knapsack items (each commando only has his own) |
Tab | — | Move the knapsack panel to the other side |
| Arrow keys, screen edges, middle drag | One-finger drag (flick to coast); two fingers also pan | Pan the camera |
Mouse wheel, numpad + / - (or = / -) | Pinch with two fingers (spread = zoom in, about the fingers' midpoint) | Zoom; numpad * or Backspace resets |
Home | — | Centre on the selection |
P, Esc | MENU button (bottom left) |
On a touch screen a tap never pans and a drag never gives an order: a finger that moves more than 10 px is a drag, and a second finger turns it into a pinch. Phones and tablets start on the medium quality preset (low on older mobile GPUs), which also caps the rendering resolution; a quality picked in OPTIONS is kept.
Each commando carries only the equipment he had in the original game; missions add or change counts.
| Commando | Weapons | Tools |
|---|---|---|
| Green Beret | knife, pistol | decoy, shovel |
| Sniper | sniper rifle (limited rounds, 5 by default), pistol | first-aid kit if neither Driver nor Spy is deployed |
| Marine | knife, harpoon gun (unlimited, shorter range than the pistol), pistol | inflatable boat, diving gear |
| Sapper | pistol, bear trap, time bombs or remote bombs (never both); grenades per mission | detonator (remote bombs), wire cutters per mission |
| Driver | pistol; submachine gun (20 bursts) only in missions 1, 2, 4 and 10 | first-aid kit (6 doses) |
| Spy | pistol, lethal injection (unlimited) | enemy uniform (found on site); first-aid kit if no Driver |
The data lives in src/items.js.
node tests/unit/run.mjs # npm run test:unit: pure simulation (grid, pathfinding, world, objectives, items…)
node tests/run.mjs [pattern] [--swiftshader] [--headed] # npm test: browser tests in headless Chromium
The unit tests run on GitHub Actions for every push and pull request. The browser runner (npm install first,
for playwright-core) starts tools/serve.mjs on a free port and launches a cached playwright Chromium on the
real GPU (--use-angle=gl); --swiftshader uses software rendering. It fails on thrown errors, page errors,
console.error and HTTP errors. Screenshots go to tests/out/ (git-ignored).
.github/workflows/pages.yml builds the web target on every push to master
(npm ci, npm run build, see tools/build/build.mjs) and deploys dist/ to GitHub
Pages. The build bundles src/ with esbuild (code-split, content-hashed file names), keeps every URL relative so
the site works under the /shadow-six/ sub-path, adds version.json, a 404.html that returns to the game and a
small service worker (sw.js).
SS_DIST=1 node tests/run.mjs webbuild checks the build in headless Chromium.
A mission is downloaded once (40–100 MB). Inside a session, RESTART MISSION, quick load and loading a save of a
mission already played reuse what is in memory (textures, models, baked terrain and trees, shader programs): no
download, no loading screen. Between visits the service worker keeps every downloaded asset in the browser's Cache
Storage, keyed by content hash, so a new deploy only re-downloads the files that changed; code, HTML and manifests
always come from the network first (never stale). After a mission loads, the next campaign mission is downloaded in
the background when the connection is not metered or in data-saver mode. Once a mission is cached it also plays
offline. OPTIONS → CLEAR CACHED GAME DATA deletes the cache. Details: docs/ARCHITECTURE.md § Asset cache;
node tools/perf/measure-restart.mjs measures (re)load times on the build.
.github/workflows/ci.yml runs the unit tests and the web build.
index.html entry page (dev: import map → vendor/three.module.js; the build bundles it)
styles/ screen, menu and HUD styles
src/main.js boot: WebGL check → Game → assets → title
src/game.js Game: states, fixed-step loop, mission loading
src/config.js gameplay and render numbers
src/items.js item catalogue and BEL default loadouts
src/core/ events, math, objectives
src/world/ grid (terrain, blocking, line of sight), pathfinding, world, map builder
src/entities/ units, commandos, enemies, vehicles, projectiles, interactables
src/ai/ perception, enemy brain, alarm
src/abilities/ one file per ability
src/engine/ renderer, camera, input, asset loading
src/input/ touch gestures and in-mission touch controls
src/physics/ blast, debris and ragdoll physics (Rapier)
src/render/ vision cones, selection markers, effects
src/art/ models, materials, terrain, water, characters
src/ui/, src/audio/ menus, HUD, briefings, credits; audio
src/debug/ debug mode: level select, solution replay, video mode (walkthrough), info HUD
src/missions/ mission definitions (m00 sandbox, m01–m20 the BEL campaign, b00 the BCD sandbox)
assets/ textures, models, HDRIs, audio, portraits, fonts (see CREDITS.md)
vendor/ three.js r186 and addons
tools/ dev server, web build (tools/build), asset build scripts (Blender, audio, portraits),
mission solutions, walkthroughs and films (tools/solutions)
tests/ browser tests and unit tests
docs/ architecture, design spec, research notes, screenshots
Read docs/ARCHITECTURE.md before changing module interfaces.
All third-party material is listed with its source, author and licence in CREDITS.md. In short:
The original game, Commandos: Behind Enemy Lines, was created by Gonzo Suárez and Pyro Studios and published by Eidos Interactive in 1998. This project exists out of admiration for it.
The original source code is released under the MIT License. Assets in assets/ and the libraries in
vendor/ keep their own licences; see CREDITS.md and vendor/LICENSE.
| Pause and objectives, cancel |
F1 | ? button | Help |
F2–F7 | — | Split-screen camera views |
F8 / F9 (Ctrl+S / Ctrl+L) | MENU → save / load | Quick save / quick load |
Ctrl+B | Notes button | Notes |