<?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: Sorceress</title>
    <description>The latest articles on DEV Community by Sorceress (@sorceressgames).</description>
    <link>https://dev.to/sorceressgames</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%2F4090276%2Fefd95a44-7442-4b2a-9499-4f08ffed366b.png</url>
      <title>DEV Community: Sorceress</title>
      <link>https://dev.to/sorceressgames</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/sorceressgames"/>
    <language>en</language>
    <item>
      <title>How to Make an HTML5 Game (Browser Loop, 2026)</title>
      <dc:creator>Sorceress</dc:creator>
      <pubDate>Sun, 23 Aug 2026 00:40:54 +0000</pubDate>
      <link>https://dev.to/sorceress/how-to-make-an-html5-game-browser-loop-2026-1g88</link>
      <guid>https://dev.to/sorceress/how-to-make-an-html5-game-browser-loop-2026-1g88</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally published on the &lt;a href="https://sorceress.games/blog/wrap-how-to-make-an-html5-game-browser-loop-2026" rel="noopener noreferrer"&gt;Sorceress blog&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; an HTML5 game is four things — an &lt;code&gt;index.html&lt;/code&gt; host page, a JS module that owns the loop, a folder of sprites and audio, and a static zip anyone can open in a tab.&lt;/p&gt;

&lt;h2&gt;
  
  
  What people actually mean
&lt;/h2&gt;

&lt;p&gt;Three deliverables share one core:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;A plugin-free canvas arcade&lt;/strong&gt; — HTML/CSS/JS drawing to a &lt;code&gt;&amp;lt;canvas&amp;gt;&lt;/code&gt;, shipped as a static folder.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A mobile HTML5 game&lt;/strong&gt; — same bundle plus a viewport meta tag and a web app manifest.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;An itch.io HTML export&lt;/strong&gt; — a zip whose &lt;em&gt;root&lt;/em&gt; contains &lt;code&gt;index.html&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All three need a canvas, a &lt;code&gt;requestAnimationFrame&lt;/code&gt; tick, relative asset paths, and zero installer.&lt;/p&gt;

&lt;h2&gt;
  
  
  The loop in one minute
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Read input&lt;/strong&gt; — drain a &lt;code&gt;keys&lt;/code&gt; object that &lt;code&gt;keydown&lt;/code&gt;/&lt;code&gt;keyup&lt;/code&gt; listeners keep updated; mirror pointer events for mobile.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Update&lt;/strong&gt; — advance each object by velocity x &lt;code&gt;dt&lt;/code&gt; (seconds since last frame), apply gravity, resolve collisions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Draw&lt;/strong&gt; — &lt;code&gt;ctx.clearRect(0, 0, W, H)&lt;/code&gt;, then one &lt;code&gt;ctx.drawImage&lt;/code&gt; per sprite.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Start audio on the first user gesture so autoplay policy stays happy. About thirty lines, zero dependencies.&lt;/p&gt;

&lt;h2&gt;
  
  
  The discipline that keeps it honest
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Draw never mutates state; update never touches the DOM.&lt;/strong&gt; Keep a plain &lt;code&gt;state&lt;/code&gt; object, a &lt;code&gt;keys&lt;/code&gt; map, and a &lt;code&gt;ctx&lt;/code&gt; reference. Update reads keys and mutates state; draw reads state and paints.&lt;/p&gt;

&lt;p&gt;One trap: size the canvas with its &lt;code&gt;width&lt;/code&gt;/&lt;code&gt;height&lt;/code&gt; &lt;strong&gt;attributes&lt;/strong&gt;, not CSS alone, or the bitmap stretches and smears.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why it is still the best first-game target
&lt;/h2&gt;

&lt;p&gt;Distribution is a URL or a zip: no store review, no signing certificate. Canvas, Web Audio and &lt;code&gt;localStorage&lt;/code&gt; are stable across browsers, and itch.io, GitHub Pages and Netlify serve static folders free.&lt;/p&gt;

&lt;p&gt;Full guide: &lt;a href="https://sorceress.games/blog/wrap-how-to-make-an-html5-game-browser-loop-2026" rel="noopener noreferrer"&gt;sorceress.games&lt;/a&gt;&lt;/p&gt;

</description>
      <category>gamedev</category>
      <category>javascript</category>
      <category>webdev</category>
    </item>
    <item>
      <title>How to Make a Snake Game in the Browser (Grid Loop, 2026)</title>
      <dc:creator>Sorceress</dc:creator>
      <pubDate>Sun, 23 Aug 2026 00:36:20 +0000</pubDate>
      <link>https://dev.to/sorceress/how-to-make-a-snake-game-in-the-browser-grid-loop-2026-4nbf</link>
      <guid>https://dev.to/sorceress/how-to-make-a-snake-game-in-the-browser-grid-loop-2026-4nbf</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally published on the &lt;a href="https://sorceress.games/blog/coil-how-to-make-snake-game-browser-grid-loop-2026" rel="noopener noreferrer"&gt;Sorceress blog&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; a fixed-tick grid, a growing body, food on empty cells, death on wall or self-collision. Under ~350 lines of vanilla JS.&lt;/p&gt;

&lt;h2&gt;
  
  
  Scope it first
&lt;/h2&gt;

&lt;p&gt;"Snake" covers three builds: a Python turtle classroom demo, a multiplayer .io arena (weeks of backend), or a single-player browser snake — fixed grid, fixed tick, arrow/WASD turns, respawning food, growth on eat, death on wall or self. The last is the weekend build.&lt;/p&gt;

