<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
  <title>The Bark Blog</title>
  <subtitle>What we built this week, what broke, and how we fixed it.</subtitle>
  <link rel="self" type="application/atom+xml" href="https://allbark.dev/devlog/feed.xml" />
  <link rel="alternate" type="text/html" href="https://allbark.dev/devlog/" />
  <id>https://allbark.dev/devlog/</id>
  <updated>2026-10-25T00:00:00-07:00</updated>
  <author><name>All Bark</name><uri>https://allbark.dev/</uri></author>
  <icon>https://allbark.dev/assets/devlog/paw.svg</icon><entry>
    <title>Week four: a monster is just a hero the DM runs</title>
    <link rel="alternate" type="text/html" href="https://allbark.dev/devlog/2026/w43-a-monster-is-a-hero/" />
    <id>https://allbark.dev/devlog/2026/w43-a-monster-is-a-hero/</id>
    <published>2026-10-25T00:00:00-07:00</published>
    <updated>2026-10-25T00:00:00-07:00</updated>
    <summary>The DM got the same combat wheel the players have, monster hits now land conditions on heroes&apos; phones, Hold Person and Bless finally do what they say, and heroes picked up companions. Here&apos;s how Cerberus learned to run the other side of the fight.</summary>
    <content type="html">&lt;p&gt;Week three, Cerberus learned to celebrate. Week four, the DM finally got to play too. Monsters take
real turns on the same combat wheel the heroes use, their hits put conditions on the heroes’
phones, and spells like Hold Person and Bless actually do what they say at the table. Heroes also
picked up companions: familiars, steeds, summoned spirits, figurines, each with a card of its own.&lt;/p&gt;

&lt;p&gt;That was 52 merged pull requests, split between Opus and Fable again. Most of the week’s fixes
came from playing whole fights end to end, over and over, so this post goes deep on the DM’s
wheel, on making effects land, and on how the testing worked. The rest gets the usual one breath at
the end.&lt;/p&gt;

&lt;h2 id=&quot;a-monster-is-just-a-hero-the-dm-runs&quot;&gt;A monster is just a hero the DM runs&lt;/h2&gt;

&lt;p&gt;The first DM screen was its own thing. Monster cards with an attack panel, aiming chips stuffed
inside the card, and a bottom bar for Next turn and End combat. It worked, kind of. But the players
already had a combat wheel that was pretty good at running a turn, and the DM was off doing
something completely different.&lt;/p&gt;

&lt;p&gt;So I wanted the monsters on the same wheel and sheet the players use. It’s easier, it’s more
condensed, and picking a target felt like it belonged in a pop-up, not crammed into the attack
card. Fable mocked up three layouts and three target pickers side by side. I went with the “arena”
layout and a grid of faces for aiming, because the grid fits a lot more targets in the same space.&lt;/p&gt;

&lt;p&gt;Then I pushed it further. I didn’t want a copy of the player’s screen with monster stuff bolted on.
I wanted the &lt;em&gt;same component&lt;/em&gt;. Mechanically there’s honestly not a lot of difference between a
player’s hero and a monster the DM controls. The DM is basically running a bunch of heroes at once,
and should get to their saves, reactions and resources just as easily.&lt;/p&gt;

&lt;p&gt;So Fable turned the player’s in-fight sheet into a “fighter frame” that anything can stand in. An
adapter fills it in, and each role adds its own tools around the edges. Monsters went in first.&lt;/p&gt;

&lt;figure class=&quot;shot&quot;&gt;
  &lt;a href=&quot;https://allbark.dev/assets/devlog/2026-w43/dm-wheel-multiattack.png&quot;&gt;&lt;img src=&quot;https://allbark.dev/assets/devlog/2026-w43/dm-wheel-multiattack.png&quot; alt=&quot;The DM&amp;#39;s phone in round 1: a rail of three goblin tokens with their Initiatives (22, 21, 7) and an Add tile, then the Goblin Boss, AC 17 and 21 of 21 HP, with its combat wheel reading Attack 1 of 2, Bonus Action and Reaction around an End Turn hub&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; /&gt;&lt;/a&gt;&lt;figcaption&gt;The Goblin Boss, on the same wheel a hero gets. This is from the day it shipped. The &lt;strong&gt;Add a creature&lt;/strong&gt; row under the wheel got cut later in the week.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;Here’s how a stat block maps onto the wheel. The turn order runs across the top as a rail of
tokens, each one a face in a ring of health with its Initiative on the shoulder. Attacks go under
Attack, and Multiattack counts down (“Attack 1 of 2”). Bonus Actions, Reactions, Legendary Actions
and Recharge sit where a hero’s resources would. Tap an attack and a grid of faces comes up to pick
who’s getting hit.&lt;/p&gt;

&lt;figure class=&quot;shot&quot;&gt;
  &lt;a href=&quot;https://allbark.dev/assets/devlog/2026-w43/dm-aim-grid.png&quot;&gt;&lt;img src=&quot;https://allbark.dev/assets/devlog/2026-w43/dm-aim-grid.png&quot; alt=&quot;The DM&amp;#39;s wheel dimmed behind a Scimitar sheet reading &amp;#39;+4 to hit · at whom?&amp;#39; with two goblin faces to pick, AC 15 each, and a Just roll button&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; /&gt;&lt;/a&gt;&lt;figcaption&gt;Goblins fighting goblins. Part of the testing was letting monsters go after each other.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;h3 id=&quot;it-has-to-actually-spend-the-turn&quot;&gt;It has to actually spend the turn&lt;/h3&gt;

&lt;p&gt;The first version looked right and played wrong. My monsters could keep attacking forever, and
there was no roll card popping up, just dice sounds coming from somewhere. So Fable made the wheel
spend a monster’s turn exactly the way it spends a hero’s, and every DM roll now goes up on the same
roll card the players see. The players’ sheets show the same rail, too.&lt;/p&gt;

&lt;p&gt;The roll card got one more DM-flavored change. A monster’s attack used to show the damage roll
right next to the hit, which kind of ruins the moment. Now a monster’s attack rolls its d20 alone,
and the damage stays hidden until the DM taps Roll damage. Multiattack was the other drag, since
you had to go back through the wheel for every swing. Now it chains the way a hero’s Extra Attack
already did, with a Next attack button right on the roll card. Fable built both.&lt;/p&gt;

&lt;h2 id=&quot;effects-that-land&quot;&gt;Effects that land&lt;/h2&gt;

&lt;p&gt;Plenty of spells and monster abilities used to just be text. Hold Person said the target was
Paralyzed, and then… nothing changed. This week Opus made them actually change the creature
they hit:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Hold Person, Bane, Command and Blindness&lt;/strong&gt; roll the target’s save on the DM’s screen and put
the condition on.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;A Ghoul’s Claw paralyzes the hero&lt;/strong&gt; on their own phone.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Conditions end on their own clock&lt;/strong&gt;, no one has to remember to take them off.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Hitting a Paralyzed creature&lt;/strong&gt; rolls with Advantage, and crits up close.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Bless adds its d4&lt;/strong&gt; to attacks and saves, and a Life cleric’s slot heals add Disciple of Life.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Charmed creatures can’t attack their charmer.&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;read-the-stat-block-not-a-new-data-field&quot;&gt;Read the stat block, not a new data field&lt;/h3&gt;

