local factory=dofile(SRC..'/bridge_probe.lua') local checks=0;local function C(v,m)assert(v,m);checks=checks+1 end local cfg={world='world1',session='session1',peer=1,n=13937,alive=true,no_manager=false,bad_array=false,extra_instance=false,wrong_world=false,missing_hex=false,bad_hex=false} local counts={world_units=0,world_entities=0,unit=0,hex=0,parent=0,sets=0} local entities,units,entity_set,entity_index,unit_set,unit_index={},{},{},{},{},{} local generic=newproxy(true);local target=newproxy(true) getmetatable(generic).__tostring=function()return 'IdString64-not-parseable'end getmetatable(target).__tostring=function()error('tostring must not be used as a converter')end local hash_generic='1111222233334444';local hash_target='c2d449ecf7facab1' for i=1,cfg.n do local e,u=newproxy(true),newproxy(true);entities[i]=e;units[i]=u entity_set[e]=true;entity_index[e]=i;unit_set[u]=true;unit_index[u]=i end local sr={Application={},Network={},World={},EntityManager={},UnitComponent={},TransformComponent={},Unit={},IdString64={}} sr.Application.main_world=function()return cfg.world end sr.Network.game_session=function()return cfg.session end sr.Network.peer_id=function()return cfg.peer end sr.World.units=function()counts.world_units=counts.world_units+1;error('d4 must not scan world units')end sr.World.entities=function(w) C(w==cfg.world);counts.world_entities=counts.world_entities+1 if cfg.bad_array then return {[1]=entities[1],[3]=entities[3]}end local out={};for i=1,cfg.n do out[i]=entities[i]end;return out end sr.EntityManager.alive=function(e)C(entity_set[e],'native number or invented Entity used');return cfg.alive end sr.EntityManager.unit_component=function(w)C(w==cfg.world);return not cfg.no_manager and 'UC'or nil end sr.EntityManager.transform_component=function(w)C(w==cfg.world);return 'TC'end sr.EntityManager.debug_name=function(e)C(entity_set[e]);return 'scene object'end sr.UnitComponent.instances=function(uc,e) C(uc=='UC'and entity_set[e]);if cfg.extra_instance then return 0,1 end;return 0 end sr.UnitComponent.unit=function(uc,e)C(uc=='UC'and entity_set[e]);counts.unit=counts.unit+1;return units[entity_index[e]]end sr.Unit.alive=function(u)C(unit_set[u]);return true end sr.Unit.world=function(u)C(unit_set[u]);return cfg.wrong_world and'foreign'or cfg.world end sr.Unit.resource_name=function(u)C(unit_set[u]);return unit_index[u]>=13935 and target or generic end sr.IdString64.to_hex=function(v) C(v==generic or v==target,'converter must receive original hash userdata');counts.hex=counts.hex+1 if cfg.bad_hex then return 'not a hex value'end return v==generic and hash_generic or '0x'..hash_target:upper() end sr.TransformComponent.instances=function(tc,e)C(tc=='TC'and entity_set[e]);return 0 end sr.TransformComponent.parent=function(tc,e) C(tc=='TC'and entity_set[e]);counts.parent=counts.parent+1 if entity_index[e]==13936 then return entities[13935]end return nil end local native={entity=415,goid=318,unit=4194837,resource=hash_target} local meta={mech_descriptors={native},candidate_descriptors={}} local function context()return {world=cfg.world,session=cfg.session,peer=cfg.peer}end local p=factory(sr);local now,prev,steps=0,0,0;local result while not result do steps=steps+1;C(steps<361,'13937 entities should not repeat d3 partial scan under fixture cost') result=p.step(context(),native,meta,now) local done=result and result.scanned or p.state.cursor-1 C(done-prev<=96,'work per normal HUD poll exceeds 96');prev=done;now=now+.25 end C(result.status=='COMPLETE_OBSERVATION_NOT_MAPPING',result.status) C(result.complete and result.scanned==13937 and result.remaining==0,'tail must be reached') C(result.errors==0 and #result.candidates==3,'userdata resources must match without tostring parsing') C(result.candidates[1].world_index==13935 and result.candidates[2].parent.world_index==13935,'parent relation observed from real opaque entities') C(result.candidates[2].parent.not_mech_ownership_proof,'must not claim cross-layer ownership') C(result.candidates[1].resource_hex==hash_target) C(result.candidates[1].resource_conversion=='IDSTRING64_TO_HEX') C(#result.samples<=20 and result.arms==nil and result.owners==nil) C(counts.world_units==0 and counts.world_entities==1) local before=counts.world_entities;C(p.step(context(),native,meta,now+100)==nil and counts.world_entities==before,'do not restart same finished scan') -- Function constructors with namespaced accessors are valid in this engine family. local real_hex=sr.IdString64;sr.IdString64=function()error('constructor should never run')end local mt=debug.getmetatable(sr.IdString64);debug.setmetatable(sr.IdString64,{__index={to_hex=real_hex.to_hex}}) cfg.n=10;p=factory(sr);local small=p.step(context(),native,meta,0) while not small do small=p.step(context(),native,meta,.25)end C(small.api.idstring_to_hex_available and small.resource_conversion_failures==0) debug.setmetatable(sr.IdString64,mt);sr.IdString64=real_hex -- A missing converter or malformed conversion is explicit evidence, not a guessed parser. sr.IdString64={};p=factory(sr);small=p.step(context(),native,meta,0) while not small do small=p.step(context(),native,meta,.25)end C(small.resource_conversion_failures==10 and #small.candidates==0) C(small.samples[1].resource_conversion=='TO_HEX_API_MISSING') sr.IdString64=real_hex;cfg.bad_hex=true;p=factory(sr);small=p.step(context(),native,meta,0) while not small do small=p.step(context(),native,meta,.25)end C(small.resource_conversion_failures==10);cfg.bad_hex=false cfg.no_manager=true;small=factory(sr).step(context(),native,meta,0);C(small.status=='NO_UNIT_COMPONENT_MANAGER');cfg.no_manager=false cfg.bad_array=true;small=factory(sr).step(context(),native,meta,0);C(small.status=='ENTITY_LIST_HOLES');cfg.bad_array=false cfg.extra_instance=true;before=counts.unit;p=factory(sr);small=p.step(context(),native,meta,0) while not small do small=p.step(context(),native,meta,.25)end C(small.status=='ENTITY_QUERY_ERRORS'and counts.unit==before,'ambiguous component returns must never enter Unit getter');cfg.extra_instance=false cfg.n=13937;p=factory(sr);p.step(context(),native,meta,0) local scanned=p.state.cursor-1;small=p.step(context(),native,meta,91) C(small.status=='TIME_BUDGET_NOT_RESTARTED'and small.scanned==scanned and not small.complete) before=counts.world_entities;C(p.step(context(),native,meta,200)==nil and counts.world_entities==before) p=factory(sr);local c=context();p.step(c,native,meta,0);cfg.world='world2';C(p.step(c,native,meta,1)==nil and p.state==nil,'stale world cleared');cfg.world='world1' p=factory(sr);p.step(context(),native,meta,0);p.reset();C(p.state==nil,'leave seat releases snapshot') local function short_probe(obj,t) local r=p.step(context(),obj,meta,t);while not r do t=t+.25;r=p.step(context(),obj,meta,t)end;return r end cfg.n=1;p=factory(sr) for i=1,3 do local d={entity=100+i,goid=200+i,unit=300+i,resource=hash_target};short_probe(d,i*10)end before=counts.world_entities;C(p.runs==3 and p.step(context(),native,meta,100)==nil and counts.world_entities==before) C(counts.sets==0) return {checks=checks,large_world_entities=13937,tail_candidates=3,completed_large_world=true,polls_for_large_world=steps,userdata_fixture=true,official_hex_converter_exercised=true,parent_edges_diagnostic_only=true,no_world_unit_scan=true,no_native_id_as_handle=true,no_in_game_calls=true,arms_fixed=false}