Inspiration

We wanted to know how simulating people moving

What it does

Evacuation Simulator is a web app for sketching buildings and estimating how long people take to get out.

  • Draw polygonal rooms, corridors, and stairs; place doors, exits, obstacles, and occupant groups
  • Work across multiple floors with linked stairs (ascent slower than descent)
  • Overlay PNG floor plans and trace over them.
  • Place hazards, a flood or fire, and watch how they change routes and outcomes.
  • Hit Run and watch agents evacuate in real time (streaming animation as the sim computes)
  • Inspect times, waits, congestion hotspots, and per-occupant routes

Built-in scenarios include offices, dual towers, a stadium, the RMS Titanic, and The Backrooms.

How we built it

Frontend: React + TypeScript + Vite, with a Konva canvas editor for polygons, placement tools, multi-floor tabs, floor-plan overlays, and playback (pause, speed, reset).

Backend: FastAPI + Pydantic + SQLAlchemy/SQLite. Buildings and simulation snapshots live in the DB. Runs stream frames as NDJSON so the UI can animate before the full timeline finishes.

Simulation engine (pure Python):

  • Builds a visibility-graph navigation network (openings + reflex-corner waypoints)
  • Routes with Dijkstra, with queue-aware exit assignment at spawn
  • Steps agents in discrete time (~0.25 s) with body radius, wall containment, and aperture-limited doors/exits
  • Models capacity at openings and stairs, plus fire / flood / smoke with different spread rules

Challenges we ran into

  • Wall tunneling: discrete timesteps made agents slip through thin walls until we tracked current-space membership and clamped motion through door apertures only.
  • Valid paths in polygons: Euclidean chords often leave the room; we needed a visibility graph with reflex corners and obstacle clearance so routes stay inside spaces.
  • Congestion that feels real: abstract flow rates weren’t enough — body radius vs opening width, slot assignment, and jams outside throats took iteration.
  • Hazards + playback: expanding fire/flood/smoke had to stay in sync with pause, scrub, and speed changes via per-frame plume state.
  • Flood physics lite: room-scoped fill with gravity down stairs (then upward) was much harder than a simple radial blob, but far more believable.
  • Large runs staying responsive: streaming NDJSON frames so the browser starts animating while the engine is still computing.

Accomplishments that we're proud of

  • A full loop: draw → save → simulate → stream → animate → stats
  • Polygonal multi-floor geometry with visibility-graph routing (not a crude grid-only model)
  • Bottlenecks driven by body size and opening width, so door width actually matters
  • Three hazard systems with distinct behaviors (radial fire, doorway flood with gravity, room-scoped smoke)
  • Showcase maps that make demos memorable (Titanic, stadium, dual offices, Backrooms)
  • Progressive streaming so long sims feel interactive
  • Clear assumption docs so the tool stays useful and honest

What we learned

  • Crowd egress is as much about geometry and capacity as about shortest path
  • Small discrete-time bugs (containment, apertures) dominate perceived realism
  • Streaming results early matters more for UX than perfect offline batch compute
  • A sharp editor UX (snap, undo, multi-floor, overlays) is half the product; the sim alone isn’t enough

What's next for Evacuation Simulator

• Mid-run dynamic replanning when hazards cut routes (instead of mostly fixed spawn routes) • Richer behaviour models (panic, following, mobility differences — we already reserve a behaviour field) • Better hazard physics and optional validation against real drills / published benchmarks • Accessibility-focused scenarios and reporting • Stronger import from real CAD/BIM floor plans • Collaborative editing and side-by-side scenario comparison (“wider doors vs second stair”)

Built With

Share this project:

Updates

Submission history