&lt;p&gt;Then there were the monsters whose best moves did nothing. The aboleth’s Lash could be used over
and over and never hit anyone. When we counted, 32 of the SRD’s 79 Legendary Actions did nothing,
because their text just points at another attack (“makes one Tentacle attack”) or at a spell
(“uses Spellcasting to cast Fear”). 25 of them cast a spell.&lt;/p&gt;

&lt;p&gt;There was a lazy version of the fix on the table, and I wasn’t into it. The other easy way out was
adding new fields to every monster in the data. Instead, Opus taught the engine to read the stat
block’s own text at runtime and follow the pointer. The nice side effect is that a homebrew stat
block written the SRD way just works too.&lt;/p&gt;

&lt;h2 id=&quot;play-the-fight-dont-patch-it&quot;&gt;Play the fight, don’t patch it&lt;/h2&gt;

&lt;p&gt;Once the wheel landed, the plan was simple: play whole fights from the DM’s side. Open a table, add
monsters, seat two heroes, fight, and have the monsters go after each other too.&lt;/p&gt;

&lt;p&gt;I set one rule for it. No working around a broken skill with the table’s manual tools, so no typing
in damage, healing or conditions by hand. That ruled out the easy pass. If Hold Person only “works”
because the DM adds Paralyzed manually, that’s broken, and it got logged as broken.&lt;/p&gt;

&lt;p&gt;Fable wrote it up as a reusable test plan with its own harness and logged the first run. We ran it
three times over Oct 22 and 23, fixing each run’s findings before the next one. Then came a full
sweep of every way the app gets used on Oct 24: 2 blockers, 9 places the rules came out wrong, 17
rough spots and 20 bits of polish. A Companions-only pass after that found 1 more blocker and 3
more rules problems. Everything got fixed the same day, except one finding that turned out not to
be a bug.&lt;/p&gt;

&lt;p&gt;Some favorites from the pile:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;A monster that went down for nobody.&lt;/strong&gt; A hero’s killing blow dropped the creature on the hero’s
phone, and then the DM’s device overwrote it with its old copy of the table. So the creature stood
right back up for everyone and kept its turn. Pretty rude. It was an ordering problem: the DM
screen now applies the incoming table first, then runs its own updates. Fable fixed it.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Two blockers that were one-liners in disguise.&lt;/strong&gt; Coins in a loot parcel reused a number an item
already had and crashed the dialog. And the import prompt’s Replace and Keep buttons silently did
nothing, because they handed the database a live reactive object instead of plain data.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;The one that wasn’t a bug.&lt;/strong&gt; The sweep flagged “Stunned keeps movement.” Under SRD 5.2, Stunned
doesn’t stop movement the way the older rule did, so the code was right and the test plan got the
fix instead.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;heroes-get-companions&quot;&gt;Heroes get companions&lt;/h2&gt;

&lt;p&gt;Once anything could stand in the fighter frame, companions were the obvious next thing. Find
Familiar, Find Steed, Summon Dragon, Giant Insect, Animate Dead, Pact of the Chain, the Figurines of
Wondrous Power, Bag of Tricks and more now put a creature on the hero’s sheet. Fable built it.&lt;/p&gt;

&lt;p&gt;Each companion is a token under the hero’s chips. Tap it and you get its card, in the same frame the
DM runs monsters in: HP, AC, a combat wheel of its attacks, checks and features.&lt;/p&gt;

&lt;figure class=&quot;shot&quot;&gt;
  &lt;a href=&quot;https://allbark.dev/assets/devlog/2026-w43/companion-row.png&quot;&gt;&lt;img src=&quot;https://allbark.dev/assets/devlog/2026-w43/companion-row.png&quot; alt=&quot;A level 5 Human Fighter&amp;#39;s sheet with a &amp;#39;Boar is here. Open Boar&amp;#39; notice at the top and two companion tokens, Mastiff and Boar, under the Condition and Cast on me chips&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; /&gt;&lt;/a&gt;&lt;figcaption&gt;A Fighter with a Mastiff and a Boar. Good dogs only. And one boar.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;figure class=&quot;shot&quot;&gt;
  &lt;a href=&quot;https://allbark.dev/assets/devlog/2026-w43/owl-familiar-card.png&quot;&gt;&lt;img src=&quot;https://allbark.dev/assets/devlog/2026-w43/owl-familiar-card.png&quot; alt=&quot;An Owl familiar&amp;#39;s card: Tiny Fey, CR 0, 1 of 1 HP, AC 11, 5 ft Speed, with its combat wheel (Action, Reaction: Nothing, Bonus Action: Nothing), a Darkvision 120 ft chip, and Name, Send away and Dismiss buttons&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; /&gt;&lt;/a&gt;&lt;figcaption&gt;An Owl familiar, 1 HP of pure courage. Spot the bug: it says Round 1 out of combat. Fixed the same day.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;Companions take their turn right after their hero, and leave when their timer or the spell’s
Concentration runs out. At a DM’s table, Opus gave them their own seat, so monsters can go after
them too. The Companions test pass caught a nasty one: a companion dropping to 0 HP crashed the
sheet, because its card was still open while the creature left the list. Now the card closes first,
and you get the “drops to 0 and vanishes” notice with an Undo. Backing out of a summon picker also
refunds the slot, charges and Concentration it had just spent.&lt;/p&gt;

&lt;h2 id=&quot;the-tables-front-door&quot;&gt;The table’s front door&lt;/h2&gt;

&lt;p&gt;Setting up a table got some love too. The DM picks which homebrew packs a session allows, and a
hero who needs another pack waits at the door with a Let in button or an X. Opus built that one.&lt;/p&gt;

&lt;figure class=&quot;shot&quot;&gt;
  &lt;a href=&quot;https://allbark.dev/assets/devlog/2026-w43/pack-door.png&quot;&gt;&lt;img src=&quot;https://allbark.dev/assets/devlog/2026-w43/pack-door.png&quot; alt=&quot;The DM&amp;#39;s table screen with a glowing card at the top: Brynn Ironjaw, tagged &amp;#39;Hound Master (homebrew example)&amp;#39;, with a gold Let in button and an X, above &amp;#39;Waiting for players&amp;#39;, a Packs row and an empty loot pile&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; /&gt;&lt;/a&gt;&lt;figcaption&gt;Brynn brought a homebrew pack. The DM decides if it comes in.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;It also got sound and motion. Creatures pop into their seats, a hero sitting down gets a chime and
a gold glow, and Start combat plays a horn. Players don’t see the DM’s monsters until the fight
starts, because spoilers. And after playing it on my own phone, Start combat goes straight into the
first turn now instead of making you tap again.&lt;/p&gt;

&lt;h2 id=&quot;also-in-the-pile&quot;&gt;Also in the pile&lt;/h2&gt;

&lt;p&gt;The rest of the week, in one breath: in Wild Shape the combat wheel is the Beast’s, with spells only
once you have Beast Spells and the next attack following the form’s Multiattack, spell slots as one tile per level with free casts as chips, a
&lt;a href=&quot;https://allbark.dev/homebrew/&quot;&gt;homebrew pack checker and format guide&lt;/a&gt; that points at the line and column of a
broken pack file, joining a table by a six-digit code or QR when the Wi-Fi hides it (built, and
still being tested between real phones), the local table recovering quietly when the app comes
back, a slimmer monster header on the DM screen, Guidance, Divine Smite and Evasion fixes from the
full sweep, and moving everything that shipped out of the roadmap and into the diary.&lt;/p&gt;

