SOURCE / PINNED RELEASE
Made of little things.
Outbreak: Soycoon City
- Release
- db7750b1d009…
- Author-recorded commit
- 3ee3f5fd27a6…
- License
- LICENSE
- Author’s source reference
- nostr://npub182jczunncwe0jn6frpqwq3e0qjws7yqqnc3auccqv9nte2dnd63scjm4rf/wss%3A%2F%2Fgit.napplet.soy%2F/n-b87c04571a9
Archive hash verified: dbebdc772b142a1c…. The source-to-build association is the author’s claim; it has not been independently rebuilt.
import { createRequire } from 'node:module';
import { realpath, readFile } from 'node:fs/promises';
import { execFileSync } from 'node:child_process';
import assert from 'node:assert/strict';
const url=process.env.SOYINDENT_PREVIEW_URL;
if(!url)throw new Error('Start soyli dev and set SOYINDENT_PREVIEW_URL to its printed URL.');
const require=createRequire(await realpath(new URL('../node_modules/@napplet/conformance-cli/package.json',import.meta.url)));
const {chromium}=require('playwright');
const profile=JSON.parse(execFileSync('soyli',['browser','path','--json'],{encoding:'utf8'}));
const executablePath=profile.executables.find(e=>e.name==='chromium-headless-shell'&&e.installed)?.path;
const fingerprint=bytes=>{let hash=2166136261;for(const byte of bytes)hash=Math.imul(hash^byte,16777619);return hash>>>0;};
const manifest=JSON.parse(await readFile('sounds/runtime.json','utf8')),names={};
const clipCount=manifest.sounds.reduce((count,sound)=>count+sound.files.length,0);
for(const sound of manifest.sounds)for(const file of sound.files){const key=fingerprint(await readFile(file.path));assert(!names[key]);names[key]=sound.id;}
const browser=await chromium.launch({executablePath,headless:true,args:['--enable-webgl','--use-gl=angle','--use-angle=swiftshader']});
const errors=[],page=await browser.newPage({viewport:{width:1200,height:900}});page.on('pageerror',e=>errors.push(e.message));
try{
await page.goto(url);const f=page.frameLocator('iframe');await f.locator('#scene canvas').waitFor();
await f.locator('body').evaluate((_,names)=>{
// Observe the real native signal path without replacing browser decoding or activation.
const probe=window.__audioProbe={decoded:0,starts:[],scheduled:[],active:new Set(),buffers:new Map(),context:null,analyser:null};
const Native=window.AudioContext;
window.AudioContext=class extends Native{
constructor(...args){super(...args);probe.context=this;}
async decodeAudioData(bytes){let hash=2166136261;for(const byte of new Uint8Array(bytes))hash=Math.imul(hash^byte,16777619);const id=names[hash>>>0];if(!id)throw Error('Unknown embedded audio');const buffer=await super.decodeAudioData(bytes);probe.buffers.set(buffer,id);probe.decoded++;return buffer;}
createDynamicsCompressor(){const node=super.createDynamicsCompressor(),nativeConnect=node.connect;node.connect=(destination,...args)=>{const analyser=this.createAnalyser();analyser.fftSize=2048;probe.analyser=analyser;Reflect.apply(nativeConnect,node,[analyser]);analyser.connect(destination,...args);return destination;};return node;}
createBufferSource(){const source=super.createBufferSource(),start=source.start.bind(source),stop=source.stop.bind(source);source.start=(...args)=>{const id=probe.buffers.get(source.buffer);probe.starts.push(id);probe.scheduled.push({id,when:args[0]??this.currentTime,buffer:source.buffer});probe.active.add(source);const ended=source.onended;source.onended=event=>{probe.active.delete(source);ended?.call(source,event);};return start(...args);};source.stop=(...args)=>{probe.active.delete(source);return stop(...args);};return source;}
};
},names);
const state=()=>f.locator('body').evaluate(()=>{const p=window.__audioProbe,data=new Float32Array(2048);p.analyser?.getFloatTimeDomainData(data);return {decoded:p.decoded,starts:p.starts,active:[...p.active].map(s=>p.buffers.get(s.buffer)),state:p.context?.state,peak:Math.max(...data.map(Math.abs))};});
assert.equal((await state()).state,undefined);
await f.locator('#startButton').click();await f.locator('#soundButton').filter({hasText:'Sound on'}).waitFor();
for(let i=0;i<100&&(await state()).decoded!==clipCount;i++)await page.waitForTimeout(50);
assert.equal((await state()).decoded,clipCount);assert.equal((await state()).state,'running');assert((await state()).active.includes('music_patrol'));
await page.keyboard.press('Space');
let signal=0;for(let i=0;i<20;i++){signal=Math.max(signal,(await state()).peak);if(signal>.0001)break;await page.waitForTimeout(30);}
assert(signal>.0001,'Real output signal must be nonzero');assert((await state()).starts.includes('shotgun_fire'));
const sequence=await f.locator('body').evaluate(()=>window.__audioProbe.scheduled.filter(s=>s.id.startsWith('shotgun_')).map(({id,when})=>({id,when})));
assert.deepEqual(sequence.map(s=>s.id),['shotgun_fire','shotgun_pump']);
assert(Math.abs(sequence[1].when-sequence[0].when-.25)<.02,'The pump must be scheduled 250 ms after the blast');
await page.keyboard.press('KeyR');await f.locator('#ammoCount').filter({hasText:'06'}).waitFor();
for(const id of ['reload_start','reload_shell','reload_finish'])assert((await state()).starts.includes(id));
const musicStarts=(await state()).starts.filter(id=>id==='music_patrol').length;
await page.keyboard.down('KeyW');await f.locator('#cameraLabel').filter({hasText:'02'}).waitFor();await page.keyboard.up('KeyW');
assert((await state()).starts.includes('footstep_stone'));assert.equal((await state()).starts.filter(id=>id==='music_patrol').length,musicStarts);
await f.locator('#soundButton').click();assert.equal(await f.locator('#soundButton').innerText(),'Sound off');assert.equal((await state()).active.length,0);
await f.locator('#soundButton').click();assert((await state()).active.includes('music_patrol'));
await page.keyboard.press('Escape');assert.equal((await state()).active.length,0);await f.locator('#startButton').click();assert((await state()).active.includes('music_patrol'));
await f.locator('#helpButton').click();assert.equal((await state()).active.length,0);await f.locator('#closeHelp').click();await f.locator('#startButton').click();
await f.locator('#editorTab').click();assert.equal((await state()).active.length,0);
await f.locator('summary').filter({hasText:'Map JSON'}).click();await f.locator('#showJson').click();const stage=JSON.parse(await f.locator('#mapJson').inputValue());stage.rooms[0].spawn={x:4.3,z:2.9};
await f.locator('#mapJson').fill(JSON.stringify(stage));await f.locator('#applyJson').click();await f.locator('#testMap').click();
const before=(await state()).starts.filter(id=>id==='music_patrol').length;
await page.keyboard.press('KeyE');await f.locator('#roomTitle').filter({hasText:'Records Corridor'}).waitFor();assert((await state()).active.includes('ambient_corridor'));
assert.equal((await state()).starts.filter(id=>id==='music_patrol').length,before);
await page.keyboard.press('KeyE');assert(!(await state()).active.includes('ambient_corridor'));
await f.locator('body').evaluate(()=>{delete window.napplet.media;delete window.napplet.theme;window.dispatchEvent(new Event('blur'));});assert.equal((await state()).active.length,0);
await f.locator('#startButton').click();assert((await state()).active.includes('music_patrol'));
await f.locator('body').evaluate(()=>window.dispatchEvent(new Event('pagehide')));assert.equal((await state()).state,'closed');assert.equal((await state()).active.length,0);
console.log(`PASS real MP3 decoding (${clipCount} clips), native activation, nonzero output (${signal.toFixed(5)} peak), shot/pump timing, reloads/steps, camera continuity, ambience, mute, pause/help/editor/blur and teardown`);
const context=await browser.newContext({viewport:{width:390,height:844},hasTouch:true,isMobile:true,deviceScaleFactor:1});
try{const touch=await context.newPage();touch.on('pageerror',e=>errors.push(e.message));await touch.goto(url);const tf=touch.frameLocator('iframe');await tf.locator('#startButton').tap();await tf.locator('#soundButton').filter({hasText:'Sound on'}).waitFor();await tf.locator('#soundButton').tap();assert.equal(await tf.locator('#soundButton').innerText(),'Sound off');await tf.locator('#soundButton').tap();assert.equal(await tf.locator('#soundButton').innerText(),'Sound on');console.log('PASS touch activation and mute/unmute');}finally{await context.close();}
assert.deepEqual(errors,[]);
}finally{await browser.close();}
