卷 II · 玩CH 07深度 07/24

难度不是数字,是玩家在学东西

觉得游戏太简单,你就把敌人血量翻倍 —— 这是新手最常做、也最没用的一件事。血量翻倍不会让玩家学到任何新东西,只会让同一件事做两遍。难度的本质是「玩家还需要掌握什么」,而在这上面,一个被严重低估的杠杆是:失败之后,重开要几秒。

心流难度的真正定义失败成本难度选项

先看那张著名的图

心理学家米哈里·契克森米哈赖提出的「心流」模型:当挑战和技能匹配时,人会进入一种高度投入的状态。挑战远超技能 → 焦虑;技能远超挑战 → 无聊。

这张图被引用了无数次,但通常被引用错了。关键不在那条斜带本身,在于它是斜的。

拖动那条红色曲线试试。你会发现一件事:一个固定的难度,一开始是挑战,玩到后面自动变成无聊 —— 因为玩家的技能一直在涨,而难度没动。

◆ 推论:不涨的难度就是在变简单

这意味着「保持难度不变」不是一个中立的选择,而是一个逐渐让游戏变无聊的选择

你必须持续加码。但加码有两种方式,效果天差地别:

  • 加数值:敌人血更厚、伤害更高。玩家不需要学新东西,只需要重复更久。这是伪难度。
  • 加要求:敌人有了新行为、场地有了新机制、需要同时应付两件事。玩家必须学会新东西。这是真难度。

难度的真正定义

把「难度」这个模糊的词拆开,它其实是三个不同的东西:

类型它要求玩家做过头的后果
执行难度 手更稳、反应更快、时机更准 变成手速游戏,把想玩的人挡在外面
理解难度 看懂正在发生什么、推理出解法 玩家卡住不是因为做不到,是因为不知道要做什么 —— 最伤人的一种卡
忍耐难度 重复更久、更不容易犯错 这就是伪难度,几乎总是错的

好游戏调的是前两种。血量翻倍调的是第三种。

◆ 一个立刻能用的检验

你想加难度的时候,问自己:玩家通过之后,会不会比之前多会一件事?

会 → 真难度。(他学会了「这个敌人抬手的时候要往后跳」)

不会 → 伪难度。(他学会了「要打更久」)

这个问题几乎每次都能把伪难度当场抓出来。

把血量翻倍换成什么

假设你有一个敌人太简单了。不要加血。按这个顺序试:

  1. 加一个新行为。它偶尔会向后跳一下 —— 现在玩家必须预判。(最便宜、最有效)
  2. 改变数量和组合。同时来两个 —— 现在玩家要管理空间和优先级。(几乎零成本)
  3. 换个环境。同样的敌人放在窄平台上 —— 现在闪避有了代价。(零成本,纯关卡设计)
  4. 加一个限制。这一段没有回血 —— 现在每次受伤都要计算。(零成本)
  5. ……第五条才轮到加数值。

注意前四条几乎都不需要写代码,全是设计和摆放。这是难度设计最反直觉的地方:你手上最强的难度杠杆,大多数是免费的。

被严重低估的杠杆:失败的成本

这一节可能是本章最有实操价值的部分。

同样一个「有 30% 概率过关」的挑战,在两款游戏里会是完全不同的体验:

游戏 A游戏 B
失败后0.5 秒后在挑战入口重生读盘 8 秒 + 跑回来 40 秒 + 看一段不能跳过的过场
玩家会连试 20 次,越试越接近试 3 次,然后关掉游戏
玩家的评价「难但很爽」「难得很恶心」

难度数值一模一样。差别全在失败成本上。

◆ 《蔚蓝》的做法

《蔚蓝》是史上最难的平台游戏之一,玩家平均死几千次,但它极少被骂。原因几乎全在失败成本:

  • 死亡到重生 不到 1 秒,没有读盘,没有动画,没有「你死了」的界面
  • 重生点就在这个房间的入口 —— 一个屏幕就是一个检查点
  • 死亡计数被展示出来当作勋章,而不是隐藏起来当作羞辱

结果是:玩家死了不会有挫败,只有「再来」。失败被设计成了循环的一部分,而不是循环的中断。

