Cleats really hold and push their pockets (t42 feedback)

Nothing carries the load on a slope but the ribs: each belt step every
rib moves one face cell and pushes the grains in its way, the layer on
the belt is only dragged by friction that gravity beats on 45 degrees,
and heaped grains roll back. Ribs never pass through grains or into
machines; a run that can't push stalls. The foot of an uphill run
scoops the feed into pockets. Ribs drawn as rubber bars in both looks.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-26 20:56:51 -04:00
co-authored by Claude Opus 5.5
parent 3ee85429fd
commit 8cdc47fd33
12 changed files with 276 additions and 52 deletions
+20 -2
View File
@@ -32,7 +32,10 @@ for(const grade of [0,-1,1]) {
else {fresh();run('for(let bx=10;bx<32;bx++)placeBlock(BP_BELT,1,bx,24,true);');s={inlet:24};}
collect(s,220,true);
const r=collect(s,600,true);rates.push(r.out/10);
check(`grade ${grade} carries a generous feed at least 60 grains/s`,r.out>0 && r.out/10>=60,JSON.stringify(r));
// uphill pockets carry about as much as a flat belt; downhill, the top only feeds a layer two
// grains deep onto the face, which the ribs hold back to belt speed
const floor = grade > 0 ? 30 : 60;
check(`grade ${grade} carries a generous feed at least ${floor} grains/s`,r.out>0 && r.out/10>=floor,JSON.stringify(r));
const end=collect(s,600);
check(`grade ${grade} leaves no load stuck`,end.left===0,JSON.stringify(end));
}
@@ -141,7 +144,22 @@ for(const grade of [-1,1]) {
}
fresh();
run('placeBlock(BP_BELT_UP,1,20,32,true);');
check('pocket capacity is bounded by the real cleat height',run('Array.from({length:CLEAT_SPACING},(_,k)=>pocketDepth(80+k,32*BW+20)).every(d=>d>=0 && d<=CLEAT_REACH*2)'));
// The ribs hold the load: under a heavy feed no grain is ever inside a rib, and a grain on the bare
// face slides down until a rib stops it, then rides up with that rib.
{
const s=line(-1);
const inRib=run(`(()=>{let worst=0;for(let k=0;k<600;k++){for(let l=1;l<=12;l++){const i=(${s.inlet}*4-l)*W+44;if(mat[i]===EMPTY)setCell(i,SAND,20,0);}
simTick();let n=0;for(const c of cleatCells)if(PH[mat[c]]===PH_POWDER)n++;if(n>worst)worst=n;}return worst;})()`);
check('under a heavy feed no grain is ever inside a rib',inRib===0,inRib);
line(-1);
// a free face cell high on the run, halfway between two ribs
const g=run(`(()=>{for(let x=90;x<100;x++){const b=((32-((x>>2)-16))*BW)+(x>>2),y=beltFaceY(blockP[b],x>>2,32-((x>>2)-16),x);
let near=99;for(let h=0;h<CLEAT_SPACING;h++){if(cleatFoot(x-h,b)||cleatFoot(x+h,b)){near=h;break;}}
if(near>=3){setCell((y-1)*W+x,SAND,20,0);return x;}}return -1;})()`);
const path=run(`(()=>{const xs=[];for(let k=0;k<40;k++){simTick();for(let i=0;i<N;i++)if(mat[i]===SAND){xs.push(i%W);break;}}return xs;})()`);
check('a grain on the bare face slides back down to a rib',g>0 && Math.min(...path)<g,JSON.stringify([g,path.slice(0,12)]));
check('then rides up with its rib',path[path.length-1]>Math.min(...path),JSON.stringify(path.slice(-8)));
}
// A stationary cleat blocks downhill crossings; the bare face still lets grains slide.
for (const grade of [-1,1]) {
const s=line(grade);