SOTCD Hydra Visual System
Live-coded visuals driven by cosmic data, synced with the DJ Bot audio.
Status
- β WebSocket data feed from Signal Bridge
- β Earthquake β chaos/distortion
- β Solar β color/brightness
- β Plasma β movement/flow
- β Planetary β geometry/rotation
- β Sigil selection system
- π Sigil image library (in progress)
- π Artwork generation from Lore Bot (planned)
Architecture
Signal Bridge (Node.js)
β
β WebSocket :8080
βΌ
βββββββββββββββββββββββββββββββββββββββ
β HYDRA EDITOR β
β hydra.ojack.xyz (browser-based) β
βββββββββββββββββββββββββββββββββββββββ€
β Data Mapping: β
β β’ earthquake β noise/modulation β
β β’ solar β color temperature β
β β’ plasma.density β kaleidoscope β
β β’ plasma.speed β oscillation β
β β’ moonPhase β rotation β
β β’ sigil β image overlay β
βββββββββββββββββββββββββββββββββββββββ
β
β Screen capture
βΌ
βββββββββββββββββββββββββββββββββββββββ
β FFmpeg / OBS β
β β Twitch Stream β
βββββββββββββββββββββββββββββββββββββββ
Quick Start
1. Start Signal Bridge (on ShadowMaster)
cd C:\Users\shdwadmin\sotcd
node signal_bridge_visual.js2. Open Hydra
Navigate to hydra.ojack.xyz
3. Paste Base Code
// SOTCD Data Connection
let d = {
signal: 0.5,
earthquake: 0.2,
solar: 0.3,
plasma: {density: 0.3, speed: 0.4, temp: 0.3},
moonPhase: 0.5,
sigil: 'phi'
}
let ws = new WebSocket('ws://localhost:8080')
ws.onmessage = (e) => {
d = JSON.parse(e.data)
console.log('π‘ Sigil:', d.sigil, '| Signal:', (d.signal*100).toFixed(0) + '%')
}
ws.onerror = () => console.log('β WebSocket error - is signal_bridge running?')4. Add Visuals
// Cosmic acid visuals
osc(3, 0.1, () => d.plasma.speed)
.rotate(() => d.moonPhase * Math.PI * 2)
.color(() => d.solar, 0.3, () => 1 - d.earthquake)
.modulate(noise(() => d.earthquake * 3), () => d.signal * 0.3)
.kaleid(() => Math.floor(d.plasma.density * 8) + 3)
.scale(() => 1 + d.signal * 0.5)
.out()Data Feed Reference
WebSocket Payload
{
"signal": 0.5,
"earthquake": 0.3,
"solar": 0.4,
"plasma": {
"density": 0.3,
"speed": 0.5,
"temp": 0.2
},
"planets": {
"mercury": 45.2,
"venus": 120.5,
"mars": 230.1,
"jupiter": 15.3,
"saturn": 280.7,
"moon": 180.0
},
"moonPhase": 0.75,
"aspects": [
{"planet": "mars", "type": "trine", "strength": 0.8}
],
"bpm": 120,
"filter": 2600,
"sigil": "phi",
"time": 1706799600000
}Data Ranges
| Field | Range | Meaning |
|---|---|---|
signal | 0-1 | Master intensity |
earthquake | 0-1 | Seismic activity |
solar | 0-1 | X-ray flux level |
plasma.density | 0-1 | Solar wind density |
plasma.speed | 0-1 | Solar wind velocity |
plasma.temp | 0-1 | Plasma temperature |
moonPhase | 0-1 | 0=new, 0.5=full, 1=new |
planets.* | 0-360 | Degrees in zodiac |
bpm | 80-160 | Music tempo |
Visual Recipes
Base: Cosmic Oscillator
osc(3, 0.1, () => d.plasma.speed)
.color(() => d.solar, 0.3, () => 1 - d.earthquake)
.out()Earthquake Chaos
noise(() => d.earthquake * 5)
.modulate(osc(10), () => d.signal * 0.5)
.thresh(0.5)
.out()Solar Flare Bloom
osc(20, 0.01, 1)
.color(1, () => d.solar * 0.5, 0)
.modulate(noise(3), () => d.solar * 0.3)
.brightness(() => d.solar * 0.5)
.out()Plasma Flow
voronoi(() => d.plasma.density * 20, () => d.plasma.speed)
.color(() => d.plasma.temp, 0.5, 1)
.modulate(noise(2), 0.1)
.out()Lunar Geometry
shape(() => Math.floor(d.moonPhase * 6) + 3)
.rotate(() => d.moonPhase * Math.PI * 2)
.scale(() => 0.5 + d.moonPhase * 0.5)
.out()Planetary Kaleidoscope
osc(5, 0.1)
.kaleid(() => Math.floor(d.plasma.density * 12) + 3)
.rotate(() => d.planets?.moon / 360 * Math.PI * 2 || 0)
.colorama(() => d.signal * 0.5)
.out()Full SOTCD Stack
// Layer 1: Base oscillation (plasma-driven)
src(o0)
.blend(osc(3, 0.1, () => d.plasma.speed), 0.1)
.out(o0)
// Layer 2: Earthquake noise
noise(() => d.earthquake * 4)
.thresh(() => 0.4 + d.signal * 0.2)
.out(o1)
// Layer 3: Solar color
osc(20, 0.01)
.color(() => d.solar, () => 0.3 - d.earthquake * 0.2, () => 1 - d.solar)
.out(o2)
// Combine
src(o0)
.modulate(src(o1), () => d.earthquake * 0.2)
.mult(src(o2), 0.5)
.kaleid(() => Math.floor(d.plasma.density * 6) + 3)
.rotate(() => d.moonPhase * Math.PI)
.out(o3)
render(o3)Sigil System
The signal bridge selects sigils based on cosmic conditions:
| Condition | Sigil |
|---|---|
| Solar flare (>70%) | eye |
| Earthquake (>60%) | spiral |
| Full moon (45-55%) | flower |
| Multiple aspects (>2) | metatron |
| Fast solar wind (>60%) | ouroboros |
| Default | Cycles through library |
Sigil Library
phi, vesica, seed, flower, metatron,
hexagram, pentacle, ouroboros, eye, spiral
Loading Sigil Images (TODO)
// Future: Load sigil images from library
s0.initImage(`sigils/${d.sigil}.png`)
src(s0).blend(src(o0), 0.3).out()BPM Sync (Advanced)
Sync visuals to the beat:
// BPM to frequency
let beatFreq = () => d.bpm / 60
osc(() => beatFreq() * 2, 0.1)
.rotate(() => time * beatFreq() * 0.1)
.out()Troubleshooting
WebSocket wonβt connect
- Ensure
signal_bridge_visual.jsis running - Check console for errors
- Firewall may block localhost:8080
Visuals are static
- Confirm data is flowing:
console.log(d)in Hydra - WebSocket might have disconnected - refresh page
Performance issues
- Reduce kaleidoscope segments
- Lower modulation complexity
- Use
render(o0)instead of multiple outputs
Future Plans
- Sigil image library integration
- Lore Bot β AI artwork generation
- Planetary conjunction special events
- Audio-reactive (FFT from SC)
- OBS shader integration