Metabolism M2.9: flora islands, gardens, walls, farmer strain, aimed work (VM AIM actions), food-limited ecology rebalance

This commit is contained in:
Dejvino
2026-10-28 12:49:17 +01:00
parent 1d497e556e
commit 476fa1833a
11 changed files with 675 additions and 120 deletions
+18 -8
View File
@@ -52,8 +52,11 @@ test('the song drops rock on heavy hits and shatters it on high ones', () => {
mute.program.rock.drop = 0;
mute.program.rock.shatter = 0;
for (let f = 0; f < 600; f++) { live.step(); mute.step(); }
assert.ok(rockMass(live) > rockMass(mute) * 1.3,
`rockfall should outpace a mute sky (live ${rockMass(live).toFixed(1)} vs ${rockMass(mute).toFixed(1)})`);
// The sky's ledger: a live song drops stone, a mute one never does.
assert.ok(live.rockFallen > 5, `rockfall should accumulate (${live.rockFallen.toFixed(1)})`);
assert.equal(mute.rockFallen, 0, 'a mute sky drops nothing');
assert.ok(rockMass(live) > rockMass(mute),
`the live world holds more stone (${rockMass(live).toFixed(1)} vs ${rockMass(mute).toFixed(1)})`);
});
test('rock is a wall: the population cannot cross it', () => {
@@ -124,7 +127,7 @@ test('builders quarry: rock goes down, soil and burden appear', () => {
let foodAfter = 0;
for (let i = 0; i < w.n; i++) foodAfter += w.resource[i];
let carry = 0;
for (let s = 0; s < w.m; s++) for (let b = 0; b < w.fc; b++) carry += w.carry[s * w.fc + b];
for (let s = 0; s < w.m; s++) for (let i = 0; i < w.n; i++) carry += w.carry[s][i];
assert.ok(after < before - 1, `quarries must open (${before.toFixed(1)} → ${after.toFixed(1)})`);
assert.ok(carry > 0.2, `the burden must be carried (${carry.toFixed(2)})`);
@@ -141,13 +144,20 @@ test('builders build: carried rock rises as walls', () => {
[OP.HALT],
];
}
// A loaded block in the middle of open ground.
// No weathering during the test: we are measuring the masons, not the rain.
for (const sec of w.program.sections) sec.operators.erode = 0;
// A loaded block on cleared, open ground.
const F = w.field;
const b = w.coarseOf[30 * F + 30];
for (let s = 0; s < w.m; s++) w.carry[s * w.fc + b] = 5;
for (let y = 26; y < 35; y++) {
for (let x = 26; x < 35; x++) w.rock[y * F + x] = 0;
}
w.refreshRockMask();
for (let s = 0; s < w.m; s++) w.carry[s][30 * F + 30] = 400;
const before = rockMass(w);
for (let f = 0; f < 60; f++) w.step();
for (let f = 0; f < 120; f++) w.step();
const after = rockMass(w);
assert.ok(after > before + 0.5,
// The four cells of the loaded block can hold 2.4 each; the weathering
// floor eats ~2% over the run — the wall rise must dominate.
assert.ok(after > before + 4,
`carried rock must rise (${before.toFixed(2)} → ${after.toFixed(2)})`);
});