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.
|
// this keeps gifts meaningful instead of a food-swapping loop.
|
||||||
if (Nourishment >= 0.55f) { Enter(NpcState.Socializing); return; }
|
if (Nourishment >= 0.55f) { Enter(NpcState.Socializing); return; }
|
||||||
float bestScore = float.MinValue;
|
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);
|
float warmth = GetWarmth(other.Name);
|
||||||
if (warmth < -0.3f) continue;
|
if (warmth < -0.3f) return;
|
||||||
if (!other.Inventory.TryGetValue(MaterialKind.Food, out float f) || f <= 3f) continue;
|
if (!other.Inventory.TryGetValue(MaterialKind.Food, out float f) || f <= 3f) return;
|
||||||
float score = warmth * 40f - Position.DistanceTo(other.Position);
|
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;
|
if (_giftSource != null) return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -503,13 +505,15 @@ public class Npc
|
|||||||
if (_targetNpc == null)
|
if (_targetNpc == null)
|
||||||
{
|
{
|
||||||
float bestDist = float.MaxValue;
|
float bestDist = float.MaxValue;
|
||||||
foreach (var other in gm.Npcs)
|
Npc? partner = null;
|
||||||
|
gm.Grid.ForEachNear(Position, 60f, other =>
|
||||||
{
|
{
|
||||||
if (other == this) continue;
|
if (other == this) return;
|
||||||
if (!TradeSystem.CanTrade(this, other, out _)) continue;
|
if (!TradeSystem.CanTrade(this, other, out _)) return;
|
||||||
float d = Position.DistanceSquaredTo(other.Position);
|
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; }
|
if (_targetNpc == null) { Enter(NpcState.Building); return; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user