-- TEST bridge: documented Stingray tagged UnitReference representation. -- Source: niklasfrykholm/stingray-engine-code-walkthrough, 21-lua.md. -- Only inspect scalar values of actual World.units results. No dereference, -- no native-ID -> Unit cast, no tostring parsing, no high-bit truncation. return function(sr) local M={state=nil,failed=nil,next_scan=0,scans=0} local ffi_ok,ffi=pcall(require,'ffi') local function get(ns,k)local ok,v=pcall(function()return sr[ns]and sr[ns][k]end);return ok and type(v)=='function'and v or nil end local function integer(n,hi)return type(n)=='number'and n==n and n%1==0 and n>=0 and n<=hi end local function need(ns,k)local f=get(ns,k);if not f then error('REF_API_MISSING:'..ns..'.'..k,0)end;return f end local function normalize(s) if type(s)~='string'then return nil end if s:sub(1,2):lower()=='0x'then s=s:sub(3)end if #s~=16 or s:find('[^%x]')then return nil end;return s:lower() end function M.decode(u) if not ffi_ok or not ffi or not ffi.abi('64bit')then return nil,'FFI_64BIT_UNAVAILABLE'end if type(u)~='userdata'then return nil,'NOT_ENGINE_USERDATA'end local ok,raw=pcall(function()return tonumber(ffi.cast('uintptr_t',u))end) if not ok then return nil,'SCALAR_CONVERSION_UNAVAILABLE'end -- Documented low tag 01 means Unit, 10 Entity; 00 ordinary pointer. -- Keep ALL remaining bits: do not coerce a pointer to uint32_t. if not integer(raw,17179869181)then return nil,'SCALAR_OUTSIDE_UNITREF32'end if raw%4~=1 then return nil,'NOT_UNIT_REFERENCE_TAG'end local ref=(raw-1)/4 if ref==0 or ref==4294967295 then return nil,'INVALID_UNIT_REFERENCE'end return ref,raw end local function same(a,c)return a and a.world==c.world and a.session==c.session and a.peer==c.peer end local function scope(c) if need('Application','main_world')()~=c.world or need('Network','game_session')()~=c.session or need('Network','peer_id')()~=c.peer then error('REF_CONTEXT_CHANGED',0)end end local function info(st) local r={method='TAGGED_UNITREF32_TEST',source_contract='stingray-walkthrough-21-lua',scans=M.scans,identity_contract_in_hd2='RUNTIME_CROSSCHECK_REQUIRED'} if st then r.enumerated=st.count;r.scanned=st.cursor-1;r.tagged=st.tagged;r.rejected=st.rejected;r.complete=st.complete==true;r.first_rejection=st.first_rejection end return r end function M.invalidate()M.state=nil end local function prepare(c) scope(c) local now=c.clock if not integer(now and math.floor(now*1000),1e15)then error('REF_CLOCK_REQUIRED',0)end if M.failed and same(M.failed,c)then return nil,M.failed.reason,M.failed.info end if M.failed then M.failed=nil;M.next_scan=0 end local st=M.state if st and not same(st.context,c)then M.state=nil;M.next_scan=0;st=nil end if not st then if now32768 or not integer(k,32768)or k==0 then error('REF_UNIT_ARRAY_BOUND',0)end high=math.max(high,k) end if count~=high then error('REF_UNIT_ARRAY_HOLES',0)end st.units=units;st.count=count end if st.complete then return true,'REF_INDEX_READY',info(st)end if now-st.started>90 then M.failed={world=c.world,session=c.session,peer=c.peer,reason='REF_INDEX_TIME_BUDGET',info=info(st)};M.state=nil return nil,M.failed.reason,M.failed.info end local began=os.clock();local last=math.min(st.count,st.cursor+511) for i=st.cursor,last do local u=st.units[i];local ref,raw=M.decode(u) if ref then if st.map[ref]then error('REF_DUPLICATE_REFERENCE',0)end st.map[ref]=u;st.tagged=st.tagged+1 else st.rejected=st.rejected+1;st.first_rejection=st.first_rejection or raw end st.cursor=i+1 if os.clock()-began>=.002 then break end end scope(c) if st.cursor<=st.count then return nil,'SPATIAL_INDEX_PENDING',info(st)end st.complete=true;st.units=nil if st.tagged==0 then M.failed={world=c.world,session=c.session,peer=c.peer,reason='REF_NO_COMPATIBLE_UNIT_TAGS',info=info(st)};M.state=nil return nil,M.failed.reason,M.failed.info end return true,'REF_INDEX_READY',info(st) end function M.prepare(c) local ok,a,b,r=pcall(prepare,c) if ok then return a,b,r end local detail=info(M.state);detail.error=tostring(a) M.failed={world=c.world,session=c.session,peer=c.peer,reason=tostring(a),info=detail};M.state=nil return nil,tostring(a),detail end local function resource(u) local r=need('Unit','resource_name')(u) local h if type(r)=='userdata'then h=normalize(need('IdString64','to_hex')(r)) elseif type(r)=='string'then h=normalize(r)end if not h then error('REF_RESOURCE_CONVERSION_FAILED',0)end return h end function M.validate(u,d,c) scope(c) local st=M.state if not st or not st.complete or not same(st.context,c)then error('REF_INDEX_NOT_CURRENT',0)end if not integer(d.unit,4294967294)or d.unit==0 then error('REF_NATIVE_KEY_INVALID',0)end local ref,raw=M.decode(u) if ref~=d.unit or raw~=d.unit*4+1 or st.map[ref]~=u then error('REF_FULL_KEY_MISMATCH',0)end if need('Unit','alive')(u)~=true then M.invalidate();error('REF_UNIT_GONE',0)end if need('Unit','world')(u)~=c.world then M.invalidate();error('REF_UNIT_WORLD_MISMATCH',0)end if resource(u)~=d.resource then error('REF_UNIT_RESOURCE_MISMATCH',0)end return raw end function M.lookup(d,c) local st=M.state if not st or not st.complete then error('REF_INDEX_NOT_READY',0)end local u=st.map[d.unit] if not u then M.invalidate();error('REF_NATIVE_KEY_NOT_INDEXED',0)end local raw=M.validate(u,d,c) return u,{native_unit=d.unit,encoded_value=raw,resource=d.resource,full_key_equal=true,world_equal=true,resource_equal=true} end function M.root_node(u) local has,node=need('Unit','has_node'),need('Unit','node') for _,name in ipairs({'root','Root'})do if has(u,name)==true then local i=node(u,name) if not integer(i,65535)then error('REF_NODE_INDEX_INVALID',0)end return i,name end end error('REF_NAMED_ROOT_NOT_FOUND',0) end return M end