SOURCE / PINNED RELEASE
Made of little things.
Crossfire
- Release
- 9614abe48623…
- Author-recorded commit
- 6f6c8299e2fb…
- License
- LICENSE
- Author’s source reference
- nostr://npub1n8ga89w8h6tvwamxusfyzexw8gjy84yxu9rxgnmk955cxtml4ujswzxydd/wss%3A%2F%2Fgit.napplet.soy%2F/n-347ab685aef
Archive hash verified: 34d5295141b419db…. The source-to-build association is the author’s claim; it has not been independently rebuilt.
import test from 'node:test';
import assert from 'node:assert/strict';
import fs from 'node:fs';
import ts from 'typescript';
import vm from 'node:vm';
const module={exports:{}};
vm.runInNewContext(ts.transpileModule(fs.readFileSync(new URL('../src/game.ts',import.meta.url),'utf8'),{compilerOptions:{module:ts.ModuleKind.CommonJS,target:ts.ScriptTarget.ES2022}}).outputText,{module,exports:module.exports});
const {createWorld,step,idle,validInput,validWorld}=module.exports;
test('eight players stay bounded and normalized diagonal movement is fair',()=>{const s=createWorld(Array.from({length:8},(_,i)=>String(i)));assert.equal(s.p.length,8);const p=s.p[0];const x=p.x,y=p.y;step(s,[{x:1,y:1,a:0,fire:false}],1/60);assert.ok(Math.abs(Math.hypot(p.x-x,p.y-y)-220/60)<.001);for(let i=0;i<600;i++)step(s,Array.from({length:8},()=>({x:-1,y:-1,a:0,fire:false})),1/60);assert.ok(s.p.every(p=>p.x>=15&&p.y>=15));assert.equal(validWorld(s),true);});
test('bullets hit any opponent, eliminate, score and respawn',()=>{const s=createWorld(['a','b','c']);s.p[0].x=80;s.p[0].y=320;s.p[1].x=900;s.p[1].y=600;s.p[2].x=180;s.p[2].y=320;for(const p of s.p)p.shield=0;const u=[{x:0,y:0,a:0,fire:true},idle(),idle()];for(let i=0;i<60;i++)step(s,u,1/60);assert.equal(s.p[0].score,1);assert.ok(s.p[2].dead>0);assert.equal(s.p[2].hp,0);for(let i=0;i<150;i++)step(s,[idle(),idle(),idle()],1/60);assert.equal(s.p[2].hp,100);assert.equal(s.p[2].dead,0);});
test('cover blocks projectiles and absent players cannot be hit',()=>{const s=createWorld();s.p[0].x=350;s.p[0].y=320;s.p[1].x=620;s.p[1].y=320;s.p[1].shield=0;for(let i=0;i<240;i++)step(s,[{...idle(),fire:true},idle()],1/60);assert.equal(s.p[1].hp,100);});
test('reject malformed and oversized peer data',()=>{for(const v of [null,{},[],{x:Infinity,y:0,a:0,fire:true},{x:10,y:0,a:0,fire:true}])assert.equal(validInput(v),false);assert.equal(validInput(idle()),true);for(const v of [null,{}, {p:[],b:[],winner:-1}, {...createWorld(),b:Array(65).fill({})}])assert.equal(validWorld(v),false);assert.equal(validWorld(createWorld()),true);});
test('seventh elimination ends the round and freezes simulation',()=>{const s=createWorld();s.p[0].x=80;s.p[0].y=320;s.p[0].score=6;s.p[1].x=180;s.p[1].y=320;s.p[1].shield=0;for(let i=0;i<80;i++)step(s,[{...idle(),fire:true},idle()],1/60);assert.equal(s.winner,0);assert.equal(s.p[0].score,7);const x=s.p[0].x;step(s,[{...idle(),x:1},idle()],1/60);assert.equal(s.p[0].x,x);});
test('player labels accept bounded names and reject oversized or non-text payloads',()=>{const s=createWorld();s.p[0].name='Alice';assert.equal(validWorld(s),true);s.p[0].name='x'.repeat(33);assert.equal(validWorld(s),false);s.p[0].name={name:'Alice'};assert.equal(validWorld(s),false);});