<!-- RUBY-BACKUP · part 467 -->
.set(i*3.5 - length*1.75, height*0.4, (Math.random()-0.5)*4);
    peak.rotation.y = Math.random()*Math.PI;
    g.add(peak);
    /* snow cap */
    if(height > 4){
      var snow = new THREE.Mesh(
        new THREE.ConeGeometry(0.8, 1.2, 7),
        new THREE.MeshStandardMaterial({color: 0xffffff, roughness: 0.6, flatShading: true})
      );
      snow.position.copy(peak.position);
      snow.position.y += height*0.45;
      g.add(snow);
    }
  }
  g.position.set(x*0.13, 0, z*0.13);
  return g;
}
function buildRoughTerrain(x, z, size){
  var g = new THREE.Group();
  /* jagged rocks */
  for(var i=0; i<30; i++){
    var rock = new THREE.Mesh(
      new THREE.DodecahedronGeometry(0.3+Math.random()*0.8, 0),
      new THREE.MeshStandardMaterial({
        color: new THREE.Color().setHSL(0.08, 0.2, 0.2+Math.random()*0.2),
        roughness: 1, flatShading: true
      })
    );
    rock.position.set(
      (Math.random()-0.5)*size,
      Math.random()*1.5,
      (Math.random()-0.5)*size
    );
    rock.rotation.set(Math.random()*Math.PI, Math.random()*Math.PI, Math.random()*Math.PI);
    g.add(rock);
  }
  g.position.set(x*0.13, 0, z*0.13);
  return g;
}
function buildCliffTrail(x, z, height){
  var g = new THREE.Group();
  /* cliff face */
  var cliff = new THREE.Mesh(
    new THREE.BoxGeometry(4, height, 1),
    new THREE.MeshStandardMaterial({color: 0x5a4a3a, roughness: 0.95, flatShading: true})
  );
  cliff.position.y = height/2;
  g.add(cliff);
  /* trail — zigzag path down */
  var trailMat = new THREE.MeshStandardMaterial({color: 0x8a6a4a, roughness: 0.9});
  var segments = 6;
  for(var i=0; i<segments; i++){
    var y = height - (i+0.5)*(height/segments);
    var segX = (i%2===0 ? 1.2 : -1.2);
    var trail = new THREE.Mesh(new THREE.BoxGeometry(2.5, 0.1, 0.8), trailMat);
    trail.position.set(segX*0.5, y, 0.6);
    g.add(trail);
    /* rope railing */
    var rail = new THREE.Mesh(
      new THREE.CylinderGeometry(0.02, 0.02, 2.5, 6),
      new THREE.MeshStandardMaterial({color: 0x6a4a2a, roughness: 0.8})
    );
    rail.rotation.z = Math.PI/2;
    rail.position.set(segX*0.5, y+0.4, 0.9);
    g.add(rail);
  }
  g.position.set(x*0.13, 0, z*0.13);
  return g;
}
function buildIsland(x, z, radius, hasVolcano){
  var g = new THREE.Group();
  /* island base — sand to grass */
  var sand = new THREE.Mesh(
    new THREE.CylinderGeometry(radius, radius*1.2, 1, 24),
    new THREE.MeshStandardMaterial({color: 0xd4b86a, roughness: 0.9})
  );
  sand.position.y = 0.5;
  g.add(sand);
  var grass = new THREE.Mesh(
    new THREE.CylinderGeometry(radius*0.8, radius*0.9, 0.8, 20),
    new THREE.MeshStandardMaterial({color: 0x3a7a3a, roughness: 0.9})
  );
  grass.position.y = 1.2;
  g.add(grass);
  /* water ring */
  var water = new THREE.Mesh(
    new THREE.TorusGeometry(radius*1.3, 0.5, 8, 32),
    new THREE.MeshStandardMaterial({color: 0x0088cc, transparent: true, opacity: 0.7, roughness: 0.2})
  );
  water.rotation.x = Math.PI/2;
  water.position.y = 0.3;
  g.add(water);
  if(hasVolcano){
    var v = buildVolcano(0, 0, radius*0.4);
    v.position.y = 1.5;
    g.add(v);
  }
  g.position.set(x*0.13, 0, z*0.13);
  return g;
}

/* HAWAIIAN VALLEYS — like home */
var VALLEYS = null;
function buildWaterfall(x, y, z, height){
  var g = new THREE.Group();
  /* falling water — translucent */
  var water = new THREE.Mesh(
    new THREE.PlaneGeometry(1.2, height),
    new THREE.MeshStandardMaterial({
      color: 0xaaddff, transparent: true, opacity: 0.7,
      roughness: 0.1, side: THREE.DoubleSide
    })
  );
  water.position.y = height/2;
  g.add(water);
  /* mist at base */
  for(var i=0; i<3; i++){
    var mist = new THREE.Mesh(
      new THREE.SphereGeometry(0.4+i*0.2, 8, 8),
      new THREE.MeshStandardMaterial({color: 0xffffff, transparent: true, opacity: 0.3})
    );
    mist.position.set((Math.random()-0.5)*1.5, 0.3, (Math.random()-0.5)*1.5);
    g.add(mist);
  }
  /* pool */
  var pool = new THREE.Mesh(
    new THREE.CylinderGeometry(1.5, 1.5, 0.2, 16),
    new THREE.MeshStandardMaterial({color: 0x0088aa, transparent: true, opacity: 0.8, roughness: 0.1})
  );
  pool.position.y = 0.1;
  g.add(pool);
  g.position.set(x, y, z);
  /* animated flow */
  var t = 0;
  var anim = setInterval(function(){
    t += 0.05;
    water.material.opacity = 0.6 + Math.sin(t*3)*0.15;
  }, 50);
  g.userData.anim = anim;
  return g;
}
function buildHawaiianValley(x, z, width, depth){
  var g = new THREE.Group();
  var green = new THREE.MeshStandardMaterial({color: 0x2a6a2a, roughness: 0.95});
  var darkGreen = new THREE.MeshStandardMaterial({color: 0x1a4a1a, roughness: 0.95});
  var paliMat = new THREE.MeshStandardMaterial({color: 0x3a5a3a, roughness: 0.9, flatShading: true});
  /* valley floor — lush */
  var floor = new THREE.Mesh(
    new THREE.PlaneGeometry(width, depth),
    green
  );
  floor.rotation.x = -Math.PI/2;
  floor.position.y = 0.05;
  g.add(floor);
  /* pali walls — steep, both sides */
  [-