Files
deepgrain-foundry/test/t_stalls.js
T

51 lines
4.1 KiB
JavaScript

// t45: finite carrying bed, local sustained jams, recovery, filters, screws and bars.
const fs=require('fs');
const {load,flatWorld,suite,ticks}=require('./harness');
const {run}=load(), {check,done}=suite();
function fresh(){flatWorld(run,256,224,208);run('RS=7;AMB.fill(20);temp.fill(20);weather.next=1e15;nextPowerBuild=0;for(const k of Object.keys(stats))stats[k]=0;');}
fresh();
run('placeBlock(BP_BELT,1,12,32,true);for(let l=1;l<=8;l++)setCell((128-l)*W+49,SAND,20,0);carryColumn(127*W+49,1,null);');
check('exactly four grains ride; the upper heap stays loose',run('Array.from({length:8},(_,k)=>mat[(127-k)*W+(k<4?50:49)]===SAND).every(Boolean)'));
check('stall tracking exists',run('typeof transportStalled==="function"'));
if(run('typeof transportStalled!=="function"')) {done();process.exit();}
for(const code of ['BP_BELT','BP_FILTER','BP_SCREW']) {
fresh();
run(`for(let bx=12;bx<20;bx++)placeBlock(${code},${code==='BP_FILTER'?128:1},bx,32,true,{m:[],inv:0});
for(let y=120;y<132;y++)for(let x=48;x<80;x++)if(mat[y*W+x]===EMPTY)setCell(y*W+x,SAND,20,0);
for(let y=110;y<136;y++)setCell(y*W+80,STONE,20,0);
placeBlock(BP_BELT,1,30,32,true);
for(let bx=19;bx<=30;bx++)placeBlock(BP_SHAFT,0,bx,34,true);
placeBlock(BP_SHAFT,0,19,33,true);placeBlock(BP_SHAFT,0,30,33,true);`);
ticks(run,10);
check(`${code}: a brief wait is not a stall`,run('!transportStalled(32*BW+19)'));
ticks(run,240);
check(`${code}: loaded blocked tail and upstream run warn`,run('transportStalled(32*BW+19)&&transportStalled(32*BW+15)'));
check(`${code}: an unrelated empty belt stays clear (same power net for belts/screws)`,run('!transportStalled(32*BW+30)') && (code==='BP_FILTER' || run('netId[128*W+60]===netId[128*W+120]')));
const clock=run('transportClock(32*BW+19)');ticks(run,20);
check(`${code}: animation clock freezes`,run('transportClock(32*BW+19)')===clock);
run('for(let y=110;y<136;y++)setCell(y*W+80,EMPTY,20,0);');ticks(run,30);
check(`${code}: clearing the blockage resumes motion`,run('!transportStalled(32*BW+19) && transportClock(32*BW+19)')>clock);
}
fresh();run('for(let bx=12;bx<40;bx++)placeBlock(BP_BELT,1,bx,32,true);spawnBar(BARCU,48,126,0,0);');
check('a steadily moving bar never reports a stall between whole-grain steps',run(`(()=>{for(let k=0;k<120;k++){simTick();if([...transportState.keys()].some(transportStalled))return false;}return ents[0].ix>90;})()`));
fresh();run('placeBlock(BP_BELT,1,12,32,true);placeBlock(BP_WALL,RSTONE,13,31,true);spawnBar(BARCU,48,126,0,0);');ticks(run,100);
check('a blocked bar also stalls its carrying belt',run('transportStalled(32*BW+12)'));
fresh();
run(`for(let k=0;k<8;k++)placeBlock(BP_BELT_UP,1,16+k,40-k,true);
for(let y=110;y<132;y++)for(let x=96;x<100;x++)setCell(y*W+x,STONE,20,0);
for(let y=110;y<166;y++)for(let x=56;x<96;x++)if(!part[y*W+x]&&mat[y*W+x]===EMPTY)setCell(y*W+x,SAND,20,0);`);
ticks(run,100);
check('a blocked cleat stops its whole slope run',run('Array.from({length:8},(_,k)=>transportStalled((40-k)*BW+16+k)).every(Boolean)'));
const phase=run('slopePhase[40*BW+16]'), slopeClock=run('transportClock(40*BW+16)');ticks(run,20);
check('stalled cleats and stripe clocks stay still together',run('slopePhase[40*BW+16]')===phase && run('transportClock(40*BW+16)')===slopeClock);
fresh();
run(`for(let k=0;k<8;k++)placeBlock(BP_FILTER_DOWN,128,16+k,24+k,true,{m:[],inv:0});
for(let y=100;y<140;y++)setCell(y*W+96,STONE,20,0);
for(let x=64;x<96;x++){const by=24+(x>>2)-16,y=beltFaceY(BP_FILTER_DOWN,x>>2,by,x);for(let l=1;l<=4;l++)setCell((y-l)*W+x,SAND,20,0);}`);
ticks(run,300);
check('a jammed downhill screen warns on its slower nudge cadence',run('transportStalled(31*BW+23)'));
fresh();run(fs.readFileSync(__dirname+'/fixtures/t45-loop.js','utf8'));ticks(run,1800);
console.log('Overloaded loop: '+run('JSON.stringify({moved:stats.moved,grains:mat.reduce((n,m)=>n+(m===SAND||m===CUORE),0),flyers:flyers.length,stalled:[...transportState].filter(([b,s])=>s.age>=STALL_TICKS).length})'));
check('overloaded loop conserves its 832 grains',run('mat.reduce((n,m)=>n+(m===SAND||m===CUORE),0)+flyers.length')===832);
done();