feat(client): animated terrain fluids (ocean/lava/rivers) on the SDF blend #222
Labels
No labels
alpha:wave-0
alpha:wave-1
alpha:wave-2
alpha:wave-3
area:assets
area:combat
area:ecology
area:infra
area:render
area:scripting
area:ui
area:world
enhancement
epic
migration
post-alpha
roadmap
tech-debt
type:bug
type:chore
type:design
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
marco/IsoMmo#222
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?
Design agreed via
critical-design-review+ owner handoff (handoff_claude_terreni_animazioni.docx). Display-only client rendering on top of the SDF ground blend (#221). Frame assets prepared inE:\Asset\Terrain Anim.Model (owner handoff, aligned with the review)
0-1-2-3-2-1-0…: ocean, coast, lake, lava, dirty-water. The surface breathes back and forth, no pop at the loop seam. 4 or 8 frames.0-1-2-…-N-0…: rivers, four orientations (L→R, R→L, N→S, S→N), 8 frames each. Flow is one-way so frames must advance and wrap (ping-pong would reverse the current). Adjacent tiles share phase + speed; curves = per-tile local direction.Assets (in
E:\Asset\Terrain Anim, 1254² RGB → process to seamless 128² like the land tiles)salt_water_ocean_anim(4) ·salt_water_coast_anim(4) ·dirty_water_anim(4) ·water_lake_anim(8) ·lava_anim(8) ·water_river_{left_right,right_left,north_south,south_north}_anim(8 each).Technical design
TerrainAnimation(pure, unit-tested):FrameIndex(seconds, count, fps, mode)— PingPong (cyclic surfaces) = triangle wave0-1-2-3-2-1(period2·(count-1)); Loop (rivers, one-way flow) =⌊t·fps⌋ % count.count=1⇒ always 0 (static biomes never offset).Timeuniform; inSampleBiome,frameOffset = TerrainAnimation(Time, params)before computing the atlas cell — arithmetic only, no branch (ps_3_0/DesktopGL safe). Weights/palette untouched → blend stays static, only the sampled frame moves.Invariants Check (
CLAUDE.md ## Design checklist) — all ✓/N-A, no ✗Load-bearing: Client engine-independence ✓ (frame selection pure in Client.Core, engine glue in renderer/shader) · Extend by type ✓ (animated biome = data in the anim-def + frames, no
switch/if biome==water) · Assets/real-art ✓ (real frames from the pack; missing ⇒ static fallback, never a synth shape) · Asset naming ✓ (<biome>_anim_NN) · Multi-platform ✓ (Time uniform + arithmetic, ps_3_0) · Screen/World HARD GATEs ✓ (logic in the render component) · Server-authoritative / protocol / persistence / AoI / GM / sim-thread N/A (no server, wire, or persisted state; walkability/sight/moveCost still from tiledata flags). Full per-line check in the PR.Server-side validation
N/A — no player-triggered behavior; zero trust boundary (animation cannot change what the server simulates).
Verification plan
TerrainAnimationTests— ping-pong (ocean) yields0,1,2,3,2,1for count 4; loop (river) wraps0,1,…,N-1,0;count=1⇒ 0.Time(only the sampled frame moves)./tpto the ocean/coast, capture a burst of consecutive frames (single-framescreenshotfired several times, VFX-burst technique) to show the water cycling + the coast blend shimmering.dotnet test+ whole-solution build 0 warnings +just build-shaderre-committed if the.fxchanges.Definition of Done
TerrainAnimationin Client.Core with unit tests (loop + ping-pong + static).waterbiome) animates in-game via the SDF blend; the coast blend animates smoothly with it; a burst screenshot shows ≥2 distinct frames.just build-shader); no OS-specific dep.docs/uo-asset-map.md(new frame ids) + a terrain-animation note indocs/architecture.md.Scope fence: first PR = cyclic ocean only. Coast/lake/lava = a data row + frames each (free later). Directional rivers (phase coherence, curves) = a follow-up.
Marco aiutami invece di farti le unghie a tema pokemon 💅
Risolta: fluidi animati (ocean/lava/rivers) su main (#222).