Posted July 13, 2026 by Chrisdalbano
#dev #bugfixing #postmortem #deployment #platform #ai
Pivoted from Unreal to Unity with ~5 days left, then coded a complete, one-click web game: main menu → guided tutorial → 3-arena campaign → champion, with a "spin to strike/parry" core, cohesive UI, juice, organic art + credited audio. Shipped as a WebGL build (primary, for the CrazyGames "Best Web Game" target) + Windows fallback.
The build itself came together fast. The last 20%... making the core feel right and consistent... was 80% of the pain, almost all of it in two areas: the ball-lethality model (which turned out to be ~5 independent bugs stacked on each other) and WebGL/Unity deploy traps that don't show up until the production build.
The dev build ran fine; the production build died instantly with Maximum call stack size exceeded. Cause: Unity's release WebGL defaults to ExplicitlyThrownExceptionsOnly, which compiled a recursion the dev build's full-exception mode tolerated. Fix: WebGL.exceptionSupport = FullWithStacktrace. Lesson: "works in dev" ≠ "works in the shipped build" — the exception/stripping settings change behavior, and a WebGL build is ~3 MB (stripped) vs ~10–11 MB (full exceptions); that size delta became a useful sanity signal.
Repeated 404s; at one point the browser asked for build.wasm, a filename that wasn't even in our zip file (ours is WebGL.wasm.unityweb). The build was provably correct (verified locally with curl); itch was serving a stale index.html from a prior upload. Fix that finally stuck: delete the upload → Save → re-upload → Save → open in Incognito (bypasses the cached/service-worker version). Lesson: when the served artifact references a name your build doesn't contain, it's a deploy/cache problem, not a build problem... don't rebuild, re-deploy.
The core "ball kills you" rule went through more iterations than anything else, because each fix revealed the next problem:
spinSkill value gated both striking and parrying, so tuning bots to be beatable (parry less) also made them stop spin-striking. Split it: always spin-strike (offense), parry by skill (defense). Suddenly the arena had stakes.
Plus a design fork mid-saga (should a moving ball always kill, or only a fast one?) that resolved into: keep the speed nuance, but make danger unmistakable with a progressive heat-up tint so "slow doesn't kill" reads as intuitive instead of buggy. Lesson: when a mechanic feels "wrong," it's often a readability problem masquerading as a rules problem.