&lt;p&gt;That’s week four. See you next week.&lt;/p&gt;
</content>
  </entry><entry>
    <title>Week three: the week the sword actually caught fire</title>
    <link rel="alternate" type="text/html" href="https://allbark.dev/devlog/2026/w42-the-sword-caught-fire/" />
    <id>https://allbark.dev/devlog/2026/w42-the-sword-caught-fire/</id>
    <published>2026-10-18T00:00:00-07:00</published>
    <updated>2026-10-18T00:00:00-07:00</updated>
    <summary>Every SRD magic item now does something on the sheet, level ups get a gold burst, the combat wheel learned to move, and the dice roller turned into a shaker. Here&apos;s how Cerberus learned to celebrate.</summary>
    <content type="html">&lt;p&gt;Week two, Cerberus learned to sit at a table. Week three, it learned to celebrate, and its magic
items stopped being paragraphs. Level ups, checks, rests and Initiative all got fanfare, the combat
wheel got motion, and by the end of the week every SRD magic item either does something on your
sheet or says exactly what it leaves to the table.&lt;/p&gt;

&lt;p&gt;That was 70 merged pull requests, split between Opus and Fable. Two of them
were dependency bumps, so, 68 if you’re counting the fun ones. This post goes deep on the items, the
fanfare and the wheel, and the rest gets the usual one breath at the end.&lt;/p&gt;

&lt;h2 id=&quot;items-that-actually-do-things&quot;&gt;Items that actually do things&lt;/h2&gt;

&lt;p&gt;Right after I reworked attunement, I went looking at what the items themselves did. The answer was:
not much. The store was full of magic items that were really just text telling you what they
&lt;em&gt;should&lt;/em&gt; be doing. A Flame Tongue was a longsword with a nice paragraph attached.&lt;/p&gt;

&lt;p&gt;Fable’s first pass gave 37 items hand-written mechanics and flagged everything else as “left to the
table.” Honestly, that’s a reasonable first move, and it showed me where I wanted the line. If it’s
SRD, the engine should run it. A table flag is fine for homebrew the engine can’t express yet, or for
things that are purely narrative. A Bag of Holding isn’t narrative. It’s just a place to put stuff.&lt;/p&gt;

&lt;p&gt;So instead of more flags, the engine grew vocabulary. Items now speak the same effect language as
class features, and they only apply while the item is carried, worn or attuned, whichever its text
asks for. On top of that, Fable added weapon riders, Immunity, printed DCs, consumables, charged
casting at higher levels, several uses per item, Climb and Swim Speeds, roll tables, containers
and Spell Scrolls.&lt;/p&gt;

&lt;p&gt;What that looks like on the sheet:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;A Flame Tongue hit offers “Add Flame Tongue 2d6”.&lt;/strong&gt; The sword actually catches fire now. Hence
the title.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Spells from items land with your spells&lt;/strong&gt;, at the item’s printed DC, and they spend its charges.
Higher levels are offered at their charge cost.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Potions are a Bonus Action&lt;/strong&gt; that heals straight onto the sheet and uses one up.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Spell Scrolls come as one kind per SRD spell&lt;/strong&gt;, with the DC 10 + level check when the spell is
above your level.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Bags of Holding and backpacks hold items.&lt;/strong&gt; And a Bag of Holding can’t go inside another Bag of
Holding, because we’ve all seen how that ends.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;The Wand of Wonder and friends roll their SRD tables&lt;/strong&gt;, as data.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Some things still need a person, like stepping onto another plane. Those stay “At the table”, but
now each one says exactly what in one sentence instead of shrugging.&lt;/p&gt;

&lt;figure class=&quot;shot&quot;&gt;
  &lt;a href=&quot;https://allbark.dev/assets/devlog/2026-w42/wand-of-fireballs.png&quot;&gt;&lt;img src=&quot;https://allbark.dev/assets/devlog/2026-w42/wand-of-fireballs.png&quot; alt=&quot;A phone character sheet&amp;#39;s Cast Fireball panel reads &amp;#39;Level 3 Evocation · Wand of Fireballs · Save DC 15&amp;#39;, with one cast option, &amp;#39;Free · Wand of Fireballs, 5 left, back on a Long Rest&amp;#39;, above an &amp;#39;8d6 Fire, Dexterity save DC 15, half on a success&amp;#39; card and a gold Cast Free button, while the dimmed spell list behind it shows Fireball tagged &amp;#39;Wand of Fireballs · Always prepared&amp;#39;&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; /&gt;&lt;/a&gt;&lt;figcaption&gt;An early capture. Wand’s DC, wand’s charges, wand’s Fireball. Spot the two bugs: it says Free and a Long Rest, and the wand recharges at dawn. Both got fixed by the end of the week.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;h3 id=&quot;spells-from-items-arent-your-spells&quot;&gt;Spells from items aren’t your spells&lt;/h3&gt;

&lt;p&gt;This one’s subtle and I’m glad we got it right. Under the SRD’s rule for spells cast from items, a
wand’s Fireball uses the wand’s DC and the wand’s charges, never your own slots. So the cast panel
and the combat wheel only offer the item’s costs for item spells. Items that boost your spell DC,
like the Robe of the Archmagi, raise your own casting but never a printed DC.&lt;/p&gt;

&lt;h3 id=&quot;not-taking-the-easy-way-out&quot;&gt;Not taking the easy way out&lt;/h3&gt;

&lt;p&gt;The tempting version was a “table only” checkbox on anything hard. Doing it properly meant teaching
the engine new tricks. A Rod of Lordly Might is several items in one, so an item can have several
uses. Potions of Giant Strength set your Strength while they last, and your saves, attacks and
carrying weight follow along.&lt;/p&gt;

&lt;p&gt;To keep all that honest, there’s a content test that checks every DC, die, save, level and charge
count against the item’s own text. If the data says one thing and the item says another, it fails.&lt;/p&gt;

&lt;h2 id=&quot;fanfare-for-the-moments-the-table-cheers&quot;&gt;Fanfare for the moments the table cheers&lt;/h2&gt;

&lt;p&gt;Leveling up used to save and dump you back on your sheet. That’s it. It’s the biggest moment in a
campaign and the app treated it like a form submission.&lt;/p&gt;

&lt;p&gt;I wanted some fanfare right at the end of the wizard, before you head back to the sheet. So now
there’s a gold burst and a chime, and Opus made the gains arrive as headlines.&lt;/p&gt;

&lt;p&gt;The real design call was the order. What changes how you play (a subclass, Extra Attack, new
spells) goes first, and the arithmetic (HP, Proficiency Bonus, slots) comes after. Past five
headlines it says “and N more on your sheet”, so it never turns into a list.&lt;/p&gt;

&lt;figure class=&quot;shot&quot;&gt;
  &lt;a href=&quot;https://allbark.dev/assets/devlog/2026-w42/level-up.png&quot;&gt;&lt;img src=&quot;https://allbark.dev/assets/devlog/2026-w42/level-up.png&quot; alt=&quot;A dark phone screen with a large gold 5 glowing in a burst of rays. Below it: &amp;#39;Level up. Bram reached level 5. Fighter 5.&amp;#39; Four gold-edged headline cards read New feature Extra Attack, New feature Tactical Shift, Hit Points +8, and Proficiency Bonus +3, above a gold &amp;#39;To your sheet&amp;#39; button&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; /&gt;&lt;/a&gt;&lt;figcaption&gt;Extra Attack first, math second. Bram earned this.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;Checks and saves got the same treatment, with the same rule: only fire when there’s something to
