<!-- LIVE · part 43 -->
{
        var good = new THREE.Mesh(new THREE.SphereGeometry(0.3, 8, 6),
          new THREE.MeshStandardMaterial({color: canvasColors[(colorIdx+g) % canvasColors.length]}));
        good.position.set((Math.random()-0.5)*3, 1.7, (Math.random()-0.5)*2);
        st.add(good);
      }
      st.position.set(x, 0.13, z);
      st.rotation.y = rot || 0;
      scene.add(st);
    }

    /* City market — 8 stalls in a row */
    for(var i = 0; i < 8; i++){
      stall(80 + i*8, -120, i, 0);
    }
    /* Village market — 6 stalls in circle */
    for(var j = 0; j < 6; j++){
      var ja = (j / 6) * Math.PI * 2;
      stall(-80 + Math.cos(ja)*25, 180 + Math.sin(ja)*25, j+2, ja);
    }

  }catch(e){ console.error(e); }
}
if(typeof buildMarkets === 'function'){ try{ buildMarkets(); }catch(e){ console.error(e); } }

/* RESIDENTIAL ZONES — where the people live. 2026-10-04. */
function buildHomes(){
  try{
    window._dynamics = window._dynamics || [];
    var wallMat = new THREE.MeshStandardMaterial({color: 0xd4c4a0, roughness: 0.9});
    var roofMat = new THREE.MeshStandardMaterial({color: 0x8a3a1a, roughness: 0.8});

    function house(x, z, rot){
      var h = new THREE.Group();
      /* Walls */
      var walls = new THREE.Mesh(new THREE.BoxGeometry(8, 5, 6), wallMat);
      walls.position.y = 2.5;
      h.add(walls);
      /* Roof */
      var roof = new THREE.Mesh(new THREE.ConeGeometry(6, 3, 4), roofMat);
      roof.position.y = 6.5;
      roof.rotation.y = Math.PI/4;
      h.add(roof);
      /* Door glow */
      var door = new THREE.Mesh(new THREE.PlaneGeometry(1.5, 3),
        new THREE.MeshBasicMaterial({color: 0xffd4a0}));
      door.position.set(0, 1.5, 3.01);
      h.add(door);
      /* Windows */
      for(var w = -1; w <= 1; w += 2){
        var win = new THREE.Mesh(new THREE.PlaneGeometry(1.5, 1.5),
          new THREE.MeshBasicMaterial({color: 0xffeebb}));
        win.position.set(w*2.5, 3, 3.01);
        h.add(win);
      }
      h.position.set(x, 0.13, z);
      h.rotation.y = rot || 0;
      scene.add(h);
      /* Chimney smoke */
      var smoke = new THREE.Mesh(new THREE.SphereGeometry(0.5, 8, 6),
        new THREE.MeshBasicMaterial({color: 0x888888, transparent: true, opacity: 0.4}));
      smoke.position.set(x + 2, 9, z);
      scene.add(smoke);
      var ph = Math.random() * 10;
      window._dynamics.push(function(t){
        smoke.position.y = 9 + ((t + ph) % 3);
        smoke.material.opacity = 0.4 * (1 - ((t + ph) % 3) / 3);
      });
      return h;
    }

    /* Village residential — 12 houses */
    for(var v = 0; v < 12; v++){
      var va = (v / 12) * Math.PI * 2;
      var vx = -80 + Math.cos(va) * 40;
      var vz = 180 + Math.sin(va) * 40;
      house(vx, vz, va + Math.PI/2);
    }
    /* City residential — 8 houses */
    for(var c = 0; c < 8; c++){
      house(100 + (c-4)*20, -50 + (c%2)*30, 0);
    }

  }catch(e){ console.error(e); }
}
if(typeof buildHomes === 'function'){ try{ buildHomes(); }catch(e){ console.error(e); } }

/* FISH — life in the water. 2026-10-04. */
function buildFish(){
  try{
    window._dynamics = window._dynamics || [];
    var fishMat = new THREE.MeshStandardMaterial({color: 0xff8800, roughness: 0.5});
    /* Schools in harbor and tide pools */
    var schools = [
      {x: -100, z: -100, n: 15},  /* Harbor */
      {x: 1200, z: 300, n: 10},   /* Tide pools */
      {x: 3200, z: 500, n: 20}    /* Ocean */
    ];
    for(var s = 0; s < schools.length; s++){
      (function(){
        var sx = schools[s].x, sz = schools[s].z, n = schools[s].n;
        var fishes = [];
        for(var f = 0; f < n; f++){
          var fish = new THREE.Group();
          var body = new THREE.Mesh(new THREE.ConeGeometry(0.4, 1.5, 6), fishMat);
          body.rotation.x = Math.PI/2;
          fish.add(body);
          var tail = new THREE.Mesh(new THREE.PlaneGeometry(0.8, 0.6), fishMat);
          tail.position.z = -0.8;
          fish.add(tail);
          fish.position.set(sx + (Math.random()-0.5)*20, 0.2, sz + (Math.random()-0.5)*20);
          scene.add(fish);
          fishes.push({mesh: fish, tail: tail, off: Math.random()*10});
        }
        var schoolT = Math.random() * 100;
        window._dynamics.push(function(t, dt){
          schoolT += (dt || 0.016) * 0.5;
          for(var i = 0; i < fishes.length; i++){
            var fh = fishes[i];
            /* Swim in circle */
            var a = schoolT + fh.off * 0.3;
            var tx = sx + Math.cos(a) * 12;
            var tz = sz + Math.sin(a) * 12;
            fh.mesh.position.lerp(new THREE.Vector3(tx, 0.2 + Math.sin(t*2+fh.off)*0.1, tz), 0.08);
            fh.mesh.rotation.y = Math.atan2(tx - fh.mesh.position.x, tz - fh.mesh.position.z);
            /* Tail wag */
            fh.tail.rotation.y = Math.sin(t*8 + fh.off) * 0.5;
          }
        });
      })();
    }
  }catch(e){ console.error(e); }
}
if(typeof buildFish === 'function'){ try{ buildFish(); }catch(e){ console.error(e); 