开放世界游戏需要允许玩家改变世界。 摧毁一座桥。 杀死国王。 结成同盟。 改变世界的动作可以多种多样,但是讨论任务会很有帮助。 任务将这些动作与动机,角色和故事捆绑在一起,形成有意义的包装。 没有这些元素,开放世界就会感觉像是一个字面的沙箱,什么都没有真正重要。

本文是关于我为使下一个游戏中的任务不会遭受组合爆炸而做出的设计决策。 与任务相关的组合爆炸是什么意思? 简而言之,这就是问题所在:
- 玩家的动作(在任务中或分别进行)需要对世界产生影响 。 否则,这些动作将毫无意义。
- 其中一些后果可能是渐进式的,例如“村庄的财富增加了20个硬币”或“巫师的声望降低了6点”。 但是还必须产生重大后果,例如“森林桥不再存在”,“矮人现在是盟友”或“玩家知道秘密通道”。 黑桃
- 这对于像Egamebook这样的非视觉媒体尤为重要。 文字通常需要更大的笔触-玩家的新剑不能比当前的大刀更好,它必须是远古兽人国王的祸根Orcthorn。 这个村庄不能再有几个人在大街上了-它必须突然间生活繁华。 新的战斗动作不能仅仅造成+3点伤害。 它一定是在砍敌人的胳膊。
- 这些后果结合在一起 。 先前任务的结果会影响下一个任务(除其他事项外)。 合并增量后果可能很容易(20个硬币+ 10个硬币=> 30个硬币),合并主要后果绝对不是。
- 这是发展中痛苦的主要根源。 和主要的bug来源。
- 随着任务数量线性增加(例如,每周1个任务),其结果的组合数量呈指数增加(例如,第一周3个结果组合,下一周9个,其后27个)。 那就是所谓的组合爆炸。
- 当组合数量激增时,这可以使项目停止。 突然,没人害怕触摸任何东西,因为他们会错过一些重要的含义。
举一个具体的例子,假设玩家在过去的任务中完成了所有这些事情:
- 与小矮人谈判达成同盟。
- 烧毁了他们领土上的一座桥梁,阻止了一支亡灵军进攻精灵,但使该军转身围攻了矮人要塞长达数月之久。
- 在决斗中杀死了一个著名的矮人英雄。
- 在远离城市并靠近矮人的福特附近操纵大型危险的野兽。
现在想象一下,玩家的王国需要矮人的帮助才能战胜另一个可怕的危险。

任务很简单:到矮人那里寻求增援。 如果您要编写这样的任务,那么您必须处理以下事情:
- 哪个对矮人更重要? 联盟还是对他们堕落英雄的记忆?
- 他们对玩家的感觉如何? 与玩家王国的联盟对他们而言,比他们不得不忍受数月的包围更加重要吗? 他们为此责怪玩家多少?
- 如果他们同意,他们将如何前进? 他们会尝试在河里游泳吗? 走很远吗? 尝试福特,知道那里有怪物吗? 他们知道吗 玩家应该自动告诉他们吗? 他们应该选择告诉他们吗?
- 如果他们不回答,他们应该提及哪些不参加的原因(如果有)? 是否可以说服他们重新考虑(例如,通过杀死福特的怪物,或者提供传奇武器来装饰他们倒下的英雄的坟墓,或者只是给他们金子)?
请记住:这只是先前四个任务的结果。 一个普通的角色扮演游戏将有数十个,通常是数百个任务。
注意 :我将“任务”一词用于任何有目标的长期任务。 在桌面游戏中,这将是一次冒险,通常(但不总是)一次玩一次。 保存人质。 传递消息。 处理老鼠出没。 杀死山王等等。 因此,这不仅是支线任务。 这也是玩家达到游戏主要目标所需要做的所有事情。
那么如何缓解这个问题呢? 这是我目前的想法,总结为规则。 一些规则已在“不起眼的小害虫”中实施。 其余的我现在要执行。 我将在下面详细讨论每个规则。
- 在结果中放置逻辑,而不是谓词。
- 在空间和时间上限制效果。
- 如果还有更多同类效果,请选择最强的效果,而忽略其余效果。
- 每个场景一种效果。
- 任务应该明确地涉及一种效果。
- 建立最常见效果的框架。
- 暂缓任务,直到有趣为止。
这是一个实现细节,但广泛适用,因此我将其放在第一位。 如果您不从事编程游戏业务,并且可以在这里使用游戏设计解决方案,则可以安全地跳过此步骤。
假设我们想要以下事件序列:
- 玩家访问邪恶贵族的遗物。
- 玩家与管家合谋。
- 那个星期晚些时候,玩家通过一个管家故意打开的窗户潜入贵族的房子,并谋杀了那个贵族。

