summaryrefslogtreecommitdiff
path: root/src/LivingVillage.Kernel/Sim.fs
diff options
context:
space:
mode:
Diffstat (limited to 'src/LivingVillage.Kernel/Sim.fs')
-rw-r--r--src/LivingVillage.Kernel/Sim.fs39
1 files changed, 39 insertions, 0 deletions
diff --git a/src/LivingVillage.Kernel/Sim.fs b/src/LivingVillage.Kernel/Sim.fs
index 62ce1e1..ebc435e 100644
--- a/src/LivingVillage.Kernel/Sim.fs
+++ b/src/LivingVillage.Kernel/Sim.fs
@@ -119,6 +119,10 @@ module Sim =
let chatSocialRestore = 40.0f
let chatValence = 0.3f
+ // 关系网派生(纯函数;仅在 dump/视图打开时调用,不进 step 热路径)
+ let relationHalfLifeTicks = 86400L // HALF_LIFE = 1 天(86400 tick)
+ let relationThreshold = 0.5f // |rel| > 0.5 视为有关系
+
let clamp (v: float32) (lo: float32) (hi: float32) : float32 = if v < lo then lo elif v > hi then hi else v
let hungerDecayPerTick = 0.0012f
@@ -429,3 +433,38 @@ module Sim =
NoHost = world.NoHost
Npcs = newNpcs
Events = [] }
+
+ // ---- 关系网派生:rel(i,j) = sum(Chatted valence * exp(-(now-tick)/HALF_LIFE)) ----
+
+ let relationDecayWeight (nowTick: int64) (eventTick: int64) : float32 =
+ let age = float (nowTick - eventTick)
+ float32 (exp (-age / float relationHalfLifeTicks))
+
+ // 30x30 对称矩阵(对角线 0):双向累加双方 Chatted 记忆的衰减 valence
+ let relationMatrix (world: World) : float32[,] =
+ let n = world.Npcs.Length
+ let m = Array2D.zeroCreate n n
+ for npc in world.Npcs do
+ let i =
+ match npc.Id with
+ | NpcId i -> i
+ for e in npc.Mind.Memory do
+ match e.Kind with
+ | Chatted partner when e.Tick <= world.Tick ->
+ let j =
+ match partner with
+ | NpcId j -> j
+ if i <> j && i < n && j < n then
+ let w = e.Valence * relationDecayWeight world.Tick e.Tick
+ m.[i, j] <- m.[i, j] + w
+ m.[j, i] <- m.[j, i] + w
+ | _ -> ()
+ m
+
+ let relationCounts (m: float32[,]) : int[] =
+ let n = Array2D.length1 m
+ Array.init n (fun i ->
+ let mutable c = 0
+ for j in 0 .. n - 1 do
+ if i <> j && abs m.[i, j] > relationThreshold then c <- c + 1
+ c)