Cabo Card Game app screenshots
Engineering Stories

Ship Fast.
Break Things.
Write It Down.

The bugs, architecture calls, and hard-won lessons from building a multiplayer card game

Modularization, WebSockets, FCM edge cases, performance — every problem we hit and how we solved it, now documented.

18
Deep Dives
4
Game Modules
50k+
Downloads

Engineering Blogs

Every article is a real problem I hit, how I diagnosed it, and how I fixed it — with code, architecture diagrams, and the decisions I got wrong first.

Crumbling stone monolith transforming into clean purple modular cubes
ArchitectureFlutter

From Monolith to Modules

9 min

Adding a third game to our app required touching dozens of files across the codebase. That was the moment I knew something had to change.

Apr 15, 2026
Read
Navigation stack diagram
FlutterNavigation

GoRouter + Provider: The Trap Nobody Warns You About

7 min

The error was always the same — 'Provider<GameService> not found' — but it only happened when entering the module from a notification tap.

Apr 15, 2026
Read
Push notification flow diagram
NotificationsFlutter

Handling FCM in All Three App States

8 min

Most FCM tutorials show one case. Real apps need to handle all three — and getting any of them wrong breaks the user experience silently.

Apr 15, 2026
Read
Thread isolation diagram
PerformanceFlutter

How a Puzzle Generator Froze Our UI

6 min

I noticed the freeze in QA but couldn't reproduce it consistently. Then I looked at which thread the generator was running on.

Apr 15, 2026
Read
Real-time presence state machine
Real-timeFlutter

Real-Time Presence in a Multiplayer Card Game

8 min

Presence seems simple — online, offline, in-game. The edge cases between those states are where multiplayer games break.

Apr 15, 2026
Read
WebSocket reconnection flow
WebSocketReal-time

WebSocket Close Code 1006 and the Reconnection Problem

7 min

The game would silently disconnect on poor networks. Users thought the app crashed. It didn't — but I had no reconnection logic.

Apr 15, 2026
Read
Analytics event flow diagram
AnalyticsFlutter

Instrumenting a Game App for Analytics That Actually Matter

6 min

After shipping the Trek game module, I had zero insight into whether players were completing puzzles, where they dropped off, or what difficulty felt right.

Apr 15, 2026
Read
iOS App Store review process
iOS

The ATT Framework Trap: Rejected Without Calling It Once

5 min

Our App Store review came back with a Guideline 2.1 violation. I'd never written a line of ATT code. That was exactly the problem.

Apr 15, 2026
Read
Presence documents disappearing on a timeline
FirebaseNotifications

How Cabo Stops Notifying Players Who Left

7 min

Active players see live statuses and get challenge requests. Offline players hear nothing. No cron job, no last_seen sweep — just Firebase TTL doing the work.

May 25, 2026
Read
XP vs PQ delta distribution chart
ArchitectureAnalytics

Why Our League Runs on XP, Not Skill Rating

8 min

Weekly PQ delta gives casual users a spread of 2–3 points. Weekly XP gives 50 to 10,000+. Same users, but now there's real movement in the ladder.

May 25, 2026
Read
Server and client XP pipeline diagram
ArchitectureBackend

The Game That Grades Itself (So You Can't Cheat)

9 min

Multiplayer games need an opponent who trusts the result. Solo games have no opponent — so the worst case is inflating your own score, clamped server-side.

May 25, 2026
Read
WebSocket disconnect detection flow
WebSocketReal-time

How Cabo Detects You Abandoned a Match

7 min

When you force-quit the app, the WebSocket drops silently. The server detects the disconnect, writes an abandoned session with -50 XP, and cleans up.

May 25, 2026
Read
Minimal session schema diagram
ArchitectureBackend

9 Fields, 5 Games: The Minimal Session That Scales

6 min

Trimmed from bloated metadata blobs to 9 fields. Each game owns its own data. The session is just a receipt — and the receipt shouldn't contain the recipe.

May 25, 2026
Read
Spin wheel with rarity tiers
BackendFirebase

Atomic Spin: Building a Cheat-Proof Reward Wheel

8 min

Spin, get a prize. But the server validates, selects, and writes atomically — so you can't double-claim, skip ahead, or predict tomorrow's wheel.

May 25, 2026
Read
52 league tiers from Bronze to Legendary
ArchitectureAnalytics

52 Leagues: Why We Killed Five Rank Bands

6 min

Casual players never moved. The five-band system was too coarse. 52 tiers driven by weekly XP means every week is a fresh race — or a demotion.

May 25, 2026
Read
PQ score distribution before and after fix
AnalyticsBackend

PQ Inflation: When a 3-Day Player Outscores a Veteran

8 min

Skill references too low, consistency maxing in 30 days, volume log giving 0.75 at 10K XP. Five constant changes later: 3-day users score 1026, veterans 1121.

May 25, 2026
Read
Firestore document with a bug
BackendFirebase

Three Firestore Gotchas That Cost Me a Weekend

7 min

Each gotcha took hours. set() flattening dotted keys into literal field names. serverTimestamp() throwing inside arrayUnion. FieldValue crashing because it's a transform sentinel, not a value.

May 25, 2026
Read
Post-game funnel flow diagram
FlutterArchitecture

The Post-Game Screen You Actually Want to Stay On

7 min

End screen, spin wheel, rare drop celebration, next-game CTA — all driven by FunnelService with Remote Config toggles. The Trek BLoC doesn't know the wheel exists.

May 25, 2026
Read