<!-- LIVE · part 60 -->
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 ===== */
/* ===== SHADOW LOCOMOTION — v206 ===== */
ActorRuntime.shadowMotion={
 velocity:new THREE.Vector3(0,0,0),
 desired:new THREE.Vector3(0,0,0),
 predicted:new THREE.Vector3(0,0,0),
 dt:0
};
ActorRuntime.calculateShadowMotion=function(dt,input,yaw,startPos){
 var R=ActorRuntime,S=R.shadowMotion,I=input||R.input;
 dt=Math.max(0,Math.min(Number.isFinite(dt)?dt:0,0.05));
 yaw=Number.isFinite(yaw)?yaw:0;
 var x=Number.isFinite(I.moveX)?I.moveX:0,z=Number.isFinite(I.moveZ)?I.moveZ:0;
 var mag=Math.sqrt(x*x+z*z);if(mag>1){x/=mag;z/=mag;mag=1;}
 var sy=Math.sin(yaw),cy=Math.cos(yaw),speed=R.physics.walkSpeed;
 S.desired.x=(sy*x-cy*z)*speed;S.desired.y=0;S.desired.z=(-cy*x-sy*z)*speed;
 var rate=mag>0?R.physics.acceleration:R.physics.braking,max=rate*dt;
 function approach(v,t){var d=t-v;return v+Math.max(-max,Math.min(max,d));}
 S.velocity.x=approach(S.velocity.x,S.desired.x);S.velocity.z=approach(S.velocity.z,S.desired.z);S.velocity.y=0;
 var base=startPos||((typeof kingPos!=="undefined"&&kingPos)?kingPos:null);
 if(base)S.predicted.copy(base).addScaledVector(S.velocity,dt);
 S.dt=dt;R.debug.ticks++;return S;
};
/* ===== END SHADOW LOCOMOTION — v206 ===== */
/* ===== LIVE SHADOW OBSERVER — v206 ===== */
ActorRuntime.shadowLive={enabled:true,lastTime:performance.now(),samples:0,lastReal:new THREE.Vector3(),lastPredictionError:null};
ActorRuntime.tickShadow=function(){
 var R=ActorRuntime,L=R.shadowLive,now=performance.now(),dt=Math.min((now-L.lastTime)/1000,0.05);L.lastTime=now;
 if(!L.enabled||R.authority!=="legacy"&&R.authority!=="ai_guarded"||typeof kingPos==="undefined"||!kingPos)return;
 var before=kingPos.clone();
 R.calculateShadowMotion(dt,R.input,(typeof camYaw!=="undefined"?camYaw:0),before);
 L.samples++;
 L.lastReal.copy(before);
 L.lastPredictionError=R.shadowMotion.predicted.distanceTo(before);
};
setInterval(function(){try{ActorRuntime.tickShadow();}catch(e){ActorRuntime.debug.lastError=String(e);}},16);
/* ===== END LIVE SHADOW OBSERVER — v206 ===== */
/* ===== TERRAIN PREDICTION — v208 ===== */
ActorRuntime.terrainPrediction={classification:"WAIT",support:false,valid:false,groundY:null,delta:null,slope:null,surface:"NONE",step:0,safe:false,samples:0};
ActorRuntime.predictTerrain=function(){
 var R=ActorRuntime,T=R.terrainPrediction,S=R.shadowMotion,WF=window.WORLD_FOUNDATION;
 T.classification="WAIT";T.support=false;T.valid=false;T.groundY=null;T.delta=null;T.slope=null;T.surface="NONE";T.step=0;T.safe=false;
 if(!WF||typeof WF.supportBelow!=="function"||!S||typeof kingPos==="undefined"||!kingPos)return T;