Fewer, smaller messages: mold percentages, markers for machine heat, short status lines

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-23 23:03:45 -04:00
co-authored by Claude Opus 5.5
parent a15af6ef9f
commit 10911d4c86
25 changed files with 164 additions and 106 deletions
+13 -2
View File
@@ -5,6 +5,7 @@ const { load, suite, flatWorld, rect, ticks, count } = require('./harness');
const { run } = load();
const { check, done } = suite();
function fresh() { flatWorld(run, 240, 160, 100); run('bot.x = 110; bot.y = 70; bag.fill(0); bagTotal = 0; for (const e of ents.slice()) removeEnt(e);'); }
run("var moldMessages = []; const collectOriginal = collectMold; collectMold = function(mo) { const s = collectOriginal(mo); moldMessages.push(s); return s; }; 0");
const cavCount = (k, m) => run(`molds[${k}].cavs[0].filter(i => mat[i] === ${m}).length`);
// automatic drops leave the short stub on the trough floor for the next firing
@@ -20,11 +21,13 @@ check('five more grains top up the stub into another bar', run('ents.length ===
// blocked mouths retain their metal and warn once, including molds from old saves
fresh();
run('bag[RSTONE] = 100; bagTotal = 100; placeMoldAt("ingot", 30, 22, RSTONE); bag[RSTONE] = 0; bagTotal = 0; EV.length = 0; { const mo = molds[0]; for (const i of mo.cavs[0]) setCell(i, COPPER, 30, F_CAST); for (let y = mo.y + mo.h; y < mo.y + mo.h + 2; y++) for (let x = mo.x; x < mo.x + mo.w; x++) setCell(y * W + x, STONE, 30, 0); } checkMolds(); checkMolds();');
check('blocked bars have a warning flag', run('molds[0].blocked === true'));
check('blocked bars stay put and warn only once', run('ents.length === 0 && molds[0].state === "ready" && EV.filter(e => e.t === "ingot_blocked").length === 1') && cavCount(0, run('COPPER')) === 28);
msg = run('collectMold(molds[0])');
check('F on a blocked ingot mold changes nothing', run('ents.length === 0') && cavCount(0, run('COPPER')) === 28 && /empty themselves/.test(msg), msg);
run('{ const mo = molds[0]; for (let y = mo.y + mo.h; y < mo.y + mo.h + 2; y++) for (let x = mo.x; x < mo.x + mo.w; x++) setCell(y * W + x, EMPTY, 30, 0); }');
run('checkMolds()');
check('dropping bars clears the warning flag', run('molds[0].blocked === false'));
check('the next check drops bars only below it', run('ents.length === 3 && ents.every(e => e.iy === molds[0].y + molds[0].h) && !molds[0].blockedSaid'));
run('for (const e of ents.slice()) removeEnt(e); { const mo = molds[0]; for (const i of mo.cavs[0]) setCell(i, COPPER, 30, F_CAST); for (let x = mo.x; x < mo.x + mo.w; x++) setCell((mo.y + mo.h) * W + x, STONE, 30, 0); } checkMolds();');
check('a new blocked spell warns again', run('EV.filter(e => e.t === "ingot_blocked").length === 2'));
@@ -145,9 +148,9 @@ run('molds[0].cavs[0].forEach((i, k) => setCell(i, k & 1 ? COPPER : IRON, 30, F_
check('mixed metal all drops as scrap without bars', under('SCRCU') === 14 && under('SCRFE') === 14 && run('ents.length === 0 && molds[0].state === "empty" && bagTotal === 0'));
ingot();
run('setCell(molds[0].cavs[0][0], SAND, 30, 0); for (let y = 92; y < 96; y++) for (let x = 120; x < 136; x++) setCell(y * W + x, STONE, 30, 0); checkMolds();');
check('blocked junk stays in the trough', cavCount(0, run('SAND')) === 1 && under('SAND') === 0);
check('blocked junk stays in the trough', cavCount(0, run('SAND')) === 1 && under('SAND') === 0 && run('molds[0].blocked === true'));
run('for (let y = 92; y < 96; y++) for (let x = 120; x < 136; x++) setCell(y * W + x, EMPTY, 30, 0); checkMolds();');
check('junk drops once there is room', cavCount(0, run('SAND')) === 0 && under('SAND') === 1);
check('junk drops once there is room', cavCount(0, run('SAND')) === 0 && under('SAND') === 1 && run('molds[0].blocked === false'));
ingot();
run('setCell(molds[0].cavs[0][0], SAND, 30, 0); setCell(molds[0].cavs[0][1], MCU, 1200, 0); checkMolds();');
check('cleaning waits for molten metal in the cavity', cavCount(0, run('SAND')) === 1 && under('SAND') === 0);
@@ -184,4 +187,12 @@ check('metal wall refund does not count cavity metal twice', run('bag[BARCU] ===
fresh();
run('addMold("bit", 30, 20, RSTONE, true); molds[0].cavs[0].slice(0, 20).forEach((i, k) => setCell(i, k & 1 ? IRON : STEEL, 30, F_CAST)); removeMold(molds[0]);');
check('compatible iron and steel return as iron bars and scrap', run('bag[BARFE] === 2 && bag[SCRFE] === 4 && bag[SCRST] === 0'));
for (const kind of ['bit', 'tank']) for (const metal of ['COPPER', 'IRON', 'GLASS']) for (const upgraded of [false, true]) {
fresh();
run(`addMold("${kind}", 30, 20, RSTONE, true); player.bitTier = player.tankTier = ${upgraded ? 3 : 0}; molds[0].cavs[0].forEach(i => setCell(i, ${metal}, 30, F_CAST)); checkMolds(); collectMold(molds[0]);`);
}
for (const state of ['empty', 'filling']) {
fresh(); run(`addMold("bit", 30, 20, RSTONE, true); molds[0].state = "${state}"; collectMold(molds[0]);`);
}
check('every collected mold message is short', run('moldMessages.every(s => s.length <= 90)'), run('moldMessages.join(" | ")'));
done();