撰写了文章 发布于 2017-04-16 19:21:09
Devlog 8
Kino病了, 这家伙吃了点胶条下肚,拉出来一半卡住了,连夜送到宠物医院给拔出来,然后还要打三天针,肚子里可能还有T_T
总之这周在游戏进度上想得多写得少,就聊聊所构思的新组件吧:
Job
作为一个建设经营游戏,游戏内的角色们来来往往做着各种事情,他们的行为需要分析到程序可以编码的抽象级别。
在我目前的思考中,角色行为的最小单位就命名为了Job,玩家和角色决策器所下达的指令都会被译解为一条条的Job,每个Job以行为为编程本体,包含一系列参数,例如执行模块的限定、目标地点等,例如:
- 玩家指定一个地块建设草地,拆分为两个Job:
- Job=搬运原料,参数原料=草皮,模块限定=搬运模块,起始位置=(x1,y1),结束位置=(x2,y2)
- Job=地表建设,参数地表类型=草地,模块限定=建设模块,位置=(x,y)
- 某学生发现自身整洁度过低,决定去洗澡:
- Job=洗澡,参数执行者限定=自身,位置=(x,y)
对于Job拆分粒度的大小,我想也足够讨论一个专题了,不过目前的原型设计中,我对游戏最终到底会有多少种行为还没有一个明确的概念,应该会等到大致确定了这一点之后,再来专门讨论下这个话题。
然后,继续说Job的工作流,对于限定执行者为自身的Job,由角色决策器直接交给自身的Job序列排队执行;其他Job会发往一个中枢组件:JobManager,来进行任务分配。

图中的箭头表示的都是Job的传递,绿色为未指定执行者的Job,有待分配;蓝色则是指定了执行者的Job,发往最终执行者。
Job的发起来源
- 玩家操作
- 在目前的设计中,玩家并不能直接操作角色,因此没有直接发往角色的Job,全部去往了JobManager待分配。
- 设施
- 设施的概念,在这个游戏中指代所有地图上的地块、家具、电器等等地图单元,他们也能自主发起Job,比如电器需要修理、地板需要擦洗等等。
- 角色决策器
- 一种是角色的决策器基于自身传感器收到的警告或者其他原因产生的对自身的Job,不进入JobManager直接进入自身的Job执行序列。
- 另一种是对外的Job,比如遇到问题需要有人帮助、或者教导主任要找某人训话(=。=),则会发往JobManager待分配。

旧设计
题外话,我原本还有这张图里的这个旧设计方案,区别在于对于指定目标的Job会跳过JobManager直接发往目标角色的Job执行序列,比如教导主任训话这事会直接交给学生手里。不过后来考虑还是不这么做了,因为这样的Job来源比较复杂,考虑到可能会遇到统筹上的困难,还是统一走JobManager比较好。
推还是拉?
那么,当任务进入了JobManager之后,这些任务是推给角色,还是由角色们自己去拉?换句话说,一个Job该由谁来做的这一决策,是交给单一中枢JobManager,还是由角色们自己决定?
中央决策/推送
- 优点
- 中央决策能将效率统筹到最优
- 情景:1个建设Job,3个闲暇工人
- 方案:中央方案下,JobManager可以从3人中挑选最近的一个,而分散决策下,时序上先执行的工人会将工作取走,但他未必是最近的一个,如果想要实现同样的就近决策,那么相应的代码量会比中央方案显著增多,而且牵涉多对象的相互沟通,代码难度也较大。
- 中央决策能将效率统筹到最优
- 缺点
- 巨型JobManager类,当Job类型很多时,JobManager可能会变成一个巨型类,外加上一节说的所有Job都统一过JobManager的决定,更加重这种可能。但是这一缺点是可以通过JobManager的模块化设计避免的。
分散决策/拉取
- 优点
- 所有角色决策器基于自己的情况进行任务拉取。不考虑复杂决策时,代码会非常简洁,可读性高。
- 缺点
- 难以进行统筹,与中央决策的优点对应。
所以对两个方案进行选择的关键点,就在于“要不要进行效率统筹”?考虑到玩家体验第一,“就近的工人不干活,远处的工人跑过来”的这种情形肯定是要避免的,因此我决定做效率统筹,因此最终选择中央方案了。
NoobPotato 1年前
太昊 [作者] 1年前
发布
陈浩 1年前
太昊 [作者] 1年前
发布