<!-- RUBY-BACKUP · part 383 -->
— only b1 takes you home */
    if(typeof mePos!=='undefined' && isFinite(mePos.x) && isFinite(mePos.z) && (Math.abs(mePos.x)+Math.abs(mePos.z)>0.01)){
      var kgy = groundY(mePos.x, mePos.z);
      mePos.y = kgy+0.1; meVel.set(0,0,0); onGround = true;
    } else {
      mePos.set(sp.x, sgy+0.1, sp.z); meVel.set(0,0,0);
      onGround = true;
    }
    camYaw = camGoal.th; camPitch = 0.55; camDist = 1.7; faceYaw = camYaw;
    aimYaw = camYaw; aimPitch = 0;
    if(!myAvatar){ myAvatar = AVATAR==='provolta' ? buildProvoltaAvatar() : (AVATAR==='king' ? buildKingAvatar() : buildCircleAvatar(0xffd700)); scene.add(myAvatar); }
    myAvatar.visible = true;
    if(!swordGrp) swordGrp = buildSword();
    camera.near = 0.05; camera.fov = 55; crownFov = 55; camera.updateProjectionMatrix();
    CROWN = false;
    codeStatus('walk — joystick runs, the triangle jumps, fly takes the sword');
  }else{
    if(myAvatar) myAvatar.visible = false;
    setFly(false);
    camera.near = 0.1; camera.updateProjectionMatrix();
    codeStatus('back to the high view');
  }
  if(typeof ghost!=='undefined' && ghost) ghost.visible = false;
}
function setFly(on){
  FLYM = !!on;
  var fb = document.getElementById('flybtn');
  if(fb) fb.classList.toggle('on', FLYM);
  if(swordGrp) swordGrp.visible = WALK && FLYM;
  if(FLYM){ aimYaw = faceYaw; aimPitch = 0; aimedAnchor = null; codeStatus('fly — drag aims the sword in 360, you follow its point'); }
}
function setWear(name){
  myWearName = name || null;
  if(myWearGrp){ scene.remove(myWearGrp); myWearGrp = null; }
  if(name){
    myWearGrp = buildWearable(name);
    if(myWearGrp){ scene.add(myWearGrp); codeStatus('wearing '+name+' — send it to a friend so they see it too'); }
    else { myWearName = null; codeStatus('no save named '+name); }
  } else codeStatus('unworn');
}
loadUndo(); loadSaves(); loadDid(); loadAnchors(); drawAnchorRings(); loadPortals(); drawPortals(); loadKings(); loadShoes();
/* eyes first — on every load, Solid sees (if chosen) */
setTimeout(function(){
  try{
    var ea = true;
    try{ ea = localStorage.getItem('ruby-eyes-auto')!=='0'; }catch(e){}
    if(ea && typeof Mainframe!=='undefined' && WATCH_ID) Mainframe.run('eyes');
  }catch(e){}
}, 4000);
try{
  /* v116 -> v117 migration: the 169 separate stones become the one whole */
  var hadOld = false;
  for(var fi=stones.children.length-1; fi>=0; fi--){ if(stones.children[fi].userData.y===-59){ stones.remove(stones.children[fi]); hadOld = true; } }
  if(hadOld){ save(); try{ localStorage.setItem(FLOOR_KEY, '1'); }catch(e){} }
  /* THE GROUND IS NEVER MISSING — build floor unconditionally */
  try{ if(typeof buildFloorMesh==='function') buildFloorMesh(); }catch(e){}
  try{ localStorage.setItem(FLOOR_KEY,'1'); }catch(e){}
  try{
    loadDigs();
    if(localStorage.getItem(LAND_KEY)==='1'){
      if(!floorMesh){ buildFloorMesh(); try{ localStorage.setItem(FLOOR_KEY,'1'); }catch(e){} }
      buildLandMesh();
      buildLandGrid();
    }
    else { /* every new world is born with land */
      if(!floorMesh){ buildFloorMesh(); try{ localStorage.setItem(FLOOR_KEY,'1'); }catch(e){} }
      buildLandMesh();
      buildLandGrid();
      try{ localStorage.setItem(LAND_KEY,'1'); }catch(e){}
    }
  }catch(e){}
}catch(e){}
/* ?body=king&crown=1 — load in the crown on the body, no punching in */
/* ?walk=1 — load walking in your body, avatars on, no punching in */
if(START_CROWN){ if(!WALK) setWalk(true); CROWN = true; glide = null; crownIntro = true; }
else if(START_WALK){ if(!WALK) setWalk(true); }
if(/[?&]far=1/.test(location.search)){ camDist = 40; camPitch = 0.35; }
if(WATCH_ID) startWatch();

/* ---- ghost: a 1-ruby whisper of the chosen shape where it will land (not a menu) ---- */
var ghostPlainMat = new T.MeshBasicMaterial({color:0xffd700, transparent:true, opacity:0.35, depthWrite:false});
var ghost = new T.Mesh(shapeGeo('cube', window.MINIMUM), ghostPlainMat);
ghost.userData.k = 1;
ghost.visible = false; scene.add(ghost);
function refreshGhost(){
  var base = shapeBase(curShapeKey), ghostly = shapeIsGhost(curShapeKey);
  var k = legalK1(base);
  ghost.geometry.dispose();
  ghost.geometry = shapeGeo(base, window.MINIMUM);
  ghost.material = ghostly ? intaglioMat : ghostPlainMat;
  ghost.scale.set(k, k, k);
  ghost.userData.k = k;
}

/* ---- the code popup: the shape's own code is the only thing that pops up on each block ---- */
var rubiEl = document.getElementById('rubicount'), rubiT = null;
function shapeCodeOf(shapeKey){
  var base = shapeBase(shapeKey), ghostly = shapeIsGhost(shapeKey);
  var c = SHAPE_CODES[base]||'?';
  return ghostly ? c.toUpperCase() : c;
}
function showShapeCode(g){
  var u = g.userData, r = u.rubies||1;
  var top = r*(u.k1||1)*window.MINIMUM;
  var v = new T.Vector3(g.position.x, g.position.y + top + 0.7, g.position.z).project(camera);
  rubiEl.style.left = ((v.x*0.5+0.5)*window.innerWidth)+'px';
  rubiEl.style.top = ((-v.y*0.5+0.5)*window.innerHeight)+'px';
 