<!-- RUBY-BACKUP · part 154 -->
ing);
    }
    var engine = new THREE.Mesh(new THREE.CylinderGeometry(1, 1.3, 1.5, 12),
      new THREE.MeshStandardMaterial({color: 0x333333, emissive: 0x0088ff, emissiveIntensity: 0.8}));
    engine.rotation.x = Math.PI/2; engine.position.z = -4.5; ship.add(engine);
    ship.position.y = 4; plat2.add(ship);
    window._creatorShip = ship;
    /* Bridge from hall to platform */
    var bridge = new THREE.Mesh(new THREE.BoxGeometry(4, 0.5, 16), darkMat);
    bridge.position.set(14, 0.25, 0); g.add(bridge);
    plat2.position.set(28, 0, 0); g.add(plat2);
    /* HALL BEACONS — giant gold light pillar, visible across the night sky (King's order) */
    var beaconMat = new THREE.MeshBasicMaterial({color: 0xffd700, transparent: true, opacity: 0.9});
    var beaconBeam = new THREE.Mesh(new THREE.CylinderGeometry(2, 3, 500, 16, 1, true), beaconMat);
    beaconBeam.position.y = 250; g.add(beaconBeam);
    var beaconOrb = new THREE.Mesh(new THREE.SphereGeometry(3, 16, 16),
      new THREE.MeshBasicMaterial({color: 0xffe766}));
    beaconOrb.position.y = 8; g.add(beaconOrb);
    /* Red and green nav lights on the hall rim — 5x bigger */
    for(var bi = 0; bi < 8; bi++){
      var ba = (bi/8) * Math.PI * 2;
      var bcol = (bi % 2 === 0) ? 0xff0000 : 0x00ff00;
      var blight = new THREE.Mesh(new THREE.SphereGeometry(1.5, 12, 12),
        new THREE.MeshBasicMaterial({color: bcol}));
      blight.position.set(Math.cos(ba)*12, 2, Math.sin(ba)*12);
      g.add(blight);
      var bbeam = new THREE.Mesh(new THREE.CylinderGeometry(0.5, 0.5, 100, 8, 1, true),
        new THREE.MeshBasicMaterial({color: bcol, transparent: true, opacity: 0.4}));
      bbeam.position.set(Math.cos(ba)*12, 52, Math.sin(ba)*12);
      g.add(bbeam);
    }
    /* Deck landing zone — world coordinates */
    window._deckZone = { x: cx + 28, z: cz, y: gy + 1.5, r: 11 };
    /* Hall landing zone — the main circle */
    window._hallZone = { x: cx, z: cz, y: gy + 1, r: 13 };
    /* Ship gentle hover */
    if(!window._shipAnim){
      window._shipAnim = true;
      var _t = 0;
      var _hover = function(){
        _t += 0.02;
        try{ if(window._creatorShip) window._creatorShip.position.y = 4 + Math.sin(_t) * 0.5; }catch(e){}
        requestAnimationFrame(_hover);
      };
      _hover();
    }

    g.position.set(cx, gy, cz);
    if(typeof scene !== 'undefined') scene.add(g);

    /* Animate the hourglass — slow rotation, honoring Playa 2.0 */
    if(!window._creatorHallAnim){
      window._creatorHallAnim = true;
      var _spin = function(){
        try{ if(window._creatorHallHourglass) window._creatorHallHourglass.rotation.y += 0.005; }catch(e){}
        requestAnimationFrame(_spin);
      };
      _spin();
    }

    if(typeof codeStatus === 'function') codeStatus('THE CREATOR HALL — for Playa 2.0');
    if(typeof trackNewThing === 'function') trackNewThing('creatorhall', 'The Creator Hall — Playa 2.0\'s Fix Station in the world');
  }catch(e){ if(typeof codeStatus==='function') codeStatus('creator hall failed'); }
}

window.handleCheatCode = function(code){ try{ runLine(code); }catch(e){} };
function runLine(line){
  var tl = line.trim().toLowerCase();
  var ec = {x:(typeof cursor!=='undefined'&&cursor)?cursor.x:0, z:(typeof cursor!=='undefined'&&cursor)?cursor.z:0};
  if(tl==='did'){ showDid(); return; }
  if(tl==='lock'){ awaitingLock=true; awaitingUnlock=false; codeStatus('tap the anchor stone to lock it in'); return; }
  if(tl==='unlock'){
    if(!lockedAnchors.length){ codeStatus('none locked'); return; }
    awaitingUnlock=true; awaitingLock=false; codeStatus('tap a locked anchor to release it'); return;
  }
  if(tl==='anchors'){ codeStatus(lockedAnchors.length ? lockedAnchors.length+' locked' : 'none locked'); return; }


/* MAP LAW: no map until you meet PROVOLTA */
var MET_PROVOLTA = false;
try{ MET_PROVOLTA = localStorage.getItem('ruby-met-provolta')==='1'; }catch(e){}
function markMetProvolta(){
  try{
    if(!MET_PROVOLTA){
      MET_PROVOLTA = true;
      localStorage.setItem('ruby-met-provolta', '1');
      try{ codeStatus('you have met PROVOLTA — the map is yours'); }catch(e){}
      try{ if(typeof giveProvoltaObjectives==='function') giveProvoltaObjectives(); }catch(e){}
    }
  }catch(e){}
}


/* THE ROBOT: it finds you. It loops until you stand still. */
var NEWPLAYER_ROBOT = null;
var ROBOT_STATE = 'waiting'; /* waiting, chasing, analyzing, done */
var ROBOT_LAST_POS = null;
var ROBOT_STILL_TIME = 0;
var ROBOT_DIALOGUE_IDX = 0;
var ROBOT_LINES = [
  'NEW PLAYER! NEW PLAYER!',
  'I see you. Come here.',
  'NEW PLAYER! NEW PLAYER!',
  'Stop running away!',
  'I have to converse with you.',
  'My programmers told me to tell you.',
  'You have to hurry up right now.',
  'Come here I need to tell you something.',
  'NEW PLAYER! NEW PLAYER!'
];
function buildNewPlayerRobot(){
  try{
    if(NEWPLAYER_ROBOT) return;
    NEWPLAYER_ROBOT = new THREE.Group();
    /* boxy robot */
    var bodyMat =