Inspiration

We wanted to play laser tags but didn't want to spend 50 bucks on 20 minutes of gameplay. So... we decided to make it playable anywhere, anytime, for free.

What it does

LTN turns a group of iPhones into a full laser-tag arena. You aim by pointing the back of your phone at another player, like sighting through a camera. Ultra-Wideband ranging and the camera feed together decide whether you actually have someone in your crosshairs — and tag them if you fire.

  • Point-and-shoot combat over a live camera viewfinder, with a reticle that locks when a real player is inside your aim cone.
  • Local multiplayer with no server — phones discover each other and run the whole match peer-to-peer.
  • Lobbies & loadouts — host or join a game, pick a role (Light / Regular / Heavy), choose free-for-all or two-team play, and tune match length and player count.
  • Hearts-based health — every hit takes one heart, with a floating health bar over each opponent.
  • Power-ups that drop into the world: Medpack, Overdrive (fire faster), Cloak (vanish from the minimap), and Reflector armor.
  • Situational awareness — a forward minimap/radar, a live kill feed, and a full-screen ELIMINATED BY: death takeover.
  • Spectator mode + kill clips — a Mac can run or watch the game, and highlight clips get published to a web gallery.

Lobby

How we built it

  • SwiftUI + ARKit for the app and the camera-as-viewfinder HUD.
  • NearbyInteraction (UWB) for phone-to-phone distance and direction, fused with the ARKit camera pose so aim and picture agree frame-to-frame.
  • Apple's Network framework + Bonjour for serverless discovery and direct phone-to-phone connections, carrying the game's message protocol — hits, health, deaths, lobby state, power-up spawns.
  • The key trick: there is no shared world coordinate frame between phones — each only knows its peers through its own pairwise UWB readings. So drops and tags travel over the wire as affine combinations of player positions (weights that sum to 1), which survive each phone resolving them into its own AR frame.
  • AVFoundation to encode kill clips, plus a small Node / Vercel web app to host and react to them.
  • A tight design system (color, spacing, and typography tokens) with hand-drawn brand icons and a custom hand-drawn font for personality.

Challenges we ran into

  • No common frame of reference. Without a shared map, "there's a drop 3 meters that way" means something different on every phone. The affine-combination trick was the breakthrough.
  • Aiming that feels fair. Turning noisy ~5 Hz UWB bearings into a crosshair that locks reliably — but not on someone standing behind a wall — took a lot of tuning.
  • Everything is real-time and peer-to-peer, so state can arrive late or out of order; the death and summary screens had to stay stable while stray messages trickled in.
  • Legibility over a live camera feed — HUD chrome, hearts, and power-up badges all have to read while you're moving.

Accomplishments that we're proud of

  • A laser-tag match that runs on real hardware with no server — no accounts, no arena, phones talk to each other directly.
  • Camera-assisted UWB aiming that feels like sighting a real blaster.
  • A complete game loop: lobby → roles → combat → power-ups → death/respawn → match summary → shareable kill clips.
  • A cohesive, hand-drawn visual identity instead of stock UI.

What we learned

  • How to fuse UWB ranging with ARKit, and why the two frames disagree without help.
  • Designing a frame-independent networking protocol for spatial data across devices that don't share a map.
  • The realities of peer-to-peer state sync — idempotency, staleness, optimistic rendering, and graceful degradation when a reading or a peer drops.
  • How much HUD restraint and color/shape redundancy matter when the background is a moving camera feed.

What's next for laser tag

  • New game modes on top of the free-for-all and team based play we already support.
  • Bigger lobbies and more robust reconnection for flaky radio environments.
  • More power-ups and roles, and map-aware drops.
  • Broader device support and cross-platform UWB interop.

Built With

Share this project:

Updates

Submission history