<!-- SAGA-STAGING · part 74 -->

    }
    part('base', new THREE.BoxGeometry(30, 4, 30), stone, 0, 2, 0);
    part('keep', new THREE.BoxGeometry(12, 12, 12), stone, 0, 10, 0);
    for(var i = 0; i < 4; i++){
      var a = i * Math.PI / 2;
      part('tower-' + i, new THREE.CylinderGeometry(3, 3.5, 14, 8), dark, Math.sin(a + Math.PI / 4) * 14, 11, Math.cos(a + Math.PI / 4) * 14);
    }
    for(var j = 0; j < 4; j++){
      var b = j * Math.PI / 2;
      part('wall-' + j, new THREE.BoxGeometry(30, 8, 2), stone, Math.sin(b) * 14, 8, Math.cos(b) * 14, b);
    }
    for(var k = 0; k < 4; k++){
      var c = k * Math.PI / 2;
      part('spire-' + k, new THREE.ConeGeometry(2, 6, 8), goldm, Math.sin(c + Math.PI / 4) * 14, 21, Math.cos(c + Math.PI / 4) * 14);
    }
    part('flag', new THREE.BoxGeometry(0.5, 4, 2.5), goldm, 0, 18, 0);
    g.position.set(x, 0, z);
    g.userData.isCastle = true;
    scene.add(g);
    window._castles.push(g);
    if(animate){
      order.forEach(function(m){ m.visible = false; });
      order.forEach(function(m, i){
        setTimeout(function(){ m.visible = true; }, i * 200);
      });
      if(window.logBuild) window.logBuild('castle raised');
      if(order.length && typeof say === 'function')
        setTimeout(function(){ say('Castle stands — forever'); }, order.length * 200);
    }
    return g;
  }catch(e){ return null; }
}
function saveCastle(x, z){
  try{
    var list = JSON.parse(localStorage.getItem('saga-staging-castles') || '[]');
    list.push({x:Math.round(x), z:Math.round(z)});
    localStorage.setItem('saga-staging-castles', JSON.stringify(list));
  }catch(e){ console.error(e); }
}
function restoreCastles(){
  try{
    var list = JSON.parse(localStorage.getItem('saga-staging-castles') || '[]');
    list.forEach(function(c){
      if(isFinite(c.x) && isFinite(c.z)) buildCastleAt(c.x, c.z, true);
    });
  }catch(e){ console.error(e); }
}
window.__sagaExecMark('6014');

/* v190 — core scope bridge active */
CODES['castle'] = {cat:'Special', desc:'Put the castle down — saved to the map forever', fn:function(a){
  var x = kingPos.x + 40, z = kingPos.z + 40;
  var g = buildCastleAt(x, z, true);
  if(g){ saveCastle(x, z); }
}};
window.__sagaExecMark('CASTLE OK');
CODES['uncastle'] = {cat:'Special', desc:'Remove the nearest castle', fn:function(a){
  var best = null, bd = 80;
  window._castles.forEach(function(g){
    var d = Math.hypot(g.position.x - kingPos.x, g.position.z - kingPos.z);
    if(d < bd){ bd = d; best = g; }
  });
  if(!best){ say('no castle near'); return; }
  scene.remove(best);
  var i = window._castles.indexOf(best);
  if(i > -1) window._castles.splice(i, 1);
  try{
    var list = JSON.parse(localStorage.getItem('saga-staging-castles') || '[]');
    var bi = -1, bdd = 80;
    list.forEach(function(c, idx){
      var d = Math.hypot(c.x - best.position.x, c.z - best.position.z);
      if(d < bdd){ bdd = d; bi = idx; }
    });
    if(bi > -1){ list.splice(bi, 1); localStorage.setItem('saga-staging-castles', JSON.stringify(list)); }
  }catch(e){ console.error(e); }
  say('castle removed');
}};
window.__sagaExecMark('UNCASTLE OK');
CODES['movecastle'] = {cat:'Special', desc:'Move the nearest castle to here', fn:function(a){
  var best = null, bd = 80;
  window._castles.forEach(function(g){
    var d = Math.hypot(g.position.x - kingPos.x, g.position.z - kingPos.z);
    if(d < bd){ bd = d; best = g; }
  });
  if(!best){ say('no castle near'); return; }
  var ox = best.position.x, oz = best.position.z;
  var nx = kingPos.x + 40, nz = kingPos.z + 40;
  best.position.set(nx, 0, nz);
  try{
    var list = JSON.parse(localStorage.getItem('saga-staging-castles') || '[]');
    var bi = -1, bdd = 80;
    list.forEach(function(c, idx){
      var d = Math.hypot(c.x - ox, c.z - oz);
      if(d < bdd){ bdd = d; bi = idx; }
    });
    if(bi > -1) list.splice(bi, 1);
    list.push({x:Math.round(nx), z:Math.round(nz)});
    localStorage.setItem('saga-staging-castles', JSON.stringify(list));
  }catch(e){ console.error(e); }
  say('castle moved');
}};
window.__sagaExecMark('MOVECASTLE OK');
window.__sagaExecMark('6063');
window._bamBlocks = window._bamBlocks || [];
function saveBamBlocks(){
  try{
    var list = window._bamBlocks.map(function(m){
      var b = m.userData.bam || {w:10, h:10, d:10};
      return {w:b.w, h:b.h, d:b.d,
        x:Math.round(m.position.x*100)/100, y:Math.round(m.position.y*100)/100, z:Math.round(m.position.z*100)/100,
        ry:Math.round(m.rotation.y*100)/100,
        sx:m.scale.x, sy:m.scale.y, sz:m.scale.z};
    });
    localStorage.setItem('saga-staging-blocks', JSON.stringify(list));
  }catch(e){ console.error(e); }
}
function restoreBamBlocks(){
  try{
    var list = JSON.parse(localStorage.getItem('saga-staging-blocks') || '[]');
    list.forEach(function(b){
      var mesh = new THREE.Mesh(new THREE.BoxGeometry(b.w, b.h, b.d), goldMat);
      mesh.position.set(b.x, b.y, b.z);
      mesh.rotation.y = b.ry || 0;
      mesh.scale.set(b.sx |