12.26
2025-12-27
周五
更改
从今天开始,日记的第一级标题将使用一个井号而不是两个
游戏开发日志
Why 推箱子?
首先,推箱子非常离散,相比连续时空中基于平台跳跃的解谜游戏(如时空幻境)甚至 3D 解谜游戏(传送门),从游戏规则和代码实现上看,离散游戏要简单得多,也更难出现 bug。从关卡设计上看,玩家行为更可控,因此更容易卡掉非预期解。当然,很重要的是,美术也简单多了!
其次,推箱子是 PSPACE 完全问题,我还没有读过证明1,但它应该是对的。所以如果你的解谜游戏玩法是推箱子的超集,它的上限不会太低,你总可以设计出足够难的关卡,方式是从推箱子难题集中抄袭。当然,这只是提供了一个真空中的球形鸡式的理论保证,因为实际上,要在关卡中足够好地融入游戏独有元素才行
Remark:我的游戏允许玩家同时推动多个箱子,实际上它不是推箱子的超集,所以它并不自动成为 PSPACE 完全问题。ChatGPT 说此时仍然是 PSPACE 完全的,因为证明过程并不强依赖玩家只能推动一个箱子。我不是很信任它,有空(寒假!)一定要读一下原始证明,搞明白这个问题
关卡规划
原本前三关不涉及活塞,完全是推箱子,我把它们从游戏中删除了,因为这不够开门见山,甚至可能让玩家厌倦。原来放这三关是想各自教玩家:
- 这是一个推箱子游戏
- 游戏中有多格的箱子,以及多目标点逻辑
- 和 Sokoban 不同,玩家可以同时推动多个箱子,就像在 Patrick’s Barabox 那样
现在我发现第一件事不需要开一关教学,任何一关都能告诉玩家这个显然的事实;第二件事,我认为玩家能自己感悟出来;第三件事,我修改了游戏的第二关,强迫玩家在第一步只能同时推两个箱子,这就完成了教学
现有的所有关卡都放在第一章 Pistons。先说说对游戏的预期:第二章计划依次引入粘性活塞和风扇,粘性活塞能拉回方块,扩展了活塞的种类,风扇引入 “超距作用”,并且让计时的实现更简单高效(目前用活塞能用
说回第一章,我把它分为三个部分:
- 基础推动规则,包括活塞推动和被推动的规则(1-9 关)
- 堵塞规则,包括活塞因末端有不可移动物体而无法推出的 “末端堵塞” 以及多个活塞冲突的 “并发冲突”(目前只做了第 10 关,计划 10-15 关)
- 综合谜题(16-25 关)
接下来就是如何设计一个关卡的问题
关卡设计
逻辑解谜游戏需要尤里卡时刻(Eureka Moment),它也叫顿悟时刻,说的是玩家在解决难题时的顿悟瞬间。一个常见的技巧是引导玩家往错误的方向思考,这样能够增加玩家发现正确做法时顿悟的程度
由于现在游戏只有活塞一个关键元素,不需要考虑多元素交互问题,只需要关心如何围绕活塞设计出合格的关卡

这是我的关卡编辑器,在经过几轮迭代后,已经比较易用,可以实时地添加和删除方块、电路,然后开始测试。可以随时扩展地图空间。还有一些高级功能:可以高亮一次关卡游玩中涉及的格子,以便在需要的时候用墙填充这些不需要用到的格子
上图是第 10 关,“堵塞” 的第一关,我设计关卡的过程是这样的:
- 这是关于堵塞的,我想在关卡里融合两个关于堵塞的谜题,让玩家分别解除堵塞和产生堵塞
- 基于这一点,在编辑器中摆放好必要的物体,让玩家能够做出这一系列动作
- 摆放墙壁,把上一步的场景围起来,留出合适的空间
- 确定正解,我希望玩家先解除堵塞,再产生堵塞
- 如何约束玩家必须走正解:产生堵塞所用的物体就是从解除堵塞中解放出来的
- 根据这一约束调整关卡布局
- 细化正解:我希望玩家必须从上往下推箱子解除堵塞
- 随机调整关卡布局,直到看起来能卡掉玩家从下往上推箱子的情况
- 叫室友来测试(serendipity_lin)
- 发现室友是天才,从下往上推箱子过了
- 尝试卡掉非预期解,方法是跑一遍正解,把没用到的一个格子用墙填上
- 再叫室友来测试
- 室友找到了新的非预期解
- 尝试卡掉非预期解,方法是增加一个新的目标点
核心就是不断迭代,让一个 idea 自己长成一个完整的关卡!
Patrick’s Barabox 的作者 Patrick Traynor 在博客上总结了一些关卡设计技巧:Puzzle Level Idea Strategies,我在设计关卡的过程中总结出的经验和其中的一部分不谋而合,他提到的其中一个策略是 :Create a possible level, then make it impossible
Start with a level that’s possible to solve, and keep making changes until it’s impossible, then undo your last change.
另一个对偶的策略是:Create an impossible level, then make it possible
Create a level that is obviously impossible to solve. Then, using that as a starting point, keep making adjustments to make it possible, and see where you end up. Or, come up with a loophole to solve a paradoxical situation, and then camoflage the loophole.
这两个方法 work 的直觉是,最后的情况在 possible 和 impossible 的交界处,距离不可解的情况只差了一个细节,这会保证过关方法不会太多
在第 10 关的设计中,第 6 步和第 8 步的迭代就是通过这两个方法的混合完成的!我让关卡反复在 possible 和 impossible 之间变化,直到找到一个平衡点,这样就能产生一个还不错的结果,最终只有两种非预期解,都能以容易的方式卡掉,得到了一个完美的关卡
Footnotes
-
很遗憾,在 TCS 导论的海报展示环节,做 reduction 的同学没有研究推箱子问题 ↩
评论区
最新评论
--