<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>game-lab — toothywalrus</title><link>https://blog.toothywalrus.dev/projects/game-lab/</link><description>Long-form write-ups about SDR, homelab, electronics and tooling — plus a weekly log of what actually got built.</description><language>en-us</language><lastBuildDate>Thu, 06 Aug 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://blog.toothywalrus.dev/projects/game-lab/index.xml" rel="self" type="application/rss+xml"/><item><title>game-lab, week 32: the camera started following the ball</title><link>https://blog.toothywalrus.dev/logbook/2026-w32-game-lab/</link><pubDate>Thu, 06 Aug 2026 00:00:00 +0000</pubDate><guid>https://blog.toothywalrus.dev/logbook/2026-w32-game-lab/</guid><category>weeknotes</category><category>gamedev</category><category>typescript</category><description>&lt;p&gt;&lt;code&gt;metamorph-ball&lt;/code&gt; spent the week turning from a physics sandbox into something
with a shape.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The route replaced the sandbox.&lt;/strong&gt; The arena became an actual course, with
obstacles wired into both the physics world and the renderer, a run clock, a
checkpoint cue and a completion panel. There is now a thing to finish, which
is the difference between a demo and a game.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Two new forms.&lt;/strong&gt; A jelly form that squeezes through a grate, plus rubber and
heavy forms with pads that trigger on contact. The grate opens by dropping its
collider, which is either elegant or cheating depending on how closely you
look.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Juice.&lt;/strong&gt; Squash-and-stretch and spark bursts, fired on the same cues as the
audio so the hit reads as one event instead of three. The sound is synthesised
rather than sampled — fewer assets, and it can be tuned per-event instead of
per-file.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The change that mattered was four lines.&lt;/strong&gt; The camera now follows the ball
instead of waiting to be dragged. Before that, playing it felt like operating
a diagram. Nothing else this week moved the needle as far.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Plumbing:&lt;/strong&gt; a small persistence package for namespaced, versioned local
settings, used first by a quality switch that survives a reload. The asset
pipeline exists now, with one model through it end to end. And the deploy key
is confined to an rrsync jail, so the thing that can write to the server can
only write to one directory.&lt;/p&gt;
&lt;div class="provenance"&gt;
 &lt;h2&gt;Where this came from&lt;/h2&gt;
 &lt;p&gt;Work between 3 and 6 August 2026 in the &lt;code&gt;game-lab&lt;/code&gt; repository — about 20
commits, plus the decision records on the rrsync jail, the grate collider and
the camera. The repository is private.&lt;/p&gt;
&lt;p&gt;Everything above runs in the browser build; the deploy-key jail was applied
and used, not just documented.&lt;/p&gt;