对于人类来说,将逻辑置于谓词中是很自然的。 当玩家与管家合谋时,我们自然会在管家上放上某种标志,稍后再将其打开窗户。 这就是我所说的谓词逻辑。
这里的问题是,在晚宴和致命的夜晚之间可能发生许多事情。 某些事情可以使管家改变主意。 贵族可以了解该计划并设置陷阱。 提供对窗口访问权限的树枝可能会掉落。 该镇可能被致命的飞行生物所困扰,这些飞行生物喜欢飞入房屋并以人为食。
因此,现在您最好确保所有这些不同的情况都知道管家上的opens_window
标志,并相应地进行更改。 错误很多。
相反,您要做的是将逻辑移到重要的时间点-结果。 您无需记住要在以后使用的状态,而可以“记住”时间到了。 运作方式如下:
- 当玩家与管家成功合谋时,您要做的就是记录下来。 该记录可以很简单,就像事件的标识符(
butler_conspires
)和实际时间戳记一样。 它进入我们称为history
的存储库中。 - 当致命的夜晚到来时,我们需要查看管家是否已打开窗户,只需查询
history
。
在最简单的情况下,您只是在询问过去是否存在butler_conspires
记录。 如果是这样,则打开窗口。
随着事情变得越来越复杂,您只需添加基于history
更多逻辑即可。 如果过去有aristocrat_learns_about_conspiracy
记录,则该窗口不会打开。 如果有flying_monster_infestation_starts
记录,但之后没有flying_monster_infestation_ends
记录,则该窗口不会打开。
这有两件事:
- 您要限制游戏中特殊标志和常规簿记的数量。 大多数事情都进入了历史。
- 您将所有关于结果的逻辑都放在一个地方-紧挨着它。 您无需去寻找代码其他部分中所有不同的if-else语句。
此外,您还知道为什么管家没有打开窗户。 history
可以告诉您决定事件何时发生,以及谁来负责(如果您将犯罪者ID与事件记录一起保存)。
它还为效果有限的寿命提供了一个简单的选择。 也许六个月前您卸下了所有园艺设备这一事实不应该影响今天的花园状态。
而且,您现在可以轻松获得不会立即生效的效果。 当玩家下令暗杀王子,然后立即去皇宫时,也许王室本来就不应该哀悼。 也许整个王国不应该有黑旗。 给刺客一两天。
技术说明:是的,与使用简单标志相比, history
方法具有较差的性能特征。 但稍加注意,它并没有您想像的那么糟糕。 对于仅涉及最新实例(大多数是最新实例)的事件,可以通过哈希映射访问O(1) 。 在大小上,平均事件可以为3个字节(事件标识符为1个字节,时间戳为1个字节,施暴者的ID为1个字节)。
这很容易。 避免永远拥有影响世界广大地区的事物。 您可能会有一些,但总的来说要保守一些。
例如,当玩家处置在当地道路附近设立行动的土匪时,请勿尝试模拟整个王国的主要涟漪效应。 让两个最近的村庄更快乐。 让玩家在那里庆祝一会儿。 也许在最近的铁匠手中解锁一些武器。 这足以让玩家感觉到自己的行为具有后果。
注意:如果确实需要,您仍然可以具有大规模效果。 进行设置,以便当玩家击败一定数量的罪犯时,整个王国会变得更加安全(国王甚至可以召唤玩家来感谢他的工作)。 只是不要尝试从每个小任务中独立影响王国。
这个问题可能会引起争议,尤其是对于像我这样具有更多模拟意识的人来说—但是我仍然值得关注。
假设玩家需要从要塞获得魔法长袍。 他或她决定使用隐身,并使隐身变得容易,这是计划:
- 确保在军营里放一桶酒,以防警卫醉酒。
- 支付一些贿赂,以伪造对要塞的攻击,造成转移。

