Faces cut into loose piles collapse outward instead of draining column by column (t93)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,58 @@
|
||||
"""Vacuum cuts in the real pixel frame loop with active browser workers and hardware graphics."""
|
||||
import pathlib
|
||||
import sys
|
||||
sys.path.insert(0, str(pathlib.Path(__file__).resolve().parents[1] / 'tools'))
|
||||
from use_venv import ensure_playwright; ensure_playwright()
|
||||
from browser import launch, consume_gpu_option, capabilities
|
||||
consume_gpu_option()
|
||||
ROOT = pathlib.Path(__file__).resolve().parents[1]
|
||||
with launch(viewport={'width': 1440, 'height': 760}) as (_, page, url):
|
||||
errors = []
|
||||
page.on('pageerror', lambda e: errors.append(str(e)))
|
||||
page.goto(url)
|
||||
caps = capabilities(page)
|
||||
assert caps['isolated'] and caps['webgpu'], caps
|
||||
print('GPU', caps, flush=True)
|
||||
page.evaluate("""() => {
|
||||
const enter = enterGame; enterGame = function() { enter(); GAME.paused = true; };
|
||||
SET.workerCap=2; SET.fog=false; SET.lighting='off'; SET.cameraLead=false; SET.autosave=0;
|
||||
startNewWorld(7,768,600);
|
||||
}""")
|
||||
page.wait_for_function('GAME.running', timeout=60000)
|
||||
page.evaluate((ROOT / 'test/pile-cut.js').read_text())
|
||||
page.evaluate("""() => {
|
||||
pileCutWorld(); pileCutSetup(160,false); pileCutSetup(416,true);
|
||||
bot.x=700;bot.y=100;for(let k=0;k<600;k++)simTick();
|
||||
renderDirty.fill(1);GPU.world=null;SM.surf=-1;
|
||||
}""")
|
||||
page.evaluate('startThreads()')
|
||||
page.evaluate("""() => {
|
||||
// Tiny isolated fixtures otherwise run inline below the production dispatch threshold.
|
||||
simPool.force=true;
|
||||
window.cutTicks=0;window.cutEnd=0;
|
||||
const tool=toolTick;toolTick=()=>{
|
||||
tool();
|
||||
if(cutEnd && tick===cutEnd+180) window.cutResult={tick,cutEnd,
|
||||
stone:pileCutProfile(160),mixed:pileCutProfile(416),helpers:simPool.activeMax};
|
||||
if(cutTicks<140){pileCutStroke(cutTicks%2?416:160);cutTicks++;if(cutTicks===140)cutEnd=tick+1;}
|
||||
};
|
||||
document.querySelectorAll('.card,.toast').forEach(e=>e.remove());
|
||||
$('hud').hidden=true;GAME.hidePreviews=true;SET.zoom=3;resizeRender();
|
||||
bot.x=288-bot.w/2;bot.y=190-bot.h/2;snapCamera();
|
||||
// Keep both heaps in view while the bot follows each vacuum stroke.
|
||||
updateCamera=()=>{}; GAME.paused=false;
|
||||
}""")
|
||||
page.wait_for_function('cutEnd>0', timeout=30000)
|
||||
for delay in (0, 60, 120, 180):
|
||||
page.wait_for_function(f'tick>=cutEnd+{delay}', timeout=15000)
|
||||
result = page.evaluate('({tick,cutEnd,stone:pileCutProfile(160),mixed:pileCutProfile(416),helpers:simPool.activeMax})')
|
||||
print('profile', delay, result, flush=True)
|
||||
page.screenshot(path=str(ROOT / f'shots/t93b-time-{delay}.png'))
|
||||
page.wait_for_function('window.cutResult', timeout=15000)
|
||||
result = page.evaluate('cutResult')
|
||||
page.evaluate('GAME.paused=true')
|
||||
page.screenshot(path=str(ROOT / 'shots/t93b-after.png'))
|
||||
assert result['helpers'] > 0, result
|
||||
assert result['stone']['cliff'] <= 2 and result['mixed']['cliff'] <= 2, result
|
||||
assert not errors, errors
|
||||
print('PASS vacuum-cut stone and mixed faces slump within 180 real-loop ticks with browser helpers')
|
||||
Reference in New Issue
Block a user