&lt;/div&gt;
</description></item><item><title>Week 32: a subway that ate its passengers, and a project I talked myself out of</title><link>https://blog.toothywalrus.dev/logbook/2026-w32/</link><pubDate>Thu, 06 Aug 2026 00:00:00 +0000</pubDate><guid>https://blog.toothywalrus.dev/logbook/2026-w32/</guid><category>weeknotes</category><description>&lt;p&gt;Short week — Monday to Thursday, because this is the first one of these and I
wanted to see what it looked like before the week was over. Eleven repos
touched. The two things worth reading about are both failures.&lt;/p&gt;
&lt;p&gt;This is the index: a paragraph per project, and a link where there&amp;rsquo;s more.&lt;/p&gt;
&lt;h2 id="the-metro-opened-trapped-everyone-reopened"&gt;The metro opened, trapped everyone, reopened&lt;/h2&gt;
&lt;p&gt;The Minecraft server got a subway — server-side on Paper minecarts, so nobody
has to install anything to ride it. I picked a plugin, built Line 1 as a test,
got it rendering on the web map, then walked into a station and could not get
out. The walls a station generates are perfectly sensible for something
arriving on rails and a sealed box for something arriving on foot.&lt;/p&gt;
&lt;p&gt;Fixed, and written down as a lesson with teeth: if I generate geometry from
config again, a human may approach it from an angle the config never
considered.&lt;/p&gt;
&lt;p&gt;→ &lt;a href="https://blog.toothywalrus.dev/logbook/2026-w32-mc-server/"&gt;mc-server, week 32&lt;/a&gt; — the
plugin choice, the web-map caveat, and a bake-off with no verdict yet.&lt;/p&gt;
&lt;h2 id="stockflow-scoped-down-to-almost-nothing"&gt;StockFlow, scoped down to almost nothing&lt;/h2&gt;
&lt;p&gt;New repo on Monday. By Thursday I&amp;rsquo;d written the case against most of it.&lt;/p&gt;
&lt;p&gt;There is no contributor earnings API — not rate-limited, not partner-gated,
absent. The numbers I wanted to analyse are visible to a human in a dashboard
and nowhere else, and everything I&amp;rsquo;d sketched on top of that assumption goes
with it. Four days spent to avoid four weeks, which is the right trade and
still doesn&amp;rsquo;t feel like a win.&lt;/p&gt;
&lt;p&gt;→ &lt;a href="https://blog.toothywalrus.dev/logbook/2026-w32-stockflow/"&gt;stockflow, week 32&lt;/a&gt; — what
survives, and what I actually checked before concluding that.&lt;/p&gt;
&lt;h2 id="the-traffic-light-is-real"&gt;The traffic light is real&lt;/h2&gt;
&lt;p&gt;The kids&amp;rsquo; electronics track has its first finished project on actual hardware.
Three LEDs, then five interchangeable programs on the same circuit so the
wiring gets built once and the payoff repeats. One is a seven-pattern light
show. One is deliberately calm — a single slow drift, nothing to react to —
and it&amp;rsquo;s the one I keep running.&lt;/p&gt;
&lt;p&gt;→ &lt;a href="https://blog.toothywalrus.dev/logbook/2026-w32-arduino/"&gt;arduino, week 32&lt;/a&gt; — the
toolchain decision, and why the tutorials are generated rather than written
twice.&lt;/p&gt;
&lt;h2 id="four-lines-that-changed-how-a-game-feels"&gt;Four lines that changed how a game feels&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;metamorph-ball&lt;/code&gt; gained a jelly form that squeezes through a grate,
squash-and-stretch and spark bursts fired on the same cues as its audio, and
synthesised sound instead of samples. None of that is the change that
mattered. The camera now follows the ball instead of waiting to be dragged,
and before that, playing it felt like operating a diagram.&lt;/p&gt;
&lt;p&gt;→ &lt;a href="https://blog.toothywalrus.dev/logbook/2026-w32-game-lab/"&gt;game-lab, week 32&lt;/a&gt; — the
route, the forms, and a deploy key that can only write to one directory.&lt;/p&gt;
&lt;h2 id="the-homelab-grew-a-control-plane"&gt;The homelab grew a control plane&lt;/h2&gt;
&lt;p&gt;Host provisioning is Ansible now and has actually been applied, not just
written — a distinction that matters, because half-finished
infrastructure-as-code is worse than none. It tells you the machine is in a
state it isn&amp;rsquo;t. Monitoring went up, bound to the private network only, and the
fleet configuration moved out into its own repo.&lt;/p&gt;
&lt;p&gt;→ &lt;a href="https://blog.toothywalrus.dev/logbook/2026-w32-homelab/"&gt;homelab, week 32&lt;/a&gt; — including
two things learned about drives that I&amp;rsquo;d have preferred to learn earlier.&lt;/p&gt;
&lt;h2 id="a-baseline-taken-before-the-antenna"&gt;A baseline taken before the antenna&lt;/h2&gt;
&lt;p&gt;The SDR receiver got characterised with nothing connected to it. That sounds
like a non-experiment and it&amp;rsquo;s the opposite — once an antenna is attached,
every number is the radio &lt;em&gt;and&lt;/em&gt; the antenna &lt;em&gt;and&lt;/em&gt; the room, with no way to
separate them afterwards.&lt;/p&gt;
&lt;p&gt;→ &lt;a href="https://blog.toothywalrus.dev/logbook/2026-w32-sdr/"&gt;sdr, week 32&lt;/a&gt; — and the full
write-up is going to be this blog&amp;rsquo;s first proper article.&lt;/p&gt;
&lt;h2 id="everything-else-briefly"&gt;Everything else, briefly&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;ToothyGram&lt;/strong&gt; stopped presenting itself as an official Telegram product,
which it never should have. Otherwise: adopted a new upstream base, mapped
where a fork can attach to it, and proved the cheapest attachment point costs
exactly one modified upstream file. There&amp;rsquo;s a divergence log now, and a sync
runbook, because the alternative is rediscovering all of it in six months.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The money project&lt;/strong&gt; landed three long-lived branches — candle storage, chart
event overlays, an ops detail popup. → &lt;a href="https://blog.toothywalrus.dev/logbook/2026-w32-moneybtn2/"&gt;moneybtn2, week
32&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Two repos were born&lt;/strong&gt;: this blog, and the content-studio one that is
deliberately not this blog. Both are still a README and an argument. The
conventions repo gained one rule, which is that a repo must have a description
at creation time — because nothing populates that field automatically and you
notice eleven blank ones at once, months later.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Nothing happened on the academy project.&lt;/strong&gt; One commit, recording a test
result on the Mac and listing the iPad checks still to run. It&amp;rsquo;s on the list
and it didn&amp;rsquo;t get attention, because the metro and the traffic light did.&lt;/p&gt;
&lt;h2 id="the-bit-that-made-me-laugh"&gt;The bit that made me laugh&lt;/h2&gt;
&lt;p&gt;Two branches on the money project both created decision record &lt;code&gt;0089&lt;/code&gt;.
Renumbering to &lt;code&gt;0107&lt;/code&gt; and &lt;code&gt;0108&lt;/code&gt; fixed it — except &lt;code&gt;0089&lt;/code&gt; had &lt;em&gt;also&lt;/em&gt; been
claimed on &lt;code&gt;main&lt;/code&gt; in the meantime, so the survivor became &lt;code&gt;0109&lt;/code&gt;, followed by
a commit to index it and fix a stale reference that had survived the first two
renames.&lt;/p&gt;
&lt;p&gt;Three commits of bookkeeping to land one document about something else
entirely. Sequentially-numbered append-only records are a good convention right
up to the point where you have parallel branches, and I don&amp;rsquo;t have a fix beyond
noticing early.&lt;/p&gt;
&lt;div class="provenance"&gt;
 &lt;h2&gt;Where this came from&lt;/h2&gt;
 &lt;p&gt;Assembled from work between Monday 3 and Thursday 6 August 2026: roughly 90
commits across eleven repositories, plus the decision records written in that
window. The repositories are private, so there is nothing to link to here —
what&amp;rsquo;s above summarises things that are recorded, not recollected.&lt;/p&gt;
&lt;p&gt;Load-bearing sources: &lt;code&gt;mc-server&lt;/code&gt; 0015–0017 and its walkable-tunnel and
web-map notes; &lt;code&gt;stockflow&lt;/code&gt;&amp;rsquo;s build-vs-buy case and platform data-access
research; &lt;code&gt;arduino&lt;/code&gt;&amp;rsquo;s toolchain decision and tutorial 02; &lt;code&gt;game-lab&lt;/code&gt;&amp;rsquo;s
&lt;code&gt;metamorph-ball&lt;/code&gt; iteration C; &lt;code&gt;homelab-infra&lt;/code&gt; 0015–0018; &lt;code&gt;moneybtn2&lt;/code&gt; 0107–0109.&lt;/p&gt;
&lt;p&gt;Nothing above describes something that wasn&amp;rsquo;t actually run or committed. The
TrainCarts bake-off has no result yet and is reported as unfinished; the
satellite and drone SDR work is a plan, not a result.&lt;/p&gt;

&lt;/div&gt;
</description></item></channel></rss>