<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Wild Shift Devlog on Tiziano Basile | Software Engineer</title><link>https://bstz.it/series/wild-shift-devlog/</link><description>Recent content in Wild Shift Devlog on Tiziano Basile | Software Engineer</description><generator>Hugo -- gohugo.io</generator><language>en</language><copyright>Tiziano Basile</copyright><lastBuildDate>Thu, 12 Nov 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://bstz.it/series/wild-shift-devlog/index.xml" rel="self" type="application/rss+xml"/><item><title>Wild Shift Devlog #2: It's always the semicolon</title><link>https://bstz.it/p/wild-shift-devlog-2/</link><pubDate>Thu, 12 Nov 2026 00:00:00 +0000</pubDate><guid>https://bstz.it/p/wild-shift-devlog-2/</guid><description>&lt;p&gt;Second update on &lt;strong&gt;The Debugger 0x03: Wild Shift&lt;/strong&gt;, my GitHub Game Off 2026 entry (theme: &lt;strong&gt;SHIFT&lt;/strong&gt;). If you missed it, &lt;a class="link" href="https://bstz.it/p/wild-shift-devlog-1/" target="_blank" rel="noopener"
&gt;Devlog #1&lt;/a&gt; covered the register and the shift. This post is a mirror of the &lt;a class="link" href="https://basteez.itch.io/wild-shift/devlog/1771895/devlog-2-its-always-the-semicolon-infinite-loop-null-pointer-and-a-duck-that-talks" target="_blank" rel="noopener"
&gt;second devlog on itch.io&lt;/a&gt;. You can also play the current build in the browser on the &lt;a class="link" href="https://basteez.itch.io/wild-shift" target="_blank" rel="noopener"
&gt;game page&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Two bosses down, one to go. Since the last devlog &lt;strong&gt;The Debugger 0x03: Wild Shift&lt;/strong&gt; got its first two real bugs to fix, a duck that talks, and two new bits for the register.&lt;/p&gt;
&lt;h2 id="infinite-loop-the-first-real-bug-epic-3"&gt;Infinite Loop: the first real bug (Epic 3)
&lt;/h2&gt;&lt;p&gt;Last time I promised a snake made of code. Here it is: &lt;strong&gt;Infinite Loop&lt;/strong&gt;, a ring of 24 &lt;code&gt;{ }&lt;/code&gt; segments biting its own tail, with an iteration counter &lt;code&gt;i = 0&lt;/code&gt; floating above it.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;It never stops.&lt;/strong&gt; The ring spins, drifts toward you and gets 5% faster on every lap. &lt;code&gt;i++&lt;/code&gt; ticks up as it goes.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;It&amp;rsquo;s always the semicolon.&lt;/strong&gt; The point where head meets tail is the loop condition, a &lt;code&gt;;&lt;/code&gt; that travels around the ring. Once per lap it opens for 1.5 seconds, and that&amp;rsquo;s the only place you can hurt it.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Weak windows.&lt;/strong&gt; Every phase has an ordered pair of bits that &amp;ldquo;reproduces&amp;rdquo; the bug. Hit the boss with it and it&amp;rsquo;s &lt;strong&gt;Patched&lt;/strong&gt; for 3 seconds: your damage goes from ×0.5 (&lt;code&gt;// resisted&lt;/code&gt;) to ×1.5 (&lt;code&gt;CRITICAL&lt;/code&gt;, in caps, with a flash). Phase 1 wants &lt;code&gt;A→D&lt;/code&gt; (Dash Strike through the open &lt;code&gt;;&lt;/code&gt;), phase 2 wants &lt;code&gt;D→A&lt;/code&gt;, so you have to shift back and forth to patch and then cash in.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Three phases, four attacks.&lt;/strong&gt; &lt;strong&gt;Head Rush&lt;/strong&gt; (the head uncoils and charges), &lt;strong&gt;Constrict&lt;/strong&gt; (the ring re-centres on you and shrinks: dash &lt;em&gt;through&lt;/em&gt; the body to get out), and in phase 3 a &lt;strong&gt;Nested Loop&lt;/strong&gt;: it splits into an outer and an inner ring, each with its own &lt;code&gt;;&lt;/code&gt;, and they open in turn. Outer ring, &lt;code&gt;A→D&lt;/code&gt;. Inner ring, &lt;code&gt;D→A&lt;/code&gt;. Switching rings means switching windows. Plus a &lt;strong&gt;&lt;code&gt;;&lt;/code&gt; Spit&lt;/strong&gt; projectile, because of course.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src="https://bstz.it/p/wild-shift-devlog-2/infinite-loop-ring-duck-bubble.png"
width="1280"
height="720"
srcset="https://bstz.it/p/wild-shift-devlog-2/infinite-loop-ring-duck-bubble_hu_3b33016cba9fc432.png 480w, https://bstz.it/p/wild-shift-devlog-2/infinite-loop-ring-duck-bubble_hu_eed89c16eb7125c6.png 1024w"
loading="lazy"
alt="Infinite Loop closing around the player"
class="gallery-image"
data-flex-grow="177"
data-flex-basis="426px"
&gt;
&lt;em&gt;Infinite Loop in phase 2 (&lt;code&gt;i = 3&lt;/code&gt;) closing around the player. On the left, the duck is still nagging me to shift.&lt;/em&gt;&lt;/p&gt;
&lt;h3 id="the-duck-gets-a-voice"&gt;The duck gets a voice
&lt;/h3&gt;&lt;p&gt;The rubber duck now lives in a text bubble under the register and teaches the fight with jokes: &lt;em&gt;&amp;ldquo;See the semicolon? It&amp;rsquo;s always the semicolon. Hit it when it opens.&amp;rdquo;&lt;/em&gt; If you just stand there, it nudges you (&lt;em&gt;&amp;ldquo;Go on, shift. It&amp;rsquo;s waiting.&amp;rdquo;&lt;/em&gt;) and after a few seconds the loop starts anyway.&lt;/p&gt;
&lt;p&gt;The lines are typed out with a squeak and a gibberish voice made with &lt;a class="link" href="https://github.com/basteez/mumble-speech" target="_blank" rel="noopener"
&gt;&lt;strong&gt;mumble-speech&lt;/strong&gt;&lt;/a&gt;, a small library of mine that turns text into gibberish speech. Its v0.3.0 added a Godot web build, so the duck can talk in the browser too. No voice acting, just a very confident duck.&lt;/p&gt;
&lt;h3 id="defeat-and-harvest"&gt;Defeat and Harvest
&lt;/h3&gt;&lt;p&gt;When the bug dies, it collapses into the line of code it should have been: &lt;code&gt;for (i = 0; i &amp;lt; n; i++) { }&lt;/code&gt;. Then the &lt;strong&gt;Harvest&lt;/strong&gt; screen shows the bit it dropped and the new windows it opens in your ring.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://bstz.it/p/wild-shift-devlog-2/harvest-loop-bit.png"
width="1280"
height="720"
srcset="https://bstz.it/p/wild-shift-devlog-2/harvest-loop-bit_hu_99e02054569721e7.png 480w, https://bstz.it/p/wild-shift-devlog-2/harvest-loop-bit_hu_539e218a7837a8b9.png 1024w"
loading="lazy"
alt="Harvest screen after Infinite Loop"
class="gallery-image"
data-flex-grow="177"
data-flex-basis="426px"
&gt;
&lt;em&gt;Harvest: Infinite Loop drops LOOP. The register becomes &lt;code&gt;[A, D, L] = 0x07&lt;/code&gt; and &lt;code&gt;D→L&lt;/code&gt; unlocks Echo Dash.&lt;/em&gt;&lt;/p&gt;
&lt;h2 id="loop-echo-dash-and-breakpoint-epic-4"&gt;LOOP, Echo Dash and Breakpoint (Epic 4)
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;LOOP (&lt;code&gt;L&lt;/code&gt;) = Echo.&lt;/strong&gt; It replays your last solo move from where you&amp;rsquo;re standing now, at 70% damage. Slash, step away, Echo: a second slash where you are. It has a 1.5 s cooldown, and if you haven&amp;rsquo;t done anything yet it just does nothing (no cooldown wasted).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Echo Dash (&lt;code&gt;D→L&lt;/code&gt;).&lt;/strong&gt; Dash, then Echo: a second dash you can point in a new direction, invulnerable the whole way through with no gap. It&amp;rsquo;s how you pass &lt;em&gt;through&lt;/em&gt; a boss, and against the next one it does more than that.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Breakpoint (&lt;code&gt;Space&lt;/code&gt;).&lt;/strong&gt; Freezes the simulation for up to 2 seconds, but shifting still works. The screen dithers, a red breakpoint dot appears, and you get to think. 12 s cooldown. &lt;em&gt;Finally, a debugger that works.&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Duck hints.&lt;/strong&gt; If you&amp;rsquo;re stuck, the duck tells you the weak window: &lt;code&gt;&amp;quot;Quack. Weak window: D→A.&amp;quot;&lt;/code&gt;. It speaks on Breakpoint (once per phase) and every third death on the same boss. In the Nested Loop phase it names the window of the ring that opens next.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="null-pointer-a-ghost-that-points-at-nothing-epic-5"&gt;Null Pointer: a ghost that points at nothing (Epic 5)
&lt;/h2&gt;&lt;p&gt;The second bug is &lt;strong&gt;Null Pointer&lt;/strong&gt;, a ghost made of &lt;code&gt;null&lt;/code&gt; glyphs. It&amp;rsquo;s &lt;strong&gt;invisible&lt;/strong&gt;: you only see it while it attacks, for a few frames when you hit it, and for a second after an Echo Dash goes through it.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Finding it.&lt;/strong&gt; A column of falling &lt;code&gt;null&lt;/code&gt; glyphs drifts under it, and it hums, panned left or right by where it is. The sky comment reads &lt;code&gt;// FIXME: who owns this pointer?&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Pointer Grab:&lt;/strong&gt; a &lt;code&gt;*&lt;/code&gt; appears behind you, then it grabs. &lt;strong&gt;Null Rain:&lt;/strong&gt; five marked areas, then &lt;code&gt;null&lt;/code&gt; falls on them.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Dangling Pointers&lt;/strong&gt; (phase 2): two decoy ghosts. They don&amp;rsquo;t hum, and hitting one just dispels it.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;NullPointerException.&lt;/strong&gt; Swing a slash at nothing while the ghost is close and you&amp;rsquo;re stunned for a third of a second. Don&amp;rsquo;t attack blindly.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Watch (hold &lt;code&gt;R&lt;/code&gt;).&lt;/strong&gt; Reveals the ghost and its decoys, shows the name of its next attack, the bit it will drop and its weak window. You move at half speed and can&amp;rsquo;t act while you hold it, so it&amp;rsquo;s a peek, not a crutch.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src="https://bstz.it/p/wild-shift-devlog-2/null-pointer-pointer-grab.png"
width="1280"
height="720"
srcset="https://bstz.it/p/wild-shift-devlog-2/null-pointer-pointer-grab_hu_b2f9da81dccff0ea.png 480w, https://bstz.it/p/wild-shift-devlog-2/null-pointer-pointer-grab_hu_fc271feb66918c8d.png 1024w"
loading="lazy"
alt="Pointer Grab tell"
class="gallery-image"
data-flex-grow="177"
data-flex-basis="426px"
&gt;
&lt;em&gt;Pointer Grab&amp;rsquo;s tell: a &lt;code&gt;*&lt;/code&gt; lands right behind the player (&lt;code&gt;@&lt;/code&gt;) while the ghost closes in. &lt;code&gt;[D, L]&lt;/code&gt; is live, so Echo Dash is one K away.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="https://bstz.it/p/wild-shift-devlog-2/null-pointer-null-rain.png"
width="1280"
height="720"
srcset="https://bstz.it/p/wild-shift-devlog-2/null-pointer-null-rain_hu_38d24c3b79e0eaf3.png 480w, https://bstz.it/p/wild-shift-devlog-2/null-pointer-null-rain_hu_a3917d901bd261e5.png 1024w"
loading="lazy"
alt="Null Rain"
class="gallery-image"
data-flex-grow="177"
data-flex-basis="426px"
&gt;
&lt;em&gt;Null Rain: five areas marked, and the column of &lt;code&gt;null&lt;/code&gt; glyphs that gives the invisible ghost away.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="https://bstz.it/p/wild-shift-devlog-2/null-pointer-watch.png"
width="1280"
height="720"
srcset="https://bstz.it/p/wild-shift-devlog-2/null-pointer-watch_hu_ddccb8d230e54ff2.png 480w, https://bstz.it/p/wild-shift-devlog-2/null-pointer-watch_hu_e69d781b81c25c78.png 1024w"
loading="lazy"
alt="Holding Watch on Null Pointer"
class="gallery-image"
data-flex-grow="177"
data-flex-basis="426px"
&gt;
&lt;em&gt;Holding Watch: the ghost shows up, with its next attack (&lt;code&gt;pointer_grab&lt;/code&gt;), its drop (&lt;code&gt;N&lt;/code&gt;) and its weak window (&lt;code&gt;D→L&lt;/code&gt;).&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;At the start of the fight the duck introduces the two new skills (&lt;em&gt;&amp;ldquo;Hold R. Pointers point *somewhere*.&amp;rdquo;&lt;/em&gt;). Beat it and it collapses into &lt;code&gt;if (ptr != null) ptr.deref();&lt;/code&gt; and drops &lt;strong&gt;NULL&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Null Dodge (&lt;code&gt;N&lt;/code&gt;):&lt;/strong&gt; half a second of intangibility, at half speed.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Clean Catch:&lt;/strong&gt; if an attack passes through you during a Null Dodge, your next damaging hit deals ×1.5, on top of Patched.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;em&gt;(The &amp;ldquo;FIGHT N / boss index N&amp;rdquo; text in the middle of the arena is still a placeholder from the scene flow: it goes away in polish.)&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Fun fact: the GDD planned Epic 5 for November 18–21. It was done on November 12, so I&amp;rsquo;m almost a week ahead of schedule.&lt;/p&gt;
&lt;h2 id="housekeeping"&gt;Housekeeping
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;The game is live on itch.io as a web build (about 28 MB), with a deploy from CI. Running it in a real browser found two pause bugs (resume with &lt;code&gt;P&lt;/code&gt; or a click when fullscreen eats &lt;code&gt;Esc&lt;/code&gt;, and a game frozen after a focus-loss pause), both fixed.&lt;/li&gt;
&lt;li&gt;The web build budget went from 30 to 32 MB to make room for the voice and the second boss.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="how-its-made"&gt;How it&amp;rsquo;s made
&lt;/h2&gt;&lt;p&gt;Same as before: I&amp;rsquo;m the director and the playtester, AI agents (Claude) write the code from specs I approve with the &lt;a class="link" href="https://github.com/bmad-code-org/BMAD-METHOD" target="_blank" rel="noopener"
&gt;BMAD Method&lt;/a&gt;, and every story is a pull request with code review and automated tests. The test suite went from 55 to &lt;strong&gt;95 test files&lt;/strong&gt;. Everything is public in the &lt;a class="link" href="https://github.com/basteez/the-debugger-0x3-wild-shift" target="_blank" rel="noopener"
&gt;GitHub repo&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id="next-up"&gt;Next up
&lt;/h2&gt;&lt;p&gt;One bug left, and it&amp;rsquo;s the worst kind. It reads and writes memory it shouldn&amp;rsquo;t, and it doesn&amp;rsquo;t care that the register is &lt;em&gt;yours&lt;/em&gt;. Plus an intro and an ending, so the run finally has a beginning and a &lt;code&gt;return&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Thanks for reading!&lt;/p&gt;</description></item><item><title>Wild Shift Devlog #1: Your weapon is a byte</title><link>https://bstz.it/p/wild-shift-devlog-1/</link><pubDate>Tue, 10 Nov 2026 00:00:00 +0000</pubDate><guid>https://bstz.it/p/wild-shift-devlog-1/</guid><description>&lt;p&gt;It&amp;rsquo;s November again, which means GitHub Game Off. Last year I built &lt;a class="link" href="https://bstz.it/p/adding-interactive-cockpit-controls-to-grav-sync/" target="_blank" rel="noopener"
&gt;Grav-Sync&lt;/a&gt; in plain JavaScript; this year the theme is &lt;strong&gt;SHIFT&lt;/strong&gt; and my entry is &lt;strong&gt;The Debugger 0x03: Wild Shift&lt;/strong&gt;, a top-down boss rush made with Godot 4.7. You can follow it on &lt;a class="link" href="https://basteez.itch.io/wild-shift" target="_blank" rel="noopener"
&gt;itch.io&lt;/a&gt;, and this post is a mirror of the &lt;a class="link" href="https://basteez.itch.io/wild-shift/devlog/1767483/devlog-1-your-weapon-is-a-byte-building-the-register" target="_blank" rel="noopener"
&gt;first devlog I published there&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The idea in one line:&lt;/strong&gt; your weapon is a bit register. Shift it left or right mid-fight, and the two leftmost bits become your two action buttons. A present-day developer and their rubber duck get pulled into a fantasy RPG where the monsters are literal software bugs: Infinite Loop, Null Pointer and Segfault.&lt;/p&gt;
&lt;h2 id="day-1-making-it-run-in-the-browser-epic-1"&gt;Day 1: making it run in the browser (Epic 1)
&lt;/h2&gt;&lt;p&gt;Before writing any gameplay, I wanted the boring stuff to work: a Godot 4.7 project that runs at a locked 60 Hz with pixel-perfect integer scaling, a web export that stays under 30 MB, and a CI pipeline that runs the tests on every pull request.&lt;/p&gt;
&lt;p&gt;Then the shell of the game:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;a &lt;strong&gt;title screen with &amp;ldquo;press to start&amp;rdquo;&lt;/strong&gt;, because browsers won&amp;rsquo;t play audio before your first input&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The Clearing&lt;/strong&gt;, the arena, framed by an IDE-style HUD: register panel on the left, log panel at the bottom, line numbers down the edge&lt;/li&gt;
&lt;li&gt;the whole scene flow with placeholders (Title → Intro → Fight → Harvest → … → Ending)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;auto-pause&lt;/strong&gt; when you switch tabs, so the boss doesn&amp;rsquo;t kill you while you read Slack&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="days-23-the-shift-has-to-feel-good-epic-2"&gt;Days 2–3: the shift has to feel good (Epic 2)
&lt;/h2&gt;&lt;p&gt;The goal of Epic 2 was simple to say and hard to do: &lt;em&gt;shifting should feel great in an empty arena, before there&amp;rsquo;s anything to fight.&lt;/em&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;The register is a ring.&lt;/strong&gt; &lt;code&gt;Q&lt;/code&gt; rotates it &lt;code&gt;&amp;lt;&amp;lt;&lt;/code&gt;, &lt;code&gt;E&lt;/code&gt; rotates it &lt;code&gt;&amp;gt;&amp;gt;&lt;/code&gt;. It only contains the bits you own, so you can never end up in a dead state. The HUD also shows its byte value, so your build is literally &lt;code&gt;0x03&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Shift juice:&lt;/strong&gt; the register slides with a small overshoot bounce, a mechanical key-click (two different sounds for left and right), and your weapon inverts for 4 frames.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ATTACK and DASH:&lt;/strong&gt; a 3-hit slash chain and an 8-frame invulnerable dash.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ordered combos:&lt;/strong&gt; the order matters. &lt;code&gt;[A, D]&lt;/code&gt; (attack then dash) is &lt;strong&gt;Dash Strike&lt;/strong&gt;, &lt;code&gt;[D, A]&lt;/code&gt; is just a dash followed by a slash.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Hit feedback:&lt;/strong&gt; hit-stop, glyph particles flying off the target, and every hit printed as a &lt;code&gt;console.log&lt;/code&gt; line.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src="https://bstz.it/p/wild-shift-devlog-1/slash-chain.png"
width="1280"
height="720"
srcset="https://bstz.it/p/wild-shift-devlog-1/slash-chain_hu_46f6b28a07312bd6.png 480w, https://bstz.it/p/wild-shift-devlog-1/slash-chain_hu_9369637b36e4d3a4.png 1024w"
loading="lazy"
alt="The 3-hit slash chain on the practice target"
class="gallery-image"
data-flex-grow="177"
data-flex-basis="426px"
&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;The 3-hit slash chain on the practice target: glyph particles and damage logged to the console.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="https://bstz.it/p/wild-shift-devlog-1/dash-strike.png"
width="1280"
height="720"
srcset="https://bstz.it/p/wild-shift-devlog-1/dash-strike_hu_8a2070696764be3.png 480w, https://bstz.it/p/wild-shift-devlog-1/dash-strike_hu_682d7451ef1c86a9.png 1024w"
loading="lazy"
alt="The register after one shift, with the Dash Strike window active"
class="gallery-image"
data-flex-grow="177"
data-flex-basis="426px"
&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;After one &lt;code&gt;&amp;lt;&amp;lt;&lt;/code&gt; the active window is &lt;code&gt;[A, D]&lt;/code&gt;: J→K fires a Dash Strike.&lt;/em&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Death and retry:&lt;/strong&gt; you have 5 HP, shown as &lt;code&gt;0b11111&lt;/code&gt;. When you die you get &lt;code&gt;Process exited with code 1&lt;/code&gt;, and one key puts you back at the start of the fight in under 2 seconds.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;A practice target:&lt;/strong&gt; &lt;code&gt;/* test */&lt;/code&gt;, with infinite HP and a frame counter, so I can check the combo numbers on screen.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src="https://bstz.it/p/wild-shift-devlog-1/process-exited.png"
width="1280"
height="720"
srcset="https://bstz.it/p/wild-shift-devlog-1/process-exited_hu_2b46cea53c299ce5.png 480w, https://bstz.it/p/wild-shift-devlog-1/process-exited_hu_d38d10e0974effc2.png 1024w"
loading="lazy"
alt="The death screen: Process exited with code 1"
class="gallery-image"
data-flex-grow="177"
data-flex-basis="426px"
&gt;&lt;/p&gt;
&lt;p&gt;Under the hood the whole simulation is deterministic: it runs on a fixed 60 Hz clock, with seeded randomness and recorded input replays. That means a bug I find while playing can be replayed exactly in a test.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;(The &amp;ldquo;FIGHT 1 / boss index 0&amp;rdquo; text in the screenshots is a placeholder: the arena is still waiting for its first boss.)&lt;/em&gt;&lt;/p&gt;
&lt;h2 id="how-its-made"&gt;How it&amp;rsquo;s made
&lt;/h2&gt;&lt;p&gt;I&amp;rsquo;m making this solo, as director and playtester. The code is written by AI agents (Claude), following specs I write and approve with the &lt;a class="link" href="https://github.com/bmad-code-org/BMAD-METHOD" target="_blank" rel="noopener"
&gt;BMAD Method&lt;/a&gt;, the same workflow I described in &lt;a class="link" href="https://bstz.it/p/a-bmad-workflow-end-to-end-shipping-a-feature-the-spec-driven-way/" target="_blank" rel="noopener"
&gt;BMAD, end to end&lt;/a&gt;: game brief → GDD → architecture → one spec per story. Every story is a pull request with code review and automated tests (55 test files by the end of Epic 2). All the design docs are public in the &lt;a class="link" href="https://github.com/basteez/the-debugger-0x3-wild-shift" target="_blank" rel="noopener"
&gt;GitHub repo&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id="next-up"&gt;Next up
&lt;/h2&gt;&lt;p&gt;The first real bug: &lt;strong&gt;Infinite Loop&lt;/strong&gt;, a snake made of code that repeats its attacks… until you find its weak window. Plus the rubber duck, who finally gets a voice, powered by &lt;a class="link" href="https://github.com/basteez/mumble-speech" target="_blank" rel="noopener"
&gt;mumble-speech&lt;/a&gt;, my own library: v0.3.0 added Godot web support, so the duck can talk in the browser too.&lt;/p&gt;
&lt;p&gt;Thanks for reading!&lt;/p&gt;</description></item></channel></rss>