diff options
| author | Somhairle H. Marisol <[email protected]> | 2026-09-22 02:57:12 +0800 |
|---|---|---|
| committer | Somhairle H. Marisol <[email protected]> | 2026-09-22 02:57:12 +0800 |
| commit | d06656aa968ccb2769ba7c90c97f57f2818bb828 (patch) | |
| tree | 4b1d8422233517830e1081c70eff86e241483590 /src/LivingVillage.Desktop/WorldBootstrap.fs | |
| parent | d3c0ef17cb1c4d30c1d586e2a5b616f58bd3d875 (diff) | |
| download | living-village-d06656aa968ccb2769ba7c90c97f57f2818bb828.tar.gz | |
feat(mapgen): 生成器序列化 + 世界站位接入(P20 第三步 A)
- MapGen.serialize:生成结果的确定性序列化(尺寸/seed/瓦片/Rivers/Bridges/
Paths/Buildings),同 seed 逐字节一致,供回归与跨机核对。
- WorldBootstrap.initialWorldWithPlacement:显式站位建世界;旧 64x48 路径
(initialWorld/initialWorldWithOccupation)字节口径不变。
- WorldBootstrap.initialWorldInMap:用生成器核心可达区做站位,30 spawn 全落
可达核心;新增 serialization/placement 两条测试。
- fsproj:MapGen 先于 WorldBootstrap 编译。
- Desktop 119->121,Kernel 90 不变。
Diffstat (limited to 'src/LivingVillage.Desktop/WorldBootstrap.fs')
| -rw-r--r-- | src/LivingVillage.Desktop/WorldBootstrap.fs | 35 |
1 files changed, 29 insertions, 6 deletions
diff --git a/src/LivingVillage.Desktop/WorldBootstrap.fs b/src/LivingVillage.Desktop/WorldBootstrap.fs index f8ba775..bf0ef65 100644 --- a/src/LivingVillage.Desktop/WorldBootstrap.fs +++ b/src/LivingVillage.Desktop/WorldBootstrap.fs @@ -35,17 +35,26 @@ module WorldBootstrap = nowTick state.Today } - let initialWorldWithOccupation (startAtDaylight: bool) (seed: uint64) (count: int) (occupation: Occupation.State option) : World = - if count < 0 || count > npcSpawnTiles.Length then + /// 以显式站位建世界:avatarTile 为玩家出生瓦片,npcTiles 为 NPC 出生瓦片序列。 + /// 64x48 旧档与世界走 `avatarSpawnPosition` + `npcSpawnTiles` 的等价调用,字节口径不变。 + let initialWorldWithPlacement + (startAtDaylight: bool) + (seed: uint64) + (count: int) + (avatarTile: int * int) + (npcTiles: (int * int) list) + (occupation: Occupation.State option) : World = + if count < 0 || count > npcTiles.Length then invalidArg (nameof count) "Desktop bootstrap supports at most 30 NPCs." + let avatarPosition = tileCenter (fst avatarTile) (snd avatarTile) let startTick = if startAtDaylight then daylightStartTick else 0L let baseWorld = Sim.initialWorldN seed count let avatar = let baseAvatar = { baseWorld.Avatar with - Pos = avatarSpawnPosition - Mind = { baseWorld.Avatar.Mind with Target = avatarSpawnPosition } } + Pos = avatarPosition + Mind = { baseWorld.Avatar.Mind with Target = avatarPosition } } match occupation with | None -> baseAvatar | Some state -> @@ -56,11 +65,11 @@ module WorldBootstrap = Needs = { needs with Money = float32 state.Profile.InitialMoney - Energy = state.Profile.InitialEnergy } } } + Energy = float32 state.Profile.InitialEnergy } } } let npcs = baseWorld.Npcs |> Array.mapi (fun index npc -> - let x, y = npcSpawnTiles.[index] + let x, y = List.item index npcTiles { npc with Pos = tileCenter x y }) { baseWorld with @@ -69,6 +78,20 @@ module WorldBootstrap = Avatar = avatar Npcs = npcs } + let initialWorldWithOccupation (startAtDaylight: bool) (seed: uint64) (count: int) (occupation: Occupation.State option) : World = + initialWorldWithPlacement + startAtDaylight + seed + count + (31, 25) + (List.ofArray npcSpawnTiles) + occupation + + /// P20 第三步:默认可玩世界。生成器的核心可达区作为站位,30 个 spawn 全部落核心可达域。 + let initialWorldInMap (startAtDaylight: bool) (seed: uint64) (count: int) (map: MapGen.Result) : World = + let avatarTile = ((map.Core.MinX + map.Core.MaxX) / 2, (map.Core.MinY + map.Core.MaxY) / 2) + initialWorldWithPlacement startAtDaylight seed count avatarTile map.Spawns None + let initialWorldForDaylight (startAtDaylight: bool) (seed: uint64) (count: int) : World = initialWorldWithOccupation startAtDaylight seed count None |
