Live: https://www.capcotier.fr - jump straight into the game at Jouer - CapCôtier, le permis côtier en 3D (free, no signup, works on mobile)
Hi all ![]()
I built CapCôtier, a 3D game to revise for the French permis côtier (coastal boat license). You take the helm in a stylized bay, navigate buoyed channels, and run graded challenges to learn maritime buoyage (IALA Region A), right-of-way rules, vessel lights/day-marks and sound signals.
It’s one Next.js app: the game lives at /game, alongside a set of guide pages.
Stack
- React Three Fiber 9 + three.js 0.184, TypeScript
- GLB models (boat, buoys, vessels, port, beach) with baked textures
- Zustand for UI state; all per-frame data lives in refs + module-scope singletons so the render loop never triggers React re-renders
Bits that were fun to build
- Stylized water - custom
ShaderMaterial: vertex wave displacement + fragment simplex-noise foam/stripes, distance blend, fog integration. A second noise octave is gated behind the “high” quality profile. - Wind-Waker-style wake - a persistent foam ribbon that widens and ages entirely in the shader; only
uTimeupdates per frame. - 100% synthesized audio, zero audio files - the ship’s horn (sawtooth ~180 Hz + lowpass + ADSR) and bell (sine + harmonics, exponential decay) used in the sound-signal challenge are generated with the Web Audio API, as is the ambience (sea, engine that tracks RPM, gulls).
- One consolidated
useFramebobs ~48 buoys and fades passage arrows instead of ~48 per-object callbacks. - Adaptive quality profiles (low/medium/high + auto via an FPS meter) and a mobile virtual joystick.
It’s all in French (it’s for the French license), but the visuals speak for themselves.
Would love feedback - especially on the water shader and perf on your devices. Thanks!