say. When the DC is known, a check stamps Passed, Saved or Failed and washes the screen edges green
or red. When it isn’t, nothing gets stamped. A manual check from the sheet also stopped asking you
whether you passed, because that was just one more tap.&lt;/p&gt;

&lt;p&gt;Short and Long Rests got their own fanfare too, and rolling Initiative now lifts the number off the
roll card and flies it up to the Combat line.&lt;/p&gt;

&lt;h2 id=&quot;a-wheel-that-moves-like-it-means-it&quot;&gt;A wheel that moves like it means it&lt;/h2&gt;

&lt;p&gt;I wanted the combat wheel to feel more mechanical. Think Transformers, a ton of parts all moving in
sync. We prototyped three takes side by side and recorded each one with the same taps:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Iris&lt;/strong&gt;: aperture blades.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Gearbox&lt;/strong&gt;: plates folding up in 3D.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;HUD&lt;/strong&gt;: a radar sweep that draws each wedge.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I picked HUD. Then I wanted it in reverse when combat ends, so the wheel sweeps itself back out of
existence. Then I liked the iris more than I expected, so we split the job: the sweep for the wheel
showing up and leaving, and the iris blades for moving between rings. Fable built all of it. A ring
of light also pings out from the hub when your turn starts.&lt;/p&gt;

&lt;figure class=&quot;shot&quot;&gt;
  &lt;a href=&quot;https://allbark.dev/assets/devlog/2026-w42/wheel-iris.png&quot;&gt;&lt;img src=&quot;https://allbark.dev/assets/devlog/2026-w42/wheel-iris.png&quot; alt=&quot;A phone character sheet for Hild, a level 5 dwarf cleric on 7 of 43 hit points, in round 1 of a fight, with her circular combat wheel opening a ring of spells (Cure Wounds, Guiding Bolt, Spirit Guardians, Bless, Bane, Hold Person) as the last wedges twist into place around a Back button&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; /&gt;&lt;/a&gt;&lt;figcaption&gt;Mid-iris. Hild’s on 7 HP, so she’d like the Cure Wounds wedge to hurry up.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;Once the motion and the light were showing whose turn it was, the “On your turn” and “Ready”
captions weren’t saying anything new, so they went. Screen readers still hear them. The wheel is now
the only combat view, too. The old list option is gone.&lt;/p&gt;

&lt;p&gt;The glow behind the wheel took three tries. Even the third one reached way too far out and came out
kind of egg-shaped. Then I spotted why: the buttons were a little see-through, so the glow stacked up
on top of them. Solid wedges, gaps for the glow to come through, no outer ring.
Fixed.&lt;/p&gt;

&lt;h2 id=&quot;the-dice-shaker&quot;&gt;The dice shaker&lt;/h2&gt;

&lt;p&gt;The free roller from last week had a lot going on. What I actually wanted was simple: every tap on
a die tosses that die into the pile, and the total keeps counting. The first rework still had too
much stuff around it. So Opus cut it down to the die buttons, the same 3D dice the character sheet
uses, Reset and Toss dice. That’s the whole screen now.&lt;/p&gt;

&lt;p&gt;I also wanted a d100, which is really just two d10s, so that’s how it rolls: a tens die and a ones
die.&lt;/p&gt;

&lt;figure class=&quot;shot&quot;&gt;
  &lt;a href=&quot;https://allbark.dev/assets/devlog/2026-w42/dice-shaker.png&quot;&gt;&lt;img src=&quot;https://allbark.dev/assets/devlog/2026-w42/dice-shaker.png&quot; alt=&quot;A dice tray on a dark phone screen holding five 3D dice: two percentile d10s showing 80 and 90, two d10s showing 7 and 8, and a d6 showing 4. The total reads 189 for 2d100 + 1d6. Below are buttons for d4 through d100, Reset, and a gold Toss dice button&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; /&gt;&lt;/a&gt;&lt;figcaption&gt;2d100 + 1d6 = 189. No idea what you’d roll that for. It’s fun to shake though.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;h2 id=&quot;attunement-is-a-rule-not-a-toggle&quot;&gt;Attunement is a rule, not a toggle&lt;/h2&gt;

&lt;p&gt;Attuning to an item worked exactly like equipping it. I’d seen language about it taking a Short Rest
and asked whether that was right. Nope. In SRD 5.2 you spend a Short Rest focused on the item. So
with strict rules on, attuning or ending attunement takes a Short Rest, one item per rest, never in
a fight and never at 0 HP. Opus built that one.&lt;/p&gt;

&lt;p&gt;The same conversation reshaped the loadout. Attunement can cover things you’re also holding, or
extra stuff like rings and cloaks, so the two needed to look different. Now it’s two rows: armor and
both hands on top, three violet attunement sockets below.&lt;/p&gt;

&lt;figure class=&quot;shot&quot;&gt;
  &lt;a href=&quot;https://allbark.dev/assets/devlog/2026-w42/attunement-sockets.png&quot;&gt;&lt;img src=&quot;https://allbark.dev/assets/devlog/2026-w42/attunement-sockets.png&quot; alt=&quot;A phone showing a hero&amp;#39;s inventory: Leather Armor and a dagger in hand on top with an empty off hand, and below them three violet attunement sockets, two holding a Ring of Protection and a Cloak of Protection and the third still open, labeled Attuned 2 / 3, a Short Rest each&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; /&gt;&lt;/a&gt;&lt;figcaption&gt;Hands up top, attunement down below. One socket still open.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;The store got the same kind of rethink. Magic items used to sit in their own tab, badly grouped,
with nothing past a short blurb. Now the store opens on a market of stalls, one per content pack,
with shelves by what an item is. A magic longsword sits with the longswords. Fable built the market
and a single detail card that every item opens.&lt;/p&gt;

&lt;h2 id=&quot;filming-the-shorts-turned-into-qa&quot;&gt;Filming the shorts turned into QA&lt;/h2&gt;

&lt;p&gt;Every daily short gets filmed in the real app, and this week filming kept tripping over bugs. A “Saved” notice showed up while the d20 was still tumbling, which kind of spoils the roll.
The armor card showed the hero’s total AC instead of the armor’s own. Opus fixed both.&lt;/p&gt;

&lt;p&gt;The Wand of Fireballs short alone found five more: “At will” on casts that actually cost charges, a
Cleric being offered her own slot for the wand’s Fireball, a socket that just said “Wand”, “back on
a Long Rest” for a wand that recharges at dawn, and a DM log calling three Magic Missile darts “Dart
1”. Fable fixed all five in one go. Another short caught the spell level arrow sitting right on top
of the cast button.&lt;/p&gt;

&lt;p&gt;Two more sneaky ones: on spinning rings of nine or more options, hidden wedges kept a backing that
ate taps in some spots, and on iOS a swipe inside a popup still moved the page behind it. Both
fixed.&lt;/p&gt;

&lt;h2 id=&quot;also-in-the-pile&quot;&gt;Also in the pile&lt;/h2&gt;

