<?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: Alexander Schikowsky</title>
    <description>The latest articles on DEV Community by Alexander Schikowsky (@alexander_schikowsky).</description>
    <link>https://dev.to/alexander_schikowsky</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%2F4210372%2Fccb9b83f-d372-4ecf-986e-a0adc63055fa.png</url>
      <title>DEV Community: Alexander Schikowsky</title>
      <link>https://dev.to/alexander_schikowsky</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/alexander_schikowsky"/>
    <language>en</language>
    <item>
      <title>We built the castle game from our childhood with Claude, in 9 days, in the browser</title>
      <dc:creator>Alexander Schikowsky</dc:creator>
      <pubDate>Tue, 27 Oct 2026 10:00:27 +0000</pubDate>
      <link>https://dev.to/alexander_schikowsky/we-built-the-castle-game-from-our-childhood-with-claude-in-9-days-in-the-browser-4bld</link>
      <guid>https://dev.to/alexander_schikowsky/we-built-the-castle-game-from-our-childhood-with-claude-in-9-days-in-the-browser-4bld</guid>
      <description>&lt;p&gt;As kids we played a lot of Stronghold. Build a castle, keep the peasants fed, set taxes too high, watch them leave, then defend the walls against a siege. We've talked about making our own version for years. Last week we finally started, with Claude Code doing most of the programming.&lt;/p&gt;

&lt;p&gt;The result is &lt;a href="https://kingdomsofsand.com/?lang=en" rel="noopener noreferrer"&gt;Kingdoms of Sand&lt;/a&gt;: a real-time castle strategy game in 3D that runs in the browser, for 1 to 8 players. It's in closed beta now. This post covers what the game is, how we worked with Claude, and some technical details.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fzm32uaqpmh5kzmay4dsb.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fzm32uaqpmh5kzmay4dsb.jpg" alt="The Kingdoms of Sand start page" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What the game is
&lt;/h2&gt;

&lt;p&gt;Kingdoms of Sand is inspired by Stronghold, but the graphics, numbers and rules are our own. It's set in a desert with oases, swamps and rock ridges.&lt;/p&gt;

&lt;p&gt;You run an economy with 62 buildings and 23 goods: wood, stone, iron, pitch from the swamp, the wheat to flour to bread chain, apples, cheese, hunting, ale, leather, weapon and armour smiths, horses and a market. Your people care about rations, taxes, ale and religion, and you pick a ruling style between gentle and harsh, which affects popularity, work speed and morale.&lt;/p&gt;

&lt;p&gt;You draw walls, palisades, moats and pitch ditches as lines or as closed rings. Soldiers walk on the walls, ballistae sit on towers, drawbridges go up and down. Attackers bring rams, catapults, trebuchets, siege towers, ladders and sappers. When a wall collapses, the soldiers standing on it fall with it.&lt;/p&gt;

&lt;p&gt;There are also dragons. You hatch them from eggs and they set towns on fire.&lt;/p&gt;

&lt;p&gt;It runs in any modern browser, including phones in portrait and landscape. Nothing to download.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3sprdpqumwluvw0tjpn1.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3sprdpqumwluvw0tjpn1.jpg" alt="A siege: the wall comes down in a cloud of dust" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Nine days
&lt;/h2&gt;

&lt;p&gt;The first entry in our changelog is v0.1.0, "The first walls", on 19 October 2026. Today we're at v0.81.3. That's 145 releases and about 250 pull requests in nine days.&lt;/p&gt;

&lt;p&gt;We planned a 2D isometric game. This is day 1:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fkrxpzwubzg9vmsfhlo5g.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fkrxpzwubzg9vmsfhlo5g.jpg" alt="Day 1: the 2D isometric version" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It worked, but it didn't look like the game we had in mind. On day 4 we asked Claude to try the same scene in 3D with three.js, next to the 2D renderer. We compared both, and by the next day the whole game was 3D.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1arkam67uzii4gvmwf8h.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1arkam67uzii4gvmwf8h.jpg" alt="Day 4: the first 3D version" width="800" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is today. Most of the last five days went into details: fire that starts at the roof and spreads, horses that walk instead of sliding, rounder fruit on the market stalls (that one is an actual changelog entry).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fq7eelj7h487a73fyr2z4.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fq7eelj7h487a73fyr2z4.jpg" alt="Today: castle, town and walls" width="800" height="385"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A few other changelog entries:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"No more confetti in the sand." Small grass tufts showed up as red and green dots on iPhones.&lt;/li&gt;
&lt;li&gt;"A desert land without rain." We had added weather including rain, then remembered it's a desert.&lt;/li&gt;
&lt;li&gt;"No more smoke walls over battles."&lt;/li&gt;
&lt;li&gt;"Battles with 10,000 soldiers."&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F31qv1nbx9qxt42x66gdl.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F31qv1nbx9qxt42x66gdl.jpg" alt="A few hundred soldiers meeting at an oasis" width="800" height="320"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How we worked with Claude
&lt;/h2&gt;

