Custom Roguelike - New Kits for All Five Classes, an Inn, and the First Music
Published 2026-10-03
9/30/26
Step 1: picking the window size
The Options screen’s Video box finally has a working Window row. Enter cycles through 1024x640, 1280x800, 1440x900, 1680x1050, 1920x1200 and 2560x1600, all the same 16:10 shape as the game, and like Fullscreen it takes effect the next time I launch. The game still draws everything at 1280x800 and stretches it to the window, so none of the screens had to change. If I pick a size bigger than the monitor, it opens at the biggest one that fits and keeps my choice for a bigger screen.
Getting the sizes to fill the window meant patching bracket-lib itself, so the project now carries its own copy of bracket-terminal 0.8.7 in vendor/, with every change listed in its PATCHES.md. The first patch: bracket-lib was shrinking the picture to a multiple of the biggest sprite tile it knows about, and my idle sheets have 128px tiles, so most window sizes (the default 1280x800 included) got thin black bars. Now the picture fills the window exactly, and the black bars in fullscreen got narrower too.
Step 2: the window stops growing between monitors
A friend dragged the game from a small monitor to a bigger one and the window doubled in size every time he switched screens. The likely cause is the two monitors using different Windows display scaling: bracket-lib let Windows scale the window up by the change each time it crossed over. The second patch keeps the window at the same real pixel size when that happens. I can’t test it on my own setup, so it still needs a try on his.
Step 3: a round of code cleanup
I went back to the refactor list and did the five safest items together, all moves with no change in how the game plays. The same “row of the sprite sheet into a list of frames” code was copied into ten animation builders; now they all call one OneShotAnimation::from_row. The end screen looked up the player’s class with the same five lines four times, and the bots checked the player’s health the same way in five places, so each got a small helper. The final boss’s “run away to another room” code moved out of the general battle-resolution file into battle/boss.rs, and the Speed Potion and Battle Shout charge counters moved next to the other buffs. The biggest one: town_state.rs was 910 lines covering the town, the cat and quest rewards, so the cat went into town_cat.rs and the reward payout into quest_rewards.rs, leaving the town file at 478 lines. I checked every move by comparing the sorted lines before and after, and the tests, the build and a launch all came out clean.
Step 4: more code cleanup
Two more items off the refactor list. Every way of spawning an item (from a template, into a starting kit, from a shop) repeated the same steps to attach its effect, technique, class, description and weapon damage, so that became one helper, and the final boss’s two spawn functions now share one body. The bots also had their own copy of the map’s pathfinding with one extra check for solid things like townsfolk and the cat; the map’s version now takes that check as an option and the copy is gone. Before deleting the copy I had a test compare the two on 400 cases across 40 generated maps, and they matched every time.
Step 5: one toolkit for placing PixelLab art
More PixelLab animations are on the way, and maybe some redos of characters I already have, so I cleaned up the scripts that put the art onto the sprite sheets. Every batch so far got its own script with its own copy of the same helpers (crop to 32x32, lift near-black, pad or sample to the sheet’s frame count, check nothing else on the sheet changed), and those copies had slowly drifted apart. They now live in one file, tools/sheet_util.py, built from the newest and sturdiest version, and the themed enemy scripts use it. The original art isn’t on my disk anymore, so to prove nothing changed I made a fake batch of random frames and ran every old and new script on it: the sheets came out byte-for-byte the same. I also brought the art instructions up to date: how to place a batch, what to update afterwards, how to redo a character without moving its rows, and how to write a PixelLab character prompt. Only the Demon Castle enemies have their prompts written down, so a redo of anything older starts from the original prompt, and from now on every prompt gets recorded. I also went back over the Leonardo rules against the four rounds the castle backgrounds took. The notes had the prompt limit as 200 characters when Leonardo’s is really 2000, which is why the early rounds were short and kept failing, so the rules now say to write the long prompt that spells out the room, with the camera wording, the empty floor zones and the negatives that finally worked.
Step 6: an Inn in town
A playtester asked for a way to heal in town, so the town has an Inn now. The empty house at the east end of the south row belongs to the Innkeeper, a stout, warm woman with a brown bun and a long white apron, made in PixelLab. Standing next to her when I’m hurt, she offers a bed for 4 gold (a bit less than a Healing Potion): ENTER heals me to full and clears every lasting effect. At full health, or without the gold, she just says so and takes nothing. She has no quests yet. The signposts now point to “Inn: South East” as well.
To make the house look like an Inn, I had PixelLab draw 64 props in one go and picked from them: a sign with a bed under a moon hangs over the door where the striped awning was, kegs and a chalkboard with a tankard stand by the door, and a plank patio the width of the house sits on the dead end of the street in front, with tables, stools, a bench and an ale barrel. I spent a second batch on icons for every ability idea on my list, so they’re ready when those get built, and the leftover town props (a quest board, scarecrows, beehives and more) are saved for dressing the rest of the town.
Two surprises came out of it. Her full set of animations made the townsfolk sprite sheet taller than my graphics card allows, and the release build crashed on startup (the debug build didn’t), so only her idle is on the sheet for now and that sheet is out of room. And she first showed up as a flat yellow figure: every townsperson and the Shopkeeper had been drawn with a yellow tint on the map all along, left over from when they were yellow @ signs. It barely showed on the others, but her cream and brown turned solid yellow. They all show their real colors now.
Step 7: dressing up the town
The rest of the town props from the Inn batch are out on the map now. The square has a quest notice board by the north road and two stone benches beside the well. The farm fields got two scarecrows (one with a pumpkin head), with a wheelbarrow, hay bales and a hay cart around them, and there are beehives by the flower beds. Around the houses there’s a chicken coop, a dog house and a laundry line. The Blacksmith’s yard has a water trough, a hitching post and firewood, and a fruit stall stands in the shop’s yard. The town’s prop cells were full, so the map tile sheet got a second block of 16 cells for the town, with 3 still free. Nothing is final: I’ll move or swap them as I play.
I also added a long-term item to the backlog: go through each map theme one at a time and look at all its art (characters, enemies, tilesets, props, backgrounds) for problems, better ways to use it, or anything worth replacing.
The ability icons from the second batch were only sitting in an ignored folder on my disk, so I copied them into the repo next to their request file, and every ability idea on my list now says which two icons belong to it. When I get around to building one, the art is already waiting.
Step 8: the story, lined up with the prologue
The run intros and most of the town’s lore were written before the prologue existed, so they still told an older story: a Demon asleep under the town, cellars full of goblins, Blades waiting at the bottom of one dungeon. I rewrote all of it around what the prologue actually shows. The last hero killed the Demon with strength alone and kept the five Blades, believing their power protected him. It didn’t. It only made him easy for the nether to find, and it took him. A Demon killed by strength doesn’t stay dead, so it’s back, and the Elder has the scattered Blades for me to bring home. When I hold all five, I have to spend them on it, not keep them.
All six run intros are new: each one now follows the pull of the Blades and the hero’s fate as a warning, instead of describing the dungeon, since the Elder names where I’m going right after. In town, the lines about the cellars and the “deepest dungeon” now point at the castle in the hills, and the Townsman and the Shopkeeper each got a new line about the last hero: he rode out waving like the fight was already over, and never bought a potion because the Blades were all the protection he needed.
Step 9: a new Barbarian kit
I went through the Barbarian’s abilities one by one. Deathblow, Counter Attack and Whirlwind stay as they are. Quick Attack used to hit twice; now it’s a normal hit, but my turn gauge starts half full afterwards, so the next turn comes around fast.
Rend is gone. A damage-over-time attack with no first hit gives me very little reason to use it, and that goes for every class: I put “damage over time needs a first hit” on the backlog for the Mage, Rogue and Hunter. In Rend’s place the Barbarian gets Reckless Swing, a triple-damage hit with a price. If it kills, there’s a 75% chance the overkill comes back at me as damage, so it’s best saved for an enemy with a lot of health left. If it doesn’t kill, it always costs 10% of my max HP. The recoil never takes my last point of HP.
The new buff is Rage. For 3 turns I take 30% less damage, and every hit I take is saved up and added to my next attack, for my next 3 attacks. The more I get hit, the harder the next swing lands. It only lasts for the fight I use it in.
The Barbarian also finally has an out-of-combat ability like every other class: Roar. I use it on the map, and my basic Attacks deal 20% more damage for my next 20 turns in battle. Every action counts as a turn, and walking around doesn’t use any of it up.
All three new abilities use icons from the batch I’d already generated: a bloody axe for Reckless Swing, a red fist for Rage and a snarling wolf for Roar. Next up is running the bots on the Barbarian while I start on the Mage.
Reckless Swing, Rage and Roar each got their own animation from PixelLab. Reckless Swing is a big overhead wind-up and swing. Rage has the Barbarian hunching forward and shaking with fury. Roar has him planting his feet and roaring out on the map. The first Roar came back with a solid grey background baked into almost every frame, so I asked for second tries of Rage and Roar, but I liked the first versions better, and the background turned out to be easy to cut away. I also added a rule to my CLAUDE.md: whenever an ability is built or changed, check whether it needs a new animation.
The first bot run with the new kit was a shock: the Barbarian won 58% of the time across every tier, down from 82% with the old kit, and 22 runs died on the very first floor where the old kit lost 3. The new abilities weren’t the problem; the bot was playing them badly. Its idea of a “tough” enemy (4 or more HP) dated from before enemy stats went up, so every Goblin counted, and it opened on them with Reckless Swing, whose overkill recoil left it at 1 HP. I rewrote how the bot plays the Barbarian: a tough enemy is now one that would take 3 or more plain attacks to kill, Reckless Swing is only for a tough enemy that hasn’t been hit yet, and never while Rage is up (Rage’s stored damage would make the recoil even bigger). Rage is for a tough enemy or a fight against 2 or more, Counter Attack is for tough enemies instead of for when I’m low on health, and Rage is never recast while it’s already going.
With the bot playing it properly, the new kit came out at 83%, level with the old kit’s 82%, and floor-1 deaths fell from 22 to 2. The one tier that moved was the Demon fight, 7 wins out of 15 against 5 with the old kit, which is the right direction but too few runs to be sure of. Since the new “tough enemy” rule applies to every class’s bot, I merged the bot changes too.
Step 10: a new Mage kit
Next class: the Mage. Fireball, Blizzard, Ice Armor and the Invisible Cloak stay. Burn is gone, for the same reason as Rend: a damage-over-time spell with no first hit isn’t worth casting. In its place the Mage gets Arcane Missiles, three shots at 50% of my attack damage each, and every missile picks a random enemy as it fires. It never wastes a shot on an enemy that’s already dead, or one a missile still in the air is about to kill.
The other new spell is Frost Bolt, a 75% hit that also halves the enemy’s speed for its next 3 turns. Casting it again just resets the 3 turns. I thought about Mana Shield and Drain Life too, but the Mage is already the strongest class in the dungeon, and I don’t want any healing abilities in the game yet (Drain Life feels more like a warlock spell anyway).
I also noticed Fireball was the only class ability described as “plus your staff’s damage”, where everything else talks about a percent of my attack damage. Fireball is now 150% of my attack damage, which comes out the same as before on the first floor, and a little stronger with the best staff. And with Ice Armor up, the Mage went from the worst Defense in the game to tied for the best, so Ice Armor now gives +5 Defense instead of +7, which only brings the Mage up to 0.
Frost Bolt gets the ice-shard icon from my ability idea batch, and Arcane Missiles the bright streaking bolt, which took over Burn’s old icon slot. Both icons double as the projectiles that fly at the enemy. For now Frost Bolt borrows Burn’s old blue casting animation and Arcane Missiles borrows Fireball’s, until PixelLab makes real ones.
Since every class is getting this treatment, I made the process repeatable. A new script, tools/ability_review.py, puts each class’s abilities side by side: the numbers, the icon, the projectile and the animation, along with the main colors of each, plus the class’s un-built ideas with their icon candidates. It also flags an ability that has no animation or borrows another one’s. Running it over all five classes turned up a few looks that don’t match: Fireball’s cast barely shows any fire, Hunter’s Freeze Trap animation has no ice in it, and Poison Shot fires a plain grey arrow. I also wrote down the whole checklist for an ability change (design rules, every file it touches, and how to test it) so the next class goes faster.
I changed my mind on Mana Shield: the Mage was the only class without a buff in battle. It absorbs the next 35 damage I’d take, and only lasts for the fight I cast it in. The buff column shows how much it has left, and the log says how much each hit it soaks up.
Then the Mage’s looks. The review sheet showed the problem right away: the Mage’s battle pose had no staff, so in every cast the staff popped in out of nowhere, and Fireball’s cast barely had any fire in it. The fix went to the root: I made a new Mage in PixelLab from the old Mage’s front-facing sprite as a reference, so it looks the same but holds the staff from every side, and then redid every one of his animations, with the colors spelled out (orange and red fire, blue ice, purple arcane magic). Fireball now actually throws fire, Frost Bolt throws an ice shard, Mana Shield wraps him in a purple ring, and the Invisible Cloak needed a second try before it faded him out to a pale ghost instead of just pulling his hood up. I also recolored the Arcane Missiles and Mana Shield icons purple, so the arcane spells don’t look like a fifth and sixth ice spell. The whole Mage stays on its own branch until the class is done; next up is running the bots on him with the new spells.
Watching the new animations in a fight, the spells fired too early: Fireball left the staff before the Mage had finished winding up. Now Fireball and Frost Bolt fire when the cast animation ends, Arcane Missiles fires on the frame where the animation shows the burst, and the cast now plays three times, one missile each time, so every missile reads on its own. Blizzard now plays its whole casting animation once, then the icicles come down while it plays a second time.
Then the bots got a turn with the new Mage: 90 runs, 15 at each tier. He won 69%, down from 82% with the old kit, and almost all of that is the Demon: only 2 wins out of 15 at 5 Blades, with 11 of the runs dying on the Demon’s floor. The other tiers held up (87%, 60%, 87%, 93%, 73%). The bot’s battle rules also changed since that old run, so it isn’t a clean comparison, and I’m leaving his numbers alone for now to get on with the next class.
Step 11: a new Hunter kit
The Hunter was next, and it needed the most help: in the bot runs it was one of the weakest classes, and it had no buff in battle and no big single-target hit. Poison Shot now hits for 75% of my attack damage before the poison starts, since a pure damage-over-time ability had very little reason to be used. Multi-shot is new: three arrows into one enemy at 60% each. Stun became Blinding Shot, a flash arrow that hits for half my attack and gives the enemy’s next three attacks a 50% chance to miss, so it always does something instead of being a coin flip. I first called it Snare Shot, but that sounds like it should slow the enemy. Feint became Hunter’s Mark, the Hunter’s buff: everything I deal to the marked enemy does 50% more damage for its next four turns, poison ticks included. Shoot, Freeze Trap and Arrow Volley stay as they were. I passed on Trueshot (ignoring Defense does nothing when no enemy has any) and Camouflage (it would have been a third stealth ability).
The art got the same treatment as the Mage. The old Hunter kicked for his attack, swung a hatchet for Stun, waved a dagger for Feint and his victory, and held an arrow like a spear to defend. I made a new Hunter in PixelLab from his old portrait, the one pose holding the bow, and redid every animation. His east-facing pose had the bow slung on his back, so all his battle animations are made facing west and mirrored. Defend took three tries before he held the bow horizontally to block, and Hunter’s Mark took two. Freeze Trap’s trap came out grey, so I recolored it ice blue. Poison Shot now fires a green arrow, Blinding Shot one with a glowing yellow head, and Multi-shot plays its shot three times, one arrow each time. Every arrow now leaves the bow on the frame he lets go of it.
Seeing it all together, a few things didn’t sit right. The enemies stand up and to my right in a battle, and shooting due east looked off, so I had every battle animation made again facing north-east and put the two sets side by side to pick from. The north-east ones lost the quiver every few frames, so the stance, the Attack and Defend stay facing east, while the four shots and Hunter’s Mark aim north-east at the enemies. The plain Attack shouldn’t be a bow shot either, since that’s what the techniques are for, so the Hunter now slashes with a hunting knife. And Hunter’s Mark finally makes sense: the Hunter points at his prey, and a crosshair appears over that enemy and stays there for as long as the mark lasts, instead of a circle at his own feet. Arrow Volley now looks like he’s actually shooting the volley: he draws and looses once for every arrow that falls, back to back, and each arrow comes down a moment after he lets it go. Every volley in the game, Blizzard and the Amazon’s Javelin Volley included, now also has three or four stray shots that hit nothing, instead of one per enemy, which looks nicer. He fires them fast, too, so a volley is a quick burst of arrows and not just Multi-shot done slowly. And the crosshair from Hunter’s Mark now just flashes on the enemy as he points; the debuff icon under the enemy keeps track of the mark after that.
Then the bots got their turn with the new Hunter, with the same 90 runs the Mage got. He won 78%, ahead of the new Mage’s 69%, and a big jump for a class that used to be one of the weakest (the old Hunter never had a run with the same settings, so I can’t compare the two exactly). By tier: 93%, 100%, 67%, 93%, 93%, and the Demon is still the wall at 3 wins out of 15, with 10 runs dying on its floor. 2 Blades was the only other weak spot, with 5 runs lost on the first two floors.
Step 12: a battle tester
Testing a new ability meant going into the Battle Arena, buying the ability in its shop and walking into a fight, every time. So now there’s a battle tester, just for me: cargo battle opens a setup screen where I pick the class, the tier, the weapon, the backdrop, how many copies of each ability and potion I carry, my starting health, any buffs I’d have used before the fight (Ice Armor, Roar, the potions, Stealth for an ambush), and up to four enemies, each picked as a theme and then an enemy from it, bosses and the Final Demon included. Enter starts the fight on the real battle screen, and when it ends I’m back on the setup screen for a rematch or a change. The same choices work as command-line options, and --go skips the screen and goes straight into the fight, so a change can come with the exact command to try it. It’s only in builds made with its own feature, so it never ships with the game, and it never touches my play history or achievements. The first version was a debug build and just sat on a black screen: a debug build takes minutes to load the 7680x4800 battle backgrounds sheet, so it’s a release build now.
Then I gave the tester a Mode setting, because sometimes I only want to watch one side. “Class only” lets just my class act: I always have my turn, the enemies never attack and can’t die, and their health bars drop with each hit before filling back up, so I can see exactly how much a move did. The enemies still take their turns quietly, so poison ticks and debuffs like Hunter’s Mark count down when they would in a real fight. “Enemies only” is the other way around: the enemies attack whenever their gauges fill, and I can’t die. I can still Defend, and it holds through every hit until I pick Attack, which only drops my guard; Flee takes me back to the setup screen. Watching hit after hit land made me want proper “hurt” animations for everyone instead of a flash, so that’s on the list for later.
Step 13: a new Amazon kit
The Amazon was next. Battle Cry became Spear Wall: she braces her spear, the next three hits she takes are 7 to 14 smaller like before, and the spear strikes each attacker back for half her attack damage, so it’s a buff that also fights. Pierce Thrust is new: a lunging thrust for 150% that runs through to the enemy standing behind its target for 75%. The brainstormed version ignored Defense, but no enemy has any Defense, so it would have done nothing. Poison Spear now opens with a full hit of my attack damage before the poison, since it’s a melee jab and should hit harder than the Hunter’s Poison Shot. Trap is now Spike Trap, so it doesn’t sound like the Hunter’s Freeze Trap. Javelin Volley got the same treatment as Arrow Volley: one quick throw per javelin, three or four of them hitting nothing.
The art took a few tries. The first new Amazon I made in PixelLab came out chibi, with a huge head and chest on tiny legs, and I should have looked at her before making all her animations. So I had four candidates made and only looked at the poses: one from the old Amazon as a reference just came out as the old plate knight again, one had a strong build but too much bare leg, one covered the legs but had thin arms, and the last one, with covered legs and strong arms, is the Amazon now. From now on a new character gets looked at before anything is animated. Every animation keeps the spear in her hands, even the throws, so it never pops in and out. I also settled on a standard for which way battle animations face: the stance, Attack, Defend and buffs face east, and projectile attacks face north-east toward the enemies. Her battle stance is now a wide stance with the spear held across her body, breathing; the first wide one pointed the spear at the enemy and looked like an attack, and PixelLab can start and end an animation on any pose I give it, so it loops in that stance instead of stepping into it every time. Spear Wall holds the spear across her like a block, and she poses with the spear at her side when she wins.
Before the bots played her, I changed Spear Wall. Taking 7 to 14 off a hit becomes 49 to 98 in the dungeon tiers, enough to block most hits completely, and the spear still struck back on top of that. Now each of the next three hits is split in half: half goes back to whoever landed it and I take the other half, with Defend and armor coming off my half as usual. It’s still her strongest ability, so it stays at three hits. I also taught the bots to use it against a group when they have no Javelin Volley, and to use Pierce Thrust against two or more enemies, since it reaches the one behind. With 15 runs on each tier, the new Amazon won 81% (93/87/80/93/93/40 from Dungeon Crawl to 5 Blades), the best of the three redesigns so far (the Hunter won 78%, the Mage 69%), and 6 of 15 at 5 Blades, where the old Amazon won 3.
Step 14: a new Rogue kit
The Rogue was the last class. Garrote was the last damage over time that did nothing on the turn I used it, so now it strangles for a full hit of my attack damage and leaves the enemy bleeding for 14 a turn for three turns. Backstab is new and it’s the ambush move: the Rogue blinks in behind the enemy, stabs it facing back the other way, and blinks home. It hits for 125%, or 350% if it’s the opening move of a Stealth ambush. To make room for it, a plain Attack out of an ambush now does 1.5x instead of triple. Take Advantage is a new hit for 150% that only works on an enemy that’s bleeding; it stays greyed out until something is, and picking a target skips anyone who isn’t. Vanish is the Rogue’s escape: it leaves the fight like Flee, but Stealth is already on for 20 moves, so walking straight back in is an ambush. The combo is Garrote, Vanish, then back in with Backstab, and every piece of it is a single-use ability I have to find or buy.
The art went better than the Amazon’s because the Rogue’s PixelLab character already had every animation; I only had to add to it. The North and South walk took far longer than it should have. They looked too wide, with both daggers held out at the sides, and the arms never swung the way a person’s do, opposite to the legs. Every try started from the Rogue’s standing pose with both hands at the sides, whatever I asked for, so I kept getting the same stiff walk with small changes. What finally worked was PixelLab’s walking template, a real walk skeleton with no starting pose to come back to: the legs step and the arms swing the right way. The stride is still a little wide and the dagger disappears for a frame when it turns edge-on, but more tries weren’t getting closer, so that’s where I left it. Next time a walk starts with the template. The battle stance is now a steady crouch, Backstab, Take Advantage and Vanish got their own animations (Take Advantage throws up a spray of blood, Vanish is a smoke bomb), and Stealth fades the Rogue into shadow. I also tried new versions of Dodge and Flurry but liked the old ones better, especially Dodge, which really looks like a power-up. That’s every class redesigned; next is a bot run to see how the new Rogue holds up.
The bots ran the new Rogue 15 times on each tier and it won 77% (87/60/80/93/93/47 from Dungeon Crawl to 5 Blades), right between the Hunter’s 78% and the Mage’s 69%. 1 Blade is its weak spot, where 5 of the 6 losses came on floor 2, but at 5 Blades it won 7 of 15, where the old Rogue only won 2 or 3.
Step 15: the first music
The game has sound now. Leonardo, which I’ve been using for the battle backgrounds, has a music model too, so I wrote prompts for a first three tracks in the style of a 16-bit SNES-era fantasy RPG soundtrack: a warm folk tune for the town, a slow, uneasy cello drone for the dungeon, and fast strings and war drums for battles. Each came back as one minute of music. The game plays them with kira, an audio library for Rust games (bracket-lib, which draws the game, has no sound of its own). The town track plays in town, the dungeon track on every dungeon floor, and the battle track in fights, each looping, with a short crossfade whenever I move from one to the next. The title screen and menus stay quiet for now.
The Options screen’s Audio rows, greyed out since I built that screen, finally work. Volume, Music and Sound each show a 10-step bar; I press Enter on one, set it with Left/Right, hearing the change straight away, and press Enter again to keep it. Music and Sound are separate channels under the main Volume, so the music can sit under the sound effects. There aren’t any sound effects yet, but the Sound channel is built and ready for the first ones, starting with the hits in battle.
Getting it to sound right took longer than the code. Under WSL, where I develop, the music stuttered: a little in town, badly while walking around the dungeon. I tried a bigger sound buffer, then found the game had been drawing everything on the CPU instead of the graphics card the whole time, using six cores even on the title screen. Switching it to the graphics card brought that down to one core, which is a nice win on its own, but the stutter stayed. In the end a plain test tone with no game running stuttered too, so it’s WSL’s own sound link to Windows. The Windows build plays the music clean, so from now on I listen to the music on the Windows build.
A second round of six tracks followed: a title theme for the title screen and the run setup menus, one for each of the Forest, Sewer, Swamp and Mountain floors, and a short brass fanfare that plays once when I win a battle. Each dungeon floor now plays its own theme’s music, and the stone Dungeon keeps the first round’s cello track. The Demon Castle, a boss battle, the Battle Arena and the game over screen are still waiting on theirs, so the castle borrows the Dungeon track and the other two use the normal battle music for now.