&lt;h2&gt;
  
  
  The grid loop in one minute
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Input&lt;/strong&gt; — read arrow/WASD presses into a one-slot &lt;code&gt;nextDirection&lt;/code&gt; buffer; reject reverses.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tick&lt;/strong&gt; — every N ms, take direction from the buffer, compute the next head cell, advance.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Eat&lt;/strong&gt; — if the next cell holds food, push a new head &lt;em&gt;without&lt;/em&gt; dropping the tail, then respawn food on a random empty cell. Otherwise push head and shift tail.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Collide&lt;/strong&gt; — if the next cell is out of bounds or in the body, stop and show Game Over.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Score&lt;/strong&gt; — increment on eat; optionally shrink &lt;code&gt;tickMs&lt;/code&gt; every few points so tension ramps.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Portals, wrap-around walls and power-ups are polish added after one apple feels fair.&lt;/p&gt;

&lt;h2&gt;
  
  
  Two details that bite beginners
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;One-slot direction buffer.&lt;/strong&gt; Writing direction on keydown lets a fast double-tap reverse the snake into itself. Queue one turn per tick, validated against the &lt;em&gt;current&lt;/em&gt; direction.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Food respawn.&lt;/strong&gt; Pick from the set of &lt;em&gt;empty&lt;/em&gt; cells, not a random cell retried until free — the retry loop degenerates as the board fills.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Picking an engine
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Vanilla JS + canvas&lt;/strong&gt; — the default. Fill rects per segment, fixed tick, paint with &lt;code&gt;requestAnimationFrame&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;DOM grid with CSS cells&lt;/strong&gt; — accessible labels per tile; heavy at larger boards.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Phaser 4&lt;/strong&gt; — Scene lifecycle and tweens; you still write the tick and reverse-guard.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Full guide: &lt;a href="https://sorceress.games/blog/coil-how-to-make-snake-game-browser-grid-loop-2026" rel="noopener noreferrer"&gt;sorceress.games&lt;/a&gt;&lt;/p&gt;

</description>
      <category>gamedev</category>
      <category>javascript</category>
      <category>webdev</category>
    </item>
    <item>
      <title>How to Make a Platformer Game in the Browser (Run Loop, 2026)</title>
      <dc:creator>Sorceress</dc:creator>
      <pubDate>Sun, 23 Aug 2026 00:31:20 +0000</pubDate>
      <link>https://dev.to/sorceress/how-to-make-a-platformer-game-in-the-browser-run-loop-2026-1ofo</link>
      <guid>https://dev.to/sorceress/how-to-make-a-platformer-game-in-the-browser-run-loop-2026-1ofo</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally published on the &lt;a href="https://sorceress.games/blog/jump-how-to-make-a-platformer-game-browser-run-loop-2026" rel="noopener noreferrer"&gt;Sorceress blog&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; model a side-view run loop with gravity, solid tiles, and a jump buffer. Get one honest jump feeling sticky before adding double-jump, dash, or wall-slide.&lt;/p&gt;

&lt;h2&gt;
  
  
  Scope it first
&lt;/h2&gt;

&lt;p&gt;"Make a platformer" hides three projects: a Metroidvania (ability gates, world map, weeks of systems work), a one-button endless runner, or a single-player side-view platformer with solid tiles, gravity, coyote time, pickups, a following camera and a goal flag. The third is the weekend build.&lt;/p&gt;

&lt;h2&gt;
  
  
  The run loop in one minute
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Input&lt;/strong&gt; — read left/right hold and jump press; set a jump-buffer timer on keydown.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Integrate&lt;/strong&gt; — add gravity to &lt;code&gt;vy&lt;/code&gt;, clamp fall speed, apply acceleration and friction.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Collide&lt;/strong&gt; — move on X and resolve solid tiles, &lt;em&gt;then&lt;/em&gt; move on Y. Only the Y pass sets &lt;code&gt;onGround&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Camera&lt;/strong&gt; — lerp the view toward the player so wide levels stay readable.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Win&lt;/strong&gt; — when the player AABB overlaps the goal flag, stop the clock.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Resolving both axes in one pass is the classic cause of leaking through corners and sticking to walls. Split it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Two timers do most of the "feel"
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Coyote time&lt;/strong&gt; — allow a jump a few frames &lt;em&gt;after&lt;/em&gt; walking off a ledge.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Jump buffer&lt;/strong&gt; — if jump is pressed just &lt;em&gt;before&lt;/em&gt; landing, fire it on touchdown.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;No engine invents these for you. Phaser gives you colliders and tweens; you still write the timers.&lt;/p&gt;

&lt;h2&gt;
  
  
  Picking an engine
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Vanilla JS + canvas&lt;/strong&gt; — the honest default. Level as a 2D tile array, blit from a tileset, draw at world coords minus camera offset. Under ~700 lines, ships as static HTML.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;DOM + CSS transforms&lt;/strong&gt; — accessible focus targets, but trades blit speed for semantics.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Phaser 4&lt;/strong&gt; — when motion polish is the product: arcade bodies, tweens, Scene lifecycle.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Full guide: &lt;a href="https://sorceress.games/blog/jump-how-to-make-a-platformer-game-browser-run-loop-2026" rel="noopener noreferrer"&gt;sorceress.games&lt;/a&gt;&lt;/p&gt;

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