SOURCE / PINNED RELEASE
Made of little things.
Napcraft
- Release
- ee47ac6a25df…
- Author-recorded commit
- 410dea87e109…
- License
- LICENSE
- Author’s source reference
- nostr://npub182jczunncwe0jn6frpqwq3e0qjws7yqqnc3auccqv9nte2dnd63scjm4rf/wss%3A%2F%2Fgit.napplet.soy%2F/n-52f9e22f5ce
Archive hash verified: 9e6e0cabb18d0d46…. The source-to-build association is the author’s claim; it has not been independently rebuilt.
// Run after public-consent.mjs has closed both original browser processes.
import {chromium,executable} from './browser-support.mjs';
import {blockPoint} from './direct-building.mjs';
import {readFile,writeFile} from 'node:fs/promises';
import assert from 'node:assert/strict';
const previous=JSON.parse(await readFile('.napplet-space/public-consent-results.json','utf8'));
assert.ok(previous.passed,'Complete public consent verification first');
const browsers=[],players=[],checks=[];
const check=name=>{checks.push(name);console.log('PASS',name)};
const saved=(p,n)=>p.frame.waitForFunction(n=>document.querySelector('canvas').dataset.confirmedEdits===String(n)&&document.querySelector('#app').dataset.pending==='0',n,{timeout:60000});
async function join(touch=false){
const browser=await chromium.launch({executablePath:executable,headless:true,args:['--disable-background-timer-throttling','--disable-renderer-backgrounding']});browsers.push(browser);
const page=await browser.newPage({viewport:touch?{width:390,height:844}:{width:1200,height:900},hasTouch:touch});
await page.goto(previous.publication.snapshotUrl,{waitUntil:'domcontentloaded'});
await page.getByRole('button',{name:'Start Napcraft',exact:true}).click({timeout:45000});
// The phone's inline listing card is below the game's documented minimum
// height; use the host's visible full-player control, as a player would.
if(touch)await page.getByText('Open player',{exact:true}).click();
const frame=await(await page.locator('iframe[title="Napcraft"]').elementHandle()).contentFrame();
await frame.locator('#app[data-ready=true]').waitFor();await frame.locator('#join').click();await frame.locator('#code').fill(previous.code);await frame.locator('#confirmJoin').click();
const peer=page.getByRole('dialog',{name:'Allow multiplayer connections',exact:true});
await peer.getByRole('button',{name:'Allow',exact:true}).click({timeout:45000});
const p={page,frame};players.push(p);return p;
}
try {
const a=await join(),b=await join(true);
const baseline=Number(await a.frame.locator('canvas').getAttribute('data-confirmed-edits'));
assert.ok(baseline>=2,'Prior public edits remain');
await Promise.all(players.map(p=>saved(p,baseline)));check(`public world retains ${baseline} saved edits after all earlier browsers closed`);
await Promise.all(players.map(p=>p.frame.waitForFunction(()=>document.querySelector('canvas').dataset.peerCount==='1',null,{timeout:60000})));
check('fresh desktop and phone-sized touch browsers see each other');
// Choose distinct columns: two default Build buttons otherwise target the
// same initial cell and correctly coalesce one identical competing write.
await a.frame.locator('canvas').click({position:await blockPoint(a.frame,2,8),modifiers:['Shift']});
await b.frame.locator('canvas').tap({position:await blockPoint(b.frame,3,8)});
await a.frame.waitForFunction(()=>document.querySelector('canvas').dataset.selected==='2,8');
await b.frame.waitForFunction(()=>document.querySelector('canvas').dataset.selected==='3,8');
await Promise.all([a.frame.locator('#place').click(),b.frame.locator('#place').tap()]);
await Promise.all(players.map(p=>saved(p,baseline+2)));check('simultaneous desktop and touch edits both persist and converge');
await a.page.locator('iframe[title="Napcraft"]').screenshot({path:'.napplet-space/promotion/public-two-players.png'});
await b.page.locator('iframe[title="Napcraft"]').screenshot({path:'.napplet-space/promotion/public-phone.png'});
await Promise.all(browsers.map(b=>b.close()));
const returning=await join();await saved(returning,baseline+2);check('all confirmed edits survive another empty-room return');
await writeFile('.napplet-space/public-return-results.json',JSON.stringify({passed:true,checks,touchViewport:[390,844],baseline,savedEdits:baseline+2,publicBackend:previous.publication.snapshotUrl},null,2));
}catch(error){
for(const p of players)if(!p.page.isClosed())console.log('RETURN FAILURE',await p.frame.locator('body').innerText(),await p.frame.evaluate(()=>({...document.querySelector('canvas').dataset,pending:document.querySelector('#app').dataset.pending})));
await writeFile('.napplet-space/public-return-results.json',JSON.stringify({passed:false,checks,error:String(error)},null,2));throw error;
}finally{await Promise.all(browsers.map(b=>b.close()));}
