Inspiration

Every esports event has dead time — pauses between maps, technical delays, pre-match hype periods. I watched fans at LCS events scrolling Instagram instead of engaging with the tournament. What if we could turn that downtime into competition?

GeoGuessr proved that "guess the location" is addictive. I asked: what's the esports equivalent? For League of Legends, the answer was obvious — the minimap. Pro players read minimaps instantly to understand game state. Could casual fans do the same?

GameTimeGuessr was born: show a minimap snapshot, challenge fans to guess the game time.

What it does

Players see a League of Legends minimap with:

  • Champion positions (blue/red circles with champion initials)
  • Tower and inhibitor status (destroyed = X mark)
  • Who's alive or dead (faded = dead)

They guess the timestamp using a slider. Scoring follows GeoGuessr's exponential decay:

$$\text{score} = 5000 \times e^{-\frac{\Delta t}{T_{max} \times 0.08}}$$

Where $\Delta t$ is the time difference in seconds. Perfect guess = 5,000 points. Way off = almost zero.

Event-ready features:

  • QR codes on tickets deep-link to pre-filled registration
  • Each ticket plays each map only once (no score farming)
  • Per-map leaderboards display live on arena screens
  • Works on any phone — no app install needed

How I built it

Backend: Python + FastAPI

  • SQLite for player sessions, scores, ticket validation
  • Real-time GRID API integration for official match data
  • Admin API for tournament operators to push new maps

Frontend: Vanilla JS + HTML5 Canvas

  • Minimap rendered dynamically from JSON game state
  • Responsive design (phone → tablet → arena display)
  • Animated score feedback with quality ratings

Data Pipeline:

  • grid_parsing_worker.py — fetches match data from GRID API
  • riot_normalizer.py — optimize the data and transform to game-ready JSON

Key technical decisions:

  • Canvas over SVG for smooth minimap rendering at any size
  • Exponential scoring (not linear) to reward precision
  • Ticket-gated plays to ensure fair competition

Challenges I faced

1. Coordinate systems Riot's API uses (x, z) coordinates where z is the vertical axis. I spent hours debugging why champions appeared in wrong positions before realizing the coordinate swap.

2. Turret positions The minimap doesn't come with building coordinates. I had to manually map all 22 turrets + 6 inhibitors + 2 nexuses by cross-referencing game screenshots. Several were wrong initially — outer turrets on bot lane were missing until I caught the bug.

3. Mobile viewport Fitting minimap + slider + timer + status panel on a phone without scrolling was brutal. I iterated through 3 layout versions before hiding the header entirely on mobile and letting the minimap breathe.

4. Fair play enforcement Preventing replay attacks while keeping UX smooth. Solution: server-side timestamp selection, one-time-use session tokens, ticket+map uniqueness constraint in database.

What I learned

  • Canvas rendering is powerful but unforgiving — every pixel matters
  • Exponential scoring creates better player psychology than linear
  • QR deep links dramatically reduce friction for event activations
  • Mobile-first isn't optional for fan engagement tools

What's next

  • VALORANT support (different minimap, same concept)
  • Real-time integration during live broadcasts
  • Prize pool automation for top leaderboard finishers
  • Analytics dashboard for event organizers

Built With

Share this project:

Updates