Grid-scope the food-gift and trade-partner searches
Route the two remaining full-population scans (a hungry villager seeking someone with food; a trader seeking a partner) through the NPC spatial grid with a 60-cell reach instead of scanning all ~80 villagers. Realistic reach, cheaper at scale. (A resource-node spatial index was also tried and reverted: benchmarked ~13% slower - at ~1,260 nodes the linear array scan is cache-friendly and beats a dictionary-of-lists ring search. The node scan was never the bottleneck; profile before optimizing next time.) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
+15
-11
@@ -453,15 +453,17 @@ public class Npc
|
||||
// this keeps gifts meaningful instead of a food-swapping loop.
|
||||
if (Nourishment >= 0.55f) { Enter(NpcState.Socializing); return; }
|
||||
float bestScore = float.MinValue;
|
||||
foreach (var other in gm.Npcs)
|
||||
Npc? giftFound = null;
|
||||
gm.Grid.ForEachNear(Position, 60f, other =>
|
||||
{
|
||||
if (other == this) continue;
|
||||
if (other == this) return;
|
||||
float warmth = GetWarmth(other.Name);
|
||||
if (warmth < -0.3f) continue;
|
||||
if (!other.Inventory.TryGetValue(MaterialKind.Food, out float f) || f <= 3f) continue;
|
||||
if (warmth < -0.3f) return;
|
||||
if (!other.Inventory.TryGetValue(MaterialKind.Food, out float f) || f <= 3f) return;
|
||||
float score = warmth * 40f - Position.DistanceTo(other.Position);
|
||||
if (score > bestScore) { bestScore = score; _giftSource = other; }
|
||||
}
|
||||
if (score > bestScore) { bestScore = score; giftFound = other; }
|
||||
});
|
||||
_giftSource = giftFound;
|
||||
if (_giftSource != null) return;
|
||||
}
|
||||
|
||||
@@ -503,13 +505,15 @@ public class Npc
|
||||
if (_targetNpc == null)
|
||||
{
|
||||
float bestDist = float.MaxValue;
|
||||
foreach (var other in gm.Npcs)
|
||||
Npc? partner = null;
|
||||
gm.Grid.ForEachNear(Position, 60f, other =>
|
||||
{
|
||||
if (other == this) continue;
|
||||
if (!TradeSystem.CanTrade(this, other, out _)) continue;
|
||||
if (other == this) return;
|
||||
if (!TradeSystem.CanTrade(this, other, out _)) return;
|
||||
float d = Position.DistanceSquaredTo(other.Position);
|
||||
if (d < bestDist) { bestDist = d; _targetNpc = other; }
|
||||
}
|
||||
if (d < bestDist) { bestDist = d; partner = other; }
|
||||
});
|
||||
_targetNpc = partner;
|
||||
if (_targetNpc == null) { Enter(NpcState.Building); return; }
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user