Metabolism: rule program, song-driven life, tribe VMs; M2.7 design (strains & allegiances, living wells)
This commit is contained in:
@@ -24,7 +24,7 @@ function load(name) {
|
||||
/** Run `seconds` of the world for song `name` with a seed. Returns world. */
|
||||
function grow(name, seed, seconds = 20) {
|
||||
const song = load(name);
|
||||
const run = new Run(song, { fps: 30, seed, width: 240, height: 135 });
|
||||
const run = new Run(song, { fps: 30, seed, width: 240, height: 135, field: 64, genesis: 0 });
|
||||
for (let f = 0; f < Math.floor(seconds * 30); f++) {
|
||||
run.world.step();
|
||||
run.camera.update(f);
|
||||
@@ -78,4 +78,31 @@ test('three songs grow fingerprints further apart than seeds of one song', () =>
|
||||
const a2 = fingerprint(grow('drone', 99).world);
|
||||
const within = divergence(a, a2);
|
||||
assert.ok(cross > within * 2, `cross ${cross} !> 2×within ${within}`);
|
||||
});
|
||||
|
||||
test('genesis pre-simulates generations so frame 0 is already an ecosystem', () => {
|
||||
const song = load('drone');
|
||||
const withGenesis = new Run(song, { fps: 30, seed: 12345, width: 240, height: 135, field: 64 });
|
||||
const without = new Run(song, { fps: 30, seed: 12345, width: 240, height: 135, field: 64, genesis: 0 });
|
||||
|
||||
assert.ok(withGenesis.world.genesisFrames > 0, 'song should demand a genesis epoch');
|
||||
// The world at frame 0 is more evolved (generations already lived)…
|
||||
assert.ok(withGenesis.world.count > without.world.count * 1.1,
|
||||
`genesis world should be more populated (${withGenesis.world.count} vs ${without.world.count})`);
|
||||
// …and the ground already carries history, where a fresh plate has none.
|
||||
assert.ok(withGenesis.world.sampleTrailMass() > 0.0001,
|
||||
`genesis world should already hold ink (${withGenesis.world.sampleTrailMass()})`);
|
||||
assert.equal(withGenesis.world.history.alive[0], 0, 'genesis must not record into the film');
|
||||
assert.equal(withGenesis.world.frame, -1, 'the film starts at frame 0');
|
||||
});
|
||||
|
||||
test('genesis is deterministic and song-scaled', () => {
|
||||
const a = new Run(load('drone'), { fps: 30, seed: 12345, width: 240, height: 135, field: 64 });
|
||||
const b = new Run(load('drone'), { fps: 30, seed: 12345, width: 240, height: 135, field: 64 });
|
||||
assert.equal(a.world.genesisFrames, b.world.genesisFrames);
|
||||
assert.deepEqual(Array.from(a.world.pop[0]), Array.from(b.world.pop[0]));
|
||||
|
||||
const runner = new Run(load('runner'), { fps: 30, seed: 12345, width: 240, height: 135, field: 64 });
|
||||
assert.notEqual(a.world.genesisFrames, runner.world.genesisFrames,
|
||||
'the genesis amount should depend on the song');
|
||||
});
|
||||
Reference in New Issue
Block a user