[claude] Phase 4: Effects modules — matrix rain, lightning, beam, runes, gravity, shockwave (#423) #444

Merged
Timmy merged 1 commits from claude/issue-423 into main 2026-03-24 18:19:30 +00:00
Member

Fixes #423

What

Phase 4 of the app.js modularization effort. Creates six self-contained ES modules under modules/effects/, each following the init(scene, state, theme) / update(elapsed, delta) contract from CLAUDE.md.

Modules Created

File Effect Lines
matrix-rain.js 2D canvas katakana/hex rain 98
lightning.js Floating crystals + lightning arcs 158
energy-beam.js Batcave vertical energy beam 52
rune-ring.js Orbiting Elder Futhark rune sprites 136
gravity-zones.js Rising particle anomaly zones 152
shockwave.js Shockwave ripple + fireworks + merge flash 175

Data Integrity Audit

Element Category Data Source
Matrix Rain DATA-TETHERED AESTHETIC state.zoneIntensity (commit activity) + state.commitHashes
Lightning Arcs DATA-TETHERED AESTHETIC state.zoneIntensitytotalActivity()
Crystal Formations DATA-TETHERED AESTHETIC state.zoneIntensitytotalActivity()
Energy Beam DATA-TETHERED AESTHETIC state.activeAgentCount
Rune Ring DATA-TETHERED AESTHETIC state.portals (count, colors, online status)
Gravity Anomaly Zones DATA-TETHERED AESTHETIC state.portals (positions, online status)
Shockwave / Fireworks DATA-TETHERED AESTHETIC PR merge events (WebSocket dispatch)
Merge Flash DATA-TETHERED AESTHETIC PR merge events → onMergeFlash() callbacks

Notes

  • app.js is not modified — final wiring into the ticker happens in Phase 5 (slim-down).
  • All modules gracefully handle missing state with safe defaults.
  • shockwave.js uses an onMergeFlash(fn) callback registration API so terrain/stars.js (Phase 5) can own its own star-flash state without cross-module coupling.
  • rune-ring.js and gravity-zones.js expose rebuild() / rebuildFromPortals() for external callers (portal health check system).

Test Plan

  1. Syntax: node --check app.js — passes
  2. Module syntax: each file in modules/effects/ passes node --input-type=module --check
  3. Integration (Phase 5): when app.js imports and calls init(scene, state, theme) on each module, effects should appear with the same visual behavior as the current monolith.
  4. Data tether verification: with no commits, matrix rain should be at minimum density (10%); with high activity, density approaches 100%.
  5. Offline state: with portals offline, rune ring sprites should dim to opacity 0.12 and gravity zones to reduced opacity.

Verification

Modules are pure additions — no runtime change until Phase 5 wires them. Existing behavior in app.js is unchanged.

Fixes #423 ## What Phase 4 of the app.js modularization effort. Creates six self-contained ES modules under `modules/effects/`, each following the `init(scene, state, theme)` / `update(elapsed, delta)` contract from CLAUDE.md. ## Modules Created | File | Effect | Lines | |------|--------|-------| | `matrix-rain.js` | 2D canvas katakana/hex rain | 98 | | `lightning.js` | Floating crystals + lightning arcs | 158 | | `energy-beam.js` | Batcave vertical energy beam | 52 | | `rune-ring.js` | Orbiting Elder Futhark rune sprites | 136 | | `gravity-zones.js` | Rising particle anomaly zones | 152 | | `shockwave.js` | Shockwave ripple + fireworks + merge flash | 175 | ## Data Integrity Audit | Element | Category | Data Source | |---------|----------|-------------| | Matrix Rain | DATA-TETHERED AESTHETIC | `state.zoneIntensity` (commit activity) + `state.commitHashes` | | Lightning Arcs | DATA-TETHERED AESTHETIC | `state.zoneIntensity` → `totalActivity()` | | Crystal Formations | DATA-TETHERED AESTHETIC | `state.zoneIntensity` → `totalActivity()` | | Energy Beam | DATA-TETHERED AESTHETIC | `state.activeAgentCount` | | Rune Ring | DATA-TETHERED AESTHETIC | `state.portals` (count, colors, online status) | | Gravity Anomaly Zones | DATA-TETHERED AESTHETIC | `state.portals` (positions, online status) | | Shockwave / Fireworks | DATA-TETHERED AESTHETIC | PR merge events (WebSocket dispatch) | | Merge Flash | DATA-TETHERED AESTHETIC | PR merge events → `onMergeFlash()` callbacks | ## Notes - `app.js` is **not modified** — final wiring into the ticker happens in Phase 5 (slim-down). - All modules gracefully handle missing state with safe defaults. - `shockwave.js` uses an `onMergeFlash(fn)` callback registration API so `terrain/stars.js` (Phase 5) can own its own star-flash state without cross-module coupling. - `rune-ring.js` and `gravity-zones.js` expose `rebuild()` / `rebuildFromPortals()` for external callers (portal health check system). ## Test Plan 1. **Syntax**: `node --check app.js` — passes ✅ 2. **Module syntax**: each file in `modules/effects/` passes `node --input-type=module --check` ✅ 3. **Integration (Phase 5)**: when app.js imports and calls `init(scene, state, theme)` on each module, effects should appear with the same visual behavior as the current monolith. 4. **Data tether verification**: with no commits, matrix rain should be at minimum density (10%); with high activity, density approaches 100%. 5. **Offline state**: with portals offline, rune ring sprites should dim to opacity 0.12 and gravity zones to reduced opacity. ## Verification Modules are pure additions — no runtime change until Phase 5 wires them. Existing behavior in `app.js` is unchanged.
claude added 1 commit 2026-03-24 18:19:12 +00:00
feat: add effects modules — matrix rain, lightning, beam, runes, gravity, shockwave
All checks were successful
CI / validate (pull_request) Successful in 6s
CI / auto-merge (pull_request) Successful in 10s
0408ceb5bc
Phase 4 of app.js modularization. Extracts all visual effects into self-contained
ES modules under modules/effects/ following the init(scene,state,theme)/update(elapsed,delta)
contract defined in CLAUDE.md.

Modules created:
- matrix-rain.js  — commit-density-driven 2D canvas rain (DATA-TETHERED AESTHETIC)
- lightning.js    — floating crystals + lightning arcs (DATA-TETHERED AESTHETIC)
- energy-beam.js  — Batcave terminal beam (DATA-TETHERED AESTHETIC)
- rune-ring.js    — portal-tethered orbiting rune sprites (DATA-TETHERED AESTHETIC)
- gravity-zones.js — portal-position rising particle zones (DATA-TETHERED AESTHETIC)
- shockwave.js    — shockwave ripple, fireworks, merge flash (DATA-TETHERED AESTHETIC)

All modules read data tethers from the state bus (state.zoneIntensity,
state.portals, state.activeAgentCount, state.commitHashes). No mocked data.
app.js unchanged — final wiring happens in Phase 5 slim-down.

Refs #423

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Timmy merged commit 35dd6c5f17 into main 2026-03-24 18:19:30 +00:00
Timmy deleted branch claude/issue-423 2026-03-24 18:19:33 +00:00
Sign in to join this conversation.