High-performance JavaScript port of Lemmings with WebMIDI sequencing support.
- Accurate, fast Lemmings engine.
- Supports over 25,000,000 simultaneous Lemmings!
- Capable of running at >60x original game speed, with 450,000 Lems
- Runs backwards at full speed
- Tick-by-tick stepping
- WebMIDI routing, input mapping, and sequencing controls.
- Fully featured level editor
- MCP servers, so your LLM can play and edit Lemmings levels!
- Efficient JSON based communication of game state & user interaction
- If you consider that "cheating", vision capture via Playwright is supported
- Interactive Spectator mode lets you watch, help, or mess with them
You can Play and Edit in your browser right now!
For a private, local copy:
- Install Node.js 20+
- Clone:
git clone https://github.com/doublemover/LemmingsJS-MIDI - Install and run:
npm installnpm start
- Open https://localhost:8080
- Open https://localhost:8080/editor.html for the standalone level editor.
- This repo is intended for local development and offline tooling, not npm distribution.
If you hit an issue, please open one: https://github.com/doublemover/LemmingsJS-MIDI/issues
LemmingsJS-MIDI includes an MCP server for automation, state inspection, input control, and vision capture using Playwright sessions.
- Run
npm run start-httpsin a separate tab. - Add the following config to Codex CLI
config.toml(version 0.77):
[mcp_servers.lemmings]
command = "node"
args = ["C:\\Users\\sneak\\Development\\Lemmings-MIDI-CODEX\\mcp\\server.js"]
[mcp_servers.lemmings.env]
LEMMINGS_MCP_BASE_URL = "https://localhost:8080"
LEMMINGS_MCP_PATH = "/?e2e=1"- Faithful & enhanced port of Lemmings
- Steel terrain accuracy improvements using
js/steelSprites.json - Minimap
- Accumulates ground at full resolution
- Shows entrances, exits, lemmings, and deaths
- Click and drag to reposition view
- Speed display on the Paws (Pause) button
- Click left/right side of bottom bar on Paws to slow down or speed up
- Use
-/=(Shift for faster steps) to adjust speed - Right click Paws resets speed to 1
- Speed is a divisor of original tick speed
(60ms / gameSpeed)
- Right click release rate buttons for instant min or max
- Configurable key bindings
F1orShift+/Show the keyboard shortcuts overlay in-game1/Shift+1: Decrease release rate by 1 / to minimum2/Shift+2: Increase release rate by 1 / to maximum3, 4, 5, 6: Select Climber, Floater, Bomber, BlockerQ, W, E, R: Select Builder, Basher, Miner, DiggerK: Apply selected skill to selected lemmingSpace: Pause/resume[/]: Step backward / forward one tick while pausedAlt+]: Step backward (mirror of step forward)B: Toggle continuous reverse playbackT/Shift+T: Nuke / instant nukeBackspace: Restart level- Arrow keys: Pan viewport (Shift for faster)
Z/X: Zoom in / out (Shift for faster)V: Reset zoom to 2-/=: Decrease / increase game speed (Shift for faster, numpad +/- also supported)Alt+=: Decrease speed (Shift for faster),/.: Previous / next levelShift+,/Shift+.: Previous / next groupTab/Shift+Tab: Cycle through skills forward / backward\: Toggle debug modeShift+Backquote: Toggle editor mode (preview only)
URL parameters (shortcuts in brackets)
version (v):- 1: Lemmings (default)
- 2: Oh no! More Lemmings
- 3: Xmas 1991
- 4: Xmas 1992
- 5: Holiday 1993
- 6: Holiday 1994
difficulty (d): 1-6 (default: 1)level (l): 1-100 (default: 1)speed (s): 0-100 (default: 1)cheat (c): true/false (default: false)debug (dbg): true/false (default: false)bench (b): Benchmark modeendless (e): Disable time limit, win/loss conditionsscale (sc): Starting zoom .0125-8 (default: 2)extra (ex): Extra lemmings per spawn 1-1000 (default: 0)performanceAPI (pa): Enable Performance API instrumentationshortcut/_: Prefer short query keys when updating the URL
Debug & Benchmarking Notes
- Right click Nuke toggles debug mode
- Blue pixel under lemmings (engine position)
- Red rectangles for triggers (traps, blockers, exit)
- Cyan rectangles show steel
- Orange and green show left/right arrow triggers
- Speed can drop below 1 in 0.1 steps and rise to 120 in steps of 10
- Bench mode spawns lemmings endlessly at max rate and shows T/TPS/Active/Spawned
- Bench sequence measures extra lemming capacity, then runs multiple entrance counts
- Standalone editor page at
editor.html. - Import/export
.nxlvand classic.lvlfiles from the editor header. P: Toggle playtest.- Shift-click or marquee to multi-select, drag to move. Alt-drag to clone.
- Palette previews are generated from sprites and cached in browser storage.
- Steel areas are editable with the Steel tool.
- Full Undo/Redo support.
- Level validation catches missing requirements.
Keybindings are configurable in keybindings.json. The in-game defaults map to the controls above.
- Enable MIDI from the left control panel (toggle persists).
- When disabled, WebMIDI is not enabled and the MIDI router is detached.
- Use the I/O section for Input/Output, Input channel, and
MIDI reset.- Input channel defaults to
Omniand can be set to a specific 1-16 channel.
- Input channel defaults to
- Use
reset allto clear stored configuration and UI state. - Base BPM is the sequencing anchor; current BPM shows
speed x base, plus ticks per second/beat/measure. - Global FX tab:
- Intensity and Accent adjust default velocity and density scaling.
- Positional Modifiers add X/Y mappings (with optional operators) and per-target min/max ranges.
- Global Repeat applies a beat window, max count, target, and amount to scale parameters on rapid repeats.
- Events/Triggers tabs:
- Configure each SFX event or trigger with mode (note/degree/chord), key+octave, or scale degree + octave.
- Chords support triad, seventh, sixth, ninth, power, sus2, sus4, and octave.
- Arps support up/down/updown; triggers can optionally run independent arps per source.
- ADSR tab lets you target Global, a specific SFX, or a trigger to override envelope values.
- UI state is stored in localStorage. Defaults come from
midi-mapping.jsonand apply only on first run or when a value is missing. - Full defaults and customization notes live in
midi-mapping.jsonanddocs/midi-mapping.md.
- Input mapping is configured in
midi-mapping.jsonunderinput. - Transport messages map to pause/resume/restart.
- Notes map to skill selection or action controls (pause/resume/restart/speed/toggles).
- CCs map to speed, BPM, intensity, accent, key/scale, view pan, repeat window, ADSR, chord defaults, and time signature.
Default MIDI mapping table
| Type | Control | Meaning | Range/Values | Default |
|---|---|---|---|---|
| Input | Channel | Input filter | omni or 1-16 |
omni |
| Transport | Start (0xFA) | Action | restart | restart |
| Transport | Stop (0xFC) | Action | pause | pause |
| Transport | Continue (0xFB) | Action | resume | resume |
| Note | Skill base | Skill select base | MIDI note | 60 |
| Note | Skill order | Skill index order | CLIMBER, FLOATER, BOMBER, BLOCKER, BUILDER, BASHER, MINER, DIGGER | set |
| Note | 36 | Action | pause | 36 |
| Note | 38 | Action | resume | 38 |
| Note | 40 | Action | restart | 40 |
| Note | 41 | Action | speedDown | 41 |
| Note | 43 | Action | speedUp | 43 |
| Note | 45 | Action | speedReset | 45 |
| Note | 47 | Action | toggleMidi | 47 |
| Note | 49 | Action | toggleViewPan | 49 |
| CC | 1 | Speed factor | 0.1-8 | 1 |
| CC | 74 | Base BPM | 60-200 | 120 |
| CC | 7 | Intensity (velocity) | 10-127 | 80 |
| CC | 11 | Accent (density boost) | 0-1 | 0.4 |
| CC | 16 | Key root | 0-11 | 0 |
| CC | 17 | Scale name | chromatic-minor, major, minor, dorian, mixolydian, pentatonic, chromatic | chromatic-minor |
| CC | 18 | X to note offset | toggle | off |
| CC | 19 | Y to velocity | toggle | on |
| CC | 20 | Y to timbre | toggle | on |
| CC | 21 | View pan | toggle | off |
| CC | 22 | Repeat max count | 0-32 | 0 |
| CC | 23 | Repeat window (beats) | 1-8 | 4 |
| CC | 24 | Env attack | 0-2 | 1 |
| CC | 25 | Env decay | 0-2 | 0 |
| CC | 26 | Env sustain | 0-1 | 1 |
| CC | 27 | Env release | 0-2 | 1 |
| CC | 28 | Chord type | triad, seventh, sixth, ninth, power, sus2, sus4, octave | triad |
| CC | 29 | Chord octave | 1-8 | 4 |
| CC | 30 | Chord degree | 0-6 | 0 |
| CC | 31 | Duration ticks | 1-24 | 6 |
npm testruns the full Mocha suite.npm run test-editorruns the editor unit tests.npm run coverage-editorenforces 100% coverage forjs/editor/**.- Individual groups are in docs/TESTING.md.
npm run lintchecks ESLint rules.npm run formatfixes formatting.
- Usage: docs/usage.md
- Offline tools: docs/offline-tools.md
- Exporting sprites: docs/exporting-sprites.md
- Editor workflows: docs/level-editor/workflows.md
- MIDI UI: docs/midi-ui.md
- Performance benchmarks: docs/performance-benchmarks.md
- Testing: docs/TESTING.md
- CI: docs/ci.md
- Config: docs/config.md
- Contributing: CONTRIBUTING.md
This repo ships with site.webmanifest and a service worker
(service-worker.js) so it can be installed as a PWA with offline caching for
core assets after the first successful load. It launches fullscreen in landscape
mode. Touch input still needs polish, so please file bugs for any issues you hit.
See docs/roadmap.md for the consolidated roadmap and phases.
- Lemmings fans and archivists
- Lemmings Forums
- Camanis.net Lemmings Archives
- tomsoftware
- oklemenz/LemmingsJS
- The Throng (Blackmirror S7E4)
- Mumdance
