Skip to content

feat(pool): the current — a drag stirs a slow, persistent flow that keeps carrying the light - #130

Merged
pyramation merged 2 commits into
mainfrom
feat/pool-current
Sep 17, 2026
Merged

pyramation merged 2 commits into
mainfrom
feat/pool-current

Conversation

@pyramation

Copy link
Copy Markdown
Contributor

Summary

Gestures now deposit motion, not just colour. Under the Pool's light sources sits a coarse velocity grid — the current. Dragging pushes on it; after release the blobs are carried by it. Pull a spot and it stretches, circle and the pool keeps turning slowly for minutes, then comes to rest. This is the "pulling clay that then animates itself" feel.

@wavegrid/pool — new Current (packages/pool/src/current.ts)

16×16 grid of (u,v) over the 0..1 square
push(x, y, vx, vy, radius, dt, maxSpeed)   // Gaussian push from a finger, speed capped (≤0.08 units/s)
step(dt)                                   // diffuse → no-flow walls → pressure projection → exp decay (τ=90s)
at(x, y)                                   // bilinear sample
release()                                  // τ → 2.5s (Dissolve)
reset()                                    // still at once (Blackout / other producer takes the grid)
snapshot()                                 // [] when still, else 512 rounded numbers

The pressure projection (a few Gauss–Seidel sweeps) is what makes a push turn into a swirl instead of piling everything in a corner: the water is incompressible, so pulling one side brings the other round.

PoolField changes

  • Every smoothed touch calls current.push(...) with its velocity; max speed scales with Motion (lerp(0.3, 1, motion) * CURRENT_MAX_SPEED).
  • Blob sources are advected: s.x += (s.vx + current.vx) * dt (rings keep their own ripple path).
  • release() / reset() forward to the current; snapshot() gains current: number[].
  • Works in Fade and Hold; in Hold this is where it shines — held colour is literally pulled around.

UI

  • socket-state parses current (defaults to []).
  • PoolCanvas draws faint white streaks per cell where the water moves — hidden in Beams only, so that view still shows exactly what the lasers get.

No new controls, no protocol changes: server still emits ordinary HSB paint/cannon cells via the same smoother; Clear/Stop/animation precedence unchanged (server tests still 100/100).

Tests (packages/pool)

  • Circling drag → measurable swirl after release, slow (< 0.1 u/s), blobs carried a fraction of a lap in 20 s, stays inside the pool.
  • Unattended current decays over tens of seconds; release() stills it within seconds; reset() at once; still pool sends current: [].

Link to Devin session: https://app.devin.ai/sessions/c4872c2982734093bdee80d04a7d5ceb
Open in Devin Desktop: https://app.devin.ai/desktop/session/c4872c2982734093bdee80d04a7d5ceb?variant=devin
Requested by: @pyramation

@devin-ai-integration

Copy link
Copy Markdown
Contributor

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment, CI, and merge conflict monitoring

@tenki-reviewer

tenki-reviewer Bot commented Sep 17, 2026

Copy link
Copy Markdown

Review complete. 🟡 1 medium

💬 Inline comments (1)


This PR introduces a flow/current simulation to the pool output: current.ts computes an incompressible velocity field over the grid, pool-field.ts integrates it into PoolSnapshot and the pool state machine, and the UI (pool-canvas.tsx, pool-tab.tsx, socket-state.ts) projects and renders the velocity streaks. It also adds unit coverage in pool-field.test.ts.

Files Change
packages/pool/src/current.ts, pool-field.ts, index.ts Add the fluid current velocity grid to the pool model and expose it via the snapshot.
packages/pool/__tests__/pool-field.test.ts Unit tests for the new state-machine current integration.
packages/ui/src/lib/socket-state.ts, pool-tab.tsx, pool-canvas.tsx Receive and render the current grid as animated streaks in the pool canvas.

One medium finding: the full 512-element current grid is re-serialized into every ~15 Hz pool frame even though painted cells are sent only on change, adding per-client wire cost.

Reviewed commit: b885847

@tenki-reviewer tenki-reviewer Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adds a fluid-velocity 'current' field to the pool snapshot and renders its streaks in the UI canvas, synced over websockets.

Key findings

Comment thread packages/pool/src/pool-field.ts
@pyramation
pyramation merged commit 109657c into main Sep 17, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant