<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Michał Kamiński</title>
    <description>The latest articles on DEV Community by Michał Kamiński (@micha_kamiski_026459c6c).</description>
    <link>https://dev.to/micha_kamiski_026459c6c</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2523322%2F60c340ff-6582-42ef-ac45-21390500bae5.png</url>
      <title>DEV Community: Michał Kamiński</title>
      <link>https://dev.to/micha_kamiski_026459c6c</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/micha_kamiski_026459c6c"/>
    <language>en</language>
    <item>
      <title>I built a game that teaches Vim motions: what I got wrong about teaching a modal editor</title>
      <dc:creator>Michał Kamiński</dc:creator>
      <pubDate>Fri, 09 Oct 2026 12:35:43 +0000</pubDate>
      <link>https://dev.to/micha_kamiski_026459c6c/i-built-a-game-that-teaches-vim-motions-what-i-got-wrong-about-teaching-a-modal-editor-2b5p</link>
      <guid>https://dev.to/micha_kamiski_026459c6c/i-built-a-game-that-teaches-vim-motions-what-i-got-wrong-about-teaching-a-modal-editor-2b5p</guid>
      <description>&lt;p&gt;Most developers I know have the same relationship with Vim: they learned just enough to exit it, and never went further.&lt;/p&gt;

&lt;p&gt;I wanted to fix that, so I built &lt;a href="https://vimrealm.com?ref=devto" rel="noopener noreferrer"&gt;Vimrealm&lt;/a&gt;: a browser RPG where you type real Vim commands to move a wizard around an isometric island made of text. Letters are stone, digits are crystal, punctuation is sandstone, spaces are grass. Press &lt;code&gt;w&lt;/code&gt; and the wizard leaps to the next word. Press &lt;code&gt;dd&lt;/code&gt; and a whole row of tiles drops away.&lt;/p&gt;

&lt;p&gt;Here's what I learned building it, including the parts I got wrong.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why vimtutor loses people
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;vimtutor&lt;/code&gt; is good at one thing: showing you that the commands exist. It's weak at three others:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Modes are invisible until they bite you.&lt;/strong&gt; You press &lt;code&gt;i&lt;/code&gt;, forget you're in Insert mode, type &lt;code&gt;dd&lt;/code&gt; and get "dd" in your file.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;There's no feedback on efficiency.&lt;/strong&gt; Reaching a word with &lt;code&gt;lllllllll&lt;/code&gt; and with &lt;code&gt;w&lt;/code&gt; looks identical to the tutorial. Vim's whole point is that these are not the same.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;You can use everything from lesson one.&lt;/strong&gt; Nothing stops you from falling back on the arrow keys, so you do.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A game can fix all three, because a game has rules.&lt;/p&gt;

&lt;h2&gt;
  
  
  The design
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Quests with a par.&lt;/strong&gt; Every quest has a par keystroke count, taken from a reference solution I wrote. Finish at or under par and you earn three stars. This turns "I got there" into "I got there well", and it's the part that makes people retry levels to find the shorter route. Commands like &lt;code&gt;:hint&lt;/code&gt;, &lt;code&gt;:help&lt;/code&gt; and &lt;code&gt;:e!&lt;/code&gt; cost nothing, so asking for help is never punished.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Spells unlock chapter by chapter.&lt;/strong&gt; Commands are "spells", and you only have the ones you've learned. Try something you haven't met yet and the game tells you which chapter teaches it. The arrow keys are sealed for good. Chapter 1 is &lt;code&gt;h j k l&lt;/code&gt;; chapter 2 adds word motions; later chapters add operators, text objects, the dot command, search and visual mode. The curriculum ends with a boss fight against the Arrow-Key Dragon.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Hints name the command.&lt;/strong&gt; Every target in a "reach" quest has a hint pointing at the spell to use. Quests come in two kinds: &lt;em&gt;reach&lt;/em&gt; (land the cursor on each gem, in order) and &lt;em&gt;edit&lt;/em&gt; (make the buffer match a goal text, with mismatched lines glowing red).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Trials after the story.&lt;/strong&gt; Once the dragon falls, 60 Trials drill known spells with a twist: banned commands, a keystroke limit, a flawless run where one failed spell ends it, or a time limit that starts at your first key.&lt;/p&gt;

