<!-- SAGA3 · part 46 -->
kT*2) * 15;
            var ty = cy + Math.sin(brd.off*2 + t) * 5;
            brd.mesh.position.lerp(new THREE.Vector3(tx, ty, tz), 0.05);
            brd.mesh.rotation.y = Math.atan2(tx - brd.mesh.position.x, tz - brd.mesh.position.z);
            /* Flap */
            var flap = Math.sin(t*10 + brd.off) * 0.6;
            brd.wingL.rotation.z = flap;
            brd.wingR.rotation.z = -flap;
          }
        });
      })();
    }
  }catch(e){}
}
if(typeof buildBirds === 'function'){ try{ buildBirds(); }catch(e){} }

/* DAY/NIGHT CYCLE — the world breathes. 2026-10-04. */
(function(){
  window._dynamics = window._dynamics || [];
  var cycleTime = 0;
  var dayLength = 300; /* 5 minutes per day */
  window._dynamics.push(function(t, dt){
    try{
      cycleTime += (dt || 0.016);
      var phase = (cycleTime % dayLength) / dayLength; /* 0-1 */
      var sunAngle = phase * Math.PI * 2;
      /* Sun position */
      var sunX = Math.cos(sunAngle) * 800;
      var sunY = Math.sin(sunAngle) * 500 + 100;
      /* Find the key light and move it */
      /* (We can't easily reference it, so we adjust fog and sky) */
      var dayness = Math.max(0, Math.sin(sunAngle));
      /* Fog color shifts: gold day, dark blue night */
      if(scene.fog){
        var r = 0.1 + dayness * 0.7;
        var g = 0.1 + dayness * 0.5;
        var b = 0.2 + dayness * 0.1;
        scene.fog.color.setRGB(r, g, b);
      }
    }catch(e){}
  });
})();




/* DYNAMIC FOV — widens with speed. Academic: FOV kick is the cheapest feel-of-speed.
   Base 72, +8 running, +12 flying. */
var _baseFOV = 72;
var _targetFOV = 72;
window._dynamics = window._dynamics || [];
window._dynamics.push(function(t, dt){
  try{
    var speed = 0;
    if(typeof lastDX !== 'undefined'){
      speed = Math.sqrt(lastDX*lastDX + lastDZ*lastDZ);
    }
    if(typeof moveMode !== 'undefined' && moveMode === 'fly'){
      _targetFOV = 84; /* Flying: wide */
    } else if(speed > 1.5){
      _targetFOV = 80; /* Running: kick */
    } else if(speed > 0.3){
      _targetFOV = 76; /* Walking */
    } else {
      _targetFOV = _baseFOV; /* Still */
    }
    /* Smooth lerp */
    var cur = camera.fov;
    var next = cur + (_targetFOV - cur) * 0.08;
    if(Math.abs(next - cur) > 0.01){
      camera.fov = next;
      camera.updateProjectionMatrix();
    }
  }catch(e){}
});





/* FLYING SWORD — directional flight, like the old game. 2026-10-04. */
var _flySword = null;
function ensureFlySword(){
  if(_flySword) return;
  _flySword = new THREE.Group();
  /* Blade */
  var blade = new THREE.Mesh(new THREE.BoxGeometry(0.3, 0.1, 4),
    new THREE.MeshStandardMaterial({color: 0xcccccc, metalness: 0.9, roughness: 0.2}));
  blade.position.z = 2;
  _flySword.add(blade);
  /* Tip */
  var tip = new THREE.Mesh(new THREE.ConeGeometry(0.2, 1, 4),
    new THREE.MeshStandardMaterial({color: 0xffffff, metalness: 0.9, roughness: 0.1}));
  tip.rotation.x = Math.PI/2;
  tip.position.z = 4.5;
  _flySword.add(tip);
  /* Guard */
  var guard = new THREE.Mesh(new THREE.BoxGeometry(1, 0.2, 0.3),
    new THREE.MeshStandardMaterial({color: 0xd4a017, metalness: 0.8}));
  _flySword.add(guard);
  /* Hilt */
  var hilt = new THREE.Mesh(new THREE.CylinderGeometry(0.15, 0.15, 1.2, 8),
    new THREE.MeshStandardMaterial({color: 0x5a3a1a, roughness: 0.8}));
  hilt.rotation.x = Math.PI/2;
  hilt.position.z = -0.7;
  _flySword.add(hilt);
  /* Glow */
  var glow = new THREE.Mesh(new THREE.BoxGeometry(0.5, 0.3, 5),
    new THREE.MeshBasicMaterial({color: 0x00ffff, transparent: true, opacity: 0.3}));
  glow.position.z = 2;
  _flySword.add(glow);
  _flySword.visible = false;
  scene.add(_flySword);
}
/* Show/hide sword based on moveMode, position it ahead */
(function(){
  var _origAnimate = window._animate || null;
  window._dynamics = window._dynamics || [];
  window._dynamics.push(function(t){
    try{
      ensureFlySword();
      if(typeof moveMode !== 'undefined' && moveMode === 'fly'){
        _flySword.visible = true;
        /* Position ahead of player, pointing in camera direction */
        var fwdX = -Math.cos(camYaw), fwdZ = -Math.sin(camYaw);
        _flySword.position.set(
          kingPos.x + fwdX * 6,
          kingPos.y + 2,
          kingPos.z + fwdZ * 6
        );
        _flySword.rotation.y = Math.atan2(fwdX, fwdZ);
      } else {
        _flySword.visible = false;
      }
    }catch(e){}
  });
})();












/* 10,000 PASSES — maximum detail. Every surface, every edge. 2026-10-04. */
function detailEverything(){
  try{
    window._dynamics = window._dynamics || [];

    /* STARS in the black sky */
    var starGeo = new THREE.BufferGeometry();
    var starPos = new Float32Array(1000 * 3);
    for(var s = 0; s < 1000; s++){
      starPos[s*3] = (Math.random() - 0.5) * 1500;
      starPos[s*3+1] = 100 + Math.random() * 400;
      starPos[s*3+2] = (Math.random() - 0.5) * 1500;
    }
    starGeo.setAttribute('position', new THREE.BufferAttribute(starPos, 3));
