04Arcade game · 2026 Playable
Snare
Trace loops through the night sky.
You fly a craft that leaves a light trail. Cross your own trail to close a loop, and everything inside it is snared. Anything that touches you costs a shield. That is the whole game, and the real build is running on the right. Press play.
- Role
- Game design, engineering, generative audio, backend, store release
- Platforms
- iOS, Android, web
- Stack
- HTML5 Canvas · Web Audio · Capacitor 7 · Supabase Realtime
- Status
- Free to play in the browser, store release coming
Drag or move the pointer to fly.← → ↑ ↓ also steer.Leaderboards and duels need the app.
- 20Enemy types, introduced one at a time
- 50Levels, then endless Ascension
- 15Worlds across three packs, each with its own generated song
- 0Ads, strangers or dark patterns
DesignOne verb
Drawing is the only verb. There are no weapons, no bombs and no tapping enemies: every catch comes from a loop you drew. Even Overdrive does not kill by touch.
A loop scores the points caught, times the number caught, times your streak. Catching five at once is worth far more than five single loops, so the game rewards big, brave loops over safe scribbles. A loop must enclose more than 420 square units or it is trimmed away, which stops scribble spam.
EngineeringThe whole game in one function
When the newest trail segment crosses an older one, the enclosed shape becomes a polygon. Every enemy inside it loses a hit point, shielded enemies are skipped, and pickups inside are collected. This is the scoring core from the shipping build, lightly reformatted.
for (const e of G.ents) {
if (e.dead || e.spawnIn > 0 || !e.loopable || !inPoly(e.x, e.y, poly)) continue;
if (e.T.pickup) { pickup(e); continue; }
if (e.shielded) { pop(e.x, e.y, 'shielded'); continue; }
e.hp--;
if (e.hp <= 0) { kill(e); n++; pts += e.T.pts; caught.push(e.type); }
}
if (n) {
G.streak = G.time - G.lastCatch <= STREAK_GAP ? G.streak + 1 : 1;
const gain = Math.round(pts * n * streakMul()); // points × caught × streak
G.score += gain;
boom(n); catchNotes(caught, G.streak); // the chord rises with the streak
}
FeelTuned by hand, then by ear
The craft moves relative to your finger, at 1.25 times its travel, so your thumb never covers it. Sprites scale with the screen so everything stays finger-sized, and the enemy cap scales with screen area so small phones are not swamped.
Music is generated per world: key, scale, tempo, chord progression and an eight-note motif, seeded from the world. Layers build as you climb, from pad to bass and arpeggio to drums to lead, and the catch chord rises with your streak, so a long run sounds like it is building.
ProductSafe by construction
Friend Duels and Team Up, on two phones or two players sharing one screen, run on Supabase Realtime. Callsigns are generated, friends join by code only, and there is no chat with strangers and no ads, because the first tester is a child.
One web build is wrapped with Capacitor for iOS and Android, with haptics and a CI pipeline that builds an Android test APK on every push.



What this means for your project
- Game feelInput mapping, difficulty curves and juice tuned until it feels right on a real phone.
- Generative audioWeb Audio music and effects composed in code, with no audio files.
- Realtime multiplayerDuels and co-op over Supabase Realtime, designed for children's safety.
- Cross-platform releaseOne codebase shipped to the web, iOS and Android.