WORKFLOW TEST — autonomous opt-in #7
Labels
No labels
agent
agent:ci
agent:done
agent:failed
agent:needs-input
agent:refined
agent:refining
agent:running
agent:skip
autonomous
driven
local
No milestone
No project
No assignees
2 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
jeroen/cartopolis#7
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Problem
"Make the water look better somehow" has no defect behind it, and the local water shader is not a rough draft — it is a deliberate, documented design. Before this can be implemented, someone has to say which of several unrelated changes is wanted, because they differ by two orders of magnitude in cost.
What exists today (local tier only):
assets/shaders/water.wgslis anExtendedMaterialoverStandardMaterial: 5 sharpened directional octaves with per-octave distance fade (water.wgsl:107–189), crest wobble to break the corduroy pattern (water.wgsl:153), deep-water dispersion (water.wgsl:137), fresnel depth tint (water.wgsl:237), whitecaps masked on chop-riding-a-crest (water.wgsl:257), and a shore lap line (water.wgsl:268).vector_tiles.rs:1259) drives shelter, a shallow tint and the foam line (water.wgsl:215,:245,:269).water.rs:214–238,water.rs:244).So the obvious wins are already spent. The genuine gaps I can cite are these, and they are not equivalent:
A. The waves always travel the same compass direction, whatever the weather is doing.
sea_statetakes its direction fromCLOUD_WIND—water.rs:217— which isVec2::new(0.04, 0.015)atmain.rs:2380, a cloud drift velocity in texture units, reused as a bearing. Normalised it is a constant ≈ENE, forever. MeanwhileObservation(weather.rs:43–52) carries onlywind_ms;parse_weatherreadswind_speedatweather.rs:176and drops the rest. I checked the live endpoint the client already calls — MET'slocationforecast/2.0/completereturnswind_from_directionin degrees in the sameinstant.detailsobject the parser is already inside. The data is fetched and thrown away. Wind speed changes the sea; wind direction does not.B. Rain does not touch the water.
weather.rs:46carriesprecipitation, wired into clouds and fog.water.rsandwater.wgslcontain no reference to it (grep: zero hits). A downpour leaves the canals glassy.C. The water is opaque, and cannot cheaply stop being so.
WaterSeaState::materialbuilds aStandardMaterialwith noalpha_mode(water.rs:147–161), so it isAlphaMode::Opaque. The "shallows" are a pure albedo tint (water.wgsl:245–250), not transmission. Making it transparent does not buy depth: the water mesh sits aty = -0.004(vector_tiles.rs:499) directly over the map tile, whose texture has already painted the same polygon flatpalette::WATER0xA8C4DA(vector_tiles.rs:170,:91). You would see flat blue paint through the water, not a bed.D. The water reflects the sky and nothing else. Reflection comes entirely from
AtmosphereEnvironmentMapLightvia the standard PBR path (water.rs:11–15). A canal in a city therefore does not reflect the houses lining it. Real reflections would need screen-space: the camera spawns with noDepthPrepassand noDeferredPrepass(free_camera.rs:335–390), and Bevy'sScreenSpaceReflectionsis deferred-only — a custom forward fragment shader is exactly the case it does not cover. This is a rendering-architecture change, not a shader tweak.E. Nobody can see a water change in the documentation image set. None of the six presets in
docs/shots.tomlframes water:city,city-dusk,avatar,route,horizon,globe.ShotMetrics(shot_harness.rs:243–281) has fields for globe tiles and route meshes but nothing for water, so--dump-statecannot answer "did water cells even build here?".Also worth stating plainly: none of this reaches the space tier.
globe_ocean.rsis a separate BRDF-mask system that shares nothing withwater.wgsl(globe_ocean.rs:3–11), and surface geometry only streams from vector sources (map_geometry.rs:243returns early on a raster template), so on the default raster basemap there is no water shader at all.Approach
Blocked on the pick in Open questions. My recommendation is A + E, and here is that spec in full so a "yes, do A+E" is enough to start:
crates/viberfox/src/systems/weather.rs— addwind_from_deg: f32toObservation(weather.rs:43), parsed frominst["wind_from_direction"]alongsidewind_speedatweather.rs:176. Missing key → keep the current constant bearing rather than defaulting to 0° (north), which would be a silent wrong answer.crates/viberfox/src/systems/water.rs—sea_statetakes the bearing as an argument instead of readingCLOUD_WIND(water.rs:217); convert meteorological from-degrees to a travel direction in the map's XZ frame.update_water_waves(water.rs:244) passesweather.latest's bearing and gains a direction term in its change gate next toWIND_EPSILON(water.rs:64) so a slow veer still rewrites the materials.crates/viberfox/src/main.rs—CLOUD_WINDstays as it is; only the water import atwater.rs:40goes.docs/shots.toml+crates/viberfox/src/systems/shot_harness.rs— awaterpreset, andwater_cells/water_renderedcounters onShotMetricsfollowing theroute_meshes/route_renderedprecedent atshot_harness.rs:279, added toCSV_HEADER(shot_harness.rs:285) andcsv_rowtogether.No shader edit is needed for A:
water.wgsl:122already consumeswind.xyas an arbitrary unit direction.Acceptance criteria
Conditional on A + E being the chosen option.
parse_weatherextractswind_from_direction; a unit test on a fixture body asserts the parsed bearing, and a second asserts a body without the key falls back to the current constant bearing rather than to 0°.wind.xyinsea_state, and that the existingthe_wind_direction_is_a_unit_vectorinvariant (water.rs:291) still holds for every bearing in 0..360.wind_from_direction = 0(wind from the north) makes the waves travel southward in the map frame. Getting this backwards is invisible in a still image, so it has to be a test.update_water_wavesrewrites materials on a direction change alone, with the wind speed unchanged — covered by the epsilon-gate logic, testable without a GPU.CLOUD_WINDis unchanged and still drives the cloud shader atmain.rs:2531.docs/shots.tomlgains awaterpreset, andcargo shots --only waterwritesdocs/img/water.png(workstation only).ShotMetricscarries water counts, present in all three sinks (log line,--csv,--dump-state) per the one-field-three-sinks rule in CLAUDE.md.Verification
In this container:
cargo checkdoes not compilecfg(test)code, so the test run is the real gate.Workstation only (no GPU here, per the container rules):
Anything about whether the water actually looks better — wave direction reading correctly against the visible wind, the shore line, the whitecaps — is unverifiable in this container and needs a human at a workstation. The shader itself cannot even be compiled here.
Out of scope
globe_ocean.rsis a per-texel BRDF mask, shares no code withwater.wgsl, and is not touched.map_geometry.rs:243); water there stays flat paint (vector_tiles.rs:170) and no shader change can reach it.CLOUD_WINDor the cloud shader.update_water_wavesiterating every live material (water.rs:274) — it is gated to a handful of runs an hour and is not a looks problem.Open questions
ExtendedMaterial. I would not start here).ShotMetricscounters without input, but awaterpreset needs a lat/lng/look, and picking one would be guessing. The manifest's own instruction is to fly there and use Dev panel ▸ 📋 Copy as preset — which needs a workstation. Either paste a[[shot]]block here, or name a water body (Noorderhaven? the Verbindingskanaal? the open Eemskanaal?) and accept that the exact framing gets tuned by whoever runscargo shots.Branch:
issue-7Original request
Make the water look better somehow.
🤖 Refined by the viberfox issue agent. Reply with @agent refine and what is wrong to have this rewritten.
🤖 Refining this before anything gets built — reading the code, no branch, no commits. If it turns out I'd have to guess at the requirements I'll stop and ask instead.
🤖 This needs a decision before I build anything. The open questions are in the description above.
Answer them and reply with @agent refine to have the spec rewritten, or @agent to make me implement it as it stands.
🤖 viberfox issue agent on the VPS — 18 turns · $1.26 · session
906450e3-b5f5-4c25-8c17-2743a4b6ab25. Reply with @agent to continue this session.