Changelog
What changed in Battle Painters, release by release.
v0.2.18 — 2026-07-20
- Keep the Go! burst rings out of the lazy GlowLayer and un-race the flash spec
v0.2.17 — 2026-07-20
- Note the celebration, UI blips, and timer pulses in the manuals
- Choreograph the results screen: staggered ranks, pip light-up, sparkline draw, confetti
- Give every UI interaction a synthesized blip and the portrait pick a pop
- Celebrate the winners on the live scene and punch up the round's start and finish
v0.2.16 — 2026-07-20
- Assert log-panel narrowing by content and run flatpak-builder directly on the runner
v0.2.15 — 2026-07-20
- Fail the production build when the menu entrypoint outgrows its byte budget
- Render store listing art in exact per-store sizes via capture:store
- Stage real payloads for the Snap and Flathub lanes and sign the MAS pkg and MSIX
- Make the paint-coalescing and camera-orbit specs tolerate a loaded machine
- Carve item valuation out of tileScoring into an itemScoring module
- Publish the release history as a static /changelog/ page
- Generate a per-version changelog from the git tag history
v0.2.14 — 2026-07-20
- Point the minimap e2e seam at RoundHud and suppress the tutorial in multiplayer sessions
- Cap Playwright at 4 workers so concurrent software-WebGL rounds stay responsive
- Expose the recorded frame count on ReplayCapture for the replay e2e seam
- Chart the new helper modules in the README tree and manuals
- Stage store packages and capture sessions through shared script kits
- Back the UI control components with pure, unit-tested logic modules
- Hand RoundController's HUD and replay wiring to RoundHud and ReplayCapture
- Lift the results-card canvas primitives into resultCanvasKit
- Carve the player checkpoint capture into a pure playerSnapshot module
- Route every workflow's Node+pnpm setup through the shared composite action
- Localise the menu footer nav's accessible name
- Keep the first-launch tutorial out of specs that click Start directly
v0.2.13 — 2026-07-17
- Tuck the sandbox out of the centre pane and hang the classroom clock by the chalkboard
- Declutter the classroom: school door, snake plant, full desk row, no art corner
- Give the classroom its own door, shelf, art line, and world map
v0.2.12 — 2026-07-16
- Keep hill backdrop depth fixed so the rocking swings clear it
- Space classroom windows in proportion to the wall width
- Deepen the classroom-bedroom split with rocking swings, a tidier room, and a number line
v0.2.11 — 2026-07-16
- Give the classroom a curtainless window band onto a playground and seat the teacher at the board
- Furnish the classroom theme with desks, decor, and a linoleum floor
v0.2.10 — 2026-07-16
- Restyle the Stats and tutorial dialogs on the Settings/About design language
- Regroup online parties under a successor host after a silent host drop
- Show a first-launch How to Play dialog gated on a persistent seen-flag
- Add a selectable Art Classroom room theme behind a theme registry
- Split the window builders into per-concern modules over the room kit
- Extract playerMotion, timedEffects, and spawnLayout from PlayerState
- Track lifetime player stats locally with a menu Stats dialog
- Build the AI coarse grid lazily and reuse per-player observations across ticks
- Cover pointerShared, the Transport contract, and gamepadMenuNav with Jest mirrors
v0.2.9 — 2026-07-13
- Publish static guide and privacy pages with crawlable interlinks
v0.2.8 — 2026-07-13
- Split itemModels into per-item builder modules over a shared kit
- Share per-tick player projections across AI snapshots
- Cover AITargeting with a Jest mirror and sync the AI docs
- Format the gameEventTypes freeze test
v0.2.7 — 2026-07-10
- Replace polling-shaped hard waits with expect.poll in e2e specs
- Extract target selection from AIController into AITargeting
- Drive menu navigation from gamepads on non-TV platforms
- Auto-retry the client reconnect with visible backoff attempts
- Cover the joinFail transport seam in the createTransport tests
- Show classified join-error copy for bad codes vs connectivity failures
- Coalesce paint GPU texture uploads to once per rendered frame
- Maintain incremental per-owner paint tallies for O(1) coverage
- Add tests for the UI store and transition wrapper
- Throttle the minimap paint-layer rescan
- Add tests for the small pure util and DOM modules
- Add invariant tests for the AI tuning tables
- Convert comment headers to JSDoc on exported APIs
- Skip AI snapshot-input building when no AI controllers exist
- Share the dash latch and canvas projection between mouse and touch input
- Extract the lobby overlay focus-preserving notify helper
- Add a jest coverage script
- Add an HTML report artifact for CI e2e triage
- Fail instead of skip when the AI or replay hook is missing in e2e
- Correct accessibility doc's themes-and-contrast section
- Remove the ready-mode PlayerCard variant and its stranded CSS
- Drop three unreferenced test-seam exports
- Remove the unused Plain-English AI label tables
- Delete the dead ReadyDialog module pair
- Split replayBinary encode/decode into per-section helpers
- Split tileScoring's itemBaseValue and cellWeight into per-case helpers
- Split aiSteering into threat, wall, and item-race sub-behaviors
- Decompose StrategySelector.choose into perception helpers
- Extract focusTrap's Tab-wrapping into a helper
- Extract EditableName error bubble and chip into module helpers
- Split Minimap.update into paint, item, and player draw passes
- Decompose makeCoverageGraph into grid, label, and polyline appenders
- Extract CameraMouseInput pointer handlers from the constructor
- Extract TouchInput touch handlers from the constructor
- Split RoundNetBridge.build into bus wiring and coordinator deps
- Extract buildClientCfg and the terminal-dialog table from _onJoinMessage
- Extract Game._showRoundOver's between-round guard and lobby handler
- Split NetworkCoordinator.setup into host and client session builders
- Split RoundController._update into countdown and playing ticks
- Split ResultImage._drawSpotlight into card and text draw helpers
- Split makeSplatShape into per-feature generators
- Split buildDustMotes into sunbeam and mote-scatter builders
- Split buildLamp into stand and shade builders
- Split swatchCardMaterial into paper and column draw helpers
- Decompose buildPlushBear into body, face, and bow builders
- Decompose buildPalette into board, dab, and brush builders
- Decompose buildPaintCans into body and open/closed-top builders
- Decompose buildChair into seat, leg, stretcher, and back builders
- Decompose buildDoor into casing, frame, panel, and hardware builders
- Decompose buildBed into frame, bedding, pillow, and board builders
- Split paintings artMaterial into per-motif draw helpers
- Split buildPrecip into material and per-particle helpers
- Split GameScene._buildWalls into materials, panels, and posts
- Split itemModels brush, potion, and bomb builders into sub-part helpers
- Extract AIController._sampleCandidate from _pickAreaScore
- Decompose buildSunMoon and buildWindowFrame into per-part builders
- Decompose ResultImage coverage chart and items card into sub-draw helpers
- Split PaintSystem._redrawFromCells into fast and fallback cell painters
- Extract HostSession peer-event handlers from the constructor
- Split NetworkCoordinator client handlers into per-message methods
- Split createRoomKit helper attachment by concern
- Decompose buildBookshelf into carcass, bay, and decor builders
- Decompose buildRockingHorse into per-assembly builders
- Decompose buildToyChest into per-part builders
- Extract SparkleTrail star texture and mesh pool from _build
- Decompose playMagicSparkles into texture, resource, and per-sparkle helpers
- Decompose playSmallExplosions into shared-resource and per-burst helpers
- Decompose playExplosion into per-layer particle builders
- Split itemModels._buildShoe into named phase sub-builders
- Decompose GameScene.buildScene into phase helpers
- Decompose RoundController._setup into _setup* phase helpers
- Split ItemState.checkPlayerCollisions into per-pass helpers
- Decompose Player.update render-half into per-aspect _sync* helpers
- Extract PlayerState._integrateJump from update()
- Dedupe ResultImage layout math, player-color, and stats-card scaffolding
- Split MenuBackground into pure geometry, canvas renderer, and mount
- Decompose AIController.update into per-behavior tick helpers
- Split tileScoring's oversized scorers into named pure sub-functions
- Share the player name-label and direction-arrow billboard material
- Split the clock item model into per-sub-assembly builders
- Share the soft-disc gradient texture and unlit-alpha material
- Decompose RoundController _setup and route teardown through a disposer bag
- Extract GameScene's slot and control-role logic into a pure module
- Decompose buildWindow into per-section builders
- Extract the AI strategy-scoring math into a pure, testable module
v0.2.6 — 2026-07-04
- Share the menu/lobby store seam and keymap-claim algorithm
- Split the shoe item model and share its material-cache scaffold
- Decompose the AI target-selection branches into pure pickers
- Extract shared timed-effect lifecycle and material helpers
v0.2.5 — 2026-07-04
- Extract the AI steering and dash policy into a pure, testable module
- Extract the AI charge-decision math into a pure, testable module
- Extract the split-screen overlay chrome out of RoundController
- Move the AI charge and steering tuning constants into tables.js
- Extract a shared consent-gated activation base for ads and analytics
- Collapse the pref singletons into a factory and unify subscription teardown
v0.2.4 — 2026-07-03
- Contain the room-code field in a real join form
- Keep server dotfiles out of the service-worker precache
v0.2.3 — 2026-07-03
- Stop the concentric-sweeper exploit: contest the wall band, interdict the frontier
v0.2.2 — 2026-07-03
- Price CPU ground by rank: hell hunts the live pairwise margin late
- Wire the recorded standings into AIController item pricing
- Teach CPUs team division of labor and item-race contesting
- Bend Hell routes around write-offs and re-tune the tier vector
- Price bot routes by the paint they earn
- Give Normal bots a competent dodge
- Sharpen AI interception and item commitment
- Teach Hard/Hell bots to spend the dash cooldown
v0.1.46 — 2026-07-02
- Add a dash: tap-to-burst speed with cooldown
v0.1.45 — 2026-07-02
- Name the collected item in the pickup toast
- Steer toward taps and clicks outside the battleground
- Fix light-theme chart labels, 720p overflow, and off-brand replay HUD
v0.1.44 — 2026-07-01
- Reshape the Magic Shoe ankle zone into a fitted high-top
v0.1.43 — 2026-06-23
- Make player cards opaque so the splatter backdrop never bleeds through
v0.1.42 — 2026-06-22
- Stop the Orejime CMP double-loading en + fr on a non-en boot
v0.1.41 — 2026-06-22
- Fix unstyled online panel on the menu (orphaned lobby.css)
v0.1.40 — 2026-06-22
- Fix Start button + dialog cards unstyled (orphaned kit CSS)
v0.1.39 — 2026-06-22
- Lazy-load PeerJS, lobby + Settings off the menu boot chunk
v0.1.38 — 2026-06-22
- Cut menu main-thread work to improve Lighthouse performance
- Add upload-assets to .gitignore
v0.1.37 — 2026-06-21
- Add Mac App Store App Sandbox entitlements to the store build
v0.1.36 — 2026-06-21
- Add store packaging + CI lanes for mobile/TV/desktop-stores/Xbox
- Add BP_STORE/BP_TV build flavors and a store-safe (no self-updater) Tauri overlay
v0.1.35 — 2026-06-21
- Give the brush item a dark-blue handle and shrink the brush, shoe, and clock items
v0.1.34 — 2026-06-21
- Attach the speed-penalty bandage to the brush body bone and seat it flush
v0.1.33 — 2026-06-18
- Rework the Magic Shoe as a laced Converse high-top
v0.1.32 — 2026-06-17
- Replace the speed-penalty bandage billboard with a 3D crossed-plaster on the brush
v0.1.31 — 2026-06-13
- Give the balloons a subtle latex sheen
v0.1.30 — 2026-06-13
- Hollow out the toy chest with toys nestled inside
v0.1.29 — 2026-06-13
- Improve the plush bear: projecting snout, lively eyes, inset ears, hugging arms
v0.1.28 — 2026-06-13
- Round out the rocking horse: connected rounded legs, neck, mane, saddle, tail
v0.1.27 — 2026-06-13
- Revert "Round out the plush bear and rocking horse into proper toys"
- Round out the plush bear and rocking horse into proper toys
v0.1.26 — 2026-06-13
- Shape the shoe into a Converse high-top and lathe the brush smooth
v0.1.25 — 2026-06-13
- Item polish: the alarm clock tells the real time, the brush goes paint-free
v0.1.24 — 2026-06-13
- Stabilize the ink sheen under camera motion and polish the item trio
v0.1.23 — 2026-06-13
- Flatten the ink to one even sheen and sharpen the emoji likeness
v0.1.22 — 2026-06-12
- Match the item models to their emojis and settle the ink into a satin sheen
v0.1.21 — 2026-06-12
- Soften the ink relief and rework the shoe, brush, and clock models
v0.1.20 — 2026-06-12
- Refine the scene: Splatoon-style ink, realistic items, glow that spares players
v0.1.19 — 2026-06-12
- Upgrade the game scene: 3D item models, wet-paint sheen, VFX glow, wall trim
v0.1.18 — 2026-06-12
- Slim the surface handle and share the HUD screen-reader announcer
v0.1.17 — 2026-06-12
- Make HUD toasts show the sentence around the player name
v0.1.16 — 2026-06-12
- Share the match-settings bar, fix latest-ref effect deps, close HC palette gaps
v0.1.15 — 2026-06-12
- Re-render the host lobby through HostLobbyModel's own store seam
v0.1.14 — 2026-06-12
- Consolidate UI helpers and remove render-phase model writes
v0.1.13 — 2026-06-12
- Attach imperative ref hosts once per mount, not once per re-render
v0.1.12 — 2026-06-12
- Run the UI on Preact via preact/compat
v0.1.11 — 2026-06-12
- Drop an inert lint suppression in the replay transport
- Rewrite the UI documentation for the React architecture
- Convert the replay picker and consent fallbacks; retire the DOM primitives
- Convert the host and client lobbies to React
- Convert the main menu to React
- Convert the replay playback chrome to React
- Convert the in-round HUD to React
- Convert the results screen and host-exit dialog to React
- Convert the between-round screen to React
- Convert the loading / ready-check screen to React
- Convert the pause dialog family to React
- Convert the settings dialog to React
- Convert the About dialog and doc viewer to React
- Convert the ready dialog to React; add the match-settings subscribe seam
- Convert the share dialog to React
- Add React UI primitives with attribute-identical DOM
- Lay the React UI foundation: build config, surface store, root, hooks
v0.1.10 — 2026-06-12
- Add an App Store-style promo page at /promo/
v0.1.9 — 2026-06-11
- Add a promo-video capture pipeline and a shared capture kit
v0.1.8 — 2026-06-11
- Open the desktop app maximized
v0.1.7 — 2026-06-11
- Add a self-updating desktop app via the Tauri updater
v0.1.6 — 2026-06-11
- Make installed-PWA updates reliably detected, re-prompted, and applied
v0.1.5 — 2026-06-11
- Refresh lobby labels in place when the language changes
- Keep the lobby active when the language changes from its Settings dialog
- Restyle the room-code row: ticket chip on its own line, accented Invite Link
- Add a lobby invite link that deep-links guests straight into the join lobby
v0.1.4 — 2026-06-11
- Update the app icon artwork and regenerate all derived icons
v0.1.3 — 2026-06-10
- Deflake the head-to-head rotation specs
v0.1.2 — 2026-06-10
- Publish a GitHub Release for every deployed version
- Auto-bump the patch version on every web deploy
- Add TV device support: Remote input, D-pad navigation, 10-foot mode
- Poll the you-card hover shadow instead of sampling one frame
- Support the stated browser floor (Chrome 87 / Edge 88 / FF 78 / Safari 14.1)
- Harden the workflows: fail-fast CI graph, least privilege, timeouts
v0.1.0 — 2026-06-10
Initial public release.