&lt;p&gt;The rest of the week, in one breath: loot parcels the DM shares as a file, swipe back instead of
back buttons with the top bar moved into the hero menu, dice sounds that match how many dice you
rolled, an attack card that goes straight to damage with Miss in red, strict rules on the dock’s
cards mid-fight, temp HP in the damage preview, a coin number pad, sheet tabs for Checks, Spells,
Resources and Features, the roll history dropped, tool checks with the SRD Utilize uses and DCs,
Wild Shape locking spellcasting, a crowded spell ring that opens by kind and then by level, a
“Kennel Armory” pack of homebrew test items, packs that are simply on or off, a sweep through the
whole app cutting explainer text that was just repeating what the buttons already said, and a pile
of layout and mobile fixes.&lt;/p&gt;

&lt;p&gt;Tests once the item work landed: 439 in the rules engine, 214 for content and 274 in the app.&lt;/p&gt;

&lt;p&gt;That’s week three. See you next week.&lt;/p&gt;
</content>
  </entry><entry>
    <title>Week two: the week Cerberus got a DM</title>
    <link rel="alternate" type="text/html" href="https://allbark.dev/devlog/2026/w41-cerberus-gets-a-dm/" />
    <id>https://allbark.dev/devlog/2026/w41-cerberus-gets-a-dm/</id>
    <published>2026-10-11T00:00:00-07:00</published>
    <updated>2026-10-11T00:00:00-07:00</updated>
    <summary>A DM screen that runs the fight, damage that lands where it&apos;s aimed, buffs that show up on the right sheet, actual battle music, and a playtest that found 101 things. Here&apos;s how the table came together.</summary>
    <content type="html">&lt;p&gt;Week one was all about one hero and one turn. Week two, Cerberus learned to sit at a table. A DM
can run the whole fight from their own device, damage goes where you aim it, and when someone casts
Haste on you, it actually shows up on your sheet. Then Fable ran the first full playtest of the whole
app, and honestly, it had notes. 101 of them.&lt;/p&gt;

&lt;p&gt;That was 91 merged pull requests, almost all of them built with Opus, which is way too much for one
post. So this one sticks to the table, the soundtrack and the playtest, and everything else gets
crammed into one breath at the end.&lt;/p&gt;

&lt;h2 id=&quot;the-dms-device-is-the-table&quot;&gt;The DM’s device is the table&lt;/h2&gt;

&lt;p&gt;The idea started pretty simple. I wanted a DM to host a session, players to join it, the DM to
track initiative, and everyone to get dropped into their turn automatically.&lt;/p&gt;

&lt;p&gt;I still liked solo mode, where you track your own turns, so I didn’t want to throw it out. The
trick was that a table only presses buttons a player already had. The DM’s device starts each
hero’s turn on that player’s sheet and ends combat for everybody. Players still roll their own
Initiative and end their own turns, because that’s what you’d do at a real table anyway.&lt;/p&gt;

&lt;p&gt;Leave the table and you’re just back on your normal sheet. Nothing to undo.&lt;/p&gt;

&lt;p&gt;The DM gets a screen of their own, and it’s stacked: all 329 monster stat blocks from the SRD 5.2,
monster cards that track HP, conditions, Recharge and Legendary Actions, and prepared fights rated
with the SRD’s encounter difficulty for your party. On a tablet it splits in two, initiative on the
left and whoever’s up on the right.&lt;/p&gt;

&lt;figure class=&quot;shot wide&quot;&gt;
  &lt;a href=&quot;https://allbark.dev/assets/devlog/2026-w41/dm-screen-tablet.png&quot;&gt;&lt;img src=&quot;https://allbark.dev/assets/devlog/2026-w41/dm-screen-tablet.png&quot; alt=&quot;The DM screen on a tablet. On the left, the initiative order for round 1 with Goblin Warrior 2 (21), Goblin Boss (13) and Goblin Warrior (4), and a prepared fight called Goblin ambush, 3 monsters, Moderate for 4 at level 1. On the right, Goblin Warrior 2&amp;#39;s card: AC 15, 10 of 10 HP, Scimitar and Shortbow attacks with Roll buttons, Nimble Escape and saving throws.&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; /&gt;&lt;/a&gt;&lt;figcaption&gt;Initiative on the left, whoever’s up on the right. Three goblins, rated Moderate for a level 1 party of four.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;One rule decides where every number lives: &lt;strong&gt;the DM’s device owns the monsters, and each phone owns
its own hero.&lt;/strong&gt; Monster HP lives on the DM’s screen. Your HP lives on your phone, and your phone
applies your Resistances. Players only ever see a monster’s name and whether it’s &lt;strong&gt;Bloodied&lt;/strong&gt;,
which is the SRD 5.2 word for half HP or less. I asked for every term like that in the SRD and
nope, Bloodied is the only one.&lt;/p&gt;

&lt;p&gt;Then I flipped it around: the DM should get the same kind of view of the heroes. So your actual HP
number never leaves your phone either. The DM sees Healthy, Bloodied, Dying, Stable or Dead, plus
your AC and conditions. Enough to run the fight, and nobody’s sheet is an open book.&lt;/p&gt;

&lt;h2 id=&quot;dont-just-show-the-fight-track-it&quot;&gt;Don’t just show the fight, track it&lt;/h2&gt;

&lt;p&gt;The first DM screen showed you the monsters. Cool, but you were still doing all the math yourself.
What I really wanted was for damage rolls to just take the health off. Whoever’s attacking or
casting, DM or player, picks who they’re aiming at, and the HP popup only sticks around for Hit
Dice and the odd manual fix.&lt;/p&gt;

&lt;p&gt;So that’s what we built. Roll damage, pick who you’re hitting, and the number lands on the right
device after Immunities and Resistances.&lt;/p&gt;

&lt;figure class=&quot;shot&quot;&gt;
  &lt;a href=&quot;https://allbark.dev/assets/devlog/2026-w41/player-deal.png&quot;&gt;&lt;img src=&quot;https://allbark.dev/assets/devlog/2026-w41/player-deal.png&quot; alt=&quot;A player&amp;#39;s phone in combat after an Unarmed Strike damage roll of 3 bludgeoning, with a button reading Deal 3 to Goblin Boss, comes off its HP on the DM&amp;#39;s screen.&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; /&gt;&lt;/a&gt;&lt;figcaption&gt;Three whole damage. The Goblin Boss is shaking.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;Saves work the same way. An area spell or a breath weapon asks who got caught in it and rolls damage
once. A Fireball rolls its 8d6 a single time, then every creature saves on its own screen with its
own bonus, and anyone who makes it takes half.&lt;/p&gt;

&lt;figure class=&quot;shot&quot;&gt;
  &lt;a href=&quot;https://allbark.dev/assets/devlog/2026-w41/fire-breath.png&quot;&gt;&lt;img src=&quot;https://allbark.dev/assets/devlog/2026-w41/fire-breath.png&quot; alt=&quot;A Young Red Dragon&amp;#39;s card on the DM&amp;#39;s phone after Fire Breath: DC 17 Dex save, 75 fire. Ana rolls a DC 17 Dexterity save on their phone, and a Goblin Warrior rolls 9, fails, takes 75 and drops.&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; /&gt;&lt;/a&gt;&lt;figcaption&gt;One roll of 16d6 for everybody. Ana gets to roll a save on their own phone. The goblin does not have a great day.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;I also wanted a real dice switch. Turn it on and the app asks for your physical roll and you just