一条数字建议

对于以执行难度为主的游戏(平台、动作、弹幕):

从失败到重新开始尝试,控制在 1 秒以内。 超过 3 秒,玩家的重试意愿会明显下降;超过 10 秒,你的游戏难度上限就被这个数字锁死了。

这意味着一些具体的工程决定:

  • 不要在死亡时重新加载场景(慢)—— 重置状态就够了
  • 不要播放不能跳过的死亡动画
  • 不要把重生点设在一段跑图之后
  • 如果一定要有过场,第二次进入时必须能跳过
⚙ Godot 落地:不要 reload_current_scene()

新手最常见的写法是死亡时调 get_tree().reload_current_scene()。这会销毁并重建整个场景树 —— 在稍大的关卡里可能要几百毫秒,而且会闪一下。

# ✗ 慢,而且会闪
func _on_player_died() -> void:
	get_tree().reload_current_scene()

# ✓ 只重置需要重置的东西,几乎瞬间
func _on_player_died() -> void:
	deaths += 1
	player.global_position = current_checkpoint
	player.velocity = Vector2.ZERO
	for e in get_tree().get_nodes_in_group("resettable"):
		e.reset()                  # 敌人、机关各自恢复初始状态
	camera.reset_to(player.global_position)

让每个可重置的对象自己实现 reset(),加进一个 group 里。这个小小的架构决定,直接决定了你的游戏能有多难。

学习曲线:难度该怎么往上走

回到那个 demo,试试「一路陡上」和「锯齿」两个预设,看统计数字的差别。

「一路陡上」看起来最合理 —— 难度稳步上升嘛。但它有两个问题:

  1. 没有喘息。玩家一直在极限状态,很快疲劳(第 16 章会专门讲节奏)。
  2. 没有「我变强了」的时刻。玩家永远在被压着打,感受不到自己的成长。

「锯齿」形状解决了这两个问题:难度上一个台阶,然后回落到低于上一个高点、但高于上一个低点的位置。

◆ 锯齿的第二个作用:让玩家体验到成长

这是锯齿形最妙的地方。

当难度从 8 回落到 4 时,玩家面对的是一个他二十分钟前会觉得很难的挑战,而现在他轻松过了。

那一刻他会感受到自己变强了 —— 而这个感受不需要任何数值系统、任何等级、任何装备。它是纯粹用关卡编排造出来的。

这是免费的成长感。个人项目应该大量使用它,因为它比做一套等级系统便宜一百倍。

新机制的引入节奏

每次引入一个新机制(新敌人、新地形、新能力),标准的四拍:

第 1 拍 安全展示  在没有威胁的地方让玩家见到它、试一下
第 2 拍 单独考核  只用这一个机制的挑战,难度低
第 3 拍 提高强度  还是这个机制,但要求更高
第 4 拍 组合    和之前学过的机制混在一起

这四拍是马力欧四十年没变过的东西,第 21 章会用一个 demo 把它拆到底。这里只强调一点:第 1 拍最容易被省略,而它是最重要的一拍。省掉它,玩家会在死了三次之后才明白这个新东西是干什么的 —— 那三次死亡纯粹是浪费的挫败。

感知难度和实际难度

还有一层容易被忽略:玩家感受到的难度,和你设计的难度,经常不是一回事。

两者之间夹着一个变量:玩家有没有理解正在发生什么

情况实际难度玩家感受该修的是
他知道该怎么做,但做不到「难,但公平」不用修,这是好状态
他不知道该怎么做可能很低「莫名其妙」引导(第 21 章),不是难度
他不知道自己为什么失败任意「随机」「不公平」反馈(第 11 章)
他做对了但没成功「这游戏有 bug」宽容窗口(第 10 章)
◆ 所以「太难了」这条反馈,通常不该用降低难度来修

当测试者说「这里太难了」,先别急着削弱敌人。按顺序排查:

  1. 他知道该做什么吗?(看他有没有反复尝试同一种错误方法 → 引导问题)
  2. 他知道自己差在哪吗?(问他「你觉得刚才为什么没过」→ 答不上来就是反馈问题)
  3. 他做对的时候真的会成功吗?(自己去试那个操作的边界 → 可能是判定太严)
  4. 失败一次要多久才能再试?(超过 3 秒 → 先修这个)
  5. 以上都没问题,才考虑真的降低难度。

