按钮之外的那一句话

先设定一个虚构的场景:王国北境的“灰塔”被叛军占领,公主艾琳被关在塔顶。玩家扮演一名年轻的游侠,刚刚在营地里听说,带队的骑士团长维克托曾经在三年前放走过一名叛军头目。到了岔路口,传统的互动电影会给出三个按钮:“强攻灰塔”“潜入灰塔”“等待援军”。

但玩家可能根本不想选这三个。他输入的是:“我不去救公主,我先回城查查维克托的过去。”

在按钮式设计里,这句话没有出口。系统要么忽略,要么强行归并到最接近的按钮上,玩家就会立刻感到,自己说的话并没有被听见。这种落差,正是互动电影里“选择感”崩塌的地方:选项越多,越显得每个选项都是编剧提前摆好的货架。

我们认为,更值得做的方向不是继续增加按钮数量,而是让自然语言本身成为剧情的输入。玩家想说什么就说什么,系统的责任是:听懂、判断、留下后果。这个过程可以拆成四个环节,本文按顺序展开:

  1. 理解意图:这句话到底想做什么;
  2. 世界许可:当前剧情状态下,这件事做不做得成;
  3. 状态更新:谁的看法、处境、时间线因此改变;
  4. 后续生成:在新状态的约束下,写出接下来的场面。
顺序很重要。如果第一步就让模型自由续写,前面三件事都会被省略,玩家看到的只是一段“像样的文字”,而不是一个真正对他的话作出反应的世界。

第一步:把一句话拆成意图,而不是关键词

“我不去救公主,我先回城查查维克托的过去”看起来只有一句,实际上包含至少三层意思:

  • 放弃当前主线目标:不去灰塔;
  • 提出替代目标:回城,调查一个人;
  • 隐含的判断:玩家怀疑维克托,这是一个带有情绪和态度的信号。

如果只做关键词匹配,系统会抓到“救公主”“回城”“维克托”,然后随便挑一个响应。更合理的做法是把输入解析成一份结构化的“意图单”,大致包含这些字段:

字段示意内容
行动类型 放弃营救(主线);前往调查(新目标)
目标对象 公主艾琳(放弃);骑士团长维克托(调查)
地点 王都(回城)
隐含态度 对维克托不信任
不确定项是永久放弃,还是暂缓?

最后一行很容易被忽略。玩家没有说明“不去救”是永远还是暂时,系统有两种选择:追问,或者按“暂缓”处理并保留修正的空间。大发娱乐AI倾向于后者:不打断玩家的节奏,把不确定性记录下来,在之后的剧情里用角色的反应来“试探”,比如公主的贴身侍女在信里问一句“您还会来吗”。

意图理解的另一个难点是玩家的话未必是行动。“他真的可信吗”可能是内心独白,也可能是向同伴提问。系统需要区分“我要做什么”“我想知道什么”“我在评价什么”,前者才会触发世界状态的改变,后两种更适合转化为角色之间的对话或调查线索。

第二步:世界是否允许——四道检查

意图确定之后,才是最容易被忽视的一步:这件事在当前世界里能不能发生。玩家想回城,看上去无伤大雅,但如果故事里“王都城门已在两天前因疫情封锁”,这个行动就需要被认真对待。

我们把检查拆成四类前置条件,每个行动过一遍:

  • 位置:玩家现在在哪里,去目标地点需要多久,路上有没有被阻断的可能;
  • 资源与物品:需要通行令牌、马匹、金钱吗,玩家有没有;
  • 知识:玩家是否真的“知道”维克托放走过叛军头目?如果这条消息只是听来的传闻,调查时就应当从“传闻”出发,而不是直接翻出证据;
  • 时间与剧情窗口:救援的最后期限是不是已经在倒数,回城这一趟会不会直接触发“公主的处刑”事件。

检查的结果不该只有“通过”和“不通过”,更适合分成几档(示意):

结果 含义 举例
可行 全部条件满足 回城调查,路上无阻
部分可行能做,但有代价回城需要绕行,多花两天
可行但有后果 能做,剧情随之改变公主在此期间被转移
不可行 世界规则不允许 城门封锁,且没有通行令牌

前三档都是“接受玩家的话,并让世界作出反应”;只有最后一档才需要特殊处理,我们放到后面的章节单独讲。

第三步:关系与状态,随一句话一起改变

假设检查结果是“部分可行”:玩家可以回城,但需要绕行,多耗两天。这时系统要做的不是生成一段文字,而是先改状态。下面是一份示意的状态变化,数字仅作举例,用来说明“一句话如何落到多个变量上”:

状态项 变化前(示意)变化后(示意)
营救倒计时剩余5天 剩余3天
玩家与公主的信任 40 35(她不知道你为什么没来)
玩家与维克托的关系60(同伴)45(他察觉玩家在回避)
玩家已掌握线索传闻1条传闻1条,待查证
叛军动向按原计划 因无人来救,提前转移人质

