Toroidal world: boundless wrapping globe, 2x2 even town grid
The map is now a torus - walk off any edge and reappear on the opposite side, no edges or corners. A new Toroidal helper carries all wrap-aware distance/direction/movement math, and every position comparison in the sim routes through it: soul pressure, node + structure sensing, gift/teacher/ neighbor scans, bonding, movement, the spatial grids (NPC and node cell index both wrap their bucket lookups at the seam), and town centroid (averaged in anchor-relative deltas, since averaging raw coordinates across the seam is meaningless). Towns re-laid as a 2x2 even grid on the torus (quarter/three-quarter points, 320 & 960 on a 1280 world): every town sits exactly 640 units from each of its two axis-neighbours in all directions, wrap included - no more edge-boxed North/South that could only forage inward. World grew 1152 -> 1280 with resources scaled to area. Verified over a 240-day soak: all four towns alive and balanced (pop 23-25), population stable ~96, 119 bonds (27 cross-town), cultures still diverge, and wrapped distances correctly cap at the torus half-diagonal (no false across-seam blowups). 183s headless. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -41,11 +41,16 @@ public class SpatialGrid
|
||||
public void ForEachNear(Vector2 center, float radius, System.Action<Npc> action)
|
||||
{
|
||||
int reach = Mathf.CeilToInt(radius / _cell);
|
||||
int cols = Mathf.CeilToInt(Toroidal.Size / _cell); // buckets per axis
|
||||
var (cx, cy) = Key(center);
|
||||
// Wrap bucket coordinates so a search near the seam also scans the
|
||||
// buckets on the far edge — the world is a torus.
|
||||
for (int dx = -reach; dx <= reach; dx++)
|
||||
for (int dy = -reach; dy <= reach; dy++)
|
||||
{
|
||||
if (_buckets.TryGetValue((cx + dx, cy + dy), out var list))
|
||||
int gx = ((cx + dx) % cols + cols) % cols;
|
||||
int gy = ((cy + dy) % cols + cols) % cols;
|
||||
if (_buckets.TryGetValue((gx, gy), out var list))
|
||||
foreach (var npc in list) action(npc);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user