最近正在开发解谜游戏,于是需要一个工具来整理谜题依赖关系图。我想要解决的问题是,搞清楚一个道具(或者信息)从哪里来,去了哪里,然后得到一张图。
因为懒得考虑节点的位置,所以没有选择可视化的工具,最终采用了 Graphviz DOT 语言,并给自己定了一些编写规范。
整个游戏大致有这么几种元素:场景(家具比如衣柜)、信息(线索,行动指引)、道具(比如钥匙)、动作(开门,拼图,撬开什么东西),这些都算作节点。
// 场景 -> 道具
衣帽架 -> 帽子
// 场景 -> 信息
笔记本 -> 沙发下面有暗格
{ 沙发下面有暗格 沙发 } -> 挪开沙发 -> 木地板
{ 木地板 撬棍 } -> 撬开地板 -> 藏宝图
虽然把「挪开沙发」和「撬开地板」这两个动作和一堆名词放在一起多少有些奇怪,并且即使没有这两个动作,这个图依然是通畅的。但是,DOT 并没有一个 AND 操作,如果想要表达需要多个线索或者道具一起得到某个结果,前面几个节点经常散布在不同的地方。所以这里添加了动作,来进行手动汇聚。
不过,有的时候可以简化并省略动作:
{ 上锁的柜子 柜子的钥匙 } -> 开锁 -> 开启的柜子
可以变成:
柜子的钥匙 -> 开启的柜子
场景中的柜子没有上游的输入,所以可以被忽略,相当于钥匙直接「变成」了可以交互的柜子。
类似的,前面的「挪开沙发」,沙发本身就在场景中,没有一个源头,也可以这样简化:
// 省略了挪开沙发的动作
笔记本 -> 沙发下面有暗格 -> 沙发下的木地板
但是,后面就没办法这样简化了。因为,道具「撬棍」是从其它的场景或者行动中获得的,「沙发下的木地板」和「撬棍」两个节点都有自己的上游。所以还得是:
笔记本 -> 沙发下面有暗格 -> 沙发下的木地板
工具箱 -> 撬棍
{ 沙发下的木地板 撬棍 } -> 撬开地板 -> 暗格里的藏宝图