Notes
Rebuilding Mystery Agents' Pass-and-Play Mode
Mystery Agents is a hidden-spy party game in the style of Spyfall: one phone, passed around a table of three to eight people. Everyone learns the location except the spy, then the table questions each other until someone's answers don't add up. The mode that made this playable at all is pass-and-play — one device, no accounts, no network required once the page has loaded — and it arrived in a state that looked finished and wasn't. Every round eventually broke something.
Five bugs, all invisible until you actually played a full round
The pattern behind most of them was the same: each one only showed up once a round actually finished, which meant a quick glance at the app never caught it. You had to sit down, play three or four people through a full round, and watch what happened at the boundary between one round and the next.
- The results screen broke at the end of every round. The layout for the end-of-round summary put a row of stretched columns inside a scrolling list. Telling a row to stretch inside something scrollable asks it to fill a height that has no defined limit, which the layout engine can't resolve — so the screen that was supposed to announce who won crashed instead, every single time a round ended. The fix was to wrap that row so its height comes from its own content instead of an undefined parent. It's a narrow rule — the same stretch behavior is fine on a non-scrolling layout — but it's the kind of narrow rule that's very easy to trip over once and very easy to miss in testing if you don't play a round through to the end.
- The timer ran twice as fast. Backing out of a round mid-play didn't cancel the countdown timer that was already running. Starting a new round then started a second timer alongside the orphaned first one, and both were counting the same clock down at the same time — which reads, to a player, as the round somehow being half as long as it was supposed to be. The fix was making sure every exit from a round — not just the normal "time's up" path — explicitly stops the timer, and that a new one is never created while an old one might still be alive.
- A tied vote used to be decided by who got voted first. The original logic scanned the votes and kept whichever name it saw reach the highest count first, which meant two players tied on votes weren't actually tied in practice — whoever happened to get accused earlier in the count lost. It's a genuinely easy mistake to make, because the code runs and returns a plausible-looking winner every time; nothing about it looks broken unless you know the rule it's supposed to be enforcing. The fix keeps every player currently in the lead and only calls it a real tie when there's more than one.
- The deal-cards button looked clickable while it wasn't. While the location data was still loading, the button read "Start game" but its handler was disabled — so it looked ready and did nothing when tapped, with no explanation on screen. The fix was cosmetic but important: the button now says "Loading location set…" until it's actually ready, so a disabled control looks disabled instead of looking stuck.
- Role names came out as English-Thai mashups. The localization step built Thai role text by replacing English words one at a time inside a longer string, which occasionally left a Thai word fused directly onto an untranslated English one with no space between them — readable to nobody. The actual fix was to stop trying to translate piece by piece and build a direct, one-to-one map covering all 163 role names instead, with the word-by-word approach kept only as a fallback for anything the map somehow misses.
Rules that were missing, not just buggy
Two rules didn't exist yet in the first version, and their absence changed how the game actually played. The spy previously had no way to win except by talking their way through the whole round undetected — there was no mechanic for the spy to make a move. The fix added a "spy calls the location" action available mid-round: the spy can guess where they think the round is set, and that guess decides the round outright — guess right and the spy wins, guess wrong and the officers win. It turns the spy's role from purely defensive into something with an actual decision to make.
The second gap was in how a tied vote resolved. Before the fix, a tie still somehow produced an accused player, because the table's vote count logic assumed someone had to be picked. The corrected rule is that a tie means nobody is caught, and the spy scores the round — which matches how the game is meant to be played, and closes a way the vote outcome could feel arbitrary to the table.
Testing a game that depends on turn order
A game like this is hard to unit-test in the usual sense, because most of what can go wrong only shows up across a sequence of turns — a vote, a round ending, a new round starting on top of state the last one left behind. The test suite that came out of this repair actually plays the game: a small helper taps through the same buttons a real player would, in the same order, and the tests assert on what the app shows after each step rather than mocking around the interaction. That approach is what caught the stretch-in-a-scroll-view crash and the double timer in the first place — a test that only checks individual functions in isolation wouldn't have noticed either one, because both bugs only exist at the boundary between one round and the next.
Why there's no ad slot in this build
An earlier version of the web build placed an ad slot near the top of the page, which seemed reasonable until I checked what was actually visible at that position. The game's interface draws itself across the entire browser window as one full-screen layer, positioned above everything else in the page — including that ad slot. Clicking exactly where the ad sat landed on the game layer, not the ad; the slot was present in the markup and completely unreachable by anyone looking at the page. A slot nobody can see or click isn't a small inefficiency, it's a strong candidate for being flagged as invalid placement, and either way it wasn't doing anything. It's out of this build until there's an actual gap in the layout the game's canvas doesn't sit on top of.
Mystery Agents is an independent game inspired by Spyfall-style hidden-role party games. It is not affiliated with or endorsed by the publishers of Spyfall.