Metabolism: decision-cadence (think slower than you move) + empty-block skip; flat typed-array bytecode; WebGPU decision-layer slice (experimental) + heavy-world benchmark
This commit is contained in:
@@ -12,7 +12,7 @@ import { analyse } from '../src/audio/analyse.js';
|
||||
import { decodeWav, mono } from '../src/audio/wav.js';
|
||||
import { buildSong } from '../src/song/song.js';
|
||||
import {
|
||||
compileStrains, runProgram, OP, S_HUNGER, S_FOOD, S_SELF, S_FOE, S_PEACE,
|
||||
compileStrains, compileFlat, runProgram, OP, S_HUNGER, S_FOOD, S_SELF, S_FOE, S_PEACE,
|
||||
A_MOVE_X, A_MOVE_Y, A_EXCRETE, A_SPAWN, A_HIT,
|
||||
} from '../src/song/strains.js';
|
||||
import { Run } from '../src/film.js';
|
||||
@@ -75,18 +75,19 @@ test('the VM branches on senses: starving seeks food, fed works', () => {
|
||||
const senses = new Float32Array(12);
|
||||
const grads = new Float32Array(12);
|
||||
const act = new Float32Array(6);
|
||||
const flat = compileFlat(code);
|
||||
|
||||
// Hungry (HUNGER high) → moves, no excrete.
|
||||
senses[S_HUNGER] = 0.9;
|
||||
grads[0] = 1; grads[1] = -1;
|
||||
runProgram(mem, 0, senses, grads, act, code);
|
||||
runProgram(mem, 0, senses, grads, act, flat.I, flat.F, flat.n);
|
||||
assert.ok(act[A_MOVE_X] > 0 && act[A_MOVE_Y] < 0, 'hungry strain should move toward food');
|
||||
|
||||
// Fed (HUNGER low) → no movement.
|
||||
senses[S_HUNGER] = 0.1;
|
||||
mem.fill(0);
|
||||
grads[0] = 1; grads[1] = 1;
|
||||
runProgram(mem, 0, senses, grads, act, code);
|
||||
runProgram(mem, 0, senses, grads, act, flat.I, flat.F, flat.n);
|
||||
assert.equal(act[A_MOVE_X], 0, 'fed strain should not chase food');
|
||||
});
|
||||
|
||||
@@ -111,15 +112,16 @@ test('the sentinel branch: hostile peace strikes, peaceful peace shadows', () =>
|
||||
const grads = new Float32Array(12);
|
||||
const act = new Float32Array(6);
|
||||
|
||||
const flat = compileFlat(code);
|
||||
senses[S_FOE] = 0.8;
|
||||
senses[S_PEACE] = 0.1; // war
|
||||
grads[3 * 2] = 1; // foe gradient x
|
||||
runProgram(mem, 0, senses, grads, act, code);
|
||||
runProgram(mem, 0, senses, grads, act, flat.I, flat.F, flat.n);
|
||||
assert.ok(act[A_HIT] > 0, 'at war the sentinel strikes');
|
||||
|
||||
senses[S_PEACE] = 0.9; // truce
|
||||
act.fill(0);
|
||||
runProgram(mem, 0, senses, grads, act, code);
|
||||
runProgram(mem, 0, senses, grads, act, flat.I, flat.F, flat.n);
|
||||
assert.equal(act[A_HIT], 0, 'at truce the sentinel does not strike');
|
||||
});
|
||||
|
||||
@@ -133,9 +135,10 @@ test('memories (registers) persist across runs', () => {
|
||||
const senses = new Float32Array(12);
|
||||
const grads = new Float32Array(12);
|
||||
const act = new Float32Array(6);
|
||||
const flat = compileFlat(code);
|
||||
senses[S_SELF] = 0.8;
|
||||
runProgram(mem, 0, senses, grads, act, code);
|
||||
runProgram(mem, 0, senses, grads, act, code);
|
||||
runProgram(mem, 0, senses, grads, act, flat.I, flat.F, flat.n);
|
||||
runProgram(mem, 0, senses, grads, act, flat.I, flat.F, flat.n);
|
||||
assert.ok(mem[1] > 0, 'register kept value across runs');
|
||||
assert.ok(Math.abs(mem[1] - 0.6) < 1e-6, `memory integrates deterministically (${mem[1]})`);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user