<!-- SAGA-STAGING · part 59 -->
 desc:'Look at x z — look 600 600', fn:function(a){
    if(a.length>=2){ kingPos.x=parseFloat(a[0])||0; kingPos.z=parseFloat(a[1])||0; }
  }},
  'skyview':{cat:'Camera', desc:'Sky view', fn:function(){
    camera.position.set(0,900,900); camera.lookAt(0,0,0);
  }},
  'vtoggle':{cat:'Camera', desc:'Toggle view mode', fn:function(){
    camDist = camDist > 30 ? 12 : 80;
  }},
  'angle':  {cat:'Camera', desc:'Set angle — angle 45', fn:function(a){
    if(a[0]) camYaw = (parseFloat(a[0])||0) * Math.PI/180;
  }},
  'glide':  {cat:'Camera', desc:'Smooth glide', fn:function(){ say('gliding'); }},
};

/* Code runner */
var codeInput = document.getElementById('codeinput');
function runCode(text){
  text = (text||'').trim().toLowerCase();
  if(!text) return;
  var parts = text.split(/\s+/);
  var cmd = parts[0], args = parts.slice(1);
  var c = CODES[cmd];
  if(c){ try{ c.fn(args); }catch(e){ say('stumbled'); } }
  else say('unknown — '+cmd);
}
document.getElementById('codesend').onclick = function(){
  runCode(codeInput.value); codeInput.value=''; codeInput.blur();
};
codeInput.addEventListener('keydown', function(e){
  if(e.key==='Enter'){ runCode(codeInput.value); codeInput.value=''; codeInput.blur(); }
});
/* Os never blocks keyboard — close Os when typing */
codeInput.addEventListener('focus', function(){
  osOpen = false;
  osEl.classList.remove('open');;
});

/* ===== CAMERA TOGGLE — cycle through modes ===== */
var camModes = [
  {n:'Orbit', yaw:0, pitch:0.5, dist:20},
  {n:'Top', yaw:0, pitch:1.45, dist:30},
  {n:'Front', yaw:0, pitch:0.35, dist:12},
  {n:'Back', yaw:Math.PI, pitch:0.35, dist:12},
  {n:'Left', yaw:Math.PI/2, pitch:0.35, dist:12},
  {n:'Right', yaw:-Math.PI/2, pitch:0.35, dist:12},
  {n:'Far', yaw:0, pitch:0.7, dist:80},
  {n:'Close', yaw:0, pitch:0.4, dist:6}
];
var camModeIdx = 0;
function toggleCamera(){
  camModeIdx = (camModeIdx + 1) % camModes.length;
  var m = camModes[camModeIdx];
  camYaw = m.yaw; camPitch = m.pitch; camDist = m.dist;
  say('camera: ' + m.n);
}

/* ===== BODY MOVEMENT TOGGLE — walk / fly / still ===== */
var moveModes = ['still', 'walk', 'fly', 'swim'];
var moveModeIdx = 0;
var moveMode = 'still';
/* ===== HYPER MOVEMENT CONTROLLER — v200 ===== */
var hyperMove = { grounded:false, verticalVelocity:0, lastGroundedAt:0, jumpQueuedAt:0, lastSafe:new THREE.Vector3(), lastTime:performance.now(), enabled:false };
function hyperDelta(){ var now=performance.now(); var dt=Math.min((now-hyperMove.lastTime)/1000,0.05); hyperMove.lastTime=now; return Math.max(dt,0); }
hyperMove.input = {x:0,z:0,rawY:0,mag:0};
hyperMove.velocity = {x:0,z:0};
hyperMove.walkSpeed=12; hyperMove.accel=28; hyperMove.brake=36; hyperMove.gravity=30; hyperMove.rootClearance=0.37;
/* ===== AI ACTOR RUNTIME — v202 ===== */
var ActorRuntime={
  version:202,
  enabled:false,
  authority:"legacy",
  actors:Object.create(null),
  input:{
    owner:"human",
    source:"touch",
    moveX:0,
    moveZ:0,
    lookX:0,
    lookY:0,
    magnitude:0,
    jump:false,
    ascend:false,
    descend:false,
    interact:false,
    sequence:0,
    timestamp:0
  },
  locomotion:{
    mode:"still",
    requestedMode:"still",
    capabilities:{walk:true,run:true,jump:true,fly:true,swim:true,vehicle:true},
    velocity:new THREE.Vector3(0,0,0),
    desiredVelocity:new THREE.Vector3(0,0,0),
    grounded:false,
    surface:null,
    slope:0,
    verticalVelocity:0
  },
  physics:{
    gravity:30,
    walkSpeed:12,
    runSpeed:20,
    flySpeed:12,
    acceleration:28,
    braking:36,
    rootClearance:0.37,
    maxSlope:50,
    stepHeight:0.6,
    coyoteMs:120,
    jumpBufferMs:140
  },
  safety:{
    lastSafe:new THREE.Vector3(),
    hasLastSafe:false,
    killY:-500,
    recovering:false
  },
  ai:{
    allowed:true,
    active:false,
    agentId:null,
    goal:null,
    target:null,
    control:"none"
  },
  debug:{
    shadow:true,
    ticks:0,
    lastError:null
  }
};
ActorRuntime.submitIntent=function(source,intent){
  if(source!=="human" && source!=="ai") return false;
  if(source==="ai" && !ActorRuntime.ai.allowed) return false;
  if(!intent || typeof intent!=="object") return false;
  var I=ActorRuntime.input;
  I.owner=source;
  I.source=source==="ai"?"agent":"controls";
  if(Number.isFinite(intent.moveX)) I.moveX=Math.max(-1,Math.min(1,intent.moveX));
  if(Number.isFinite(intent.moveZ)) I.moveZ=Math.max(-1,Math.min(1,intent.moveZ));
  I.magnitude=Math.min(1,Math.sqrt(I.moveX*I.moveX+I.moveZ*I.moveZ));
  I.jump=!!intent.jump;
  I.ascend=!!intent.ascend;
  I.descend=!!intent.descend;
  I.interact=!!intent.interact;
  I.sequence++;
  I.timestamp=performance.now();
  return true;
};
ActorRuntime.releaseAI=function(){
  ActorRuntime.ai.active=false;
  ActorRuntime.ai.agentId=null;
  ActorRuntime.ai.goal=null;
  ActorRuntime.ai.target=null;
  ActorRuntime.ai.control="none";
  ActorRuntime.input.owner="human";
};
window.ACTOR_RUNTIME=ActorRuntime;

/* ===== ACTOR MOBILE DEBUG — v203 ===== 