World/Brain: denser breathing mesh — support neurons + resting shimmer
ci / gates (push) Has been cancelled
ci / rust (push) Has been cancelled
ci / sandbox-k8s (push) Has been cancelled
ci / frontend (push) Has been cancelled
ci / e2e (push) Has been cancelled

Hierarchy (neural-brain) v2:
- structure nodes (org/company/team) join as dim support-neurons, so the brain
  has body even with one or two agents (a real mesh, not a few dots).
- a resting-state shimmer: every neuron occasionally self-activates a touch, so a
  dormant brain still breathes.
- agents brighten on working status AND on a recent touch (real activity), then
  fire signals along pathways that chain through the support mesh.

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
This commit is contained in:
Omar Sobh
2026-06-23 23:24:35 -07:00
co-authored by Claude Opus 4.8
parent 3b012b12bf
commit 9725d620cf
+32 -19
View File
@@ -395,30 +395,43 @@ export function WorldCanvas({ roots, selectedId, onSelect, expanded, onToggleExp
// Neural-brain view: agents are neurons in a dormant mesh; active agents fire // Neural-brain view: agents are neurons in a dormant mesh; active agents fire
// signals along pathways to neighbors (chaining), so the brain comes alive. // signals along pathways to neighbors (chaining), so the brain comes alive.
const renderBrain = (dt: number) => { const renderBrain = (dt: number) => {
const ids: string[] = []; // Neurons = agents (bright, drive firing) + structure nodes (org/company/
const seen = new Set<string>(); // team) as a dim support mesh, so even a near-idle brain has body.
type Neuron = { id: string; color: string; agent: boolean; boost: number };
const neurons: Neuron[] = [];
for (const p of engine.pawns.values()) { for (const p of engine.pawns.values()) {
ids.push(p.id); const recent = p.idle < 2.5 ? 1 : 0; // a recent touch lights the neuron
seen.add(p.id); neurons.push({ id: p.id, color: p.color, agent: true, boost: (p.status === "working" ? 0.9 : 0) + recent });
if (!brainPositions.has(p.id)) brainPositions.set(p.id, neuronPos(p.id)); }
const pos = brainPositions.get(p.id)!; for (const n of engine.nodes.values()) {
let g = neuronGlows.get(p.id); if (n.tier === "org" || n.tier === "company" || n.tier === "team")
neurons.push({ id: n.id, color: n.color, agent: false, boost: n.heat });
}
const ids = neurons.map((n) => n.id);
const seen = new Set(ids);
for (const ne of neurons) {
if (!brainPositions.has(ne.id)) brainPositions.set(ne.id, neuronPos(ne.id));
const pos = brainPositions.get(ne.id)!;
let g = neuronGlows.get(ne.id);
if (!g) { if (!g) {
g = newGlow(brainGroup); g = newGlow(brainGroup);
neuronGlows.set(p.id, g); neuronGlows.set(ne.id, g);
} }
let act = neuronAct.get(p.id) ?? 0.06; let act = neuronAct.get(ne.id) ?? (ne.agent ? 0.06 : 0.03);
if (p.status === "working") act = Math.min(1, act + dt * 0.9); act = Math.min(1, act + ne.boost * dt * 1.3);
act = Math.max(0.06, act - dt * 0.22); if (Math.random() < dt * 0.5) act = Math.min(1, act + 0.08); // resting shimmer → the brain breathes
neuronAct.set(p.id, act); act = Math.max(ne.agent ? 0.06 : 0.025, act - dt * 0.22);
neuronAct.set(ne.id, act);
g.position.copy(pos); g.position.copy(pos);
const gs = 16 + act * 36; const base = ne.agent ? 16 : 8;
const gs = base + act * (ne.agent ? 36 : 16);
g.scale.set(gs, gs, 1); g.scale.set(gs, gs, 1);
const gm = g.material as THREE.SpriteMaterial; const gm = g.material as THREE.SpriteMaterial;
gm.color.set(p.color); gm.color.set(ne.color);
gm.opacity = 0.18 + act * 0.82; gm.opacity = (ne.agent ? 0.16 : 0.06) + act * (ne.agent ? 0.84 : 0.5);
const nbrs = brainAdj.get(p.id); // fire a signal along a pathway (chaining through the mesh)
if (nbrs && nbrs.length && Math.random() < act * dt * 7) { const nbrs = brainAdj.get(ne.id);
if (nbrs && nbrs.length && Math.random() < act * dt * (ne.agent ? 7 : 3.5)) {
const tid = nbrs[(Math.random() * nbrs.length) | 0]; const tid = nbrs[(Math.random() * nbrs.length) | 0];
const tp = brainPositions.get(tid); const tp = brainPositions.get(tid);
if (tp) { if (tp) {
@@ -427,8 +440,8 @@ export function WorldCanvas({ roots, selectedId, onSelect, expanded, onToggleExp
const dz = tp.z - pos.z; const dz = tp.z - pos.z;
const len = Math.hypot(dx, dy, dz) || 1; const len = Math.hypot(dx, dy, dz) || 1;
const speed = 150; const speed = 150;
spawn(pos.x, pos.y, pos.z, p.color, (dx / len) * speed, (dy / len) * speed, (dz / len) * speed, speed / len + 0.25); spawn(pos.x, pos.y, pos.z, ne.color, (dx / len) * speed, (dy / len) * speed, (dz / len) * speed, speed / len + 0.25);
neuronAct.set(tid, Math.min(1, (neuronAct.get(tid) ?? 0.06) + 0.12)); neuronAct.set(tid, Math.min(1, (neuronAct.get(tid) ?? 0.05) + 0.14));
} }
} }
} }