Stage 18 — Island 2 as a real playable zone Goal: the low, hazy islands on the far left of the starting view stop being cheap backdrop geometry and become a real second island you can reach by motorboat, moor at, and walk around on. It should read as the edge of a large swampy mainland: a low mangrove shoreline, a river mouth facing island 1, and a swamp river leading inland into jungle. This stage is only the foundation. River water, jungle and the wooden boat come in later stages. 1. Location and terrain - Find how the distant islands are built now and replace them with island 2 in the same spot, about 380 m from the boat pier, so crossing at full throttle takes 1–2 minutes. Keep one of the old far islands as scenery. - Give island 2 its own heightfield module (separate from island 1's grid and with its own seeded RNG, so island 1's placement never shifts). Build the coastline mask, run an exact distance transform, then add noise: a muddy shore 0.2–0.6 m high, a gentle rise inland to about 4 m, and hills/karst in the west up to about 25 m where the river "comes from". - Carve the river system into the terrain now: Catmull-Rom splines for a main channel, a branch, a backwater and two creeks, each with width and depth tables along its length (about 20 m between sand spits at the mouth, a wider estuary, about 7 m in the hills). Add floodplains with small ponds, and a shallow muddy delta in front of the mouth. River water level is flat (sea level), so one reflection plane stays correct. - Bake the data grids later stages will need: height, real distance to water, calm-water gradient, sand, channel proximity (for planting) and coast. Add CPU and GLSL accessors so getHeight, getShoreDist, the water shader, the underwater composite, the ripple sim and rain all understand island 2. 2. Level-of-detail zones - Two zones, island 1 and island 2. Only the zone the player is in gets the full detail set: layered ground, grass, undergrowth, LOD trees, shadows, planar reflection. The other zone gets a cheap far mesh plus tree impostors, faded by aerial perspective. - Switch smoothly with hysteresis. Build detailed 80 m terrain chunks nearest-first in time-budgeted slices (no frame over about 30 ms) while the player is still at sea, dither them in over the far mesh, and dispose of everything when you leave. When looking from island 2 back at island 1, hide small objects by screen size. - Shadow cascades, water sim windows, caustics and reflections must follow the player to island 2. Check float32 precision at x ≈ −900 for shimmering or jitter. 3. Sea between the islands - Rework the soft world boundary so a corridor to island 2 is open while the rest of the sea still pushes you back. Shape the seabed as deep water rising to a muddy shallow at the mouth. - Near island 2, fade out waves, swell, surf and foam, and shift the water colour from turquoise to murky green-brown with no visible seam. From island 1, island 2 should read as a hazy silhouette with calm reflections, by day and at night. 4. Landing - Build an old, half-rotten wooden dock at the river mouth, with missing and broken planks, pilings and a step down to the shore. Motorboat mooring works with E like on island 1, and an empty berth is reserved for the wooden boat. - Walking, colliders, swimming in the mouth and temporary vegetation (existing palms, ficus and ferns) all work, so the island isn't bare. Rules: High-quality visuals on island 1 must not get worse. Record draw calls, triangles and frame time before and after at the start, at sea, at the mouth and on the river. Done when: island 2 sits where the far islands were, you can sail there with no popping, moor, step ashore, and sail back. Stage 19 — The swamp river and its water (the flagship stage of this round) Goal: water that matches the reference shots (dusk with a heron at a bend, a moonlit night, golden morning fog). Dark, tannin-stained, mirror-still water with wavy reflections and low fog lying on it is the whole point of this round. More frame budget is allowed here, but spend it on smart techniques, not brute force. Never simplify the water on High. 1. A dedicated river water shader (its own material and module; leave the ocean shader alone) - Mirror: a high-resolution planar reflection on the flat river level, where trees, trunks, sky, the boat and its lamp must all reflect, plus an analytic sky with a softened sun disc. - Wavy reflections: fine ripples (a normal map advected along the flow with a two-phase flow map) break up the mirror. They are stronger in fast water and under wind gusts and almost zero in quiet backwaters. - Colour: an almost black green-brown water body ruled by Fresnel. Looking straight down you see dark depth and mud in the shallows; at grazing angles it becomes a pure mirror. Visibility is under 1 m, and the underwater view is dark olive murk. - Sun and moon glitter paths, blurred by the ripples and shadowed by the sun shadow map, plus lamp glints at night. - The ocean fades smoothly into the river at the mouth, with no seam. - The existing ripple sim works on the river too (player, boat, thrown stones, rain), with low damping so wakes travel far. 2. Flow - Bake a flow field along the river splines (fastest in the middle, still in backwaters) as a CPU function and a GPU texture. Ripples, duckweed and drifting leaves follow it, and the future wooden boat and fishing bobber will use the same field. 3. Fog over the water (the most important thing after the mirror) - Height fog for the island-2 zone, with presets per time of day and weather: turquoise-green at dusk, cold at night, golden and backlit in the morning. It thickens far up the river so the river disappears into it. - Low volumetric mist banks on the water, raymarched at half resolution, drifting with the wind, lit through the sun shadow map so light shafts appear between trunks in the morning. High only. 4. Surface life and banks - About 900 lily pads with flowers in shallow quiet patches. They bob on the ripple sim, get pushed aside by the hull and swimmers, and drift back after about 5 s. - Shader-based duckweed near the banks that drifts and gets cleared by the wake. Leaves and twigs float downstream around the camera. - Fallen snags along the banks with colliders, and muddy bars on the inside of bends where boats can run aground later. 5. Time of day and weather: check four times of day × clear/overcast/rain on the river. Each should match a reference or beat it. Extra tasks for this stage: - Extend the river north through the western hills and back east (about 780 m total) so you can see deep into the island. - Fix the harsh turquoise-to-dark jump at sea: drive murk from a wider 4 m distance-to-shore grid, ramp it over about 165 m, and blend transmittance instead of absorption coefficients. - Cut the cold shader-cache startup (about 84 s on D3D): bake height once and share one normal-from-height shader, defer texture bakes to the first render, queue all programs early with parallel shader compile, and precompile the scene before the first frame. Done when: at the mouth and at three spots upstream, at dusk, night and morning, a screenshot holds up next to the references. Duckweed visibly drifts, rings from stones and the boat spread, and island 1 and the sea are unchanged. Stage 19.1 — Fixes after testing stage 19: fog, motorboat on island 2, carrying logs, river wake A. The fog looks like faint noisy textures, not fog (top priority) Symptoms: a flat veil over the whole frame (the same near and far), blotchy grainy patches inside it, and white sparkle noise in the tree reflections. Suspected causes: the mist noise is a flat 2D texture in xz with hard smoothstep edges; it is raymarched at half resolution with a plain, depth-unaware upscale (halos around trunks, visible jitter grain); the height fog has no clear zone near the camera; mist outside the shadow cascade is fully sunlit; the mist doesn't show up in the mirror while the height fog does; and the reflection target has no MSAA, so alpha-tested leaves sparkle. Plan: - Switch the mist to a tiling 3D noise texture (64³), stretched along the river, drifting with the wind and slowly rising. Use soft edges, keep it densest 0–1.5 m above the water and almost gone over land. - Add a clear zone near the camera: fog builds up from near zero at about 6–10 m to full at 60–150 m, and the height-fog falloff gets steeper so treetops stay dark silhouettes against the sky. - Stability: temporal accumulation at half resolution (history about 0.88, reprojection through scene depth, neighbourhood clamp, reset on camera jumps), then a bilateral depth-aware upscale. - Lighting: past the shadow cascade, use a cheap canopy mask (land under the sun ray at canopy height, plus noise for gaps) so shafts still form between the crowns. Use a softer Henyey-Greenstein phase (g about 0.38) plus a narrow peak around the sun disc, and keep mist cold and faint at night. - Mirror: give the reflection target a depth texture so the river shader can rebuild the reflected path length and add analytic mist along it, and use 4× MSAA for the mirror on the river on High. B. The motorboat stutters on island 2, as if catching on the texture Diagnose first with logs (grounded and scrape state, contact count, frame times). Suspects: stick-slip on a shallow bed with stiff contact, a hidden mid-channel sandbar, width noise making the centre shallow, mismatch between the far mesh and the physics, chunk-build hitches at 9 m/s, and snags whose collider is a small cylinder while the mesh is a long trunk. Plan: the channel centre is at least 0.8 m deep across the middle 60%, with width noise only near the banks, and sandbars become visible muddy spits by the inner bank. Make the bed soft mud (softer and more damped contact, normals sampled over 1.6 m, friction that grows with slip speed). Give snags capsule colliders along the full trunk and keep them out of the channel centre. Cap chunk building at 2.5 ms per frame and build ahead in the direction of travel. Done when: a full-throttle run from the dock to the end of the river and back has no camera jerks. C. Carrying a log twists the hands, and adding it to the fire hitches Cause: the carry pose rolls the forearms about 158° (palms up), and blending through a half-turn makes the hands spin. The hitch comes from compiling new material programs on the first pickup or feed, plus allocations and a new audio panner on each event. Plan: a natural two-handed carry (palms in, thumbs up, roll under 90°) with the log scaled to the hand span. Precompile the held-log material at startup, give the campfire a pool of ready-made logs, use one persistent panner for the fire, and make the particle burst allocation-free. Done when: picking up and feeding a log 5 times in a row adds no more than 3 ms to the worst frame. D. No boat wake on island 2's water Cause: the river shader only reads the ripple sim's slopes; the foam trail and V-waves came from the ocean shader, which is faded out on the river. Plan: make the wake as visible as on island 1 or more so: a bow wave and long, slow Kelvin V-waves (about 19°) that reach the banks, reflect weakly and break the mirror into wavy pieces. Use faster sim wave speed and stronger, pulsed hull excitation on the river. Draw a subtle trail of churned water with bubbles behind the stern, read from the foam buffer (no white sea foam on dark tannin water). Check ripples from swimming, stones and rain, and that lily pads bob on the wake. General: island 1, the sea and the rest of stage 19 stay unchanged, and Low stays fast (no mist banks, but it gets the same clear zone). Record before/after measurements on the river at night, at the mouth in the morning, along the boat route and at the campfire.