Inspiration
Most earthquake simulators let users pick a magnitude with a slider, with no connection to the actual hazard at the user's location. Tremor bases shaking on the room's coordinates, nearby faults, and recorded ground motion from past earthquakes. The project also targets two questions existing tools leave unanswered for home contents: how aftershocks affect objects already displaced by the mainshock, and what fixes give the most safety improvement for a limited budget.
What it does
- Site hazard lookup. The demo apartment is in Livermore, CA. The app displays the ASCE 7-22 design spectral acceleration for the site (0.72 g), the site soil class, and the nearest Quaternary faults. The closest fault is the Greenville fault at 6.7 km.
- Scenario and historical earthquakes. The app includes four USGS scenario earthquakes (Greenville M6.9, Las Positas, Calaveras, Hayward) and four historical events (1980 Livermore, 1989 Loma Prieta, 1984 Morgan Hill, 1906). Each event runs at the ground motion USGS ShakeMap estimates for the site.
- Recorded ground motion playback. Loma Prieta uses the strong-motion record from the Dublin Fire Station. 1980 Livermore uses the Fremont record, scaled to Livermore's estimated peak. The screen shows the station name and scale factor.
- Aftershock sequences. After a mainshock, an aftershock can be triggered starting from the room's post-mainshock state. Aftershock magnitudes come from Båth's law and Gutenberg-Richter statistics.
- Fix ranking by cost. A "Best value fixes" card sorts recommended fixes by safety score improvement per dollar. For example, a $10 container of museum putty can rank above a $35 wall bracket.
- Video export. Each simulation is recorded and can be saved to Photos.
How we built it
- Baked-in USGS data. Data from five USGS services (the ASCE 7-22 design value service, ComCat, ShakeMap grids, the BSSC2014 scenario catalog, and the Quaternary Fault and Fold Database) was queried once, sampled at a point in downtown Livermore, and bundled with the app. The demo makes no network requests.
- Strong-motion processing. Records came from CESMD (the California Geological Survey and USGS strong-motion archive). A Python script converts the USGS SMC and CSMIP V2 formats into the app's internal format. In Swift, each record is scaled to the site's peak ground acceleration, trimmed to the strong-motion window based on cumulative energy, and tapered at both ends to avoid sudden onset.
- Aftershock magnitudes. The largest aftershock is set 1.2 magnitude units below the mainshock (Båth's law), and aftershock n is reduced by an additional log₁₀(n). The app's existing ground-motion model converts these magnitudes to site shaking. The room state persists between events, and results accumulate across the sequence.
- Fix ranking. For each fix, the app recomputes the room's safety score with the covered objects excluded, using the same formula as the main score, then divides the score change by the hardware cost from FEMA E-74.
- Video. RealityKit snapshots are encoded to H.264 with AVFoundation on a background queue and saved through PhotoKit.
- Stack. SwiftUI, RealityKit, AVFoundation, PhotoKit, and 31 new XCTest cases.
Challenges we ran into
- Undocumented API behavior. The CESMD archive required a registered email, station codes with a network prefix (
NP1689rather than1689), and an undocumenteddownload=Pparameter. Without the parameter, requests returned HTTP 204 with no error message. - Fixed-width file parsing. SMC files contain adjacent values with no separator (for example,
1.1465E+0-2.5943E-1), so parsing has to go by column position instead of whitespace. - Scaling limits. The only available Morgan Hill record would have required 5× amplification to match Livermore's estimated shaking. Scaling is capped at 3.5×, and any synthetic motion is labeled as generated.
- Video capture performance. RealityKit's post-processing hook crashes in the iOS Simulator, so capture uses snapshots instead. The first implementation recorded at under 8 fps. Allowing snapshot requests to overlap roughly doubled the frame rate.
- Carrying results across a sequence. Per-object outcomes needed a rule for combining across events. An object sliding in the mainshock and toppling in an aftershock is recorded as toppled.
- UI scope. Five features were added without cluttering the main view. The room view gained one chip; all other controls are in sheets or on the results screen.
Accomplishments that we're proud of
- Every hazard value on screen links to a USGS event ID or a named recording station, and the app displays the associated uncertainty. ShakeMap estimates at a single site can range from about half to nearly double the actual value, and the app states the range.
- The real Loma Prieta record produces 0.11 g in Livermore and moves almost no objects, while the Greenville M6.9 scenario causes widespread damage in the kitchen.
- In one test sequence, five objects left standing after the mainshock toppled in an M5.7 aftershock at 0.21 g.
- The full demo runs offline, and all 736 tests pass.
What we learned
- A strong-motion record already includes the site response of the soil at the recording station. The record should be amplitude-scaled to the target site, not given a separate soil amplification on top.
- Båth's law: the largest aftershock is typically about 1.2 magnitude units smaller than the mainshock.
- Showing real USGS values increases user trust, so stating uncertainty explicitly matters more.
- Public seismic data is extensive but poorly documented. Most development time went into finding the correct queries and formats, not implementing the calculations.
What's next for Tremor
- Live hazard lookup for any address, replacing the bundled Livermore data.
- Using the actual M5.4 aftershock following the 1980 Livermore earthquake two days later, instead of a computed aftershock.
- Audio and on-screen captions in exported videos, and frame rate testing on physical iPhones.
- Additional strong-motion records near other cities, so more historical events can use recorded shaking instead of generated shaking.

Log in or sign up for Devpost to join the conversation.