← Development journal

/ 4 min read

The living surface

2026-11-01. Water increment 2: the surface moves, and a wind.

The first water increment put the river in its bed and drew it flat. Today the surface took the data the generator had been carrying all along. build/water.json knows, for every point of every reach, how fast the water moves, how deep it is and whether it is calm, rapids or a fall; the mesh builder now writes those into each vertex, with a UV that runs down the stream in metres, and a new material (M_Water, the engine's Single Layer Water) slides a generated ripple normal down that UV at the point's own speed, blows a second set of ripples across it with the wind, and foams the rapids and the falls. A calm reach crawls, the cascade out of lake-D16 hurries, and the lakes only ripple. Nothing was added to the mesh but data.

The wind is one thing for the whole scene: a direction, a speed and a slow gust on the stage, written every frame into a material parameter collection that the water and the tree crowns read. The crowns lean and rock in the material itself, more toward the apex, each on its own phase by where it stands. It runs on the director's clock, the one that never stops, so a scene standing still under the fly camera has moving water and swaying trees: that is what the review flights are.

the stand at Sallow Ford, crowns in the wind the sun on lake-D9 from the March camp
the stand in the wind the glint on the lake

Left: the frontier's stand with the crowns leaning (a frame; the sway is in the movie). Right: the lake at dusk is a black mirror with the sun in it, which is what this sky gives it; the glint is where the ripples read from afar.

the glint, closer

The frame was measured, not guessed. A new tools/ue.sh fps runs the game in real time and logs the mean and worst frame after a warm-up; three views were run before and after, twenty seconds each at 1600 by 900:

view before, mean ms after, mean ms worst frame before → after
the opening at release 16.8 17.0 551 → 547 (the known tile-load hitch)
the long lake, 40 m up 13.8 13.9 26.3 → 26.2
the cascade below lake-D16 12.9 12.9 32.7 → 33.8

Within the gate with the water's reflection on and the sway at its default reach of 400 m. The look gate's frames of the opening are pixel-identical: there is no live water in it and its trees are the dead ones, which do not sway.

What the build taught, kept in the decisions: rebuilding the parameter collection regenerates its ids, so the materials that read it are rebuilt with it; the water's output node survives clearing a material, so the water material is recreated instead; the vertex colour's alpha pin cannot be linked from the build script, so the river-or-lake flag comes from the UV; and an instanced Nanite mesh's object position is not the instance's base, so the sway's height term is the pre-skinned vertex height. The first ripple scale was invisible from 300 m; the one kept is 8 m tiles with a finer octave. The river's first flight read worse than the lake's: hard corners at the 16 m hydro cells and a texture smeared across the width. The ribbon now runs on a spline through the cells and its across-stream coordinate is in metres, so the tiles stay square at any width.

Two fourteen-second flights were rendered for the review, low over the long lake from its south end north into the sun, and up the main river below lake-E12 from downstream, with the wind bed alone under them (LW_MOVIE_MIX=wind). At this hour the river lies in its channel's shadow and reads less than the lake; the first flights, aimed away from the sun, showed black water, which is the lesson: judge this water into the light. The reviewer's check that separates the three moving things, the wind at zero so the ripples and the crowns stand still, left the river's water changing between two frames half a second apart: the flow is the data's. Spec: docs/superpowers/specs/2026-11-01-water-living-surface-design.md.

Lowwater is in development. These notes capture the game at the time of writing; plans and visuals may change.

More from the making of Lowwater.

Follow along ↗