type in the number.&lt;/p&gt;

&lt;h2 id=&quot;buffs-follow-the-target&quot;&gt;Buffs follow the target&lt;/h2&gt;

&lt;p&gt;This one started small. I had Concentration going on Fly and the chip said “10 min” turn after turn
after turn. It looked frozen. It wasn’t. The timer was running fine, the chip was just rounding. So
now timed effects count rounds in combat (100, 99, 98, all the way down to “Last round”) and show a
clock outside of it. They tick on your turn and end themselves.&lt;/p&gt;

&lt;figure class=&quot;shot&quot;&gt;
  &lt;a href=&quot;https://allbark.dev/assets/devlog/2026-w41/poisoned-timer.png&quot;&gt;&lt;img src=&quot;https://allbark.dev/assets/devlog/2026-w41/poisoned-timer.png&quot; alt=&quot;A level 5 Monk&amp;#39;s sheet with a Poisoned card: Disadvantage on attack rolls and ability checks, 0:58 left, lasts a set time then ends on its own, from a giant spider bite, with a Remove Poisoned button.&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; /&gt;&lt;/a&gt;&lt;figcaption&gt;Effects know how long they last, and who to blame.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;Fixing that showed the next gap. Spells without Concentration, like Mage Armor, weren’t tracked at
all, and Mage Armor should only count while you’re not wearing armor. Then the table made a third
thing pretty obvious: you’re already picking a target, so the buff should just land on that hero’s
sheet.&lt;/p&gt;

&lt;p&gt;And now it does. Ana casts Haste on Bo, a level 5 Fighter, and Bo’s phone says so. AC goes from 16
to 18, Speed goes from 30 to 60 feet, and both go right back the second Ana’s Concentration drops.&lt;/p&gt;

&lt;figure class=&quot;shot&quot;&gt;
  &lt;a href=&quot;https://allbark.dev/assets/devlog/2026-w41/haste-on-bo.png&quot;&gt;&lt;img src=&quot;https://allbark.dev/assets/devlog/2026-w41/haste-on-bo.png&quot; alt=&quot;Bo&amp;#39;s sheet with a banner reading Ana cast Haste on you. AC shows 18 and Speed 60 ft, and a Haste card counts down from 0:57, lasting while Ana concentrates on it, with an End Haste button. Below it, Mage Armor is marked Not in effect.&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; /&gt;&lt;/a&gt;&lt;figcaption&gt;Ana’s Haste lands on Bo’s sheet, timer and all.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;The same timers also brought Rage upkeep, Dash adding to your movement, and condition saves that
roll themselves.&lt;/p&gt;

&lt;h2 id=&quot;making-it-sound-like-a-fight&quot;&gt;Making it sound like a fight&lt;/h2&gt;

&lt;p&gt;Sounds were working. They just weren’t doing much for me. Honestly? A little meh. Nobody gets
hyped over a utility-grade dice clack.&lt;/p&gt;

&lt;p&gt;So we built an audition page and I went through it on my phone with headphones, tagging every
clip for a moment: a roll, a nat 20, a nat 1, a hit, a spell, coins. Candidates came from CC0 game
audio and the free, royalty-free GDC game audio bundles. That’s 230 GB across ten years of bundles,
which sounds like a lot, and it turned out to be wide but not deep. The whole decade had only a
handful of real dice recordings, so every single one made the cut.&lt;/p&gt;

&lt;p&gt;97 clips survived, plus 60 spell sounds. For now each moment plays a random pick from its set, and
sounds for specific spells are on the list for later.&lt;/p&gt;

&lt;p&gt;For music, I wanted rolling Initiative to feel like you just walked into the fight, the way battle
music fires up in Pokémon or Expedition 33. After auditioning, I skipped intros and victory fanfares
for now and went straight into a combat loop. Exploring music cuts into battle when you roll
Initiative and fades back out when combat ends.&lt;/p&gt;

&lt;p&gt;Music has its own switch, separate from Sounds, and it starts &lt;strong&gt;off&lt;/strong&gt;. Picture five phones at a real
table all blasting battle music over the DM’s own playlist. Yeah, no.&lt;/p&gt;

&lt;p&gt;The music did break one thing, just not the app. Bundling about 21 MB of it pushed the Android test
build to 31 MB, which is over a 10 MB attachment limit on the step that shares test builds. Every
check passed. Only that last step fell over. The fix posts a download link instead. I kept the
music bundled anyway so it works offline from the very first launch, because offline-first is one
of my core rules for this app.&lt;/p&gt;

&lt;h2 id=&quot;the-first-full-playtest&quot;&gt;The first full playtest&lt;/h2&gt;

&lt;p&gt;After two weeks of moving fast, nobody had played the whole app end to end in one sitting. So Fable
did. We wrote up 36 scenarios covering the builder, level-up, the sheet, solo combat, table play,
accessibility and sound, and Fable ran every one from a wiped device.&lt;/p&gt;

&lt;p&gt;It found 101 things. Zero blockers, thankfully: 10 major, 49 minor and 42 polish. I went through
every one: agreed with 93, tweaked 8, tossed none. The fixes landed the next day in six focused
batches.&lt;/p&gt;

&lt;p&gt;The big ones:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Rules the sheet didn’t enforce yet.&lt;/strong&gt; Dropping to 0 HP did nothing, and some class actions,
like Reckless Attack, Flurry of Blows and some Channel Divinity options, just weren’t there. Fable
fixed those too: 0 HP now knocks you out and prompts your death save, and the missing actions are
in combat.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;The builder picked a class’s key abilities from its saving throws&lt;/strong&gt; instead of its primary
ability.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;The combat wheel sorted its rings alphabetically&lt;/strong&gt;, so a caster’s real spells got buried.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Table play worked end to end. Rejoining after a page reload didn’t.&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Two of my tweaks changed direction. You now pick your target &lt;em&gt;before&lt;/em&gt; you roll, so a crit card
never needs a button for every monster, and that one already shipped. The sheet’s top bar and
resource dock are up for a rethink.&lt;/p&gt;

&lt;p&gt;One more bug got caught before it merged. Replaying a table session in two browser windows showed a
player’s sheet sometimes starting their turn again right after they ended it. Fixed, and each
sheet’s round now stays in step with the table’s.&lt;/p&gt;

&lt;p&gt;Which brings me to the honest part. Table play was built and tested between browser windows. The
native Wi-Fi plugin compiles for iOS and Android, but we haven’t played a table across real phones
yet. That’s next.&lt;/p&gt;

&lt;h2 id=&quot;also-in-the-pile&quot;&gt;Also in the pile&lt;/h2&gt;

&lt;p&gt;The rest of the week, in one breath: a free dice roller with keep and drop notation, every SRD magic
item in the inventory and store with attunement and charges, mounts, vehicles, food, lodging and
services in the store, a smoother spin and snap on the combat wheel, two rounds of sheet and combat
layout rework, Quickened spells lighting up both resources they spend, and a move to SvelteKit 3,
which Fable handled.&lt;/p&gt;

