Inspiration Urban spaces are full of hidden potential — wide sidewalks, open parks, long straight streets. We wanted to take the timeless challenge of golf and bring it out of the country club and into the city. What if Chicago's streets were fairways? What if Millennium Park was the 9th hole? SideSwing was born from that idea: a game where the course is wherever you are.

What it does SideSwing is a location-based mobile golf game that turns real city streets into a full 18-hole course. Players physically swing their iPhone to hit a virtual ball, then walk the real-world distance their shot traveled to reach their next lie.

Motion-based swinging — CoreMotion detects your actual golf swing, classifying it as a perfect drive, fade, slice, hook, or whiff Real GPS walking — you earn your yards; if you drive 200m, you walk 200m to your ball Outdoor + Couch modes — play outside with full GPS or simulate from your couch First-person street view — MapKit Look Around shows you exactly where your ball landed on real Chicago streets AR putting — use ARKit to detect a real flat surface and putt on your actual floor Multiplayer — real-time WebSocket lobbies with room codes, turn-based play, and live position sharing 16 pre-built Chicago courses — Millennium Park, Grant Park, Lincoln Park, and more How we built it SwiftUI + @Observable for reactive state across a complex multi-phase game loop CoreMotion with a custom "tilted clock" swing detection algorithm using SIMD quaternion math MapKit for walking route snapping, POI-based building obstruction detection, and Look Around street imagery ARKit + SceneKit for the putting mini-game with real-world plane detection and 3D physics CoreLocation for cumulative GPS walking distance with jitter filtering WebSocket multiplayer backend with a message-based protocol for lobby management and shot sync LookAroundCache — a custom prefetch layer that loads street imagery during ball flight to eliminate loading lag Challenges we ran into Dual coordinate system: Snapping the ball to a walkable sidewalk was visually essential, but naively snapping would rob players of earned distance. We maintained separate visual (snapped) and physics (true) positions so the ball looks right without cheating the player. Swing detection on a phone: Phones aren't clubs. We modeled swings as rotations around a dominant axis, scored energy on-plane vs. off-plane, and added a backswing reversal bonus to reward proper form — all while ignoring pocket bumps and casual gestures. GPS jitter on city streets: Urban canyons cause GPS noise that would make "walking" feel random. We implemented cumulative distance filtering with 2m minimum and 50m maximum per-update thresholds, forgiving players at 80% of shot distance reached. Building obstruction without 3D data: We approximated building footprints by querying MapKit POIs along the shot corridor, projecting them onto the shot bearing, and stopping the ball before the nearest obstacle. Accomplishments that we're proud of A swing detector that gives real golf feedback — coaching tips like "keep the swing on one plane" based on actual motion data Look Around prefetching that makes the game feel seamless — imagery loads during the 1.2-second ball flight so there's zero wait when you land A complete, playable 18-hole golf game set in real Chicago geography A multiplayer system built and tested in a weekend What we learned Building a game on top of a real city is humbling. The real world doesn't cooperate — GPS drifts, buildings have no edges in MapKit, and swinging an iPhone in a crowded venue produces wild quaternion data. We learned to design systems that gracefully degrade: every feature has a fallback (AR → Look Around → stylized horizon, motion swing → tap UI, outdoor → couch mode).

What's next for SideSwing More cities and community-created courses Leaderboards and persistent scoring via CloudKit Club upgrades and progression system Apple Watch companion for more natural swing detection Sharing shot replays with street-level video compositing

Built With

  • claude
Share this project:

Updates