Case study / Simulation
Offshore Racing
A physics-first browser sailing game where the server owns the world, real forecast data drives the water, and the frontend simply renders the truth.

The problem
Make ocean racing strategic, not decorative.
Most browser sailing games simplify the environment until weather becomes a painted layer. Offshore Racing treats the atmosphere, ocean, boat polar, geography, and event rules as one simulation. The result must remain believable to a sailor while still running efficiently for a fleet.
My role
Domain model, product direction, and system architecture.
The project draws directly on offshore tactics, routing, race management, and visual design. I defined the physics and state boundaries, built the product architecture with AI-assisted development, and continuously check technical decisions against how a boat actually behaves on the water.
Architecture
One authoritative engine.
- A headless Python engine computes every boat in array operations; iterative per-boat physics loops are rejected.
- PostgreSQL is the source of truth. Redis carries read-only snapshots and live updates, never game logic.
- The FastAPI gateway and engine run as separate services and communicate only through explicit data boundaries.
- NOAA wind, HYCOM currents, and a shared geography mask drive the physical environment.
- CesiumJS renders the globe, weather, tracks, races, and commands without owning persistent state.
Notable decisions
Complexity stays behind clear contracts.
Binary snapshots keep live state bounded. Area-of-interest filtering prevents every browser from receiving the whole ocean. Race and time-trial modes share the same event model, while history retention expands during an active event so multi-day tracks remain intact.
Current state
A working foundation under active development.
The simulation, API, globe frontend, weather and current ingestion, race modes, authentication lineage, and persistent trails exist. The next work is operational: strengthening deployment, restoring the full service stack when dependencies fail, and refining the player experience against real racing expectations.