[关闭]
@longfei 2016-12-14T04:54:53.000000Z 字数 4098 阅读 3070

地图生成机制

未分类


概述

饥荒采用基于叙事的世界生成机制,最核心的三个层面分别为level,task和room,可以对应理解为一个世界,一片地形和一块小区域(比如猪王村)。
在沙盒模式下,我们对于level,task,room这些概念不容易理解。但换成了冒险模式,一切就容易理解了。

level

冒险模式要过好几关,每一关都是一个世界,也就是level(关卡),要跳转关卡,通常都会改变整个世界的样子。所以,从沙盒模式来看,地上、地下世界,每个世界各成一个level,SW的世界完全不同于ROG,也是一个level。简单来说,我们可以理解为,一个世界就是一个level。

task

在冒险模式中,我们需要冲破冲冲阻碍获得零件,而在这个过程中,我们要解决一个个阻碍,比如说,你可能需要穿过一片蜘蛛森林地形之后,才能找到存在着牛的大草原。这可以类比RPG中的任务:你完成了穿过蜘蛛森林的任务,来到了大草原。如果你没有完成穿过森林的任务,那么你是不能抵达大草原的。在饥荒的生成机制里,这样的表述使用的是locks和keys对应来做的。大草原有一个lock,它需要蜘蛛森林的key才能解锁。于是通过这样的lock-key对,我们就设定了蜘蛛森林会和大草原连在一起。

room

在每一个任务中,我们都会需要进出各种小房间以获取需要的资源和信息。对应着饥荒的地图,一个task就是由许多的room组成。比如说你要穿过蜘蛛森林,那你就需要燧石和小树枝做出长矛,木头和干草做出木甲。要获得这些资源,我们就必须在一片地形(task)上到处行走搜集。room就是地图定制的最小单位,一个task有若干个room,每个room可以定义资源和布局的分布情况,还可以选定地皮属性。
假定我们在一个名为deepforest的room中获得木头和小树枝,再在一个名为BGGrass的room中获得燧石和干草。这样,我们就有了最初的原材料,可以做出武器防具,向蜘蛛森林进发了。
prefab
我们可以理解为“东西“,是这个世界的最小组成单位。在地图上的每一棵树,每一块石头,都是一个prefab,当我们砍倒了树,掉落了几块木头,那就有了好几个新的prefab。其它诸如池塘,猪人房,鱼人房还有各种生物,也都是prefab。

layout/布局

上面的level-task-room架构,只能泛泛地设定一些参数,然后让prefab按这些参数,随机地分布在地图上。它们是没有办法弄出像猪王+四座固定方尖塔组合,或者冬季陷阱等各种奇遇的。但我们某些时候,还是需要一些固定相对位置的prefab组合,这时候,就需要layout了。layout是一个很大的类别,奇遇、蘑菇环、猪王+四座方尖碑,都算是layout的一种。总的来说,layout可以算是room和prefab的中间桥梁,让我们得以按一定的规则来排布prefab的位置。

代码解释

在scripts/map文件夹下,存放着所有和地图有关的脚本文件。本文讲的内容都来自于这个文件夹的内容。
对饥荒地图的修改有两种方式,一般是相互结合着使用的。
第一种是注册新内容,比如新增加一个level,task或者room。
第二种是修改官方原有的内容,比如调整某个room的资源分布密度或比例。
大多数时候我们并不想从level开始完全重造一个世界,只是想给原有的世界添加一些新东西。这时候就需要先注册新内容,然后再在原世界中修改,在其中加入新内容。

注意:这部分的代码必须放在modworldgen.lua内,否则会出错。

注册新内容

注册新内容是通过一系列Add函数来实现的。具体见下表。

函数调用格式 变量描述 功能描述
AddLevel(type, data) type-字符串-level类型,一般默认为"SURVIVAL"。
data-表-数据
添加新level,需要注意的是,level的id是在data表内的,这里的type只是用于游戏模式的识别,一般不需要改动。
AddTaskSet(id, data) id-字符串-TaskSet的id,会在level的taskset属性中被使用
data-表-数据
添加新TaskSet。TaskSet是level的data表中的一个必选参数,主要用于描述这个level要用到的所有task的集合,以及一些奇遇在各个task上的分布情况
AddStartLocation(name, data) name-字符串-类似TaskSet的id
data-表-数据
添加新StartLocation。StartLocation指的是出生点所在的那一小块节点,大小约合一个room。可以为这个特殊的节点设置各种属性,三箱开局就是通过更换StatrLocation来实现的。
AddStartLocation(name, data) name-字符串-名字
data-表-数据
添加新StartLocation。StartLocation指的是出生点所在的那一小块节点,大小约合一个room。可以为这个特殊的节点设置各种属性,三箱开局就是通过更换StatrLocation来实现的。
AddTask(name, data) name-字符串-对应task的id属性
data-表-数据
添加新task
AddRoom(name, data) name-字符串-对应room的name属性
data-表-数据
添加新task