&lt;h2&gt;
  
  
  The technical part: a Vim emulator in plain JS
&lt;/h2&gt;

&lt;p&gt;The game is plain HTML, CSS and JavaScript. No bundler, no framework, no client-side dependencies, and the free chapters even work from &lt;code&gt;file://&lt;/code&gt;. The core is an emulator that handles Normal, Insert, Replace, Visual, Visual Line and Command-line modes, with counts, operators plus motions, text objects, registers, undo/redo, dot-repeat and search.&lt;/p&gt;

&lt;p&gt;Each keystroke flows through one pipeline:&lt;br&gt;
&lt;code&gt;keydown → normalize key → quest.feed(key) → vim.feed(key) → event&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;vim.feed&lt;/code&gt; returns an event describing what happened (&lt;code&gt;move&lt;/code&gt;, &lt;code&gt;edit&lt;/code&gt;, &lt;code&gt;mode&lt;/code&gt;, &lt;code&gt;undo&lt;/code&gt;, &lt;code&gt;yank&lt;/code&gt; and so on) and the game reacts: sounds, hero animation, tile changes, win overlay. Keeping the engine and quest rules free of any DOM code was the best decision I made, because the same files run in Node.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Testing it.&lt;/strong&gt; The emulator has to behave like real Vim, or you teach people the wrong thing. Every behaviour I add gets a test case like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nf"&gt;t&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;lines&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;keys&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;start&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Keys are written in a small notation (&lt;code&gt;&amp;lt;Esc&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;CR&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;C-r&amp;gt;&lt;/code&gt;), so a test reads like something you'd actually type.&lt;/p&gt;

&lt;p&gt;A second test suite replays &lt;strong&gt;every level's reference solution&lt;/strong&gt; through the real quest rules and fails if any key is rejected or the quest can't be won. That's also how par stays honest: change a level's buffer and the build tells you the solution no longer works.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Where I stopped.&lt;/strong&gt; The emulator covers what the course teaches, not all of Vim. There are no macros, marks, named registers, ex ranges or &lt;code&gt;:s&lt;/code&gt;, and search matches literal text rather than regex. I drew the line at the point where emulating more would teach less. A beginner doesn't need &lt;code&gt;qa&lt;/code&gt; in week one, and every feature I add is one more place for the emulator to disagree with real Vim.&lt;/p&gt;

&lt;p&gt;One small deviation I kept deliberately: in Normal mode, Backspace takes back the last pending key. Real Vim does something different there, but for a beginner who typed &lt;code&gt;d&lt;/code&gt; by mistake, an undo for the pending key is friendlier than a cursor move.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I don't know yet
&lt;/h2&gt;

&lt;p&gt;Vimrealm is new and I haven't had real players go through it yet, so I can't tell you which levels are confusing or where people quit. I have guesses: I suspect the jump from reach quests to edit quests in chapter 6 is the steepest point, and that par is either too strict or too forgiving.&lt;/p&gt;

&lt;p&gt;That's exactly what I'd like to find out.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try it
&lt;/h2&gt;

&lt;p&gt;The first five chapters (13 quests, all movement) are free, with no sign-up:&lt;/p&gt;

&lt;p&gt;👉 &lt;strong&gt;&lt;a href="https://vimrealm.com?ref=devto" rel="noopener noreferrer"&gt;vimrealm.com&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The rest (operators, text objects, the dot command, search, visual mode and the dragon) is a one-time $7.99. I'd rather say that up front than hide it.&lt;/p&gt;

&lt;p&gt;If you'd rather read than play, I wrote two guides built around worked examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://vimrealm.com/vim-text-objects.html" rel="noopener noreferrer"&gt;Vim text objects&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://vimrealm.com/vim-dot-command.html" rel="noopener noreferrer"&gt;The Vim dot command&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I'd love to hear which chapter you got stuck on, and which Vim habit you'd want a game to teach.&lt;/p&gt;

</description>
      <category>vim</category>
      <category>javascript</category>
      <category>gamedev</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
