DEV Community

Manuel Escrig
Manuel Escrig

Posted on Edited on Originally published at manuelescrig.hashnode.dev

Making a UIKit app feel like an arcade game

Geo Adventures app icon

Geo Adventures is a geography game: you're dropped into a real street view somewhere in the world, you look for clues, and you pin your guess on a map. It launched in August 2026. It's built with plain UIKit and Auto Layout in code. The challenge was making it not feel like UIKit at all 🎮

Replace the system chrome

Games don't have navigation bars and standard alerts, so I built my own:

  • GameButton: chunky 3D "arcade pill" buttons with a pressed state.
  • GameHeaderView instead of UINavigationBar.
  • GameAlertController instead of UIAlertController.
  • SpringModalTransition for bouncy modal presentations.
  • A starfield background, confetti, Core Haptics patterns and system sounds for feedback.

A ThemeManager (the same pattern I use in Email Me) switches between four themes: Midnight, Ocean, Sunset and Daylight.

Two map SDKs, each where it fits

  • Google Maps SDK shows the Street View panoramas.
  • MapKit handles the guess map and the result map, so those screens don't need a Google key.

Play first, sign up later

You can play right away as a guest, even offline. Accounts are optional, and they're built behind a small AuthProvider protocol, with Sign in with Apple and Google Sign-In. Either way, the app exchanges the login for a bearer token from the game's own API. Scores sync to the server, and Game Center keeps a leaderboard for each difficulty.

Geo Adventures App Store screenshots: home, a street view round, the result map and multiplayer

Fairness is a backend problem

The Daily Challenge gives everyone the same rounds and a shared leaderboard. That brought edge cases I hadn't planned for:

  • A player quits halfway. Now leaving early ends today's run with the rounds already played.
  • A player closes the app or switches devices in the middle of a run. Now rounds are saved as you play.
  • In multiplayer, one player leaves. Now the match ends for everyone, instead of leaving a frozen lobby.

Localization from day one

Every string ships in 10 languages, including Chinese, Japanese, Korean and Brazilian Portuguese.

Lessons

  • Custom components are cheaper than fighting the system ones until they look like a game.
  • Make accounts optional. Friction before the first round kills a game.
  • Write down what "fair" means before you build a leaderboard.

Get Geo Adventures on the App Store →

Website: geoguesserapp.com

Thanks for reading! And if you play, tell me your Daily Challenge score in the comments 😄

I write about the other side of building apps, the stories and decisions, on my newsletter: manuelescrig.substack.com.

Manuel

Top comments (0)