local Mount=load('mount_policy') local Ref=factory(sr);local runtime=load('spatial_runtime')(sr,N,Z,policy,Ref,Mount) local mounts={};local mount_calls=0 local function names(d) local socket=d.resource=='79e4b3d2da5e45e3'or d.resource=='35dbf54f016f3624' return {L=socket and 'attach_turret_l_socket'or'attach_turret_l',R=socket and 'attach_turret_r_socket'or'attach_turret_r'} end local function scene(gap) for k,d in ipairs(FIXTURE.mechs)do local x=(k-1)*gap;poses[d.entity]={x,0,0};mounts[d.entity]={L={x-1,0,3},R={x+1,0,3}} poses[FIXTURE.arms[(k-1)*2+1].entity]={x-1,0,3};poses[FIXTURE.arms[(k-1)*2+2].entity]={x+1,0,3} end end sr.Unit.num_scene_graph_items=function(u)actual(u);return 198 end sr.Unit.has_node=function(u,name) local d=actual(u).descriptor if name=='StingrayEntityRoot'then return not ctl.no_root end mount_calls=mount_calls+1 if not d or not Z.models[d.resource]then return false end local n=names(d);return not ctl.no_mount and (name==n.L or name==n.R) end sr.Unit.node=function(u,name) local d=actual(u).descriptor;if name=='StingrayEntityRoot'then return 1 end local n=names(d);C(name==n.L or name==n.R) if ctl.invalid_mount_index then return -1 end return name==n.L and (ctl.changed_mount_index and 54 or 53)or 87 end sr.Unit.world_position=function(u,index) local d=actual(u).descriptor if index==1 then return poses[d.entity]end C(index==53 or index==54 or index==87,'no hardcoded serialized node indices') if ctl.invalid_mount_position then return {0/0,0,0}end return mounts[d.entity][index==87 and 'R'or'L'] end local real_clock=os.clock;os.clock=function()return 0 end scene(4) case('fresh close scene resolves actual indexed arm units using named mount API, with no far history',function() local result,why,detail,stable for i=1,28 do time=time+.25;result,why,detail,stable=runtime.resolve(FIXTURE.mechs[1],metadata(),ctx())end C(result and #result==2 and why=='SPATIAL_HEURISTIC',tostring(detail.error)) C(detail.root_reason=='SPATIAL_COMPETING_MECH'and detail.match_method=='MOUNT_POINT_TEST') C(#detail.mount_nodes==6 and detail.mount_nodes[1].node==53 and stable()) C(result[1].entity==FIXTURE.arms[1].entity and result[2].entity==FIXTURE.arms[2].entity) end) case('all three close driving targets select their own distinct descriptors',function() for k=1,3 do ctl.current=k;local result,_,detail,stable=runtime.resolve(FIXTURE.mechs[k],metadata(),ctx()) C(result and #result==2 and stable(),tostring(detail.error));C(result[1].entity==FIXTURE.arms[k*2-1].entity and result[2].entity==FIXTURE.arms[k*2].entity) end;ctl.current=1 end) local function refused(code) local r,why,d=runtime.resolve(FIXTURE.mechs[1],metadata(),ctx());C(not r and why=='SPATIAL_UNAVAILABLE'and d.error==code,tostring(d.error));return d end case('missing mount, invalid API index, invalid coordinate, config opt-out are fail closed',function() ctl.no_mount=true;local d=refused('MOUNT_NAMED_NODE_MISSING');C(d.mount_check.exists==false);ctl.no_mount=false ctl.invalid_mount_index=true;refused('MOUNT_NODE_INDEX_INVALID');ctl.invalid_mount_index=false ctl.invalid_mount_position=true;refused('MOUNT_POSITION_INVALID');ctl.invalid_mount_position=false local c=ctx();c.allow_mounts=false;local calls=mount_calls;local r,why=runtime.resolve(FIXTURE.mechs[1],metadata(),c);C(not r and why=='SPATIAL_COMPETING_MECH'and mount_calls==calls) end) case('post-health mount node, position, candidate, resource and seat changes reject publication',function() local _,_,_,stable=runtime.resolve(FIXTURE.mechs[1],metadata(),ctx());ctl.changed_mount_index=true;local ok,why=stable();C(not ok and why=='MOUNT_NODE_CHANGED');ctl.changed_mount_index=false local _,_,_,stable=runtime.resolve(FIXTURE.mechs[1],metadata(),ctx());local old=mounts[FIXTURE.mechs[1].entity].L;mounts[FIXTURE.mechs[1].entity].L={old[1]+1,old[2],old[3]};local ok,why=stable();C(not ok and why=='MOUNT_MOVED_DURING_SAMPLE');mounts[FIXTURE.mechs[1].entity].L=old local _,_,_,stable=runtime.resolve(FIXTURE.mechs[1],metadata(),ctx());mounts[FIXTURE.mechs[1].entity].L={old[1]+.4,old[2],old[3]};local ok,why=stable();C(not ok and why=='SPATIAL_SELECTION_CHANGED',why);mounts[FIXTURE.mechs[1].entity].L=old local _,_,_,stable=runtime.resolve(FIXTURE.mechs[1],metadata(),ctx());ctl.wrong_resource=true;local ok,why=stable();C(not ok and why=='REF_UNIT_RESOURCE_MISMATCH');ctl.wrong_resource=false local _,_,_,stable=runtime.resolve(FIXTURE.mechs[1],metadata(),ctx());ctl.current=2;local ok,why=stable();C(not ok and why=='SPATIAL_SEAT_CHANGED');ctl.current=1 end) case('mount path retains context, existence, liveness and native graph revalidation',function() for _,change in ipairs({{'alive',false},{'exists',false},{'graph_valid',false},{'peer',2},{'session','changed'},{'world','changed'}})do local r,_,_,stable=runtime.resolve(FIXTURE.mechs[1],metadata(),ctx());C(r and stable) local old=ctl[change[1]];ctl[change[1]]=change[2];C(not stable(),change[1]);ctl[change[1]]=old end end) case('overlapping same-resource mounts are rejected; far path never calls mount APIs',function() scene(0);local r,why=runtime.resolve(FIXTURE.mechs[1],metadata(),ctx());C(not r and (why=='MOUNT_COMPETING_ARM'or why=='MOUNT_COMPETING_SLOT'),why) scene(30);ctl.no_mount=true;local calls=mount_calls;local r,_,d,stable=runtime.resolve(FIXTURE.mechs[1],metadata(),ctx());C(r and d.match_method=='BODY_ROOT_MARGIN'and stable()and mount_calls==calls);ctl.no_mount=false;scene(4) end) case('full HUD: close-start warmup, distinct HP switching, walking, overlap and restored display',function() Ref=factory(sr);runtime=load('spatial_runtime')(sr,N,Z,policy,Ref,Mount) sr.GameSession.in_session=function()return true end;sr.GameSession.objects_owned_by=function()return {10}end sr.GameSession.game_object_is_type=function()return true end;sr.GameSession.game_object_field=function()return 20 end sr.Gui.resolution=function()return 1920,1080 end local Reader={sample=function() if not ctl.seated then return nil,'EMPTY','NOT_SEATED'end local d=FIXTURE.mechs[ctl.current];return {vehicle=d,model=Z.models[d.resource],hull=1800,hull_max=1800,hull_valid=true,zones={}} end} local Arm={discover=function()return {},'AMBIGUOUS',metadata()end,read=function(g,d) for i,v in ipairs(FIXTURE.arms)do if N.same(v,d)then return {descriptor=d,hp=hp[i],main=hp[i],max=800,valid=true,side=Z.side_by_resource[d.resource],source='main',zones={}}end end error('wrong arm')end,verify=function()return ctl.roster end} local D={mode='MECH',clear=function()end,reset=function()end,ensure=function()return true end,draw=function(w,h,v)_G.MOUNT_VIEW=v end} CowboyBingusModLoader={api=1};update=function()return 'old',nil,7 end local S=load('hud')(sr,N,Reader,function()return{}end,Z,function()return {debug=true,poll=.25,spatial=true,tagged_ref=true,mount_match=true}end,{},function()return D end,Arm,load('json'),runtime) local function tick(n)for i=1,n or 1 do local a,b,c=update(.25);C(a=='old'and b==nil and c==7)end end local function shown(k) C(S.arms and #S.arms==2,'expected mounted arms');C(S.arms[1].hp==hp[k*2-1]and S.arms[2].hp==hp[k*2],'wrong mech HP');C(S.arm_association=='SPATIAL_HEURISTIC'and MOUNT_VIEW.arm_association=='SPATIAL_HEURISTIC') end tick(29);C(not S.arms);tick();shown(1) for _,gap in ipairs({3,2,1,2,4,8,12,8,4})do scene(gap);tick();shown(1)end for k=2,3 do ctl.current=k;tick();C(not S.arms);tick(2);shown(k)end ctl.seated=false;tick();C(not S.arms and not S.rows);ctl.seated=true;tick(3);shown(3) scene(0);tick();C(not S.arms and S.rows);scene(4);tick(6);shown(3) ctl.roster=false;tick();C(not S.arms);ctl.roster=true;tick(3);shown(3) _G.MOUNT_HUD_RESULT={close_start=true,mode_transition_no_blanket_hide=true,distinct_hp=true,walking_hidden=true,overlap_refused=true,roster_guard=true} end) os.clock=real_clock return {cases=cases,checks=checks,hud=MOUNT_HUD_RESULT,mount_api_calls_mocked=mount_calls,real_engine_calls=0,live_mount_fit_verified=false}