2021年的字节夏令营,我们队伍的目标是为吃鸡游戏或其他箱庭游戏快速生成3D地图,或辅助设计师进行游戏地图的设计。PCG的生成质量评估有以下5个维度:
- 可靠性:生成的内容总能符合预期需求,不存在无解或者bug。
- 可控性:应当将场景样式的主要参数暴露给用户,让用户可以通过调参生成特征不同的场景,例如植被的覆盖率、水体覆盖率、地形的平坦程度……
- 表现力与多样性:即使给定同样的参数,也应当能够生成重复性低、表现多样、有差异性的地图。
- 创造力和可信度:不能让人一眼就看出来是程序生成的。
- 速度与效率:不同的应用场景(离线/在线)有不同的效率要求。
项目简介
我们主要的应用场景是类PUBG的吃鸡环境或其他箱庭玩法的游戏。它是在一个海岛上,同时生成丘陵、原野与城市相混合的两种地形。我们的目标是为类PUBG游戏生成满足游戏素材要求与玩法规则限制的游戏大地图内容,并在Unity中渲染生成好的游戏场景。用户可以定义地图参数,如海岛数量、植被覆盖率、水体面积、人迹面积(城镇区域占海岛陆地总面积的比例)、城镇数量、城镇的连通方式(一字型、星型、环型)等,算法利用用户给定的资源素材与参数自动生成一个满足用户需求的3D地图。
我们方法的主要流程如下所示:
1 大地图地形地貌生成
我们首先在全是海域的地图中随机取一个点作为初始的种子点seedPoint,然后用并查集的思想,从这颗种子处逐渐生长扩张,长成一个岛屿。伪代码如下所示:
array.push(seedPoint)
result.push(seedPoint)
while(!array.empty() && result.length < count) // count为陆地的总面积
{
randomID = randInt(array.length) // randomID取随机数[0, array.length)
if(array[randomID]的上下左右皆为陆地){
array.remove(randomID)
continue;
}
从array[randomID]的上下左右四个区域中随机挑选出一个类型为海域的点newLand
array.push(newLand)
result.push(newLand)
}
由大数定理知:岛屿的扩展方向在任意方向上是相同的,因此最终生成的陆地区域趋近圆形。
如果大陆由N个岛屿组成,则可以先通过泊松分布采样方法分别采样N个起始种子点,再将N个种子点同时用同样的速度进行生长扩张,并用水域隔开不同的岛屿,就能得到由N个岛屿组成的大陆。
可以在岛屿区域上取表征地形高度的噪声(如柏林噪声),生成高低起伏的地形。高于某一阈值的区域未来会进一步生成丘陵区域,低于该阈值的平坦区域未来有可能采样成城镇区域,没有采样成城镇区域的平坦地区未来会成为原野。如下图所示。
2 生成河流
河流可以从丘陵中最高的位置为起点做DFS,每一次都向4个方向中最低的方向流动(如果最低的方向有多个,则随机取一个方向流动),直至汇入到其它水域。如下图所示:
3 城镇区域与主干道
在陆地区域利用柏松分布采样,采样出M个城镇区域的种子点。这M个种子点作为起点,分别同时向周围平坦的区域进行增长,可以生长出M个城镇区域。
设置城镇房屋的样本形状(矩形与 L 形)作为采样建筑库,随机生成建筑的形状参数与层数,即随机生成一个房屋。将生成的房屋随机分布在城镇范围内,并在每个房屋中确定门所在的坐标。先用最小生成树算法生成在同一片城镇的所有建筑入口之间的连通关系,用这棵生成树将同一城镇的所有建筑的入口连通;再通过bfs算法,将各个房屋的门用道路连接在一起,并让这些道路绕过建筑(避障)。
当所有的城镇区域内部的街道全部生成之后,再采用多源bfs的方法生成连接不同城镇道路的主干道。具体做法是:把同一片区域里的道路节点分别编号为区域编号,然后做多源BFS,当遍历到其它区域编号的节点时回溯形成连接这两个编号区域的主干道。直到所有的城市区域全部连通。
4 房间划分
房间划分参考了(Alegre, 2015)。 这一步的目的是任意给定一个房子的外观结构与占地形状后,我们根据功能将房子内部划分为不同的房间,以便之后在特定功能的房间里布置特定功能的家具。例如厕所里只能出现马桶、洗手池或浴缸,不应该出现厨具。
第一步,对房间格子进行划分:
- 先选取墙壁内角交汇的点的x、y轴方向作为分割线,就像红色的线条(L型专有的处理)
- 先选取墙壁内角交汇的点的x、y轴方向作为分割线,就像红色的线条(L型专有的处理)。
- 再选取一个距离tw,二分的去横向切割之前生成的格子,这个过程是递归完成的,直到不再有格子的宽度大于tw。
第二步,房间种子选取:
采用预设的规则采样K个格子作为K个房间的种子点。利用热度图评分计算每个种子点成为特定房间类型的概率。例如有窗户的房间更适合成为厨房、餐厅或卧室;距离门近的房间更适合社交,更适合成为客厅或餐厅;距离门远的房间更适合做卧室……
第三步:种子房间生长:
将所有房间种子的房间类型确定之后,他们将开始争夺未放置的格子来执行房间扩展。首先是将每个单格子的房间扩大到其类型要求的最小大小,每次迭代会根据概率选取方向扩展,直到达到所需的最小大小或者没有可供扩展的方向。
如果上一个步骤中有房间没有达到最小尺寸要求的房间,会试图收缩其周围的房间,并使其向其他方向扩展。直至所有的房间都满足其最小大小。
最后,生成连接大门和较深房间的走廊,每个走廊的宽度为1。当走廊生成之后,不属于任何房间的闲置格子会就近并入最近的房间。
5. 室内家具内饰的自动生成
房间类型确定之后,每个房间可以放置的家具类型也确定。我们采用(Merrell,2011)的方法,用遗传算法来生成特定房间类型中的家具摆设方式。 这一步是通过优化一个能量函数来实现的,这个能量函数由控制功能性与控制美学的两部分组成:控制功能性的部分主要是为了让每个家具都可达,让每个家具都能够以符合人体工学的方式在房间内布置;控制美学的部分是为了让家具的摆放满足视觉对称性、对齐房间的形状与突出视觉重点的要求。
6. 地表装饰
在非城市区域的丘陵与原野区域,以用户给定的概率点缀树木、岩石、花草、蘑菇等地表装饰。
结果展示
该项目需要用户输入少量的参数后一键自动生成不同的地图。
并且,不仅有宏观的地形图,还有微观的景象甚至室内装饰,所有细节都是随机生成的,保证玩家每次进入游戏之后都能在一个全新的地图上探索。
结论
尽管“类PUBG”游戏(《绝地求生》、《荒野行动》、《和平精英》、《堡垒之夜》等)非常火爆,但截止目前为止,尚没有自动生成游戏地图的“类PUBG”游戏。而人工设计师设计开放世界大地图需要较高的人力成本,因此游戏中的地图更迭较慢,而此技术可以直接用于每局游戏地图的随机生成,让每一局游戏都有充满新鲜感的地图体验。 另一方面,游戏地图的绘制对技美水平的要求很高。即使是Houdini这种专业的电影特效PCG软件,也需要用户有专业的地图绘制技能。我们的项目极大缩减了专业建模软件的参数复杂度与使用门槛,即使是青少年也可以通过少量、直观的调参得到庞大、具象的生成结果。它不仅适合作为专业地图设计师的辅助设计工具,让设计师在众多生成结果中挑选满意的生成结果进行二次开发;也可以帮助完全没有地图设计经验的独立游戏制作团体或个人从繁琐的地图制作工作中解放出来,专心致力于游戏玩法与规则机制上的探索。