Skip to content

Concepts & architecture

Three layers, strictly separated

  1. Math layer — engine-light and unit-testable. USceloHazardModels (pure parametric hazard functions) and FSceloFinancialEngine (pure loss/financial transforms). These never touch actors, rendering or networking; they port anywhere.
  2. Simulation layer — the UObject world, threaded. USceloPortfolioAsset (exposure + vulnerability data, CSV ingestion, geo-projection), USceloSimulationSubsystem (Monte Carlo orchestration on a background thread, results marshalled to the game thread via delegates), USceloBridgeSubsystem (optional HTTPS hand-off to the Scelo platform).
  3. Spectacle layer — actors, Niagara, UMG. ASceloCycloneActor / ASceloFloodActor live events, USceloVfxDirector (maps physics intensity onto Niagara user parameters), ASceloExposureVisualizer (instanced-mesh portfolio rendering), USceloMetricsWidget (UMG base class auto-wired to the simulation delegates).

Data flow

CSV portfolio CSV vuln curves JSON catalog DATA PortfolioAsset exposure · curves · projection SIM SimulationSubsystem background thread · 100k+ years RESULT PortfolioMetrics AAL · EP · TVaR live tick LIVE Cyclone / Flood actor same math, per tick VfxDirector Niagara MetricsWidget · HUD BridgeSubsystem → Scelo
One portfolio asset feeds both the batch engine and the live actors, which is what lets the picture and the numbers agree exactly.

The live/batch invariant

Live cinematic events reuse the same math as the batch engine: dollars accrue as a running max of hazard intensity over exactly the analytic swath's discrete samples, so end-of-event live totals equal the analytic event totals bitwise — logged as a floating-point-exact assert. Scelo.CityTestEvent demonstrates it: a static test cyclone whose shown loss is asserted equal to the analytic loss. Scelo.Audit runs every registered actuarial invariant on demand, and Scelo.AuditBadge on keeps an on-screen badge running fast checks continuously.

Threading model

  • RunMonteCarlo copies the catalog, takes a TStrongObjectPtr on the portfolio, and runs entirely on a worker thread (Async(EAsyncExecution::Thread, …)).
  • No UObject is mutated off-thread. Progress and completion are marshalled back with AsyncTask(ENamedThreads::GameThread, …) through a TWeakObjectPtr guard.
  • Live actors tick on the game thread only; their per-tick portfolio sweep is O(locations) of pure math. The 60-location demo is trivially cheap; very large books (50k+ locations) move to a job batch on the roadmap.

Coordinate convention

Equirectangular projection around (OriginLatitude, OriginLongitude):

  • +X = East, +Y = South (UE left-handed), Z = elevation
  • UnitsPerMetre (default 100, i.e. 1uu = 1cm) over WorldScaleDivisor (default 50) compresses real geography so a 400 km hurricane track fits a playable level (~890,000 uu ≈ 8.9 km of level space).

Determinism

Stochastic draws run through SceloDeterministicRandom with explicit seeds — the same seed reproduces the same year-loss table, and several commands (Scelo.Quake, Scelo.Tornado, Scelo.QuakeFracture) accept a seed argument. The weather system exposes Scelo.WeatherHash, a deterministic per-tick trace hash, and Scelo.WeatherOff restores the authored sky bit-identical.

What is analytic vs illustrative

The hazard physics and the financial engine are the analytic core. Two subsystems are deliberately stylized and labeled ILLUSTRATIVE everywhere they appear on screen:

  • Recovery model — functionality-recovery timelines following the resilience literature (Bruneau et al. 2003; Kates et al. 2006; HAZUS recovery times by damage state). Each building's damage splits into a funded share (its insured recovery over its ground-up loss — deductibles, limits and penetration flow straight through) repairing exponentially after a claims-settlement delay, and an unfunded remainder on a much slower time constant, or abandoned for destroyed and underfunded buildings. The same per-building structs drive the rebuilt-percentage metric and the on-screen tint, so picture and numbers cannot disagree.
  • Climate Studio scenarios — pathway presets, the coastal flood proxy and the adaptation levers are decision-communication tools, not calibrated climate models.

Known limitations (v0.2.0)

  • LoadCatalogFromJSON does not parse tornado fields (TornadoPeakWindMs / TornadoTrackKm); JSON-loaded tornado events keep struct defaults. Tornado events are fully parameterized via code, console args, or Blueprint.
  • Tornado damage reuses the TropicalCyclone vulnerability curves (wind proxy).
  • Scelo.Tsunami is a visual + physics demo, not priced through the book (the Lab's tsunami is priced).

Extending

  • New peril — add an enum value, a hazard function, catalog fields, and a case in ComputeEventGrossLoss. Vulnerability curves come free via CSV.
  • Real GMPE / surge model — swap the body of the relevant USceloHazardModels function; signatures are stable.
  • Reinsurance structures — layer on top of FSceloFinancialEngine::ApplyTerms (a per-event cat XL program with Scelo.Reinsurance, parametric community cover with Scelo.Parametric, and capital allocation with Scelo.Capital are already included).