现在,作为开发人员,您如何应对这种情况? 两种明显的方法是:
- 模拟 。 值班醉酒的守卫和虚假的攻击都是游戏自动模拟的。 只需告诉游戏让守卫喝醉,现在就会有一定数量的盗版者进行伪造的攻击,它会弄清楚该怎么做。
如果可以的话,这是理想的选择。 但让我们面对现实吧,大多数游戏模拟都不够丰富,无法处理您(或您的作家)扔给他们的所有东西。 您想在游戏中进行多少次虚假攻击? 玩家在重复之前可以容忍多少? 而且,如果您习惯对游戏中只使用一次或两次的事物实施模拟,那么您是否会完成游戏?
- 手动组合 。 为警卫既醉又受假冒袭击的可能性做准备。 为此创建新的作品。 “嘿,上尉。 上尉 醒来。 没有攻击。 嗝! 在这种情况下,请确保玩家有额外的时间潜入要塞。
这比上面的模拟工作少,但工作量不大。 您基本上必须为所有可能的效果组合编写特殊的代码。 再次:组合爆炸。
相反,只选择最有影响力的因素,而忽略其余因素。 在我们的示例中,可以肯定地说伪造的攻击对球员潜入能力的影响要比警卫的醉酒影响更大。 守望者争先恐后地捍卫墙壁,从架子上拿走武器,大喊大叫等等。事实上,他们喝醉是次要的。
如果应用得当,播放器将不会注意到,您作为开发人员已经为自己节省了很多工作。
缺点是玩家可能会注意到并感到失望。 但是我的假设是,您为玩家提供了更多有趣的选择,这一缺陷并不能完全抵消这一缺陷,而这些行为会导致更为戏剧性的后果。
那么,您如何判断两种效果的相对强度呢? 在大多数情况下,一种效果本质上比另一种效果更强。 殴打比醉酒强。 被毁的桥比倒在道路上的树更坚固。 杀死家庭成员比侮辱一个家庭要强大。 但是有时,时空起着作用。 最近的事迹,即使是次要的事,也可以取代旧的事迹。 假设玩家帮助铁匠将铁匠铺从火中救了出来。 这是几年前的事,但事迹至今仍然记忆犹新。 现在玩家回到村庄,向铁匠请求一点好处,例如借马。 但是就在玩家要马之前,他或她严重侮辱了铁匠。 侮辱与拯救某人的生计相比,其内在作用要弱一些,但我认为您会同意,如果铁匠在这一点上做出义务,那将是很奇怪的。 在这种情况下,较新的契约优先于较实质但较旧的契约。
最后说明:您不能在所有地方都使用此方法。 必须将某些效果结合起来,并且无法解决。 例如,如果玩家神奇地使整个驻军进入睡眠状态并下令进行虚假攻击,那么您必须写下接下来发生的事情。 您绝对不能让守夜人争先恐后地抵御进攻,并且您可能无法让强盗只是忽略您的任务。
首先,一些定义。 像Egamebook这样的游戏中的场景是任务的第一步。 它通常绑定到一个地方。 例如,从巫师的塔中取出魔法剑的任务可能具有以下场景:
- 穿过荒地潜入塔楼。
- 在巡逻中与巫师的两个小兵作战。
- 装扮成仆从进入塔楼。
- 用人工制品找到合适的房间。
- 闯入装有剑的胸部。
- 与小兵在楼梯上作战。
- 偷马。
- 追逐荒原。
根据他们的选择,不同的玩家将有不同的场景(例如,另一位玩家可能选择不使用隐身,而只是靠近塔顶)。

