Inspiration

Finding a pickup game at UCI is mostly luck. You walk to the ARC hoping there's a game, find a court someone booked an hour ago, or show up with a full squad to find the field empty. Group chats fill up with "anyone down to play?" and die out, and there's no way to know whether the people who said yes will actually show up.

We wanted one place where Anteaters can see what's being played right now, jump in, or start a game and trust that people will come.

What it does

ZotPlay is a pickup-games app for UC Irvine students.

  • Live campus map: Real maps of the ARC (indoor and outdoor) and six housing communities: Mesa Court, Middle Earth, Arroyo Vista, Campus Village and Verano Place. Every court and field is color-coded live as free, hosted in ZotPlay, or occupied by people not on the app. Click a spot to zoom in and see its courts, what's playing now and today's schedule.
  • Host or join in seconds: Pick a court, sport, time and skill level, and the game is posted. The app blocks double-booked courts and players already in an overlapping game, and it handles full basketball courts made of two half courts.
  • Crowd-confidence ring: When you host at an ARC spot, a ring next to the court's name shows how sure our crowd model is about how busy that spot will be at the time you picked. It updates as you change the time and shows red, yellow or green.
  • Reliability score: Everyone starts at 100. Show up and you gain points; no-show and you lose them. Hosts can require a minimum score, so games fill with people who actually come.
  • Earned skill levels: After a game, players rate the teammates they played with. Your level blends what you said about yourself with what your teammates saw.
  • Live updates: Joins, cancellations and new games in sports you follow appear instantly, without refreshing.
  • UCI-only: Sign in with your @uci.edu Google account.

How we built it

Frontend

React and Vite. The maps are real UCI maps, with hotspots placed as percentages so they line up at any screen size. For the housing maps, a small script finds the yellow court shapes in each image and fits a rotated rectangle around each one, so even tilted courts line up.

Backend

FastAPI with SQLAlchemy on SQLite.

  • Court bookings use exclusive (BEGIN IMMEDIATE) transactions, so two people can't grab the last spot or the same court at once.
  • A background scheduler auto-cancels games that don't fill, completes finished ones and sends reminders.
  • Live updates stream to the browser over Server-Sent Events, and only after the database commit succeeds, so the UI never shows a change that was rolled back.

Crowd model

A Bayesian Poisson regression written in pure Python, with no ML libraries. The headcount $$y$$ at a location and hour is modeled as

$$ y \sim \text{Poisson}(\lambda), \qquad \lambda = \exp\left(\beta_0 + \sum_i \beta_i x_i\right) $$

where the features $$x_i$$ come from the UCI academic calendar (quarters, midterms, finals, breaks, holidays), the weekday, the hour and events like intramurals.

  • Every weight has its own uncertainty, $$\beta_i \sim \mathcal{N}(\mu_i, \sigma_i^2)$$, and that uncertainty becomes the confidence shown in the ring.
  • Because the model is multiplicative, each effect is easy to read: a feature scales normal traffic by $$e^{\beta_i}$$.
  • When users report headcounts, the model updates with Kalman-style steps scored by cross-entropy, so surprising reports make it adapt faster.
  • We trained it on 61,000+ simulated hourly headcounts built on the real 2025–26 UCI calendar.

Auth and email

Google Identity Services restricted to the UCI Workspace domain, with JWT sessions and rate-limited endpoints, plus an email-code fallback through Resend, Mailgun or SMTP.

Testing

64 backend tests covering booking conflicts, reliability penalties, peer ratings and the crowd model.

Challenges we ran into

  • One less hacker
  • had problems with sso deployment but fixed using google cloud
  • Race conditions: "Join the last spot" and "book this court" both had to be safe when two people tapped at once. We solved it with exclusive SQLite transactions instead of adding infrastructure.
  • Overlapping courts: A full basketball court has to block both of its half courts and the other way around, while fields allow several games at once. We modeled this with explicit overlap lists between courts.
  • Placing courts on real maps: The housing maps are flat images with labels drawn over the courts, and some courts are tilted. Hand-placed boxes kept missing, so we wrote a pixel-detection script that fits rotated rectangles.
  • Honest confidence: We didn't want the ring to look precise when it wasn't. Rare periods like Thanksgiving week get visibly lower confidence than normal class weeks, and spots the model doesn't know yet show a grey "—" instead of a made-up number.
  • Schema changes mid-hackathon: Adding courts, sports and locations without wiping everyone's database meant making startup seeding safe to run every time, including updating the allowed sports on courts that already exist.

Accomplishments that we're proud of

  • A working app with real UCI maps covering the ARC and six housing communities.
  • A crowd model built from scratch that recovers effects hidden in the simulated data. For example, it learned that finals week runs at
  • deployment on both mobile and web app

$$ e^{\hat{\beta}_{\text{finals}}} \approx 0.46 \quad \text{vs. a true value of } 0.45 $$

of normal traffic, and its predictions are within about 7% of the simulator's noise-free crowd.

  • A reliability system that holds people accountable, plus teammate skill ratings.
  • Booking that stays correct when people act at the same time, backed by tests.

What we learned

  • Small rule details, like when attendance is marked, who can rate whom and what happens when a host cancels, took more design time than the code.
  • Bayesian models let you show uncertainty to users directly, and users understand uncertainty when it's shown well.
  • Server-Sent Events are a simple way to make an app feel live without WebSockets.
  • Splitting work cleanly between frontend, backend and modeling, and agreeing on IDs early, saved us when merging under time pressure.

What's next for ZotPlay

  • Real data for the crowd model: Train it on real ARC headcounts and extend it to the housing courts so every spot gets a confidence ring.
  • A mobile app with push notifications when a game in your sport is about to start nearby.
  • Fairness tools: A way to dispute no-show marks, a penalty for leaving a game at the last minute, and fake-occupancy reports that resolve themselves when trusted users agree.
  • Better matching: Player tags (shooter, setter, goalie) so hosts can find the players they need.
  • More of campus: More courts and fields, and Postgres plus Redis to scale past one server.

Built With

Share this project:

Updates

Submission history