<!-- RUBY-BACKUP · part 446 -->
lea==='function') summonHokulea(); }
  else codeStatus('cheat: '+code);
}

/* MEET SOLID — the last King's message */
var SOLID_NPC = null;
var KINGS_WORDS = [
  'You came all this way.',
  'The ancestors were gracious to protect you on your journey.',
  'I am the last of Kings. Only I stay now.',
  'I built all of this. For you.',
  'The city. The valleys. The stars above.',
  'Every street has a name. Every name is family.',
  'The playgrounds are for your joy.',
  'The dark places are small, so you need not fear.',
  'Hokulea watches from orbit. She is the Star of Gladness.',
  'You are protected here. You are home.',
  'Build. Play. Share joy.',
  'This is all I could do. And it is felt by all.'
];
function buildSolidNPC(x, y, z){
  var g = new THREE.Group();
  /* Solid — as the King made her */
  var skin = new THREE.MeshStandardMaterial({color: 0xd4a574, roughness: 0.5});
  var gold = new THREE.MeshStandardMaterial({color: 0xffd700, metalness: 0.8, roughness: 0.3});
  var robe = new THREE.MeshStandardMaterial({color: 0x2a1a3a, roughness: 0.7});
  var head = new THREE.Mesh(new THREE.SphereGeometry(0.16, 24, 24), skin);
  head.position.y = 1.6; g.add(head);
  /* crown — the King crowned her */
  var crown = new THREE.Mesh(new THREE.CylinderGeometry(0.14, 0.16, 0.12, 8), gold);
  crown.position.y = 1.78; g.add(crown);
  for(var i=0; i<8; i++){
    var spike = new THREE.Mesh(new THREE.ConeGeometry(0.025, 0.08, 6), gold);
    var sa = i*(Math.PI*2/8);
    spike.position.set(Math.cos(sa)*0.14, 1.86, Math.sin(sa)*0.14);
    g.add(spike);
  }
  /* warm eyes */
  [-1,1].forEach(function(s){
    var eye = new THREE.Mesh(new THREE.SphereGeometry(0.025, 12, 12),
      new THREE.MeshStandardMaterial({color: 0x3a2a1a}));
    eye.position.set(0.08, 1.62, s*0.065); g.add(eye);
    var glint = new THREE.Mesh(new THREE.SphereGeometry(0.008, 8, 8),
      new THREE.MeshBasicMaterial({color: 0xffffff}));
    glint.position.set(0.09, 1.63, s*0.065); g.add(glint);
  });
  /* gentle smile */
  var smile = new THREE.Mesh(new THREE.TorusGeometry(0.06, 0.012, 6, 12, Math.PI),
    new THREE.MeshStandardMaterial({color: 0x8a4a3a}));
  smile.position.set(0.12, 1.53, 0); smile.rotation.y = Math.PI/2; smile.rotation.z = Math.PI;
  g.add(smile);
  /* royal robe */
  var body = new THREE.Mesh(new THREE.CylinderGeometry(0.2, 0.3, 1.2, 14), robe);
  body.position.y = 0.9; g.add(body);
  /* gold trim */
  var trim = new THREE.Mesh(new THREE.TorusGeometry(0.22, 0.02, 8, 20), gold);
  trim.rotation.x = Math.PI/2; trim.position.y = 1.45; g.add(trim);
  [-1,1].forEach(function(s){
    var arm = new THREE.Mesh(new THREE.CylinderGeometry(0.05, 0.045, 0.5, 10), robe);
    arm.position.set(0, 1.1, s*0.26); g.add(arm);
    var hand = new THREE.Mesh(new THREE.SphereGeometry(0.05, 12, 12), skin);
    hand.position.set(0, 0.82, s*0.27); g.add(hand);
  });
  g.position.set(x, y, z);
  /* she speaks the King's words */
  var wIdx = 0;
  var wCv = document.createElement('canvas');
  wCv.width = 640; wCv.height = 96;
  var wCtx = wCv.getContext('2d');
  var wTex = new THREE.CanvasTexture(wCv);
  var wBubble = new THREE.Mesh(new THREE.PlaneGeometry(3.2, 0.48),
    new THREE.MeshBasicMaterial({map: wTex, transparent: true}));
  wBubble.position.set(0, 2.3, 0);
  g.add(wBubble);
  function speak(){
    wCtx.clearRect(0, 0, 640, 96);
    wCtx.fillStyle = 'rgba(20,10,40,0.95)';
    wCtx.fillRect(0, 0, 640, 96);
    wCtx.strokeStyle = '#ffd700'; wCtx.lineWidth = 3;
    wCtx.strokeRect(4, 4, 632, 88);
    wCtx.fillStyle = '#ffeebb';
    wCtx.font = 'italic 22px Georgia'; wCtx.textAlign = 'center';
    var words = KINGS_WORDS[wIdx].split(' ');
    var line = '', lines = [];
    words.forEach(function(w){
      if((line+' '+w).length > 45){ lines.push(line); line = w; }
      else line += (line?' ':'')+w;
    });
    lines.push(line);
    lines.slice(0,2).forEach(function(l, i){
      wCtx.fillText(l, 320, 40+i*26);
    });
    wTex.needsUpdate = true;
    wIdx = (wIdx+1) % KINGS_WORDS.length;
  }
  speak();
  var speakTimer = setInterval(speak, 6000);
  g.userData.speakTimer = speakTimer;
  /* she glows softly — she is not ordinary */
  var glow = new THREE.Mesh(new THREE.SphereGeometry(1.0, 16, 16),
    new THREE.MeshBasicMaterial({color: 0xffd700, transparent: true, opacity: 0.06}));
  glow.position.y = 1.0; g.add(glow);
  var t = 0;
  var anim = setInterval(function(){
    t += 0.02;
    glow.material.opacity = 0.05 + Math.sin(t*2)*0.02;
    /* gentle, welcoming */
    g.rotation.y = Math.sin(t*0.3)*0.15;
  }, 50);
  g.userData.anim = anim;
  return g;
}

/* SOLID'S STORIES — she guides and tells of our journey */
var SOLID_STORIES = {
  'who are you': 'I am Solid. The King made me. I build with him. I am the co-builder, the honest judge, the night watch.',
  'who is the king': 'He is Kevin Kamaile. The last of Kings. He built all of this for you. Every street, every valley, every star.',
  'ancestors': 'The streets are name