上面提到的data表,内中参数众多,会在下面单独列一节出来讲解。

修改原有内容

这是通过一系列Mod API实现的,具体见下表

函数调用格式 功能描述
AddLevelPreInit(levelid, fn) 修改指定的level
AddLevelPreInitAny(fn) 修改全部level
AddTaskSetPreInit(tasksetname, fn) 修改指定的taskset
AddTaskSetPreInitAny(fn) 修改全部taskset
AddTaskPreInit(taskname, fn) 修改指定的task
AddRoomPreInit(roomname, fn) 修改指定的room

data表释义

level

参数名 描述
id 系统用于识别level的依据
name level的名字,会在主持房间时,在世界选项设置里看到
desc level的描述,和名字一样会在世界选项中看到,写在名字的下方
location 位置,forest为地上,cave为地下。location是一个类,它的数据表里有override表,内含所有必须填写的override数据。这些数据可以被level的override表中的同名属性覆盖
numrandom_set_pieces 全图随机奇遇的数量
random_set_pieces 版本,目前固定为2,一般不要改动
version 版本,目前固定为2,一般不要改动
overrides 覆盖表,里面有很多重要的信息。下面的其中参数的具体介绍
overrides表的参数 描述
task_set 指定要使用的taskset
start_location 指定要使用的start_location
season_start 指定开始季节
layout_mode 指定地图生成模式,地上(LinkNodesByKeys)和地下(RestrictNodesByKey)的生成模式是不一样的
wormhole_prefab 指定用作虫洞的物品
roads 设定道路生成数量

还有一些额外的属性也是在这张表里的,但这些属性是为世界设置服务的,可以在房间设置中进行设置。

taskset

参数名 描述
name taskset的名字,会在level的override里的task_set属性中用到
location 同level的location
tasks 一张表,囊括所有固定要用于生成世界的task
numoptionaltasks 随机选择task的数量
optionaltasks 一张表,生成世界时,会在这张表中随机不放回的选取numoptionaltasks个task
valid_start_tasks 一张表,生成世界时,会随机从中选择一个作为生成世界的第一个task,可能会影响到世界的生成结果
set_pieces 奇遇表。其中的元素格式为["奇遇名"]={count=奇遇数量,tasks=可用该奇遇的所有task的表。这些奇遇在哪个task上生成,是随机选择的

task

参数名 描述
locks locks表。在生成世界时,所有的lock都必须被解锁,否则无法生成。
keys_given keys表。提供key解锁lock。两个task之间由此连接起来。
room_choices 组成这个task的room表,可以为每个room设定数量,还可以设定随机的数量(写成函数形式)
room_bg task的背景,这一项会在地图上生成一些花纹之类的图案,比如墓地的雾就是由此设置的
background_room 用于填充的room。在生成世界时,如果room_choices中的room太少,就会随机生成一些填充room。如果不希望生成这些填充room,此项可以填"Blank"
colour 用途不明,估计是用于Debug的

room

参数名 描述
colour 同上,用于Debug
tags 标签表,会决定一些特别的东西,比如切斯特眼骨是否有机会在这个room上生成
contents room中最为重要的一张表,决定了room的内容,下面单独介绍表中的每项属性
contents的参数 描述
distributepercent 资源分布密度,设置得越大,资源越丰富,可以超过1
distributeprefabs 一张表,设置资源分布的种类和比例,可以随意设置数字,最后会按比例来计算
countstaticlayouts 一张表,设置静态布局的种类和数量
countprefabs 一张表,设置固定数量的资源的种类和数量,设置是几个,就会生成几个
prefabdata 设置生成prefab的初始状态,比如蜘蛛巢的等级。由于该项与prefab的Onload函数联系紧密,所以实际上能直接做的修改不多。官方也只修改了蜘蛛巢等级和树木是否被烧焦而已
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注