The pitch
A distant-future software engineer and her AI assistant enter a virtual world to learn Vim, and find themselves trapped by a corrupting force that turns the tutorial into a nightmare. Master the ancient discipline, or be consumed by the Aether.
The conceit that makes it work: you are not the hero. You are the neural chip. Zara — the Supreme Techno-Magista — is the one with the body; you are the AI fused into her subconscious. You type the commands, she moves. Her line, before any of it goes wrong:
As my AI assistant you are merged with my subconscious, I’m sure nothing can go wrong.
Zara, Act I
The tone starts light and whimsical and descends into digital horror.
The Corruption announces itself in scrambled text with a real message
underneath it —
Yslofu tghogught ydoud dwedree asgrafe oint the gidi mgital
alarealm resolving to
“You thought you were safe in the digital realm.”
Four narrative pillars hold it together, and two of them are rules rather than themes. The Mind as Battleground mandates permanent ambiguity — “Never definitively answer the origin question. Theories are allowed; certainty is not.” And Code is Power, which is the whole design in four words: “VIM commands aren't metaphors for power — they are power.”
The Aether
The map is not decoration — it is the game’s progress screen, drawn under a procedurally generated fog of war that burns away region by region as you unlock them.
Who is down there
Zara has seven portraits — neutral, angry, crying, happy, laughing,
sad, surprised — called by name in the dialogue scripts. The Sprout
speaks in pollen metaphors. The boss is a photograph of a well-known
Vim streamer with the eyes set on fire, committed under the message
add primeagen.
The text is the terrain
The game is a Phaser canvas layered over a live CodeMirror editor
running a real Vim engine. That is not a visual metaphor — the two
are physically coupled. Every rendered character is measured at
runtime with document.createRange() and
getBoundingClientRect(), converted into world space, and
given an invisible physics body in the words group.
So the letters on screen are the platforms Zara stands on. Delete a line and the floor goes with it. Resize the window and the whole terrain is rebuilt, because the text reflowed.
A door is one character
Objects live inside the buffer as single obscure Unicode letters, so Vim's word motions treat each one as exactly one character:
| Object | In the buffer | Which means |
|---|---|---|
| Closed door | Ɖ | f Ɖ jumps the cursor to it |
| Open door | Ď | the level exit |
| Spike | * | x deletes the hazard |
| Memory chip | ϻ | a collectable you must reach |
| Key / lock | Ƙ / Ƚ | a two-character puzzle |
A custom tokenizer tags each character and CSS swaps the glyph for a sprite. The player sees a door; Vim sees one letter. Both are correct.
Rules as data, not code
Win and lose conditions are fourteen composable checks defined declaratively — reach the open door, time limit, collect at least n, text is correct, text changed, cursor on char, key in list, line count below n, keypress limit, missing characters, wrong inserted characters. Each carries a field schema that the editor renders into a form automatically, and they combine into groups with All/Any operators and an action.
That is how a level like “solve this in two keystrokes or restart” exists without anybody writing code for it.
The game is its own level editor
Fourteen components, about 4,000 lines, running in the browser beside
the game. A scene tree down the left, a live document preview with the
collectable sitting on the text, and the rules as coloured cards —
green for “Next level if all rules apply: collect at least 1
mushroom”, red for “Restart if: key presses limit 2 — too
many keys pressed”. It has a Notion-style / command
palette with fuzzy search, drag-and-drop dialogue with bezier-curved
arrows between lines, and it saves straight to disk.
Two things worth stealing
Dangerous Dave’s PC speaker, ported
The sound effects are not samples. They are the original 1988
Dangerous Dave PC-speaker data — arrays of hex divisors where
the frequency is 1193180 / divisor, 0x0000
is silence and 0xFFFF ends the sequence — replayed
through the Web Audio API with an envelope tuned for the sharp attack
and release a real PC speaker had. The commit that added it:
testing legendary dangerous dave sounds for reference.
The diff that paints corruption
A vendored Patience Diff compares your buffer against the target text, and the result is rendered as infection: wrong characters get an overlay, missing ones get a floating tooltip. The masking is done with stacked CSS gradients — one stop per character — so a single animated element shows through only where the text is corrupted.
Its author's own assessment is preserved in the git log, and it is the most honest commit message in any of these repositories:
i think the paintCode algo is ready. don’t ask me whats going on there
2025-07-04
Where it stands
Live and playable at vimancer.com. Fourteen scenes and 96 segments are built, with login required from scene four and early access ending at scene nine. Core systems, the level editor and the playable prototype are all done; what remains is the back half of the story.
Act III has a written strategy and a sharp idea behind it — nine remaining command groups collapsed into four narrative beats (Learning to Change, Destroy, Remember, Command) rather than nine chapters, on this principle:
Stop relying on NPCs. Trust the text itself. If a level is designed so that only one command solves the puzzle, the player will discover that command without being told.
docs/01_Narrative_Design/Act_III_Design_Strategy.md