当前版本在 OilWell / oil_reservoir 上存在稳定的世界生成偏差,表现不是单纯的坐标偏移,而是同时包含“数量不对”和“位置不对”两类问题,且主星、副星都可能出现。
具体例子:BAD-A-1348425178-0-D3-0ADC15C2 上,oni_world_app 当前输出的 储油石 归一化后为 101,41、184,46、234,64,而 oxygen-not-included-worldgen 给出的 oil_reservoir 是 101,41、133,35、184,47、234,64,也就是oni_world_app版少了一个 133,35,并且 184,46 与 184,47 还有 1 格偏差;V-FRST-C-1586174440-0-D3-AVUZOM12 上,oni_world_app版当前输出归一化后只有 19,50、179,43、96,38 这 3 个 储油石,而 oxygen-not-included-worldgen 给出的 oil_reservoir 多出了 188,15、179,28、89,30、28,41、84,36。我已经用游戏实测过 oxygen-not-included-worldgen 的结果确实是正确的。
按目前对游戏反编译的分析,OilWell 处理链路大致是:WorldGen.SpawnMobsAndTemplates(...) 先 DetectNaturalCavities(...),然后用 SeededRandom(data.globalTerrainSeed) 遍历 TerrainCells;对每个 cell,先走 MobSpawning.PlaceFeatureAmbientMobs(...),从 node.featureSpecificTags 找到 feature,例如 features/oilpockets/OilWell,再取 tc.GetAvailableSpawnCellsFeature() 作为候选点;这里 GetAvailableSpawnCellsFeature() 的语义是 availableSpawnPoints - availableTerrainPoints,也就是 feature 占掉的那部分 spawn cells;随后过滤 avoidCells(原版这里来自 claimedPOICells,并且会额外排除 Katairite/Unobtanium),再通过 GetMobPossibleSpawnPoints(...) -> IsSuitableMobSpawnPoint(...) 做最终筛选;OilWell 的 mob 配置是 AnyFloor,核心判定包括:锚点在 cavity 中、占用区非 solid、底部需要 solid 支撑;候选点再 ShuffleSeeded(...),最后由 SpawnCountMobs(...) 实际放置并写入 alreadyOccupiedCells。feature ambient 之后,原版才继续 PlaceBiomeAmbientMobs(...)。
尚不清楚是否有更简单的等价实现方案,我也做了修复尝试但失败了。
当前版本在
OilWell / oil_reservoir上存在稳定的世界生成偏差,表现不是单纯的坐标偏移,而是同时包含“数量不对”和“位置不对”两类问题,且主星、副星都可能出现。具体例子:BAD-A-1348425178-0-D3-0ADC15C2 上,oni_world_app 当前输出的 储油石 归一化后为 101,41、184,46、234,64,而 oxygen-not-included-worldgen 给出的 oil_reservoir 是 101,41、133,35、184,47、234,64,也就是oni_world_app版少了一个 133,35,并且 184,46 与 184,47 还有 1 格偏差;V-FRST-C-1586174440-0-D3-AVUZOM12 上,oni_world_app版当前输出归一化后只有 19,50、179,43、96,38 这 3 个 储油石,而 oxygen-not-included-worldgen 给出的 oil_reservoir 多出了 188,15、179,28、89,30、28,41、84,36。我已经用游戏实测过 oxygen-not-included-worldgen 的结果确实是正确的。
按目前对游戏反编译的分析,
OilWell处理链路大致是:WorldGen.SpawnMobsAndTemplates(...)先DetectNaturalCavities(...),然后用SeededRandom(data.globalTerrainSeed)遍历TerrainCells;对每个 cell,先走MobSpawning.PlaceFeatureAmbientMobs(...),从node.featureSpecificTags找到 feature,例如features/oilpockets/OilWell,再取tc.GetAvailableSpawnCellsFeature()作为候选点;这里GetAvailableSpawnCellsFeature()的语义是availableSpawnPoints - availableTerrainPoints,也就是 feature 占掉的那部分 spawn cells;随后过滤avoidCells(原版这里来自claimedPOICells,并且会额外排除Katairite/Unobtanium),再通过GetMobPossibleSpawnPoints(...) -> IsSuitableMobSpawnPoint(...)做最终筛选;OilWell的 mob 配置是AnyFloor,核心判定包括:锚点在 cavity 中、占用区非 solid、底部需要 solid 支撑;候选点再ShuffleSeeded(...),最后由SpawnCountMobs(...)实际放置并写入alreadyOccupiedCells。feature ambient 之后,原版才继续PlaceBiomeAmbientMobs(...)。尚不清楚是否有更简单的等价实现方案,我也做了修复尝试但失败了。