&lt;p&gt;We're a small software company in Germany, not a game studio. No 3D artist, no sound designer. Claude wrote most of the code. We played every build and decided what to change.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;We wrote the plan first.&lt;/strong&gt; Before any code there were concept documents: a master plan, the architecture, a simulation spec with the formulas, a netcode spec and a backlog. They're in the repo, and Claude reads and updates them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;We ran many small threads in parallel.&lt;/strong&gt; Instead of one long conversation, each task got its own thread: fix the horse animation, add clans and tournaments, translate the game to English, find out why it stutters on laptops. Each thread has its own branch and opens its own PR. On busy days that meant a few dozen PRs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Rules go into &lt;code&gt;CLAUDE.md&lt;/code&gt;.&lt;/strong&gt; With several threads working at once, they need shared rules. Two of ours:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Every change players can see gets a changelog line in German and English, written for players. That's also how we know what happened on which day.&lt;/li&gt;
&lt;li&gt;Pick the version number last. Before merging, a thread merges &lt;code&gt;main&lt;/code&gt;, looks at the newest entry and takes the next free number. This stopped most of our merge conflicts.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Every change comes with a test.&lt;/strong&gt; New behaviour gets a new test, a bug fix gets a test that fails without the fix. There are about 1,250 unit tests and 21 Playwright end-to-end specs that register players, start matches, build walls, run sieges and check the phone layout. Every PR runs typecheck and the quick tests. Every push to &lt;code&gt;main&lt;/code&gt; runs all tests and the Docker build before it deploys.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Every visual change comes with screenshots.&lt;/strong&gt; Claude takes before/after screenshots and short clips with Playwright against a local server and attaches them to the PR. Reviewing a picture is much faster than reviewing a diff, especially for graphics.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;We make the design calls.&lt;/strong&gt; Our feedback was usually short and concrete: the walls are too weak, the knight looks like a toy, a horse doesn't move like that. Claude then figured out how to fix it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F8xp6eklrzgufq276owkh.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F8xp6eklrzgufq276owkh.jpg" alt="The HUD: resources, popularity, the lord's abilities and the build menu" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Technical details
&lt;/h2&gt;

&lt;p&gt;TypeScript monorepo with pnpm workspaces, about 80,000 lines:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;packages/sim       deterministic game simulation (no DOM, no clock, no Math.random)
packages/content   buildings, units, recipes, balance tables as typed data
packages/protocol  binary snapshots and deltas, shared by client and server
packages/ai        the AI opponents
apps/server        Node, WebSocket, PostgreSQL, matchmaking, replays
apps/client        React HUD and three.js renderer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Deterministic simulation.&lt;/strong&gt; Positions are integers in 1/256 of a tile, random numbers come from a seeded RNG stored in the world state, and entities are always processed in the same order. The same start state and the same commands produce the same world, which tests check with a hash. Replays, reconnects and live spectating all use this: they replay the command log.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Server-authoritative netcode.&lt;/strong&gt; Each match runs on the server at 10 ticks per second in a worker thread. Clients send commands, the server validates them and sends binary deltas back. Each player and their allies get their own delta stream that only contains what they can see. Fog of war is enforced on the server, so a modified client has nothing hidden to reveal.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Large battles.&lt;/strong&gt; A match allows up to 10,000 soldiers. Soldiers given the same order share one pathfinding result, so 1,000 of them start moving after 0.2 seconds. In our benchmark, two armies of 2,000 take about 18 to 22 ms per tick on the server, against a budget of 100 ms.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3D without a 3D artist.&lt;/strong&gt; Buildings, walls, terrain, water and fire are generated in code with three.js. The characters started as AI-generated rigged models. Claude wrote a Blender Python script that cleans them up, attaches weapons and shields, selects the animations and exports a compact binary format. The animation data is stored in a texture, so the GPU animates the soldiers and a few thousand of them still run smoothly.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fjczz6lzekun4x6pryhbe.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fjczz6lzekun4x6pryhbe.gif" alt="Fire spreading through the town until the roofs collapse" width="640" height="309"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;AI opponents.&lt;/strong&gt; Four strategies: a defensive one, a trader, a raider and a siege specialist. They differ in castle layout, when they attack, how many troops they keep at home and which units they build. We balance them with a headless benchmark that plays every pairing on several maps from both starting positions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The rest.&lt;/strong&gt; PostgreSQL, OpenSkill for matchmaking (visible ranks from Squire to Emperor), ranked 1v1, 2v2 and 4-player free-for-all, clans, knockout tournaments, live spectating, replays, an offline mode against up to seven AI opponents that saves when you leave, a three-mission tutorial, and German and English.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fk1do67godc3zm1hvhjjy.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fk1do67godc3zm1hvhjjy.jpg" alt="A dragon over the town during a battle" width="800" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What we learned
&lt;/h2&gt;

&lt;p&gt;The code was rarely the bottleneck. Deciding what we wanted was. Small, specific requests with a screenshot of the problem worked much better than large, vague ones.&lt;/p&gt;

&lt;p&gt;Anything we had to say twice went into &lt;code&gt;CLAUDE.md&lt;/code&gt;. After that, new threads followed it without reminders.&lt;/p&gt;

&lt;p&gt;Tests are what allowed us to merge this fast. Most mistakes failed a test before anyone played them.&lt;/p&gt;

&lt;p&gt;Our end-to-end tests render real 3D in headless browsers with software WebGL. That got too slow for the CI runners, so the full end-to-end suite now runs on demand instead of on every deploy.&lt;/p&gt;

&lt;h2&gt;
  
  
  Closed beta
&lt;/h2&gt;

&lt;p&gt;We're looking for players who build strange castles, find exploits, start 8-player matches and tell us what breaks. Developers and strategy game fans are very welcome.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://kingdomsofsand.com/?lang=en#warteliste" rel="noopener noreferrer"&gt;Join the waitlist on kingdomsofsand.com&lt;/a&gt;&lt;/strong&gt;. Leave your email address and we'll send you an invite code.&lt;/p&gt;

&lt;p&gt;If you have questions about the stack, the netcode or working with Claude on a project like this, ask in the comments.&lt;/p&gt;

</description>
      <category>gamedev</category>
      <category>ai</category>
      <category>threejs</category>
      <category>typescript</category>
    </item>
  </channel>
</rss>