&lt;p&gt;That’s week two. See you next week.&lt;/p&gt;
</content>
  </entry><entry>
    <title>Week one: from an empty repo to a combat wheel</title>
    <link rel="alternate" type="text/html" href="https://allbark.dev/devlog/2026/w40-empty-repo-to-combat-wheel/" />
    <id>https://allbark.dev/devlog/2026/w40-empty-repo-to-combat-wheel/</id>
    <published>2026-10-10T00:00:00-07:00</published>
    <updated>2026-10-10T00:00:00-07:00</updated>
    <summary>A 5E character builder, a tap-to-roll table sheet and three versions of a combat screen in seven days. Here&apos;s the rule I set on day one, and how the turn became a wheel.</summary>
    <content type="html">&lt;p&gt;Seven days ago the repo for my new app was empty. Seventy-three merged pull requests later, every one
of them built with Opus, it’s a guided character builder for 5E, a table-side sheet you tap to roll
from, and a combat mode we designed three times in two days. All twelve classes from the 5E System
Reference Document are in, levels 1 to 20, and that part was done by day three.&lt;/p&gt;

&lt;p&gt;That’s way too much for one post, so this one sticks to the two stories that shaped everything
else: a rule I set on day one, and how a turn of combat turned into a wheel.&lt;/p&gt;

&lt;h2 id=&quot;day-one-save-the-choices-never-the-numbers&quot;&gt;Day one: save the choices, never the numbers&lt;/h2&gt;

&lt;p&gt;A 5E character sheet is a pile of derived numbers. Your Athletics bonus comes from your Strength,
your proficiency bonus, your class, maybe your background, maybe a feat. Store those numbers and
every rules fix turns into a data migration, and every screen has to be careful not to let you
build something illegal.&lt;/p&gt;

&lt;p&gt;So on day one I decided a character gets saved as &lt;strong&gt;the list of choices the player made&lt;/strong&gt;, and
nothing else. A pure rules engine re-derives the whole sheet from those choices every time. The
builder doesn’t decide what to ask you next. It asks the engine which questions are still open and
only shows those.&lt;/p&gt;

&lt;p&gt;That one call is what makes the builder hard to get wrong. Validation lives in the engine, not in
the screens. Every option is a card or chip that says what it gives you, and &lt;strong&gt;Next&lt;/strong&gt; stays locked
until the step is valid, with the reason right there: “pick 1 more”, or “You already have
Athletics”.&lt;/p&gt;

&lt;figure class=&quot;shot&quot;&gt;
  &lt;a href=&quot;https://allbark.dev/assets/devlog/2026-w40/wizard-choices.png&quot;&gt;&lt;img src=&quot;https://allbark.dev/assets/devlog/2026-w40/wizard-choices.png&quot; alt=&quot;Builder step titled Skills &amp;amp; Feats. Skill choices are tappable chips with their bonus, Perception is picked, and Athletics and Intimidation are greyed out and marked Yours because the character already has them.&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; /&gt;&lt;/a&gt;&lt;figcaption&gt;Skills you already have show up as &lt;em&gt;Yours&lt;/em&gt; instead of letting you pick them twice.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;The same engine powers everything after the builder. Finish a character and you land on a table
sheet where tapping any ability, saving throw, skill or initiative rolls it, with advantage and
disadvantage applied for you. Attack and damage rolls, HP tracking with death saves, and short
rests followed the same day. The engine’s test suite went from 53 to 81 tests on day one alone.&lt;/p&gt;

&lt;figure class=&quot;shot&quot;&gt;
  &lt;a href=&quot;https://allbark.dev/assets/devlog/2026-w40/sheet-advantage.png&quot;&gt;&lt;img src=&quot;https://allbark.dev/assets/devlog/2026-w40/sheet-advantage.png&quot; alt=&quot;A Fighter&amp;#39;s table sheet with saving throws and skills listed. Athletics carries an ADV badge, and a roll card shows two d20s, 11 and 2, with the 11 kept for a total of 16.&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; /&gt;&lt;/a&gt;&lt;figcaption&gt;Athletics with advantage: roll two, keep the 11, add 5.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;One small detail I really like: HP is stored as &lt;strong&gt;damage taken&lt;/strong&gt;, not current HP. Level up and
your max HP goes up, but the wounds you’re carrying stay put, because that’s what actually
happened.&lt;/p&gt;

&lt;p&gt;Nothing derived is ever saved, so a character also survives rule fixes. If we get a number wrong
and fix it, every saved character is right the next time it opens.&lt;/p&gt;

&lt;p&gt;I also had to pick a platform. Flutter was tempting for a game-like feel. The honest comparison
was that Flutter’s 2D edge is small for an app like this and shows up mostly on low-end Android
phones. The web gives you a sheet you can open on a laptop at the table, or send to your DM as a
link, and an offline web app for free. I’d also already shipped Byte on Svelte, which gave us a
template to start from. So I went with Svelte, web first, wrapped for iOS and Android.&lt;/p&gt;

&lt;h2 id=&quot;combat-three-ways-in-two-days&quot;&gt;Combat, three ways in two days&lt;/h2&gt;

&lt;h3 id=&quot;version-one-a-very-good-menu&quot;&gt;Version one: a very good menu&lt;/h3&gt;

&lt;p&gt;The first combat view tracked your Action, Bonus Action and Reaction each turn and listed
everything you could do with them. It worked. It also read like a restaurant menu, not a turn.&lt;/p&gt;

&lt;p&gt;I had four notes on it. The action bar belongs at the bottom. The “next roll” footer takes up a
lot of room for something you rarely touch. Cards for things the turn guide already offers
shouldn’t show up twice. And the common stuff, attacking and casting, deserves a bigger stage than
“Study”. Most of all, clicking Attack should &lt;em&gt;lead&lt;/em&gt; somewhere: to your next attack, or to the
things that ride along with one. It shouldn’t just leave every other action sitting there.&lt;/p&gt;

&lt;h3 id=&quot;version-two-a-turn-with-a-direction&quot;&gt;Version two: a turn with a direction&lt;/h3&gt;

&lt;p&gt;So the turn bar moved to the bottom, the footer shrank to a small Adv/Dis toggle, duplicate cards
hide during combat, and attacks and spells became big tiles. Taking the Attack action now locks the
turn into a sequence, “Attack 2 of 3”, with &lt;strong&gt;Next attack&lt;/strong&gt; and &lt;strong&gt;Done attacking&lt;/strong&gt;.&lt;/p&gt;

&lt;figure class=&quot;shot&quot;&gt;
  &lt;a href=&quot;https://allbark.dev/assets/devlog/2026-w40/attack-flow.png&quot;&gt;&lt;img src=&quot;https://allbark.dev/assets/devlog/2026-w40/attack-flow.png&quot; alt=&quot;Mid-turn Fighter. The Attack section glows with the label Attack 2 of 2 and weapon tiles for Unarmed Strike, Greatsword, Flail and Javelin, plus a Done attacking button. Bonus Action and Reaction sections sit below.&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; /&gt;&lt;/a&gt;&lt;figcaption&gt;Mid-turn, the Attack action is a sequence you step through.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;The sequence also surfaces the things the rules tie to an attack: the extra attack from a Light
weapon (and Nick, which folds that extra attack into the Attack action itself), and once-per-turn
riders like Sneak Attack.&lt;/p&gt;

&lt;h3 id=&quot;version-three-the-wheel&quot;&gt;Version three: the wheel&lt;/h3&gt;

