summaryrefslogtreecommitdiff
path: root/src/LivingVillage.Headless/Program.fs
diff options
context:
space:
mode:
authorSomhairle H. Marisol <[email protected]>2026-09-19 02:24:26 +0800
committerSomhairle H. Marisol <[email protected]>2026-09-19 02:24:26 +0800
commit4627a29302aa780ba8de1e537a869650601debc3 (patch)
treefe9639ce194298372bb59a80244698cbee7811c0 /src/LivingVillage.Headless/Program.fs
parent59458d149d7cecf73e708faa6d9e6db2bcd89dfd (diff)
downloadliving-village-4627a29302aa780ba8de1e537a869650601debc3.tar.gz
feat: M2a NPC 心智基础 — Needs 衰减 + Personality(seed) + 决策层v1(需求缺口×性格权重) + 四语义点直线移动 + headless NPC 摘要 + 对拍/衰减测试
Diffstat (limited to 'src/LivingVillage.Headless/Program.fs')
-rw-r--r--src/LivingVillage.Headless/Program.fs18
1 files changed, 16 insertions, 2 deletions
diff --git a/src/LivingVillage.Headless/Program.fs b/src/LivingVillage.Headless/Program.fs
index ea8b1b0..8c2b6d6 100644
--- a/src/LivingVillage.Headless/Program.fs
+++ b/src/LivingVillage.Headless/Program.fs
@@ -40,6 +40,13 @@ let nextSegment (rng: RngState) (until: int64) : Driver =
Until = until + segmentTicks
Input = { MoveX = dirX * mag; MoveY = dirY * mag } }
+let actionName (k: NpcActionKind) : string =
+ match k with
+ | Eat -> "eat"
+ | Sleep -> "sleep"
+ | Wander -> "wander"
+ | Work -> "work"
+
let runSimulation (days: int64) (seed: uint64) : int =
let totalTicks = days * ticksPerDay
printfn "living-village headless days=%d seed=%d ticks=%d tickrate=%d" days seed totalTicks ticksPerSecond
@@ -63,10 +70,17 @@ let runSimulation (days: int64) (seed: uint64) : int =
if Single.IsNaN p.X || Single.IsNaN p.Y || Single.IsInfinity p.X || Single.IsInfinity p.Y then
nonFinite <- nonFinite + 1L
if p.X < 0.0f || p.X > maxX || p.Y < 0.0f || p.Y > maxY then outOfBounds <- outOfBounds + 1L
- if t % 1000L = 0L then
+ if t % 2000L = 0L then
+ let day = float t / float ticksPerDay
let mem = GC.GetTotalMemory(true)
+ for npc in world.Npcs do
+ let n = npc.Mind.Needs
+ let p' = npc.Pos
+ printfn "npc=%A tick=%d day=%.4f pos=(%.1f,%.1f) hunger=%.2f energy=%.2f social=%.2f money=%.2f action=%s"
+ npc.Id t day p'.X p'.Y n.Hunger n.Energy n.Social n.Money (actionName npc.Mind.Action)
+ if t % 1000L = 0L && t % 2000L <> 0L then
let day = float t / float ticksPerDay
- printfn "tick=%d time=%.4fs day=%.4f pos=(%.1f,%.1f) mem=%d rng=%016x" t world.Time day p.X p.Y mem world.Rng.State
+ printfn "tick=%d time=%.4fs day=%.4f pos=(%.1f,%.1f) rng=%016x" t world.Time day p.X p.Y world.Rng.State
printfn "done tick=%d non-finite=%d out-of-bounds=%d" world.Tick nonFinite outOfBounds
if nonFinite > 0L || outOfBounds > 0L then 1 else 0