Luke Miskelly

Taking projects for early 2027

Start a project

WorkSnare

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
Snare · web build Standby T+00:00.0 9 : 18

Drag or move the pointer to fly.← → ↑ ↓ also steer.Leaderboards and duels need the app.

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.

www/index.html · resolveLoop()excerpt
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