<!-- LIVE · part 90 -->
), tipMat);
    tip.position.set(tx, th + tw*0.4, tz);
    scene.add(tip);
  }
  /* 2. Sky bridges between towers */
  var bridgeMat = new THREE.MeshStandardMaterial({color: 0x808080, metalness: 0.6, roughness: 0.4});
  for(var b = 0; b < 15; b++){
    var a1 = rnd() * Math.PI * 2, d1 = 100 + rnd() * 200;
    var a2 = a1 + 0.5 + rnd() * 0.5, d2 = 100 + rnd() * 200;
    var x1 = cityX + Math.cos(a1)*d1, z1 = cityZ + Math.sin(a1)*d1;
    var x2 = cityX + Math.cos(a2)*d2, z2 = cityZ + Math.sin(a2)*d2;
    var h = 120 + rnd() * 80;
    var len = Math.sqrt((x2-x1)*(x2-x1) + (z2-z1)*(z2-z1));
    var bridge = new THREE.Mesh(new THREE.BoxGeometry(len, 4, 8), bridgeMat);
    bridge.position.set((x1+x2)/2, h, (z1+z2)/2);
    bridge.rotation.y = -Math.atan2(z2-z1, x2-x1);
    scene.add(bridge);
  }
  /* 3. World: more mountains */
  var greenMat = new THREE.MeshStandardMaterial({color: 0x2a6a2a, roughness: 0.9});
  for(var m = 0; m < 80; m++){ /* Doubled */
    var mx = (rnd()*12000)-6000, mz = (rnd()*12000)-6000;
    /* Keep clear of city */
    var cdx = mx-100, cdz = mz+100;
    if(Math.sqrt(cdx*cdx+cdz*cdz) < 500) continue;
    var mr = 60 + rnd()*100, mh = 100 + rnd()*150;
    var mtn = new THREE.Mesh(new THREE.ConeGeometry(mr, mh, 9, 5), greenMat);
    mtn.position.set(mx, mh/2, mz);
    solidifyTerrain(mtn);
    scene.add(mtn);
  }
  if(typeof say === 'function') say('Massive upgrade complete');
}, 7000);

window.__sagaExecMark('FOUNDATION');

/* ============================================================
   WORLD FOUNDATION 1 — OBSERVATION ONLY
   2026-10-07

   RULE:
   This system may MEASURE the world.
   It may NOT move kingPos or modify world geometry.
   ============================================================ */

(function(){

  /* Survive accidental re-execution instead of resetting ourselves. */
  if(window.WORLD_FOUNDATION && window.WORLD_FOUNDATION.version === 1){
    return;
  }

  var WF = window.WORLD_FOUNDATION = {
    version: 1,
    unitsPerMeter: 1,
    killY: -500,

    colliders: [],
    colliderByUUID: Object.create(null),

    debug: {
      enabled: false,
      support: null
    }
  };

  var DOWN = new THREE.Vector3(0, -1, 0);
  var ray = new THREE.Raycaster();

  /*
   * Register a mesh without modifying its geometry, transform,
   * material or appearance.
   *
   * UUID is used only as runtime identity in Foundation 1.
   * Persistent world IDs come later.
   */
  WF.registerSurface = function(mesh, kind, metadata){
    if(!mesh || !mesh.isMesh) return null;

    if(WF.colliderByUUID[mesh.uuid]){
      return WF.colliderByUUID[mesh.uuid];
    }

    var entry = {
      runtimeId: mesh.uuid,
      mesh: mesh,
      kind: kind || 'terrain',
      metadata: metadata || {}
    };

    WF.colliders.push(entry);
    WF.colliderByUUID[mesh.uuid] = entry;

    return entry;
  };

  WF.unregisterSurface = function(mesh){
    if(!mesh || !WF.colliderByUUID[mesh.uuid]) return false;

    var entry = WF.colliderByUUID[mesh.uuid];
    delete WF.colliderByUUID[mesh.uuid];

    WF.colliders = WF.colliders.filter(function(e){
      return e !== entry;
    });

    return true;
  };

  /*
   * Find the nearest registered surface immediately below a position.
   *
   * IMPORTANT:
   * This is a SUPPORT query, not a "search the entire world from
   * the sky" query.
   *
   * maxDrop deliberately limits how far below the player we look.
   * Therefore a bridge ABOVE the player can never become support.
   */
  WF.supportBelow = function(position, options){
    options = options || {};

    if(!position) return {
      hit:false,
      valid:false,
      reason:'no_position'
    };

    var startOffset =
      options.startOffset === undefined ? 2.0 : options.startOffset;

    var maxDrop =
      options.maxDrop === undefined ? 8.0 : options.maxDrop;

    var maxSlope =
      options.maxSlope === undefined ? 60 : options.maxSlope;

    if(WF.colliders.length === 0){
      return {
        hit:false,
        valid:false,
        reason:'no_surfaces'
      };
    }

    var origin = new THREE.Vector3(
      position.x,
      position.y + startOffset,
      position.z
    );

    var meshes = WF.colliders.map(function(e){
      return e.mesh;
    });

    ray.set(origin, DOWN);
    ray.near = 0;
    ray.far = startOffset + maxDrop;

    var hits = ray.intersectObjects(meshes, false);

    if(!hits.length){
      return {
        hit:false,
        valid:false,
        reason:'no_support_in_range',
        origin:origin,
        maxDrop:maxDrop
      };
    }

    /* v198: choose nearest hit at or below player support height. */
    var hit = null;
    for(var hi=0; hi<hits.length; hi++){
      if(hits[hi].point.y <= position.y + 0.05){ hit = hits[hi]; break; }
    }
    if(!hit) return {hit:false, valid:false, reason:"no_support_below"};
    var entry = WF.colliderByUUID[hit.object.uuid] || null;

    var normal = hit.face
      ? hit.face.normal.clone().transformDirection