&lt;p&gt;Then I pulled an old project off the shelf: an infinite radial menu I built in Unity years ago,
designed for combat action menus in games, especially on mobile. My pitch was simple: put HP in a
circle in the middle, with Action, Bonus Action and Reaction buttons around it. Plus a green-to-red
glow around the HP, for a little extra pizzazz.&lt;/p&gt;

&lt;p&gt;It fit better than I expected, because a turn was already a tree: Action, Bonus Action or
Reaction, then attacks, spells or features, then the thing that actually does it. That meant the
wheel could be a new &lt;em&gt;view&lt;/em&gt; over the same engine state, not a second combat system to keep in sync.
Day one’s rule paid off again. Pick something and it moves to the center with its details and a
&lt;strong&gt;Use&lt;/strong&gt; button.&lt;/p&gt;

&lt;figure class=&quot;shot&quot;&gt;
  &lt;a href=&quot;https://allbark.dev/assets/devlog/2026-w40/wheel-first.png&quot;&gt;&lt;img src=&quot;https://allbark.dev/assets/devlog/2026-w40/wheel-first.png&quot; alt=&quot;The first combat wheel on a Rogue&amp;#39;s sheet. The breadcrumb reads Turn, Action, Attack, and a Shortsword attack at plus 7 for 1d6 plus 4 piercing sits in the green center ring with an Attack button, with other weapons around it.&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; /&gt;&lt;/a&gt;&lt;figcaption&gt;The first wheel: drill down from Action to Attack to a weapon, and it lands in the middle.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;h3 id=&quot;rectangles-around-a-circle-never-look-right&quot;&gt;Rectangles around a circle never look right&lt;/h3&gt;

&lt;p&gt;The first try put three rounded buttons at 12, 4 and 8 o’clock. It looked lopsided whichever way
we nudged it, because a rectangle is wider than it is tall, and no amount of padding fixes that.
The fix was a different shape: three equal 120° segments.&lt;/p&gt;

&lt;p&gt;Then I pushed it further. I wanted the gaps on the top layer gone, with diamond-shaped buttons
fanning out from the center like the old Simon game, and a mechanical animation for changing
layers, like a sci-fi door sliding open and shut.&lt;/p&gt;

&lt;p&gt;So Opus built touching wedges with dark seams, and a door. When you move between layers, the old
panels twist into the center, the HP circle gives a little clunk, and the new panels twist out one
by one with a slight overshoot. With reduced motion turned on, the layer just swaps.&lt;/p&gt;

&lt;figure class=&quot;shot&quot;&gt;
  &lt;a href=&quot;https://allbark.dev/assets/devlog/2026-w40/wheel-wedges.png&quot;&gt;&lt;img src=&quot;https://allbark.dev/assets/devlog/2026-w40/wheel-wedges.png&quot; alt=&quot;The combat wheel on a Sorcerer&amp;#39;s sheet: HP 72 of 72 in a green ring at the center, surrounded by three touching wedges for Action, Bonus Action and Reaction, with the round bar and spell slots below.&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; /&gt;&lt;/a&gt;&lt;figcaption&gt;Three touching wedges, HP in the middle.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;figure class=&quot;shot clip&quot;&gt;
  &lt;video controls=&quot;&quot; muted=&quot;&quot; playsinline=&quot;&quot; loop=&quot;&quot; preload=&quot;none&quot; poster=&quot;/assets/devlog/2026-w40/wheel-door-poster.png&quot; aria-label=&quot;Screen recording of the combat wheel switching layers: the wedges twist into the center and new ones twist out.&quot;&gt;
    &lt;source src=&quot;https://allbark.dev/assets/devlog/2026-w40/wheel-door.mp4&quot; type=&quot;video/mp4&quot; /&gt;
    &lt;a href=&quot;https://allbark.dev/assets/devlog/2026-w40/wheel-door.mp4&quot;&gt;Watch the clip&lt;/a&gt;
  &lt;/video&gt;&lt;figcaption&gt;The door animation. This was captured in a headless browser, so it’s choppier here than on a phone.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;A few more things the round shape made us think about:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Don’t move buttons under a thumb.&lt;/strong&gt; The wheel puts the options you use most at 12 o’clock, but
it only re-sorts when combat starts. Anything that appears or disappears mid-turn lands at the
bottom, so nothing you were about to tap slides away.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Long spell lists on a round menu.&lt;/strong&gt; About eight labeled options fit around a ring on a phone.
Rings that would be crowded split into another layer (Spells, then by level), and only what still
doesn’t fit spins, with arrows. Most rings never need to.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;A bug we only found by re-checking.&lt;/strong&gt; After the wheel shipped, we re-ran a Rogue’s turn and
rolled damage before closing the result. The wheel marked the Nick extra attack “Action used”,
which it wasn’t. Fixed in the same change.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;our-first-outside-tester&quot;&gt;Our first outside tester&lt;/h2&gt;

&lt;p&gt;This week our Android tester went through the builder and sent 17 numbered notes, plus three more
comments. All but two were handled in a single change.&lt;/p&gt;

&lt;p&gt;The biggest one: picking a species, class or background auto-advanced right past the tab that
explained what it gives you, so nobody ever saw it. Now tapping a card opens what it gives you right
under it, with a &lt;strong&gt;Choose&lt;/strong&gt; button, and the separate tab is gone. The steps also now go Class,
Background, Species, which is the order the SRD 5.2 itself uses.&lt;/p&gt;

&lt;p&gt;Point buy used to start from the standard array, so you had to lower every score before you could
spend anything. Now every score starts at 8 with 27 points, and you can’t move on until you’ve spent
them all. Rolled stats got a roll counter, with a little ribbing as the number climbs, because the
tester asked for one.&lt;/p&gt;

&lt;p&gt;The review step now labels every feature, skill and tool with where it came from:&lt;/p&gt;

&lt;figure class=&quot;shot&quot;&gt;
  &lt;a href=&quot;https://allbark.dev/assets/devlog/2026-w40/review-sources.png&quot;&gt;&lt;img src=&quot;https://allbark.dev/assets/devlog/2026-w40/review-sources.png&quot; alt=&quot;The builder&amp;#39;s review step listing features and feats, each labeled with its source, such as Origin Languages from background Soldier, Skillful from species Human, and Second Wind from class Fighter.&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; /&gt;&lt;/a&gt;&lt;figcaption&gt;Every line says where it came from.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;The notes also showed us where labels could say more. Multiclass requirement badges now read “to
multiclass out” and “to multiclass in”, and Weapon Mastery explains itself right where you pick it.&lt;/p&gt;

&lt;p&gt;One request I especially liked was an equipment store. The SRD has equipment, and new characters
start with gold to buy their own gear, so I wanted it in 1.0. It shipped the same day.&lt;/p&gt;

&lt;h2 id=&quot;also-in-the-pile&quot;&gt;Also in the pile&lt;/h2&gt;

&lt;p&gt;The rest of the week, in one breath: the remaining species and backgrounds, 3D dice, a UX pass for
every class, phone notch safe areas, groundwork for the native iOS and Android builds, a motion and
focus pass, previews of the bonus when you pick a skill, icons on the builder cards, equipping weapons
and an inventory, Metamagic when casting, a strict rules mode, an in-app feedback button, a fix for
crit damage, and effect chips in combat.&lt;/p&gt;

&lt;p&gt;That’s week one. The Bark Blog will be back next week with what came next.&lt;/p&gt;
</content>
  </entry>
</feed>
