🎈 Whirlbird on Steroids

A first-person 3D balloon-flying game that lives inside Reddit β€” fly through a metallic space corridor, dodge obstacles, thread arches, rack up points, and publish your score for the whole subreddit to see.


πŸ’‘ Inspiration

The original Whirlbird was a charming side-scrolling balloon game. I asked: what if we cranked it up to 11? β€” full 3D, first-person perspective, a deep-space corridor, and the social layer of Reddit baked right in. The result is an adrenaline-fuelled flying game you can play without ever leaving your feed.


πŸš€ What It Does

Feature Details
3D Flight First-person chase-cam through a procedurally-spawned space corridor
Lane-Based Obstacles Trees, rings, and arches spawn across 5 lanes with progressive difficulty
Arch Rules You must fly through arches β€” flying past one is game over
Leaderboard Top-3 scores stored server-side in Redis and displayed on the splash screen
Publish to Reddit One tap to post your score as a reddit custom post so the community can compete
Responsive Plays on desktop (WASD / Mouse) and mobile (touch / tilt)
Space Environment Starfield, metallic corridors, nebula clouds, ACES filmic tone mapping

πŸ›  How I Built It

Client (Three.js + TypeScript)
  β”œβ”€β”€ game.ts        – main loop, camera, physics, score, UI overlays
  β”œβ”€β”€ obstacles.ts   – lane-based spawner, object pooling, difficulty curves
  β”œβ”€β”€ splash.ts      – leaderboard fetch, animated splash UI
  └── game.html/css  – HUD, loading screen, game-over, publish modals

Server (Hono + Devvit)
  β”œβ”€β”€ index.ts       – security middleware, error handler, 404 catch-all
  └── routes/
       β”œβ”€β”€ api.ts    – /init, /score, /leaderboard, /publish
       β”œβ”€β”€ menu.ts   – moderator menu actions
       β”œβ”€β”€ triggers.ts – onAppInstall auto-post
       └── forms.ts  – devvit form handling

Shared
  └── api.ts         – TypeScript interfaces shared between client & server

Key architecture decisions:

  • Object pooling for obstacles keeps the garbage collector quiet at 60 fps
  • Lane system (5 lanes, 3 units apart) guarantees playable paths exist
  • normalizeModel() auto-scales any GLB to a target bounding box β€” no manual fiddling
  • Redis sorted sets for the leaderboard β€” O(log N) upserts, O(N) range queries
  • Security-first middleware β€” content-type enforcement, rate limiting, input validation, no stack-trace leaks

πŸ§— Challenges We Ran Into

  1. GLB model sizing β€” models came in wildly different scales; solved with bounding-box normalisation
  2. Arch collision detection β€” detecting whether the balloon flew through vs over/beside an arch required a two-zone box approach (ARCH_HALF_W, ARCH_OPEN_H)
  3. Devvit platform constraints β€” no window.alert, limited DOM APIs, custom post rendering, Redis-only persistence
  4. Rate-limit races β€” concurrent score submissions could bypass a naΓ―ve in-memory limiter; Redis timestamps solved it
  5. Responsive 3D β€” getting FOV, touch controls, and CSS to behave across phone and desktop inside a Reddit embed

πŸ† Accomplishments We're Proud Of

  • Full publish-to-subreddit flow: play β†’ score β†’ confirm β†’ post appears on the feed
  • Chaos engineering test suite validating boundary values, malformed input, Redis failures, and rate-limit hammering
  • Zero any types β€” every interface has readonly properties and explicit return types
  • Loading screen with real progress bar tracking individual GLB asset loads
  • Security hardened: OWASP-aligned headers, content-type guards, bot-proof rate limits, username sanitisation

πŸ“š What We Learned

  • Chaos engineering β€” hypothesis-driven fault injection catches bugs unit tests miss
  • Playwright POM β€” page objects + role-based selectors keep E2E tests maintainable
  • Three-layer API thinking β€” validate on both client and server, never trust the wire
  • Security as a first-class feature β€” rate limiting, input validation, and header hardening are table stakes, not afterthoughts
  • Object pooling matters at 60 fps β€” one stray new THREE.Mesh() in the hot loop and you feel it

What's Next

  • More obstacle types β€” spinning blades, moving platforms, gravity wells
  • Power-ups β€” shield, magnet, speed boost
  • Multiplayer ghosts β€” see other players' replays in real time
  • Daily challenges β€” curated obstacle sequences with unique leaderboards
  • Sound design β€” spatial audio for whooshes, dings, and the satisfying arch pass chime
  • Achievement badges β€” Reddit flair for milestones (100 arches, 1000 score, etc.)

Built With

Share this project:

Updates