我是一名独自开发的多人休闲钓鱼游戏的开发者,业余时间在开发,我遇到了一个我一开始甚至没意识到是 bug 的问题。森林看起来...有点太整齐了!
山谷中的每棵树、每块石头、每根芦苇、每朵花和每只萤火虫都是通过有种子的散射(scatter)放置的,因此每个玩家看到的世界都是一样的。
我的散射函数使用了线性同余生成器(LCG,经典的“乘、加、取模”随机数生成器),并将结果对 x 和 z 位置取模 448。
陷阱在于:LCG 的低位在非常短的周期中会重复。仅仅对数字取模只保留了这些弱的低位,因此位置的随机性并不像看起来那样强。当我测量时,63% 的树木最近邻在同一方向,这说明它们排列成行。
修复方法很小:
- 将 LCG 换成 mulberry32,一个体积小但 32 位的生成器,仍然有种子且决定性。
- 在四分之一块位置上放置物体,而不是原始的模组网格上。
- 添加一个测试,测量最近邻方向并检查它们均匀分布,防止问题悄然重现。
两件我没料到的事:
- 更改生成器会导致所有散射所放置的内容都移动,而不仅仅是树木。由于它是有种子的,所有人看到的都是一样的,但整个地图会整体平移。
新布局让一棵树和一块岩石紧贴在某个小屋的墙壁旁。因此,现在树木和草地岩石在小屋四周保持了清晰的空地。
最大的收获是:“随机”和“看起来随机”并不相同,快速的统计测试(在这里最近邻方向效果很好)比肉眼检查截图快得多,能及时发现问题。
还有其他人也被弱随机数生成器在程序生成中咬过吗?现在你用什么做有种子的散射?
评论 (0)