<!-- SAGA-STAGING · part 76 -->
Group();
    var tube = new THREE.Mesh(new THREE.CylinderGeometry(0.28, 0.36, 3.2, 16), darkMetal);
    tube.rotation.x = Math.PI/2; barrel.add(tube);
    [ -1.2, 0, 1.2 ].forEach(function(bz){
      var band = new THREE.Mesh(new THREE.TorusGeometry(0.34, 0.06, 8, 20), gold);
      band.position.z = bz; barrel.add(band);
    });
    var muzzle = new THREE.Mesh(new THREE.CylinderGeometry(0.42, 0.34, 0.35, 16), gold);
    muzzle.rotation.x = Math.PI/2; muzzle.position.z = 1.7; barrel.add(muzzle);
    barrel.position.set(0, 1.35, 0.4);
    barrel.rotation.x = -0.5;
    g.add(barrel);
    g.userData.barrel = barrel;
    var fx = -Math.cos(camYaw), fz = -Math.sin(camYaw);
    if(typeof kingPos !== 'undefined'){
      g.position.set(kingPos.x + fx*8, groundY, kingPos.z + fz*8);
      g.rotation.y = Math.atan2(fx, fz);
    }
    g.userData.isCannon = true;
    scene.add(g);
    window._cannons.push(g);
    if(typeof trackNewThing === 'function') trackNewThing('cannon', 'A cannon — built by the King');
    return g;
  }catch(e){ return null; }
}
function fireCannon(){
  try{
    var c = null, best = 1e12, i, cc, dx, dz, d;
    for(i=0;i<window._cannons.length;i++){
      cc = window._cannons[i];
      if(!cc || !cc.position) continue;
      dx = cc.position.x - kingPos.x; dz = cc.position.z - kingPos.z;
      d = dx*dx + dz*dz;
      if(d < best){ best = d; c = cc; }
    }
    if(!c || best > 1600){ c = buildCannon(); say('cannon stands ready'); }
    if(!c) return;
    /* muzzle flash */
    var flash = new THREE.Mesh(new THREE.SphereGeometry(0.8, 10, 10),
      new THREE.MeshBasicMaterial({color:0xffcc33, transparent:true, opacity:0.9}));
    flash.position.set(c.position.x, c.position.y + 2.2, c.position.z);
    scene.add(flash);
    var ft = 0;
    (function flashAnim(){
      ft += 0.05;
      flash.scale.set(1+ft*3, 1+ft*3, 1+ft*3);
      flash.material.opacity = Math.max(0, 0.9 - ft*2);
      if(flash.material.opacity > 0) requestAnimationFrame(flashAnim);
      else scene.remove(flash);
    })();
    /* boom */
    try{ if(window.AudioSys && AudioSys.blip) AudioSys.blip(120, 35, 0.5, 'sawtooth', 0.3); }catch(e){ console.error(e); }
    /* cannonball — ballistic arc */
    var ball = new THREE.Mesh(new THREE.SphereGeometry(0.35, 12, 12),
      new THREE.MeshStandardMaterial({color:0xffd700, emissive:0xff8800, emissiveIntensity:2, roughness:0.4}));
    var fx2 = -Math.cos(camYaw), fz2 = -Math.sin(camYaw);
    ball.position.set(c.position.x + fx2*2, c.position.y + 2.2, c.position.z + fz2*2);
    var vel = new THREE.Vector3(fx2*46, 14, fz2*46);
    scene.add(ball);
    var t = 0;
    (function ballAnim(){
      t += 0.033;
      vel.y -= 26 * 0.033;
      ball.position.x += vel.x * 0.033;
      ball.position.y += vel.y * 0.033;
      ball.position.z += vel.z * 0.033;
      if(ball.position.y <= 0.2 || t > 6){
        var pop = new THREE.Mesh(new THREE.SphereGeometry(1.2, 10, 10),
          new THREE.MeshBasicMaterial({color:0xff8833, transparent:true, opacity:0.8}));
        pop.position.copy(ball.position); pop.position.y = Math.max(0.5, pop.position.y);
        scene.add(pop);
        var pt = 0;
        (function popAnim(){
          pt += 0.06;
          pop.scale.set(1+pt*2, 1+pt*2, 1+pt*2);
          pop.material.opacity = Math.max(0, 0.8 - pt*1.6);
          if(pop.material.opacity > 0) requestAnimationFrame(popAnim);
          else scene.remove(pop);
        })();
        scene.remove(ball);
        return;
      }
      requestAnimationFrame(ballAnim);
    })();
    say('fire!');
  }catch(e){ say('stumbled'); }
}
function buildCannonBtn(){
  if(window.STAGING_CLEAN_MAP) return; // Clean map: old builder disabled
  if(document.getElementById('cannon-btn')) return;
  var b = document.createElement('button');
  b.id = 'cannon-btn';
  b.innerHTML = '💥';
  b.title = 'Fire cannon';
  b.style.cssText = 'position:fixed;right:16px;bottom:96px;z-index:101;' +
    'width:64px;height:64px;border-radius:50%;' +
    'background:#d8a920;border:2px solid #ffd700;color:#111;font-size:28px;' +
    'cursor:pointer;padding:0;-webkit-tap-highlight-color:transparent;' +
    'box-shadow:0 0 20px rgba(255,215,0,0.4);' +
    'display:flex;align-items:center;justify-content:center;';
  b.addEventListener('click', function(){ fireCannon(); });
  document.body.appendChild(b);
}
window.__sagaExecMark('6250');

/* AVATAR AND CANNON - v99, no hiding. */
buildCannonBtn();
spawnNewBody();

window.__sagaExecMark('6280');

/* ===== THE FIRST GAME — v85, King's order 2026-10-05 ===== */
/* The old computer at Playa 2.0. Proximity absorbs you to the mission. */
var _oldComputer = null;
var _absorbed = false;
function buildOldComputer(){
  if(window.STAGING_CLEAN_MAP) return; // Clean map: old builder disabled
  if(_oldComputer) return;
  var g = new THREE.Group();
  /* Desk */
  var desk = new THREE.Mesh(new THREE.BoxGeometry(3, 0.2, 1.5),
    new THREE.MeshStandardMaterial({color:0x5a3a1a, roughness:0.