Files
deepgrain-foundry/test/t_vacuum_collapse.py
T

59 lines
3.0 KiB
Python

"""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')