All projects
SwiftUI · Combine

Bubble Game

2025Mobile · iOS · SwiftUI · Game · Combine

BubblePop is a SwiftUI arcade game built solo for a UTS iOS course. You enter a name, tune the max-bubble count and countdown, then pop bubbles before time runs out — rarer colours are worth more points, and popping the same colour in a row earns a 1.5× combo. Bubbles fade out on a random lifespan and refill each second, and high scores persist across launches.

Under the hood it's a clean MVVM app. Navigation is type-safe: an AppRoute enum carries its parameters as associated values over SwiftUI's NavigationPath, so page arguments are checked at compile time rather than passed as loose strings. Bubbles are placed with a rejection-sampling algorithm that guarantees they never overlap — each candidate position is distance-checked against every existing bubble, with a capped retry so a crowded board simply spawns fewer bubbles instead of hanging the main thread. A 0.1s timer drives the fade lifecycle and per-second refills, and the leaderboard is persisted through UserDefaults and Codable.

The project is a signal of independently structuring a full SwiftUI app end-to-end — a counterpart to the team SwiftUI work where the contribution was the data-integration layer rather than the whole architecture.

Key features & challenges

  • Rejection-sampling placement guarantees bubbles never overlap, with a capped retry so a crowded board spawns fewer bubbles instead of hanging the main thread
  • Type-safe navigation using an AppRoute enum with associated values over SwiftUI's NavigationPath
  • Weighted-random spawning where rarer colours are worth more points
  • Same-colour combo scoring and a fade-out lifecycle driven by a 0.1s timer
  • Persistent high-score board via UserDefaults and Codable

My contributions

  • Solo build — the entire app: architecture, gameplay, scoring, persistence, and UI
  • Designed the MVVM structure (Models / ViewModels / Views) and the routing layer
  • Implemented the non-overlap spawning algorithm and the weighted colour distribution