"""Headless browser run: load the page, start a world, play a little, take screenshots.""" import sys, time, pathlib from playwright.sync_api import sync_playwright root = pathlib.Path(__file__).resolve().parent.parent out = pathlib.Path(sys.argv[1] if len(sys.argv) > 1 else root / 'shots' / 'playthrough') out.mkdir(parents=True, exist_ok=True) url = (root / 'dist' / 'index.html').as_uri() with sync_playwright() as p: b = p.chromium.launch(args=['--autoplay-policy=no-user-gesture-required']) pg = b.new_page(viewport={'width': 1440, 'height': 860}) logs = [] pg.on('console', lambda m: logs.append(f'{m.type}: {m.text}')) pg.on('pageerror', lambda e: logs.append(f'PAGEERROR: {e}')) pg.goto(url) pg.wait_for_timeout(800) pg.screenshot(path=str(out / '01-title.png')) pg.click('#btn-new') pg.fill('#nw-seed', '424242') pg.click('#btn-generate') pg.wait_for_function('GAME.running === true', timeout=20000) pg.wait_for_timeout(1500) pg.screenshot(path=str(out / '02-spawn.png')) # dig straight down for a while pg.mouse.move(720, 560) pg.mouse.down() pg.keyboard.down('s') pg.wait_for_timeout(2500) pg.keyboard.up('s') pg.mouse.up() pg.wait_for_timeout(400) pg.screenshot(path=str(out / '03-digging.png')) print('bag', pg.evaluate('bagTotal'), pg.evaluate('JSON.stringify(BAG_ORDER.filter(m=>bag[m]>0).map(m=>[MD[m].name,bag[m]]))')) # build a coal fire scenario directly through the core API near the bot, then ignite with the tool pg.evaluate('''() => { const bx = Math.floor(bot.x)+12, by = Math.floor(bot.y)+3; bag[COAL] += 300; bag[CUORE] += 120; bag[STONE] += 400; bagTotal += 820; for (let y=by-14; y<=by+6; y++) for (let x=bx-2; x<=bx+26; x++) setCell(y*W+x, EMPTY, AMB[y], 0); for (let y=by-12; y<=by+6; y++) { setCell(y*W+bx-2, STONE, AMB[y], 0); setCell(y*W+bx-1, STONE, AMB[y], 0); setCell(y*W+bx+25, STONE, AMB[y], 0); setCell(y*W+bx+26, STONE, AMB[y], 0); } for (let x=bx-2; x<=bx+26; x++) { if (x < bx+11 || x > bx+13) { setCell((by-12)*W+x, STONE, AMB[by-12], 0); setCell((by-13)*W+x, STONE, AMB[by-13], 0);} setCell((by+6)*W+x, STONE, AMB[by+6], 0); } const r = mulberry32(4); for (let y=by-4; y<=by+5; y++) for (let x=bx; x<=bx+24; x++) setCell(y*W+x, r()<0.3 ? CUORE : COAL, AMB[y], 0); for (let k=0;k<50;k++){ toolIgnite(bx+3, by-5); toolIgnite(bx+20, by-5); simTick(); } window.__fx = {bx, by}; }''') pg.wait_for_timeout(9000) pg.screenshot(path=str(out / '04-furnace.png')) pg.keyboard.press('h') pg.wait_for_timeout(300) pg.screenshot(path=str(out / '05-lens.png')) pg.keyboard.press('h') pg.keyboard.press('3') pg.wait_for_timeout(200) pg.screenshot(path=str(out / '06-parts.png')) pg.keyboard.press('n') pg.wait_for_timeout(300) pg.screenshot(path=str(out / '07-notebook.png')) pg.keyboard.press('Escape') pg.keyboard.press('Escape') pg.wait_for_timeout(200) pg.click('#pm-settings') pg.wait_for_timeout(200) pg.screenshot(path=str(out / '08-settings.png')) perf = pg.evaluate('JSON.stringify({frameMs, simMs, fps: fpsSm, view: [R.bw, R.bh]})') print('perf', perf) print('molten copper', pg.evaluate('(()=>{let n=0,c=0;for(let i=0;i