<!-- SAGA-STAGING · part 60 -->
*/
ActorRuntime.debug.mobile=false;
ActorRuntime.debugElement=null;
ActorRuntime.toggleDebug=function(){
  ActorRuntime.debug.mobile=!ActorRuntime.debug.mobile;
  if(!ActorRuntime.debugElement){
    var d=document.createElement("div");
    d.id="actor-runtime-debug";
    d.style.cssText="position:fixed;top:62px;left:8px;z-index:999999;background:rgba(0,0,0,.82);color:#fff;border:1px solid rgba(255,255,255,.35);border-radius:8px;padding:8px 10px;font:11px/1.35 monospace;white-space:pre;pointer-events:none;max-width:calc(100vw - 16px)";
    document.body.appendChild(d);
    ActorRuntime.debugElement=d;
  }
  ActorRuntime.debugElement.style.display=ActorRuntime.debug.mobile?"block":"none";
};
ActorRuntime.updateDebug=function(){
  if(!ActorRuntime.debug.mobile||!ActorRuntime.debugElement||ActorRuntime.debug.showingTest||ActorRuntime.debug.shadowLiveDisplay)return;
  var I=ActorRuntime.input,L=ActorRuntime.locomotion,A=ActorRuntime.ai;
  ActorRuntime.debugElement.textContent=
    "ACTOR RUNTIME v"+ActorRuntime.version+"  SHADOW\n"+
    "AUTHORITY  "+String(ActorRuntime.authority).toUpperCase()+"\n"+
    "OWNER      "+String(I.owner).toUpperCase()+"\n"+
    "MODE       "+String(L.requestedMode).toUpperCase()+"\n"+
    "STICK      "+I.moveX.toFixed(2)+" / "+I.moveZ.toFixed(2)+"\n"+
    "MAG        "+I.magnitude.toFixed(2)+"\n"+
    "SEQUENCE   "+I.sequence+"\n"+
    "AI         "+(A.allowed?(A.active?"ACTIVE":"READY"):"LOCKED")+"\n"+
    "CONTROL    "+(ActorRuntime.enabled?"LIVE":"SAFE / SHADOW");
};
setInterval(function(){try{ActorRuntime.updateDebug();}catch(e){}},100);
window.ACTOR_RUNTIME=ActorRuntime;

/* ===== VIRTUAL CONTROLLER TEST — v204 ===== */
ActorRuntime.runControllerTest=function(){
  ActorRuntime.debug.showingTest=true;
  var R=ActorRuntime,results=[],startSeq=R.input.sequence;
  var startPos=(typeof kingPos!=="undefined"&&kingPos)?kingPos.clone():null;
  function test(name,ok){results.push({name:name,pass:!!ok});}
  function send(v){return R.submitIntent("ai",v);}

  var oldEnabled=R.enabled,oldAuthority=R.authority;
  R.enabled=false;
  R.authority="legacy";

  test("AI INTENT API",send({moveX:0,moveZ:0}));
  send({moveX:0,moveZ:1});
  test("FORWARD",R.input.moveX===0&&R.input.moveZ===1);
  send({moveX:0,moveZ:-1});
  test("BACKWARD",R.input.moveX===0&&R.input.moveZ===-1);
  send({moveX:-1,moveZ:0});
  test("LEFT",R.input.moveX===-1&&R.input.moveZ===0);
  send({moveX:1,moveZ:0});
  test("RIGHT",R.input.moveX===1&&R.input.moveZ===0);
  send({moveX:9,moveZ:-9});
  test("CLAMP",R.input.moveX===1&&R.input.moveZ===-1&&R.input.magnitude===1);
  send({moveX:.5,moveZ:.5});
  test("DIAGONAL",Math.abs(R.input.magnitude-Math.sqrt(.5))<.001);
  test("AI OWNER",R.input.owner==="ai");
  test("SEQUENCE",R.input.sequence>startSeq);

  R.submitIntent("human",{moveX:0,moveZ:0});
  test("HUMAN TAKEOVER",R.input.owner==="human"&&R.input.magnitude===0);

  var unchanged=true;
  if(startPos&&kingPos) unchanged=startPos.distanceTo(kingPos)<0.0001;
  test("NO KINGPOS WRITE",unchanged);
  test("AUTHORITY SAFE",R.authority==="legacy"&&R.enabled===false);

  R.enabled=oldEnabled;
  R.authority=oldAuthority;

  var passed=results.filter(function(x){return x.pass;}).length;
  R.debug.lastTest={passed:passed,total:results.length,results:results,time:Date.now()};

  if(!R.debug.mobile) R.toggleDebug();
  if(R.debugElement){
    R.debugElement.textContent=
      "AI CONTROLLER SELF TEST v204\n\n"+
      results.map(function(x){return (x.pass?"PASS  ":"FAIL  ")+x.name;}).join("\n")+
      "\n\n"+passed+" / "+results.length+" PASS\n"+
      "MOVEMENT AUTHORITY  "+String(R.authority).toUpperCase();
  }
  return R.debug.lastTest;
};
/* ===== END VIRTUAL CONTROLLER TEST — v204 ===== */
/* ===== ACTOR PERCEPTION SENSOR — v205 ===== */
ActorRuntime.perception={support:false,grounded:false,airborne:true,falling:false,safeStand:false,safeSave:false,groundY:null,delta:null,slope:null,surface:"NONE",lastSense:0};
ActorRuntime.senseWorld=function(testPos){
 var P=ActorRuntime.perception,WF=window.WORLD_FOUNDATION,pos=testPos||((typeof kingPos!=="undefined")?kingPos:null);
 P.support=false;P.grounded=false;P.airborne=true;P.falling=false;P.safeStand=false;P.safeSave=false;P.groundY=null;P.delta=null;P.slope=null;P.surface="NONE";
 if(!WF||typeof WF.supportBelow!=="function"||!pos){P.lastSense=performance.now();return P;}
 var s=WF.supportBelow(pos,{startOffset:2,maxDrop:8,maxSlope:ActorRuntime.physics.maxSlope});
 if(s&&s.hit){P.support=true;P.groundY=s.height;P.delta=pos.y-s.height;P.slope=s.slope;P.surface=s.kind||"surface";var contact=Math.abs(P.delta-ActorRuntime.physics.rootClearance)<=0.18;P.grounded=!!(s.valid&&contact);P.airborne=!P.grounded;P.safeStand=!!(P.grounded&&s.valid&&P.slope<=ActorRuntime.physics.maxSlope);P.safeSave=P.safeStand;}
 P.falling=P.airborne&&ActorRuntime.locomotion.verticalVelocity < -0.05;P.lastSense=performance.now();return P;
};
/* ===== END ACTOR PERCEPTION SENSOR — v205 