<!-- RUBY-BACKUP · part 439 -->
tion(s){
    var stripe = new THREE.Mesh(new THREE.BoxGeometry(0.02, 0.06, 0.3), yellow);
    stripe.position.set(0.1, 1.1, s*0.15); g.add(stripe);
  });
  /* turnout gear body */
  var body = new THREE.Mesh(new THREE.CylinderGeometry(0.2, 0.24, 0.9, 12), gear);
  body.position.y = 1.0; g.add(body);
  /* reflective band */
  var band = new THREE.Mesh(new THREE.CylinderGeometry(0.215, 0.215, 0.08, 12), yellow);
  band.position.y = 1.1; g.add(band);
  [-1,1].forEach(function(s){
    var leg = new THREE.Mesh(new THREE.CylinderGeometry(0.08, 0.07, 0.55, 8), gear);
    leg.position.set(0, 0.28, s*0.11); g.add(leg);
    var boot = new THREE.Mesh(new THREE.BoxGeometry(0.2, 0.1, 0.12),
      new THREE.MeshStandardMaterial({color: 0x222222, roughness: 0.8}));
    boot.position.set(0.05, 0.05, s*0.11); g.add(boot);
  });
  /* holding empty hands out — where's the hydrant? */
  [-1,1].forEach(function(s){
    var arm = new THREE.Mesh(new THREE.CylinderGeometry(0.055, 0.05, 0.45, 8), gear);
    arm.position.set(0.1, 1.1, s*0.28); arm.rotation.x = s*0.6; arm.rotation.z = -0.4;
    g.add(arm);
  });
  /* speech — "Where's the hydrant?" */
  var cv = document.createElement('canvas');
  cv.width = 512; cv.height = 80;
  var ctx = cv.getContext('2d');
  ctx.fillStyle = 'rgba(255,240,240,0.95)';
  ctx.fillRect(0, 0, 512, 80);
  ctx.strokeStyle = '#cc3300'; ctx.lineWidth = 4;
  ctx.strokeRect(4, 4, 504, 72);
  ctx.fillStyle = '#cc3300'; ctx.font = 'bold 24px Arial'; ctx.textAlign = 'center';
  ctx.fillText("Where's the hydrant?", 256, 48);
  var tex = new THREE.CanvasTexture(cv);
  var bubble = new THREE.Mesh(new THREE.PlaneGeometry(2.2, 0.34),
    new THREE.MeshBasicMaterial({map: tex, transparent: true}));
  bubble.position.set(0, 2.1, 0);
  g.add(bubble);
  /* fire hydrant — hidden nearby for the player to find */
  var hydrant = new THREE.Group();
  var hBody = new THREE.Mesh(new THREE.CylinderGeometry(0.15, 0.18, 0.4, 10),
    new THREE.MeshStandardMaterial({color: 0xff0000, roughness: 0.5}));
  hBody.position.y = 0.3; hydrant.add(hBody);
  var hTop = new THREE.Mesh(new THREE.SphereGeometry(0.12, 10, 10),
    new THREE.MeshStandardMaterial({color: 0xcc0000, roughness: 0.5}));
  hTop.position.y = 0.55; hydrant.add(hTop);
  [-1,1].forEach(function(s){
    var cap = new THREE.Mesh(new THREE.CylinderGeometry(0.06, 0.06, 0.08, 8),
      new THREE.MeshStandardMaterial({color: 0xaa0000, roughness: 0.5}));
    cap.rotation.z = Math.PI/2;
    cap.position.set(0, 0.35, s*0.18); hydrant.add(cap);
  });
  /* hide it — behind a building, player must find */
  hydrant.position.set(x+8, 0, z+5);
  hydrant.visible = false; /* hidden until found */
  g.add(hydrant);
  g.userData.hydrant = hydrant;
  g.position.set(x, y, z);
  var t = Math.random()*10;
  var anim = setInterval(function(){
    t += 0.03;
    /* searching — looking left and right */
    g.rotation.y = Math.sin(t*1.2)*0.8;
    bubble.rotation.y = -g.rotation.y;
  }, 50);
  g.userData.anim = anim;
  return g;
}
function placeOfficerAndFirefighter(){
  if(typeof scene==='undefined' || typeof mePos==='undefined') return;
  if(OFFICER_GROUP){
    OFFICER_GROUP.forEach(function(o){
      try{ scene.remove(o); }catch(e){}
      if(o.userData.anim) clearInterval(o.userData.anim);
    });
  }
  OFFICER_GROUP = [];
  var px = mePos.x, pz = mePos.z;
  /* officer — near downtown */
  var officer = buildPoliceOfficer((px+10)*0.13, 0, (pz+10)*0.13);
  scene.add(officer);
  OFFICER_GROUP.push(officer);
  /* firefighter — near downtown */
  var ff = buildFirefighter((px-10)*0.13, 0, (pz-10)*0.13);
  scene.add(ff);
  OFFICER_GROUP.push(ff);
  codeStatus('officer needs his pad. Firefighter needs a hydrant. Help them.');
}

/* 60 SIDE QUESTS — randomly generated */
var SIDE_QUESTS = [
  {id: 1, giver: 'Officer', text: 'Find my missing pad', loc: 'city'},
  {id: 2, giver: 'Firefighter', text: 'Find the hidden hydrant', loc: 'city'},
  {id: 3, giver: 'Kai', text: 'Find three gears for the broken robot', loc: 'dark'},
  {id: 4, giver: 'Leilani', text: 'Share water with the tree beggar', loc: 'dark'},
  {id: 5, giver: 'Makoa', text: 'Help the question guy find one answer', loc: 'dark'},
  {id: 6, giver: 'Nalani', text: 'Sing with the homeless soul', loc: 'dark'},
  {id: 7, giver: 'Shopkeeper', text: 'Deliver goods to the market', loc: 'city'},
  {id: 8, giver: 'Farmer', text: 'Help harvest the crops', loc: 'rural'},
  {id: 9, giver: 'Elder', text: 'Listen to the tribal story', loc: 'tribal'},
  {id: 10, giver: 'Child', text: 'Play at the playground', loc: 'plaza'},
  {id: 11, giver: 'Fisherman', text: 'Catch a fish at storm beach', loc: 'dark'},
  {id: 12, giver: 'Sailor', text: 'Wave to Hokulea in orbit', loc: 'spaceport'},
  {id: 13, giver: 'Teacher', text: 'Bring a book to the school', loc: 'city'},
  {id: 14, giver: 'Healer', text: 'Gather herbs from the valley', loc: 'valley'},
  {id: 15, giver: 'Builder', text: 'Help raise a new tower', loc: 'city'},
  {id: