Inspiration

Big crowds can cause big accidents. In 2022, approximately 100,000 people celebrated Halloween in Itaewon. Due to poor planning and crowd management, there were over 160 deaths.

But these risks aren't limited to parties. They can happen at conferences, hackathons, stadiums and public spaces. Yet, there’s no public software that lets the average person simulate crowds.

That's why we built Crowd Control.

What it does

Crowd Control lets anyone test how a crowd moves through a space before the event happens, with no engineering degree required.

  • Describe a venue and a crowd in plain language ("a hackathon check-in with four desks and a steady stream of arrivals"), and Crowd Control plays it out in your browser: people arrive, queue, wander, react to hazards and head for the exits, while density by zone is measured live.
  • While a run is playing, you can talk to the simulation: type an intervention like "close the north door" or "make a person fall by the stairs", review the proposal, and apply it.
  • The engine updates the crowd on the spot. Every acknowledged intervention is recorded with the run, and the Past runs page compares peak density by zone and mean zone density in the ten simulated seconds before and after it.
  • You can ask "why did it go wrong at 2:14?" and get an answer grounded only in the recorded metrics and events, citing the event IDs it used.
  • Generated safety reports are built from the run's measured facts, and saved runs belong to the signed-in user so no one else sees your history.

It's for school principals, event organizers, conference teams, venue staff, and anyone who's ever said "it'll probably be fine." It is a planning tool, not certified safety advice.

How we built it

We built Crowd Control as a browser-based simulation system with three main layers: a natural-language planner, a deterministic simulation engine, and a real-time renderer.

Gemini translates requests into structured JSON describing agents, goals, schedules and interventions. We validate these against shared TypeScript schemas, then pass them through a compiler that resolves selectors, places agents, builds geometry and produces engine-ready instructions. The same operation contracts support initial setup and live changes.

Venue geometry is rasterized into a walkability grid containing blocked cells, traversal costs, zone IDs and portal IDs. Navigation accounts for each agent’s body radius, so an open cell does not automatically mean a person can fit through it. Uploaded floor plans can be calibrated against a known distance to convert image coordinates into metres.

Agents share destination-based flow fields. We compute these backward from destination cells using breadth-first search for uniform traversal costs and Dijkstra’s algorithm for weighted terrain. Agents follow decreasing route costs, with continuous lookahead points that reduce movement toward shared grid-cell centres.

Local steering supplements those routes. Each moving agent checks for slower traffic and evaluates nearby bypasses using remaining route cost, detour distance and crowd occupancy. Summed-area grids make rectangular crowd queries constant-time. Candidate paths must preserve progress toward the destination and pass clearance checks; explicit queue and service waits retain their admission rules.

The engine uses a spatial hash to find nearby agents, acceleration and speed limits to control movement, and swept-disc collision checks to detect collisions along a movement segment. Movement is subdivided into smaller steps when necessary to prevent fast agents from passing through walls or other people.

Goals run through explicit execution states for travel, waiting, wandering, queueing and interaction. A scheduler handles timed operations and event rules. Fixed timesteps and agent-specific seeded random streams make runs reproducible. Rewind restores checkpoints and replays recorded interventions to the selected simulation tick.

Rust compiles to WebAssembly and runs inside a Web Worker. PixiJS renders published agent frames, while React handles controls, editing and analytics. Gemini operates at the scenario and intervention level; movement updates stay inside the engine.

We measure zone occupancy, density, departures and portal flow, then associate acknowledged interventions with simulation timestamps. Tiger Data stores those records for history and comparisons. Gemini receives recorded evidence for explanations and reports, with Auth0 identities scoping access to each user’s saved runs.

How We Used Gemini, Tiger Data, Auth0, and Vultr

Gemini powers the AI features in Crowd Control. It turns plain-language prompts into structured scenario plans and proposed changes, answers “why did that happen?” questions using simulation analytics, and generates safety-planning reports from saved run data.

Tiger Data stores simulation runs, metric samples, and acknowledged interventions so people can review their work later. It also supports the history page’s analytics, including peak density by zone and comparisons around interventions. Run records are scoped to the signed-in user.

Auth0 handles sign-in and protects user data. The frontend obtains an access token, and the API verifies it before allowing access to protected features. The verified user identity is used to scope saved simulations, so users see their own run history rather than another person’s data.

Vultr hosts Crowd Control’s frontend and Node API through Docker containers. The API connects the application to Gemini, Tiger Data and Auth0, while the Rust simulation runs directly in each user’s browser through WebAssembly.

What's Next?

Our next priority is improving crowd behavior and performance across more demanding scenarios. We want agents to navigate congestion more naturally and keep larger simulations responsive.

We also want to improve floor-plan import, support multi-floor venues and accessibility constraints, and let users compare alternative layouts and interventions side by side. Most importantly, we want to validate the simulation against observed crowd movement, so its assumptions and limitations are supported by evidence.

+ 4 more
Share this project:

Updates

Submission history