实践中,前四条能解决大部分「太难了」的反馈 —— 而且解决之后,游戏的实际难度一点没降,玩家却不再抱怨了。

一个具体的调难度流程

当你确认确实需要调难度时,按这个顺序动手,成本从低到高:

1. 改摆放     把敌人往后挪两格,给玩家多半秒反应时间     成本:0
2. 改数量     三只变两只                                 成本:0
3. 改环境     把窄平台加宽一格                           成本:0
4. 改节奏     在这段之前加一个喘息段                     成本:低
5. 改行为     减慢敌人的攻击前摇                         成本:低
6. 改数值     降低伤害 / 提高玩家血量                     成本:低,但最后才用

为什么数值排最后?因为它是唯一一个会连带影响其他所有关卡的手段。改一个敌人的伤害,整个游戏里所有出现这个敌人的地方都变了。而前四条都是局部的,改坏了只影响一处。

关于难度选项

「要不要做简单 / 普通 / 困难三档?」这是个人开发者常问的问题。

◇ 老实说:第一个游戏不要做

理由:

  • 它让你的调试工作量乘三。你要把每个关卡在三个档位下都调到好玩,而你连一个档位都还没调好。
  • 它常常是逃避决定的借口。「这个敌人该多强?」—— 不知道,那就做三档吧。这是把设计决定推给了玩家,而玩家没有信息做这个决定(他还没玩过,怎么知道自己该选哪档?)。
  • 它会稀释你的设计意图。如果你的游戏是关于「在极限压力下保持冷静」,那简单模式就把这个体验删掉了。

更好的做法(也更便宜):做一个精心调过的难度,然后提供「辅助功能」而不是「难度档位」。

《蔚蓝》的辅助模式是这方面的范本:它不提供「简单难度」,而是提供一组开关 —— 无限冲刺、无敌、游戏速度调慢。并且明确告诉玩家「这些会改变设计好的体验,但我们希望每个人都能看到这个故事」。

这个做法的好处:你只需要调好一个难度,辅助开关是正交的、几乎不需要额外调试的。

本章小结

  • 心流带是斜的:不涨的难度=在变简单,因为玩家一直在变强。
  • 难度分三种:执行、理解、忍耐。加血量调的是忍耐,那是伪难度。
  • 检验:玩家通过后会不会多会一件事?不会就是伪难度。
  • 你最强的难度杠杆大多是免费的:新行为、组合、环境、限制 —— 加数值排第五。
  • 失败成本比难度数值更重要。从失败到重试控制在 1 秒内,你的难度上限会高得多。
  • 锯齿形曲线的隐藏价值:回落时玩家会亲身体验到免费的成长感
  • 第一个游戏不做难度档位,做辅助开关。
⇄ 换个类型
  • 卡牌 / 肉鸽:难度主要是理解难度(认识卡的组合)加信息难度。失败成本天然很高(一局半小时没了),所以这类游戏必须靠元循环补偿 —— 「虽然死了但解锁了新卡」。没有元解锁的肉鸽,失败成本高到劝退。
  • 塔防:难度几乎全在理解上(看懂敌人组成、算清 DPS 缺口)。它的失败成本设计有个专属技巧:允许中途重开当前波次,而不是整关重来。
  • 模拟经营:难度是规划难度,失败往往是慢性的(几个游戏日之后才崩)。这类游戏最大的难度设计问题是反馈延迟 —— 玩家犯错和承受后果之间隔了太久,学不到东西。修法:加预警(「食物将在 3 天后耗尽」)。
  • 叙事解谜:几乎纯粹是理解难度,也是最容易做出「恶性卡关」的类型 —— 玩家不知道自己该干什么,也不知道自己离答案有多近。必须设计「接近正确」的反馈:试对一半时给出部分响应,而不是沉默。
  • 动作 / 平台:三种难度都有,但失败成本是决定性的。这类游戏可以难到离谱,前提是重开够快。这也是本章那条「1 秒内」建议最直接适用的地方。