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
- fastapi
- konva
- pydantic
- react
- sqlalchemy
- sqlite
- typescript
- vite
Log in or sign up for Devpost to join the conversation.