可以看到,这一句话同时改动了倒计时、两段关系、线索状态和一个非玩家角色的行动。每一项都有明确的来源,之后的生成才有“依据”。如果不做这一步,玩家在回城以后会遇到一个和之前毫无联系的酒馆老板,而公主的处境、维克托的态度全部停在原地,故事就像一个只认最后一句话的健忘者。

这里有一个设计上的判断:关系数值只是用来约束生成的“护栏”,不是最终的表现。数值告诉生成模块“维克托此刻对玩家有点警惕”,至于他是冷笑、沉默还是话里有话,交给后面的生成去处理。

“不允许”时:不要拒绝,要解释并给出路

现在换一个输入:玩家写的是“我直接飞到塔顶把公主带走”。玩家没有飞行能力,世界里也没有相关设定。这属于“不可行”。

最糟糕的处理是直接返回一句“该操作无法执行”,这会把玩家从故事里立即踢出来。较合理的做法是三步:

  1. 世界内的解释:不是系统在拒绝,而是世界在回应。“你抬头看向三十丈高的塔顶,风把塔尖上的旗帜吹得猎猎作响。你没有翅膀,也没有绳梯。”
  2. 保留意图:玩家真正想要的是“快速接近公主”。这个意图是合理的,系统应当识别出来。
  3. 提供替代路径:用世界里已有的东西回应这个意图,比如“塔的东侧有一条排水渠,也许可以从那里攀上去”,或者“你想起营地里的工匠提过,他们有一副用来修塔的钩索”。

替代路径要满足一个条件:必须来自世界已经存在的元素,而不是临时凭空发明。如果为了迁就玩家,突然在剧情里冒出一副早没提过的飞行披风,规则就被玩家“说服”了,之后所有的限制都会失去意义。关于这一点,我们在玩家输入一句完全没写过的行动,怎样判断能不能做里有更细的分级方法。

最后才轮到生成

四个环节里,大语言模型最擅长的是最后一个:把新的状态写成有质感的场面。但这里的生成也不是“自由发挥”,它拿到的是一份有明确边界的任务书:

  • 当前的世界状态摘要(时间、地点、在场角色);
  • 本次意图单和检查结果(“部分可行,绕行两天”);
  • 相关角色的人设与当前关系(维克托目前警惕,但仍保持礼貌);
  • 必须写到的事件(人质被转移的消息在三天后到达);
  • 不得触碰的内容(不得让公主在此时死亡,不得出现设定外的能力)。

生成之后还需要一次校验:输出里有没有违反状态的内容,比如提到了已经离场的角色,或者让维克托突然对玩家十分亲切。如果有,宁可重新生成,也不要放行。至于这些约束由谁来把关,由哪一层来决定“三天后必须发生什么”,则属于导演层的设计:让玩家自由地说,让作者预设的骨架始终立着。

从玩家的视角走一遍三个回合

把上面的环节放回一次实际的游玩里,玩家看到的大致是这样的(示意):

  • 第一回合:玩家输入“我不去救公主,先回城查维克托”。屏幕上没有任何提示词,只有维克托的一句低声回应:“你要回去?灰塔可等不了太久。”这句话里已经带着倒计时和他的警惕,对应的是状态表里那两项变化。
  • 第二回合:玩家在城里向档案官打听,得到一页残缺的记录。系统把它登记为“线索:残缺记录,来源可信度中”,而不是直接告诉玩家“维克托是叛徒”。是否可信、要不要再验证,仍然由玩家决定。
  • 第三回合:玩家想回灰塔,但此时人质已被转移。故事没有惩罚玩家,而是把“救公主”从强攻变成了追踪,主线目标被改写,公主对玩家的信任也留下了一道需要之后修复的裂痕。

三个回合里,玩家没有点过一次按钮,却始终感觉自己在推动剧情。这才是自然语言输入真正带来的差别:选择不再是从清单里挑一项,而是把自己的判断说出来,并且看到世界因此变了样

哪里最容易出错,边界在哪

把整条链路走一遍,我们认为最容易出问题的有四处:

  • 意图误读:玩家说的是反话或玩笑,系统当成了真实行动。缓解办法是遇到高后果动作(比如“杀了他”)时,用角色对话的形式确认一次,而不是弹窗;
  • 状态漏写:生成很精彩,但没有把变化写回状态,两轮以后剧情就“忘了”。因此“先写状态,再写文字”,而不是反过来;
  • 规则被说服:玩家不断换着说法,试图让系统放宽限制。规则应当稳定,变化只发生在规则允许的范围之内;
  • 过度追问:为了确保理解正确而不断询问玩家,等于把自然语言退回到了另一种形式的选项。
以上是设计思路与一个虚构场景的推演,其中的数值均为示意,不代表实际产品的参数,也不代表任何已经达成的效果。互动剧情的整体思路可以参考互动剧情栏目

回到开头的那句话。“我不去救公主”之所以有意思,不是因为它是一个叛逆的选择,而是因为它检验了一个系统是否真的有“世界”:玩家说了话,有人听见,有东西改变,有代价,也有出路。真正的AI互动电影,不是让按钮变多,而是让每一句话都不白说。