<!-- LIVE · part 103 -->
   spireCrown.position.set(CX, DEPTH + 86, CZ);
    scene.add(spireCrown);

    /* FOUR GUARDIAN SPIRES */
    var guardians = [{x: 40, z: 0}, {x: -40, z: 0}, {x: 0, z: 40}, {x: 0, z: -40}];
    for(var g = 0; g < guardians.length; g++){
      var gx = guardians[g].x, gz = guardians[g].z;
      var tower = new THREE.Mesh(new THREE.CylinderGeometry(2, 4, 40, 6), chromeMat);
      tower.position.set(gx, DEPTH + 22, gz);
      scene.add(tower);
      var tip = new THREE.Mesh(new THREE.OctahedronGeometry(3), goldMat);
      tip.position.set(gx, DEPTH + 44, gz);
      scene.add(tip);
    }

    /* THRONE */
    var throne = new THREE.Group();
    var seat = new THREE.Mesh(new THREE.BoxGeometry(6, 1, 4), goldMat);
    seat.position.y = 3;
    throne.add(seat);
    var backrest = new THREE.Mesh(new THREE.BoxGeometry(6, 8, 1), goldMat);
    backrest.position.set(0, 7, -1.5);
    throne.add(backrest);
    throne.position.set(CX, DEPTH + 2, CZ + 15);
    throne.rotation.y = Math.PI;
    scene.add(throne);

    
    
    /* SPARSE VILLAGE — few homes, much nature. Sun for all living things.
       King's word 2026-10-07: sparse below, sky open above. */
    (function buildSparseVillage(){
      var seed = 777;
      function srand(){ seed = (seed * 16807) % 2147483647; return (seed - 1) / 2147483646; }

      var woodMat = new THREE.MeshStandardMaterial({color: 0x6b4a2f, roughness: 0.9});
      var leafMat = new THREE.MeshStandardMaterial({color: 0x2d6a2d, roughness: 0.8});
      var stoneMat = new THREE.MeshStandardMaterial({color: 0x888888, roughness: 0.85});
      var glowMat = new THREE.MeshBasicMaterial({color: 0xffd700, transparent: true, opacity: 0.6});

      /* Village center: between THRONE CROWN and NORTHGATE, in the valley */
      var VX = 0, VZ = -200;

      /* Get terrain height at a point */
      function groundY(x, z){
        if(!window.LIVE_TERRAIN) return 0;
        var T = window.LIVE_TERRAIN;
        /* Bilinear sample from heightmap */
        var gx = Math.round((x + T.size/2) / T.size * T.seg);
        var gz = Math.round((z + T.size/2) / T.size * T.seg);
        gx = Math.max(0, Math.min(T.seg, gx));
        gz = Math.max(0, Math.min(T.seg, gz));
        var vi = gz * (T.seg + 1) + gx;
        return T.geo.attributes.position.getY(vi);
      }

      /* SPARSE HOMES — only 7, spread wide */
      for(var hh = 0; hh < 7; hh++){
        var ang = (hh / 7) * Math.PI * 2 + srand() * 0.5;
        var dist = 40 + srand() * 60;
        var hx = VX + Math.cos(ang) * dist;
        var hz = VZ + Math.sin(ang) * dist;
        var hy = groundY(hx, hz);

        var home = new THREE.Group();
        /* Hut body */
        var body = new THREE.Mesh(new THREE.CylinderGeometry(4, 5, 6, 6), woodMat);
        body.position.y = 3;
        home.add(body);
        /* Cone roof */
        var roof = new THREE.Mesh(new THREE.ConeGeometry(6, 4, 6), leafMat);
        roof.position.y = 8;
        home.add(roof);
        /* Warm window glow */
        var win = new THREE.Mesh(new THREE.PlaneGeometry(1.5, 1.5), glowMat);
        win.position.set(0, 3, 5.1);
        home.add(win);

        home.position.set(hx, hy, hz);
        home.rotation.y = srand() * Math.PI * 2;
        scene.add(home);
      }

      /* TREES — many, for sun and shade */
      for(var t = 0; t < 60; t++){
        var tang = srand() * Math.PI * 2;
        var tdist = 20 + srand() * 150;
        var tx = VX + Math.cos(tang) * tdist;
        var tz = VZ + Math.sin(tang) * tdist;
        var ty = groundY(tx, tz);
        if(ty < 2) continue; /* No trees in water/low */

        var tree = new THREE.Group();
        var trunkH = 4 + srand() * 4;
        var trunk = new THREE.Mesh(new THREE.CylinderGeometry(0.5, 0.8, trunkH, 5), woodMat);
        trunk.position.y = trunkH / 2;
        tree.add(trunk);
        var crownR = 2 + srand() * 2;
        var crown = new THREE.Mesh(new THREE.SphereGeometry(crownR, 7, 6), leafMat);
        crown.position.y = trunkH + crownR * 0.6;
        /* Slight squash for natural look */
        crown.scale.y = 0.8;
        tree.add(crown);

        tree.position.set(tx, ty, tz);
        tree.rotation.y = srand() * Math.PI * 2;
        scene.add(tree);

        /* Gentle sway */
        window._dynamics.push((function(tr, ph){
          return function(time){
            tr.rotation.z = Math.sin(time * 0.8 + ph) * 0.03;
          };
        })(tree, srand() * 10));
      }

      /* PLANTS — ground cover, sun-lovers */
      var plantMat = new THREE.MeshStandardMaterial({color: 0x3d8a3d, roughness: 0.9});
      for(var p = 0; p < 100; p++){
        var pang = srand() * Math.PI * 2;
        var pdist = 10 + srand() * 180;
        var px = VX + Math.cos(pang) * pdist;
        var pz = VZ + Math.sin(pang) * pdist;
        var py = groundY(px, pz);
        if(py < 1) continue;

        var plant = new THREE.Mesh(new THREE.ConeGeometry(0.8 + srand()*0.8, 1.5 + srand()*1.5, 5), plantMat);
        plant.