第 2 章
雷神之锤下的计时器
他的手指悬在空格键上方,屏幕上的角色在起点平台边缘反复起跳、落下。每一次,他都死死盯住角色模型与地面的接触点,在心里默数着帧数。一帧,落地;下一帧,起跳——那个在录像里清晰无误的一帧间隔,在他的键盘上却怎么也复现不出来。他松开手指,又试了一次。两次。二十次。无论他如何提前预判、如何疯狂地敲击,他的角色从落地到再次腾空,总需要至少三帧。不是反应速度的问题。他暂停游戏,切回播放器,重新打开那个名为 e1m1_012.dem 的录像文件。这一次,他不再看屏幕中央的角色,而是死死盯住画面边缘墙角那道灰褐色的贴图接缝。
帖子的后半段附了一段伪代码。不是从 id Software 泄露的源代码——《雷神之锤》的源码要到几年后才公开——而是 Thresh 根据自己在死亡竞赛中反复测试移动机制后反推出来的逻辑结构。伪代码描述了速度向量在每一帧的更新规则:地面摩擦力如何衰减速度,空中如何保留速度,起跳帧如何绕过摩擦力计算直接读取当前速度值。最后一行注释写道:“如果你在起跳帧按下两个方向键,引擎会叠加它们的向量。如果你在下一帧释放其中一个键,叠加效果保留。这就是全部秘密。”
这篇帖子在讨论组里引发了两种截然不同的反应。第一种是验证冲动:几十个玩家立刻打开游戏,按照 Thresh 描述的键位组合进行测试。他们很快确认了机制的存在——在起跳的瞬间同时按下前进键和侧移键,角色的空中速度确实明显快于普通跳跃。有人用秒表粗略测量,发现叠加后的空中速度比地面奔跑速度快了大约百分之十五到二十。这不是一个微小的边际增益。这是整个移动模型的根本性改写。
第二种反应更安静,但影响更深远。一些玩家开始重新观看 Nolan 的录像——不是看他的路线,而是逐帧标注每一次空中转向的精确时机和角度。他们发现了一个模式:Nolan 的空中转向总是发生在跳跃轨迹的特定阶段,通常在起跳后第七到第九帧之间,也就是速度向量开始衰减的那个窗口。他在那个窗口内完成转向,然后在下一次起跳的瞬间再次叠加侧移速度。这不是即兴操作。这是一套被精确执行的输入序列,每一帧的键位组合都经过设计。
那个反复观看录像的玩家,在 Thresh 的帖子发布两天后上传了自己的第一关录像。文件名是 e1m1_013.54。十三秒半。比他之前的任何一次尝试都快了将近一秒半,但仍然比 Nolan 慢了整整一秒半。他在附言里写了一段话,这段话后来被转贴到好几个 Quake BBS 上,成为那个时期速通社群讨论的常见引文:
“我复现了他所有的跳跃时机和转向角度。我的帧输入序列和他的录像逐帧比对完全一致。但我仍然慢了一点五秒。这意味着问题不在输入序列本身,而在输入序列的执行精度——我的手指在键盘上的物理移动比他慢了几帧。我需要找到一种更快的按键方式。”
这段话暴露了一个此前没有人明确提出过的前提:速通的瓶颈正在从“知道该做什么”转移到“用多快的速度做出来”。在《毁灭战士》时代,录像分析的核心是路线——哪条走廊更短,哪个敌人可以跳过,哪扇门可以提前触发。这些是知识问题。一旦你知道了最优路线,复现它只是时间问题。《雷神之锤》的加速跳机制改变了这个等式。知道该在起跳帧同时按下两个方向键是一回事;在每一次落地的瞬间精确地做到这一点——间隔不超过一帧,持续整段关卡——是另一回事。知识不再是瓶颈。身体变成了瓶颈。
那个玩家在接下来的两周里反复练习同一段关卡。他不再试图优化路线——Nolan 的路线已经被社群拆解得足够透彻。他练习的是手指速度。他尝试了不同的键位布局:把跳跃键从空格移到鼠标右键,让右手拇指控制跳跃,左手食指和中指分别控制前进和侧移。他尝试了不同的按键节奏:不是“按下-释放-按下”,而是“保持前进键不释放,在起跳帧快速敲击侧移键然后立即释放”。
他录制了几十段失败的demo,每一段都比 Nolan 慢,但慢的幅度在缩小。十四秒。十三秒八。十三秒二。十二秒九。在某个深夜的尝试中,他跑出了十二秒四。屏幕上跳出的数字是 00:12.41。比 Nolan 慢了零点三八秒。但这是他第一次跑进十二秒五以内。他看着那个数字,然后打开浏览器,连接到 Quake demo 的公共 FTP 服务器。服务器上已经有十七段第一关的录像,全部是最近两周内上传的。文件名按时间排列:e1m1_012.03——Nolan 的原版。e1m1_012.45。e1m1_012.18。e1m1_011.97。e1m1_011.82。e1m1_011.54。每一个新数字都代表某个人在某个深夜的手指训练成果。零点一秒。零点二秒。零点三秒。差距在缩小,但缩小得越来越慢。十二秒像一道无形的墙,每向它逼近零点一秒都需要指数级增长的练习时间。他关掉 FTP 客户端,重新打开游戏。加载第一关。起跑。
第一次跳跃——前进键和侧移键同时按下,间隔不超过一帧。空中转向——鼠标向右偏转大约三十度,把侧移速度转换成前进速度。落地。起跳。第二次叠加。
他的手指在键盘上做着那些已经被重复了几百次的动作,但这一次他注意到了一些不同的东西。在第三次跳跃落地的瞬间,他的角色没有像往常一样立即弹起。有一个微小的延迟——可能只有两帧,但在逐帧分析中清晰可见。他失去了速度。那个损失发生在起跳帧本身:他的手指在那一帧没有完全按下侧移键,键位信号没有被引擎读取,速度叠加失败。
他停止跑步,打开记事本,开始写。他写下了每一次跳跃的精确时机,每一次空中转向的角度,每一次速度损失的位置和可能原因。他写下了自己尝试过的不同键位布局及其效果。他写下了那些仍然无法解释的速度差异——那些差异太小了,小到可能只是键盘硬件响应时间的个体差异,也可能是引擎在特定帧率下的计算误差。他在文档末尾写道:“如果有人能把这些数据和其他人的测试结果交叉比对,我们可能能找出速度损失的规律。”
他把文档上传到 BBS。标题是:“e1m1 加速跳的帧级测试数据——请求交叉验证。”
第二天早上,有三个人回复了他的帖子。每个人都附上了自己的测试数据。其中一个人用不同帧率的游戏实例做了对照实验,发现引擎的物理计算在低于三十帧时会丢失部分速度数据——这意味着低配电脑的玩家在客观上无法达到和高配电脑玩家相同的速度上限。另一个人测量了不同地面材质上的速度保持率,发现金属地面的摩擦力略低于石质地面,这意味着路线选择不仅要考虑距离,还要考虑地面材质。第三个人——那个使用“Thresh”网名的玩家——只回了一句话:“你们现在在做的事情,就是我想在死亡竞赛圈推广的方法。别停。”
他们没有停。在接下来的几周里,第一关的通关时间继续下降。十一点五秒。十一点二秒。十一点零秒。每一次突破都伴随着大量的测试数据、帧分析帖和键位讨论。加速跳从一个被偶然发现的隐藏机制,变成了一套被系统拆解、分类和优化的技术体系。
玩家们为不同的跳跃类型创造了术语:单次叠加跳、连续叠加跳、墙角借速跳、斜面加速跳。他们绘制了每一关的地面材质分布图,标注了每一段走廊的最佳跳跃次数和转向角度。他们开始讨论不同鼠标DPI设置对空中转向精度的影响,不同键盘轴体的响应时间差异,不同帧率下物理计算的稳定性。
这不是一群人在玩游戏。这是一群人在对一套规则系统进行集体逆向工程。
id Software 的开发者们没有预料到这一点。他们给《雷神之锤》装上计时器,是因为约翰·卡马克认为玩家“可能想知道自己用了多长时间”。那个计时器的显示格式——分:秒:毫秒——是卡马克在某个下午随手写的几行代码,没有经过设计会议讨论,没有出现在任何产品需求文档里。它只是一个工程师的直觉判断:如果你想显示时间,那就显示精确的时间。但这个直觉改变了速通的物质基础。
在《毁灭战士》时代,“更快”是一个模糊的相对概念。你这段录像比那段录像快,但你无法精确地说出快多少。你可以通过文件大小估算,可以通过外部秒表测量,但这些方法都隔着一层不确定性。计时器撕掉了那层薄膜。
它把时间从一个主观感受变成了一个客观数字,然后把这个数字推到了玩家的脸上——每一关结束时,它就挂在屏幕中央,浅灰色等宽字体,没有任何装饰效果,但占据着通关画面的第一行。它不说“干得好”或“你进步了”。它只说一个数字。00:12.03。然后你下一次跑出 00:12.41。那个数字告诉你:你退步了。不是感觉上的退步,不是印象式的退步,是精确到百分之一秒的退步。
这种反馈的即时性和精确性改变了玩家的欲望结构。通关不再是目标;通关时间才是目标。而通关时间是一个永远不会被真正满足的目标,因为计时器的存在本身就在不断暗示同一件事:那个数字还可以更小。
它只是一个工程师的直觉判断:如果你想显示时间,那就显示精确的时间。
但这个直觉改变了速通的物质基础。在《毁灭战士》时代,“更快”是一个模糊的相对概念。你这段录像比那段录像快,但你无法精确地说出快多少。你可以通过文件大小估算,可以通过外部秒表测量,但这些方法都隔着一层不确定性。
计时器撕掉了那层薄膜。它把时间从一个主观感受变成了一个客观数字,然后把这个数字推到了玩家的脸上——每一关结束时,它就挂在屏幕中央,浅灰色等宽字体,没有任何装饰效果,但占据着通关画面的第一行。它不说“干得好”或“你进步了”。它只说一个数字。
00:12.03。然后你下一次跑出 00:12.41。那个数字告诉你:你退步了。不是感觉上的退步,不是印象式的退步,是精确到百分之一秒的退步。
这种反馈的即时性和精确性改变了玩家的欲望结构。通关不再是目标;通关时间才是目标。而通关时间是一个永远不会被真正满足的目标,因为计时器的存在本身就在不断暗示同一件事:那个数字还可以更小。
00:11.97 的下方是 00:11.96。00:11.96 的下方是 00:11.95。这个数列没有尽头。它只受限于物理引擎的硬边界——最大可能速度、最小可能转向角度、最短可能帧间隔。
但没有人知道那些边界在哪里。计时器不说“你已经到达极限”。它只显示你这一次用了多长时间。极限只能通过反复测试、集体分析和不断逼近来推断。而每一次逼近都会引发新的问题:这个边界是引擎的硬限制,还是我们还没有找到突破它的方法?
1996年秋天,在某个 QuakeWorld 服务器上,八个旁观者正在观看一个玩家反复尝试第二关。那个玩家的最好成绩是四十四秒二七。他在第三十秒的跳跃段落总是损失速度。旁观者们在聊天框里讨论可能的解决方案。一个人建议调整空中转向的时机;另一个人认为问题不在转向,而在起跳前的助跑距离——第二关的起始走廊比第一关短,没有足够的空间让速度叠加到最大值。
第三个人贴出了一段帧数据,显示速度损失发生在起跳后的第七帧,这意味着侧移键的按下时间可能晚了。那个正在跑的玩家没有回复——他的手指不能离开键盘。但在下一次尝试时,他调整了助跑距离,在起跑后的第三步而不是第二步开始第一次跳跃。屏幕上的角色以一种略微不同的节奏弹跳前进,在第三十秒的跳跃段落保持了更多速度。通关画面弹出。计时器显示:00:43.89。聊天框里安静了几秒。然后有人打出一行字:“我们需要把这个路线拆开,写完整的帧分析。谁有时间?”
有人回复:“我已经在做了。明天早上发到 BBS。”
他在BBS上发帖描述了这些发现。标题是:“手指疲劳对加速跳连续执行的影响——个人测试数据。”帖子开头列出了他的测试条件:连续跑第一关二十次,记录每一次的通关时间和主观疲劳感受。数据显示,前十次的平均成绩是十二秒八;后十次的平均成绩是十三秒四。差距零点六秒。他在帖子末尾写道:“这意味着速通不仅考验你对引擎机制的理解,还考验你的肌肉耐力。我不知道Nolan练了多少次才跑出十二秒零三,但我怀疑那个数字背后是几百次甚至上千次的重复。我们看到的是一段十二秒的录像。我们没有看到的是让那十二秒成为可能的几千次失败。”
这篇帖子引发了另一轮讨论。有人提出,也许不应该只用第一关做测试——第一关太短了,十二秒的持续时间不足以充分暴露疲劳效应。应该用更长的关卡,或者连续跑多个关卡,观察成绩衰减曲线。
有人开始设计专门的训练方案:不是反复跑完整关卡,而是把关卡拆分成若干段落,每个段落单独练习,直到手指能够在那个段落内稳定执行加速跳序列,然后再把段落拼接起来。这个思路来自音乐演奏的训练方法——钢琴家不会反复演奏整首奏鸣曲,而是把困难的段落单独抽出来练习,直到肌肉记忆固化。
速通玩家开始用同样的方式对待游戏关卡。他们把第一关拆分成六个跳跃段落,每个段落包含三到五次加速跳。他们为每个段落设定了目标时间,然后反复练习,直到能够在连续十次尝试中稳定达到目标。
这种训练方法的引入改变了一些东西。在此之前,速通是一种相对混沌的活动——你打开游戏,跑,如果成绩不好就再跑一次。你可能会注意某些段落总是损失时间,但你不会系统性地拆解和训练那些段落。现在,速通开始变得像一种运动训练。它有分解动作、有重复练习、有成绩追踪、有疲劳管理。它甚至开始有自己的术语体系。玩家们在BBS上创造了“段落成绩”这个词,用来指代单个跳跃段落的通过时间;创造了“衔接损耗”,用来描述段落拼接时因为节奏变化而导致的速度损失;创造了“疲劳曲线”,用来追踪长时间练习中成绩下降的规律。这些术语不是从游戏设计里来的。它们是从社群的分析实践中生长出来的。
与此同时,另一群人正在从不同的方向逼近同一个问题。他们不练手指速度。他们分析帧数据。
在某个Quake BBS的“技术分析”子版块,一个用户名为“FrameCounter”的玩家发布了一篇长帖,标题是:“e1m1加速跳的完整帧序列——逐帧标注版。”帖子包含一个表格,列出了Nolan录像中每一次跳跃的精确帧数:起跳帧编号、空中转向开始帧、转向结束帧、落地帧、下一次起跳帧。表格右侧是一列注释,标注了每一帧的键位状态——前进键是否按下、侧移键是否按下、鼠标的近似转向角度。
这个表格不是通过任何自动化工具生成的。《雷神之锤》的demo文件格式还没有被公开文档化,没有现成的解析器可以提取帧数据。FrameCounter是用最原始的方法做的:在demo播放器中逐帧前进,肉眼观察屏幕上的角色位置变化,手动记录每一帧的状态。一段十二秒的录像,在三十帧每秒的播放速率下,包含大约三百六十帧。
他逐帧看完了全部三百六十帧,标注了每一次键位变化和每一次速度变化。这个工作量是巨大的。他在帖子开头写道:“我花了三个晚上做这个表格。我不知道它有没有用,但我觉得我们需要一个共同的参考标准。如果每个人都在用自己的方法分析录像,我们永远无法精确地比较结果。这个表格是一个起点——你们可以检查我的数据,指出错误,补充遗漏。我们一起来完善它。”
回复来得很快。有人在表格中发现了三处标注错误——两次空中转向的角度估算偏差了大约五度,一次落地帧的编号偏移了一帧。FrameCounter修正了错误,更新了表格。另一个人补充了速度值的估算数据:虽然demo文件不直接记录速度数值,但可以通过角色在连续两帧之间的位移距离来反推速度。他附上了一套计算公式和一组估算结果,显示Nolan在每次加速跳后的速度峰值大约在每秒六百到六百二十个单位之间,而普通奔跑速度只有大约每秒四百个单位。这个差距——大约百分之五十——远远超出了大多数人的预期。这不是一个微小的技巧增益。这是整个移动系统的根本性重写。
第三个人提出了一个更深刻的问题。他在回复中写道:“如果加速跳能提高百分之五十的移动速度,那意味着id Software在设计移动系统时要么没有考虑到这种键位组合的效果,要么考虑到了但认为玩家不会在实战中持续使用它。无论哪种情况,我们正在玩的游戏和开发者以为他们做的游戏,已经不是同一个东西了。”
这段话在讨论组里引发了一场小型争论。有人认为,加速跳是引擎机制的合理运用,既然引擎允许这种操作,它就是合法的。有人则认为,加速跳违背了开发者的设计意图,是一种“漏洞利用”,不应该被接受为速通的标准技术。
争论持续了几天,最终以一种务实的方式解决:没有人有权定义什么是“合法”的。速通没有裁判,没有官方规则,没有认证机构。它只有玩家和他们的录像。如果一个玩家用加速跳跑出了更快的成绩,其他玩家可以选择接受这个成绩、尝试超越它,或者拒绝接受、继续用自己的方法跑。
但计时器是客观的。00:11.54就是比00:12.03小。那个数字不关心你的技术是否符合开发者的意图。它只测量时间。而时间——正如某个玩家在争论中写下的那句话——“是唯一不会说谎的裁判。”
这句话后来被引用到多个BBS的签名档里,成为早期速通社群的某种非正式格言。它抓住了那个时刻的核心张力:速通正在从一种模糊的、主观的“玩得快”变成一种精确的、客观的“测量得快”。而测量的工具——那个在通关画面上冷静地显示着的计时器——正在重塑玩家和游戏之间的关系。
你不再问“我通关了吗”。你问“我用了多长时间”。这两个问题的答案可能完全不同。你可以通关一百次,但只有其中一次的时间值得记住。那个时间被精确地记录下来,成为你的新基准,然后你开始尝试打破它。
每一次打破都更困难,因为你的成绩越接近引擎的物理极限,可以榨取的边际增益就越小。十二秒零三。十一秒九七。十一秒八二。十一秒五四。差距从零点几秒缩小到零点零几秒。每一毫秒的推进都需要更精确的输入、更优化的路线、更深入的对引擎机制的理解。
到1996年深秋,第一关的最佳纪录已经逼近十一秒。没有人知道理论极限在哪里。
有人在BBS上发帖,试图用数学方法推导加速跳的最大可能速度。帖子包含一组方程式,描述了速度向量在连续叠加下的增长曲线,以及摩擦力对速度的衰减效应。结论是,在理想条件下——每一帧的输入都完美执行,没有任何时机误差——第一关的理论最短时间大约是十秒半。
这个数字引发了新一轮的练习狂潮。十秒半。比当前最佳纪录还快半秒。半秒在日常生活里短得无法感知——眨一次眼的时间大约是零点三秒——但在速通的世界里,半秒是一片广阔的未知领域。它意味着还有未被发现的优化空间,还有可以被榨取的速度,还有可以被突破的边界。
那个计算理论极限的玩家在帖子末尾加了一句话:“当然,这个数字假设你的手指能以完美的精度执行每一帧的输入。但人类的手指不是为帧级精度设计的。所以真正的极限可能不是引擎的极限,而是我们身体的极限。问题在于:我们不知道那个极限在哪里。我们只能不断逼近它,直到某一天,没有人能再快哪怕一毫秒。那一天可能永远不会到来。”
在另一个QuakeWorld服务器上,一场非正式的观赛正在进行。一个玩家正在尝试第二关的速通,旁观者列表里有十五个人。这个数字在今天看来微不足道,但在1996年,十五个同时在线观看同一个游戏画面的旁观者,已经是一个小型社区的规模。旁观者们的画面各不相同——每个人的视角都可以自由旋转,可以放大缩小,可以切换跟随目标——但他们都在看同一件事:那个玩家操控的角色在灰褐色的哥特式走廊里弹跳前进,每一次落地的瞬间都精确起跳,在空中做着微小的转向调整。
旁观者聊天框里的讨论从技术分析逐渐转向了另一种东西。有人开始为那个玩家的每一次成功跳跃打出鼓励的文字。有人在关键时刻屏息——虽然没有人能真的看到彼此屏息,但聊天框的沉默传达了同样的信息。当那个玩家在第三十秒的跳跃段落成功保持了速度,聊天框里刷出了一排感叹号。当他最终冲过终点,计时器显示00:43.76——比之前的服务器最佳纪录快了零点三秒——聊天框里爆发出一阵文字欢呼。
这不是一段存档的录像。这是一个正在发生的事件。十五个人分布在不同的时区、不同的城市、不同的国家,通过拨号上网连接到同一台服务器,在延迟和像素化的画面中共同见证了一次纪录的诞生。那个跑出纪录的玩家在聊天框里打出了几个字:“谢谢大家观看。我要去睡觉了。”然后他退出了服务器。旁观者们继续在聊天框里讨论了几分钟,分析他这次奔跑的每一个技术细节,然后也逐渐散去。服务器恢复了安静。但那个数字留在了每个人的记忆里:00:43.76。它会在第二天早上出现在BBS上,附带着帧分析、路线图和讨论帖。它会成为新的基准,新的目标,新的起点。
这种观看经验与观看录像有本质的不同。录像是完成的、封闭的、不可改变的。你观看一段录像时,你已经知道结果——你知道那个玩家用了多长时间,知道他有没有失误,知道他最终成功了还是失败了。录像是一种档案。但实时观看是一种事件。你不知道下一秒会发生什么。
屏幕上的旁观者画面仍然粗糙模糊。QuakeWorld 的旁观者模式在拨号上网条件下只能以每秒五到八帧的频率更新画面,每个玩家模型只是几十个多边形的粗糙组合,缺乏纹理细节,移动轨迹带着明显的跳跃和滞涩。
但在那些像素化的画面背后,一套全新的游戏关系正在成形。它不再是玩家和游戏之间的二元关系——一个人面对一个关卡,试图通关,试图更快。它变成了玩家、游戏和其他玩家之间的三角关系:一个人跑,其他人看;一个人发现,其他人验证;一个人提出问题,其他人用帧数据回答。那个在结算画面上冷静地显示着的数字——00:43.89——既是一段个人操作的终点,也是一场集体分析的起点。在服务器的旁观者列表里,第九个人悄悄加入了。他的网名没有出现在聊天框里。
他只是看着那个玩家重新加载关卡,再次开始奔跑。屏幕上的角色开始在灰褐色的走廊里弹跳前进,每一次落地的瞬间都精确地再次起跳,在空中做着那些微小的、几乎不可见的转向。
他的画面在旁观者的屏幕上延迟了大约零点三秒,带着拨号上网特有的像素化和跳跃感。但他正在被观看。不是作为一段存档的录像,不是作为一个已经完成的结果,而是作为一个正在发生的事件。那个事件还没有名字。它要等到很多年后才会被叫做“速通”。但在1996年秋天的那个深夜,在某个 QuakeWorld 服务器的旁观者列表里,它的雏形已经完整了:一个人跑,其他人看,计时器记录下每一个毫秒,然后所有人一起把那几毫秒拆开。