In the spirit of Halloween, I set out to build an edge-native, zero-framework multiplayer browser game called Trick or Take.
The game is completely open source under the MIT license on GitHub:
š GitHub Repository: https://github.com/zicojiao/trick-or-take
š® Play Live: https://trickortake.com
Here is a deep-dive breakdown into the architectural decisions, client-side rendering pipeline, edge-based serverless state synchronization, and low-latency voice integration.
1. The Game Loop: "Take the Candy. Don't Get Caught."
The core gameplay loop is deceptively simple and high-tension:
- Lily is busy at the kitchen counter, and a candy bowl sits right behind her.
- Hold (via Spacebar, mouse click, or mobile touch) to snatch candy treats. The longer you maintain your hold, the faster your snatch rate accelerates.
- Release to instantly assume an innocent posture.
- Lily turns around unpredictably every 0.90 to 1.35 seconds, with a brief 0.55sā1.90s warning jitter.
- If caught holding while Lily looks back: you get a broom bonk, a stun penalty, and your unbanked candy drops straight to zero!
- Rounds last 60 seconds. Playable solo or in multiplayer rooms (2ā6 players) with optional live voice chat.
2. Zero-Framework Vanilla Canvas 2D Engine
Modern frontend stacks often default to heavy component libraries or monolithic game engines. For Trick or Take, the objective was maximum responsiveness and sub-second cold starts across low-end mobile devices and desktops alike.
Why Vanilla Canvas 2D?
- Ultra-Lightweight Footprint: The entire client codebase compiles to less than 45 KB of gzipped JavaScript.
- Instant Cold Start: Loads and renders within 50 ms without hydration lag or virtual DOM overhead.
-
Rock-Solid 60 FPS: Pure
requestAnimationFrameloop driving standard HTML5 2D context drawing operations. -
Asset-Free Audio Synthesizer: Instead of loading megabytes of MP3/OGG sound files, all background tunes and broom-bonk SFX are procedurally synthesized using the Web Audio API (
AudioContext,OscillatorNode, andGainNode).
3. Serverless Edge Architecture (Cloudflare Workers + D1)
Rather than maintaining dedicated GameLift or containerized WebSocket servers, the backend runs entirely on Cloudflare's serverless edge infrastructure:
[Browser: Canvas + Web Audio]
ā
ā¼ HTTPS / JSON
[Cloudflare Workers Edge API]
ā
āāāŗ [Cloudflare D1: SQLite Room State]
āāāŗ [HTMLRewriter: 12-Language SSR Localization]
āāāŗ [Agora RTC & RTM Token Minting]
Optimistic Concurrency with Monotonic Versioning
Multiplayer rooms (2 to 6 players) share state via Cloudflare D1. To avoid race conditions when multiple players press "Ready" or report state updates simultaneously without the cost of distributed locks:
- Each room record maintains a monotonic
versioncounter. - State updates use conditional SQL queries:
UPDATE rooms
SET data = ?1, version = version + 1
WHERE id = ?2 AND version = ?3;
- If a write conflict occurs, the Worker applies bounded exponential backoff with jitter and retries.
4. Ephemeral Live Voice Chat (Agora RTC)
Multiplayer parties are ten times more hilarious when players can yell warnings to each other before Lily turns!
- Edge Token Minting: Cloudflare Workers generate short-lived Agora RTC authentication tokens on demand for authorized room members. The primary Agora App Certificate is securely isolated in Workers secrets and never touches browser bundles.
- Microphone Handling: When players join voice, the browser establishes peer audio streams via the Agora Web SDK, with automated reconnection and graceful degradations if a player has unstable network connectivity.
5. Anti-Cheat & Verified Leaderboard Runs
In casual browser games, client-side score manipulation is notoriously rampant. Trick or Take implements a dual-layer verification model:
- Deterministic PRNG Seed: Each round generates a cryptographic seed governing Lily's turn timestamps and warning durations.
- Input-Trace Replay: Solo runs do not submit arbitrary integer scores. Instead, the browser logs a micro-trace of timestamps representing user press and release actions. The Cloudflare Worker re-simulates the run against the round's seed. If a player was holding during an active turn or exceeded physical limits, the score is rejected.
6. Open Source & Contributions
The entire project is licensed under the MIT License and welcoming contributions:
- š» GitHub Repository: https://github.com/zicojiao/trick-or-take
- š® Live Game: https://trickortake.com
Whether you're interested in browser gamedev, edge-native architectures, or just want to play a fun Halloween heist with friends, feel free to try it out, clone the repo, or open a pull request!
Top comments (0)