← All projectsKylan Thomson

Simulation · Geospatial · Decision Support

Wildfire Sentinel

A live-data wildfire simulator that fights real terrain, real buildings, and real weather — then races autonomous drone doctrines against identical fires to find out which response would have saved the most.

Role
Sole engineer — simulation core, data layer, response algorithms, and interface
Status
Live · public demo
Period
2025 – present
45,930
Structures mapped
12,100
Simulation cells
5
Response doctrines
0
API keys required

Overview

What it does

Pick any point on Earth and any historical date range, and Wildfire Sentinel assembles a working simulation of that place: elevation from terrain tiles, building footprints and critical facilities from OpenStreetMap, water bodies, and hour-by-hour reanalysis weather for the dates you chose. No API keys, no backend, no bundled fixtures — every input is fetched live from open sources in the browser.

It started as a hackathon prototype that projected fire spread onto a hand-drawn PNG of Pacific Palisades. The rebuild replaced every part of that: real terrain instead of an image, a physically-grounded spread model instead of weighted coin flips, and a comparison harness instead of a single playthrough.

The capability that makes it a decision tool rather than a visualization is the Strategy Lab. It clones a paused incident, races response doctrines against seeded-identical fires, and ranks them by what they actually saved — so the answer to "what should we do right now" is measured rather than argued.

Architecture

Six-stage pipeline

01Define02Assemble03Ignite04Respond05Forecast06Race
  1. 01

    Define

    A scenario is a center point, a radius, and a date range — everything downstream is derived from those three inputs.

  2. 02

    Assemble

    Four public sources are fetched in parallel and rasterized onto a common grid, with fallbacks for every one of them.

  3. 03

    Ignite

    The engine advances fire by accumulating arrival progress toward each neighbour at a physical rate of spread.

  4. 04

    Respond

    Drone stations dispatch under a pluggable doctrine each planning cycle, laying retardant ahead of the front.

  5. 05

    Forecast

    An ensemble projects the fire forward against the real wind timeline to map burn probability and expected loss.

  6. 06

    Race

    The Strategy Lab clones the paused incident and runs doctrines head to head, then ranks them by value saved.

Fire model

Wind decides the shape

A fire that spreads at the same rate in every direction draws a circle, which is the one shape wind-driven fires never make. Computing rate of spread per direction — fast with the wind, slow across it, almost nothing against it — is what makes the burn footprint resemble the real thing.

WINDignitionHeadruns with the windFlankcreeps sidewaysBackingnear zeroRate of spread is computed per neighbour direction, so the same fire produces a cigar-shaped burn rather than a circle.

Approach

How it works

Arrival accumulation, not coin flips

The prototype rolled a weighted die per cell per hour, which meant spread rate was a tuning knob with no physical meaning. The rebuilt engine has every burning cell push progress into its neighbours at a rate of spread in metres per hour, and a neighbour ignites once the front has actually covered the distance to it. Spread speed now denominates in real units, which is the precondition for validating against a real fire at all.

Elliptical wind field

Rate of spread is computed per direction rather than isotropically: the head runs hard downwind at up to ▓▓▓ the base rate, flanks creep, and backing spread is near zero. This is what produces the cigar-shaped burns real wind-driven fires make instead of the expanding circles a naive model draws.

Lagged fuel moisture

Dead fuels dry and re-wet on a time constant of about ▓▓▓, layered over a multi-day rain memory. Fires therefore stay dangerous into the evening after a hot afternoon and stay suppressed for days after a storm — behaviour that a model reading only the current hour's humidity cannot produce.

Ember spotting

Strong winds loft embers downwind on an exponentially distributed distance, and they only take hold where fuels are dry enough to receive them. This is the mechanism by which real fires cross rivers, motorways, and retardant lines — without it, any containment strategy looks far more effective than it is.

Paired-seed experiments

Comparing response strategies against separately randomized fires measures noise. Every clone in a Strategy Lab race is seeded identically, so all doctrines fight the same fire, ember for ember, and the difference in outcome is attributable to the strategy rather than to luck. The comparison harness is the product; the fire model is what makes it credible.

One code path for live and offline

The same planner drives the running simulation and the offline races, so a doctrine that wins an experiment is the exact code that then takes over the live incident. Diverging the two would make every experimental result a claim about a system nobody is running.

Progressive assembly under a latency budget

Terrain and weather land first so the map is interactive in about a second; building footprints stream in behind it across mirrored endpoints and repaint as they arrive. Everything is cached locally, so returning to a region is instant. A tool that takes thirty seconds to become useful does not get used during an incident.

Strategy Lab

Racing doctrines against the same fire

Pause a live incident and the lab clones it once per response doctrine. Because every clone is seeded identically, they all fight the same fire down to the ember, so the gap between outcomes measures the strategy rather than the weather it happened to draw.

PAUSEDLive fire statemid-incidentNo drones (control)Nearest threatValue priorityDownwind interceptsame seed · same fireRANKEDOutcomesvalue saved

Rigor

Measuring it honestly

Validated against the real Palisades fire

The default scenario replays January 2025 with the recorded ignition point and the actual Santa Ana wind timeline. An uncontained run destroys roughly 7,500 structures against about 6,800 in the real event, and reproduces the observed pattern of wind-driven westward runs punctuated by stalls at high humidity.

Order of magnitude from first principles

That agreement comes with no per-fire tuning — no fitted constants for this incident. Being roughly right without being fitted is what licenses the comparative claims: if the model tracks reality unaided, then "doctrine A saves more than doctrine B" carries real information.

Uncertainty, not a point guess

Damage forecasts run a Monte Carlo ensemble whose members diverge through wind variability, producing a burn-probability field and an expected-loss curve rather than one confident trajectory. A single projected outline would imply precision the underlying physics does not have.

Value-weighted rather than area-weighted

Outcomes are scored on what was protected, not on hectares burned. Critical facilities carry weights well above ordinary structures, so a strategy that gives up scrubland to hold a hospital ranks correctly instead of looking like a failure.

Trade-offs

Why it's built this way

Everything in the browser, no keys, no backend

Every data source is a key-less public API, so there is nothing to provision, no secret to leak, and no server to keep alive. The cost is working within CORS and rate limits; the benefit is that the whole thing deploys as static files and still runs years from now.

Live data over bundled fixtures

Shipping a canned dataset would have been faster and would have made the tool a demo of one fire. Fetching live means any location and any date since the reanalysis record begins, which is the difference between a case study and an instrument.

Fail soft on every source

Each input has a fallback — a second elevation provider, mirrored infrastructure endpoints, a land-use estimate when building queries fail, bundled weather of last resort. An incident tool that returns nothing when one upstream is down is worse than one that degrades and says so.

Repaint only what changed

The hillshaded base is drawn once per scenario and the dynamic layer repaints only cells that changed since the last frame, cutting per-frame draw work by roughly 90%. The headroom that buys is spent on ensemble forecasting, which is a better use of the frame budget than redrawing static terrain.

Built with

Stack & data sources

Simulation

  • JavaScript
  • Cellular fire engine
  • Monte Carlo ensembles
  • Seeded RNG

Interface

  • React
  • Canvas 2D
  • Three.js terrain
  • Layered repaint

Delivery

  • Static browser app
  • No backend
  • Vercel

Terrain

  • AWS Terrain Tiles (30 m DEM)
  • Elevation API fallback

Infrastructure

  • OSM building footprints
  • Critical facilities
  • Water polygons

Weather

  • ERA5 hourly reanalysis
  • Wind, gusts, humidity, rain
← All projectsTalk about this work