现在,程序员如何确保该顺序受玩家过去的选择愉快地影响? 我们已经知道,最好将逻辑放入给定的场景中,查询history
,而不是试图通过设置脆弱状态来“影响”。 我们也知道,只尝试挑选一种最有影响力的人,而忽略其余的人。
但是,仍然很有可能(而且非常人性化)。 过去的一项行为可能会影响许多场景。 例如,如果玩家在出发前往塔楼之前就询问了向导的前任中尉,那么这可能会影响:
- 穿越荒地被发现是多么容易(前中尉知道最好的道路)
- 是否有可能说服各部不要战斗(各部更忠于前中尉而不是巫师)
- 找到房间有多容易(前中尉为玩家制定计划)
- 打开箱子有多容易(前中尉给玩家钥匙)
等等。 不难想出其他方式,一个讯问可以在每个步骤中影响这一追求。 同样,这会导致组合爆炸,因为您将需要给玩家至少一些选择来准备任务,并且如果所有这些选择都影响大多数场景,那么这些场景将不得不处理很多影响。 玩家都在询问前中尉和建造箱子的木匠。 因此,玩家可以打开胸部,也知道它被困住了。 现在,您必须处理两者的结合。
然后,您想到了一个绝妙的主意,即小仆袍上没有叮当铃,因此会阻碍玩家的隐身能力。 因此,穿着这些长袍的球员很难保持沉默。 现在,您必须处理一系列新的后果组合。
相反,对于每个场景,仅决定一种影响类型。 不要把胸部困住。 只需将其锁定并允许玩家将其破坏,锁定或使用钥匙即可。 不要让长袍上有叮当的铃铛,或使它们与场景无关。 对胸部场景唯一允许的影响是如何打开胸部。
其他场景将具有其他类型的影响。 “找到合适的房间”场景可能是隐身的。 如果玩家具有该地点的地图,则隐藏得更好。 另一方面,愚蠢的叮当铃会使其更难以有效隐藏。
骑马时逃脱时,某种外部干扰可能会使玩家的工作更轻松。 不要仅仅因为可以就将干扰分散到另一个场景中。
通过将影响类型划分为专用场景,可以避免组合爆炸的另一个来源。
这是上一条规则的伴随。 当您给玩家提供影响未来的机会时,请明确表明影响仅限于一种影响。
例如,当您说吹粘土之角将带来增援,并使玩家的部队更加艰苦奋斗时,您的生活将变得更加艰难。
取而代之的是,使“粘土之角”成为唯一的装备。 相信我,这比玩家通常从与游戏世界互动中获得的结果更有意义。 他们不会因为号角也不会使部队更加努力而感到难过。
即使您认真地使用了以上所有规则,您仍会开始看到在各个任务中效果非常相似,并且即使大量使用也不会有重复的效果。
那是您应该开始考虑模拟它们的时候了。
例如,玩家可以做的许多动作都会给他或她一个临时伴侣。 开始护送任务? 这是您陪同的人。 从龙的巢穴中救出公主? 她和你一起成为强大的战士。 向市长寻求帮助? 这是镇守的成员。
您可以为每个相关场景编写自定义代码,以检查您是否有同伴并采取相应的行动。 但是鉴于有多少场景会因此而改变,因此需要进行大量工作。
相反,只需编写具有党员身份的通用代码。 这意味着跟随玩家的角色的代码,聊天的代码,战斗的更新代码……换句话说,就是许多新代码。 但是仍然比手动处理要好得多。
根据您要构建的游戏,其他此类值得进行仿真的方面可能是:
- 状态(例如,骑士团打开了通常是农民无法进入的区域,降低了价格并添加了对话框选项)
- 魔法力量(例如死灵法术可以举起并指挥任何尸体)
- 威慑(例如,恐怖的表情会使敌人更早地逃离战斗,并使强制审讯更加有效)
- 惊喜(例如,伏击将对战斗的前几分钟产生深远影响)
- 解剖(例如,砍掉手臂会阻止其所有者使用它)
这最后一条规则并不能直接防止组合爆炸,但它与先前影响未来任务的行动的想法有关。
假设您有一个很好的杀死老龙的任务。 该任务的场景之一实际上是在山上找到巨龙的巢穴。 默认情况下,玩家需要基本搜索山脉的每个山谷和峰顶。 不好玩。 但是玩家也可以通过其他任务之一的NPC了解巢穴的位置,并且还有一种方法可以从附近城市的一本书中将位置拼凑在一起。

您可能在想:太好了! 找到巢穴的三种方法,每种方法都非常不同。
但是随后您的玩家开始探索游戏,几乎所有人最终都通过在山上行走找到了巢穴。 为什么? 因为他们在与NPC交谈或找到这本书之前就偶然发现了这个任务。 尽管寻找巢穴的过程可能很有趣,但实际上-对于大多数玩家而言-并非如此。 在您有机会使他们感兴趣之前,您已经向他们打开了任务。
相反,请等待介绍任务(甚至生成龙),直到至少有其他选项可用。
这可以使玩家的路径更加线性(您基本上要求玩家先提供X或Y,然后再提供Z),但是我认为这是一笔不菲的代价,需要完成许多有趣的任务,这些任务来自于玩家过去的行为。
我希望这是一个有趣的阅读。 我很高兴它不在我的系统中。 如果没什么,这将是向Egamebook推介新手作家的好方法。
有问题,想法吗? 请伸出手。