第 5 章

秋叶原街机与东工大岁月

第5章 秋叶原街机与东工大岁月

东京工业大学大冈山校区的食堂里,一碗拉面卖一百八十日元。岩田聪端着餐盘在靠窗的位置坐下,从书包里掏出两样东西:一本《计算机体系结构导论》的英文教材,和一本边角已经卷起的笔记本。那是1978年5月的某个中午,他刚入学不到两个月,就读于东京工业大学计算机科学系。食堂里坐满了穿着白衬衫和深色裤子的工科学生,大多数人在讨论课程作业或者抱怨教授的口音,但岩田聪的目光落在笔记本上那些用铅笔画的方框和箭头上——那是他前一天晚上在秋叶原一家街机厅里记录下来的东西。他画的是《太空侵略者》的基板布局。不是凭空想象。他确实在那家街机厅里蹲下来,透过机台侧面的散热格栅看到了基板的一部分。街机厅的经营者不会允许顾客擅自打开机台,但散热格栅的缝隙足够让他看到一些关键的芯片编号和板卡结构。他认出了那块英特尔8080中央处理器——因为他在东工大的计算机体系结构教材里见过它的指令集架构。

他也认出了那些德州仪器的动态随机存取存储器芯片,每块容量是1千比特,整块基板上大概有十六到二十块,这意味着整机的内存容量在2千字节左右。2千字节。他在札幌南高中用HP-65写棒球游戏时,程序步数是一百步。现在他面对的是可以容纳几千行汇编代码的硬件平台,但这个平台不是用来写课后作业的,是用来制造商品的。他把芯片编号记在笔记本上,然后在旁边标注了每块芯片的功能推测。中央处理器负责游戏逻辑和输入输出,专用移位寄存器芯片负责画面的水平滚动,一块可编程只读存储器存储了游戏程序和图形数据,另一块较小的只读存储器可能用于存储字符发生器。这些推测不是全部准确的——他后来在计算机体系结构课上才完整理解了总线架构和内存映射输入输出的原理——但那个中午在食堂里,他已经在做一件事:把一台商业街机拆解成它的技术组件,再反过来推导这些组件是如何被组织起来制造出一种特定的玩家体验的。这不是课后作业。这是他自己给自己布置的任务。东工大的课程在同步推进。

入学第一学期,他修了离散数学、微积分和一门用Fortran语言教学的编程入门。Fortran不是他喜欢的语言——它的语法生硬,设计初衷是科学计算而非交互式应用——但东工大的计算机中心里那台日立大型机让他第一次接触到了批处理操作系统。你需要把程序写在一叠穿孔卡片上,交给操作员,然后等上几个小时甚至一天才能拿到打印出来的运行结果。如果程序里有一个错误,你就得重新打孔、重新提交、重新等待。这种反馈周期对岩田聪来说几乎是一种折磨。他在高中时习惯了在HP-65上即时输入代码、即时看到结果、即时调整参数的工作方式。批处理系统把写代码和看到结果之间的时间拉长到几个小时,迫使他不得不在脑中反复模拟程序的执行过程,在提交之前尽可能多地排除错误。他的同学们抱怨这种低效率,但岩田聪发现自己在适应它。他学会了在纸上逐行检查代码,用笔在变量旁边标注它们在不同执行阶段的值,像棋手在脑中推演棋局一样推演程序的状态变化。

这种习惯后来成为他作为程序员的核心能力之一。在HAL研究所的同事后来回忆说,岩田聪可以在没有计算机的情况下坐在桌前写满一整本笔记本的汇编代码,然后一次性输入机器,编译,运行,几乎没有错误。这不是天赋,是在东工大那台批处理大型机上被迫训练出来的。但真正让他建立起程序员思维和玩家思维之间桥梁的,不是课堂,而是秋叶原。秋叶原在1978年还不是后来那个以动漫和女仆咖啡闻名的旅游胜地。它是东京的电子元器件集散地,是战后日本电器商人从黑市小贩转型为正规经销商的历史产物。沿着电气街口往南走,两侧的店铺门口堆满了电阻、电容、晶体管、真空管、继电器和二手测试仪器。空气中弥漫着焊锡和绝缘漆的气味。这里的顾客主要是电子工程师、业余无线电爱好者和自己组装音响设备的发烧友。但街机厅正在改变整条街的面貌。那些街机厅通常开在电器店的二楼或者地下室,门口挂着鲜艳的塑料帘子,里面用黑色墙纸和低亮度照明制造出一种与外界隔绝的氛围。

每台街机机台都发出自己的声音——太东的《太空侵略者》是那种心跳般的低音节拍,南梦宫的《小蜜蜂》是更尖锐的电子合成旋律,雅达利的《打砖块》则是一种单调但有节奏的撞击声。这些声音在有限的空间里混在一起,形成了一种嘈杂但令人兴奋的声场。岩田聪后来在2005年游戏开发者大会的演讲中提到过这个声场,他说那是他第一次意识到,电子游戏不只是屏幕上的像素移动,而是一种完整的感官体验。他开始系统性地研究街机游戏。不是以玩家的身份,而是以程序员的身份。他给自己定了一个规则:每款游戏先投币玩三次,熟悉基本操作和游戏规则,然后不再投币,而是站在旁边观察其他玩家。他观察他们什么时候笑,什么时候皱眉,什么时候猛拍按钮,什么时候把硬币放在机台面板上排队等待下一轮。他注意到一个现象:《太空侵略者》的玩家在敌人只剩最后一个时,身体会明显前倾,呼吸会变浅,手指会以更快的频率敲击发射按钮。

而当那个最后的敌人被击毁时,他们会有一个短暂的、几乎察觉不到的放松——肩膀下沉,后背靠回椅背,手指离开按钮。这种玩家行为的变化,不是随机发生的。它是游戏设计者通过算法刻意制造出来的。随着敌人数量减少,它们的移动速度会加快,音效的频率会升高,留给玩家的反应时间会缩短。整个系统在向玩家施加一种逐渐增强的压力,然后在最后一刻突然释放。岩田聪在笔记本上写下:“难度的增加不是线性的。它需要给玩家一种‘几乎就要输了但还能再撑一会儿’的感觉。”

他后来在HAL研究所设计的游戏里反复使用这个原则。在《星之卡比》里,关卡初期的小怪几乎不会对玩家构成威胁,但中后期的敌人配置和地形设计会制造出一种逐渐收紧的压迫感,让玩家在轻松上手之后不知不觉地进入高度专注的状态。那些游戏的难度曲线看起来平滑,但背后是岩田聪在秋叶原的街机厅里,用几百个小时观察陌生玩家的身体反应,然后一条一条拆解出来的算法逻辑。1979年夏天,他遇到了一个改变他思维方式的技术问题。那年七月,南梦宫在东京的街机厅里投放了《小蜜蜂》的升级版——《Galaxian》。这款游戏的技术规格在当时令人瞩目:它是第一款使用RGB彩色显示的街机游戏,精灵图可以脱离固定的网格独立移动,而且敌人会以俯冲攻击的方式脱离编队,而不是像《太空侵略者》那样只做水平移动。岩田聪第一次看到《Galaxian》的画面时,他的第一反应不是惊叹,而是困惑。他困惑的是:这些彩色精灵图是怎么实现的?

《太空侵略者》的黑白画面使用的是单色帧缓冲,每个像素对应内存中的一位,像素的移动通过改变帧缓冲中的特定地址来实现。《Galaxian》的彩色画面意味着每个像素至少需要多位来表示颜色信息,这会让帧缓冲的大小成倍增加。但当时的动态随机存取存储器价格昂贵,一块2千字节的存储芯片成本高达数千日元。如果全屏使用帧缓冲,《Galaxian》的基板成本将远超街机厅经营者愿意支付的价格。他花了三个周末在秋叶原的几家街机厅里研究《Galaxian》的机台。他不能拆开机台,但他可以通过观察屏幕上的画面变化来推断硬件架构。他注意到一个关键细节:屏幕上同时显示的彩色精灵数量是有限的,大概在八个左右,而且它们的颜色似乎不依赖于背景画面。这意味着游戏可能不是使用全屏帧缓冲,而是使用了一种硬件精灵系统——每个精灵由独立的硬件电路控制,有自己的位置寄存器和颜色属性,由中央处理器通过写入特定内存地址来控制它们的移动。这个推断后来被证明是正确的。

任天堂红白机使用的图像处理单元就采用了类似的硬件精灵架构,岩田聪在HAL研究所为红白机开发游戏时,对这套架构的理解远比其他第三方开发者深刻。他不是在拿到红白机开发文档后才开始学习的,他是在秋叶原的街机厅里,通过观察屏幕上的像素闪烁和移动模式,提前三年逆向工程了这套系统的基本原理。但东工大的课程并不是总和他的街机研究同步。1979年秋季学期,他修了一门操作系统原理课。课程的核心内容是进程调度、内存管理和文件系统,教材是麻省理工学院开发Multics操作系统时编写的技术文档。教授在课堂上讲解信号量和互斥锁的原理,用黑板上的方框和箭头演示哲学家进餐问题。大部分学生把这些内容当作抽象的理论来学习——考试时能画出正确的状态图就行。但岩田聪在听课的时候,脑子里想的是街机游戏。一款街机游戏本质上是一个实时系统。它有多个并发的“进程”:玩家输入处理、敌人移动、碰撞检测、音效播放、得分更新。

这些进程共享同一块中央处理器时间和内存空间,必须在每一帧的时间内完成所有计算,否则画面就会丢帧,操作就会延迟。他在笔记本上画了一张图,把《太空侵略者》的游戏循环拆解成六个并发的任务,然后在每个任务旁边标注了它所需的中央处理器周期估算和内存占用。他在图的下方写了一行字:“这不是一个程序。这是一个操作系统。”

这个认识后来直接影响了他在HAL研究所设计的游戏主循环架构。传统的游戏程序通常使用一个简单的循环结构:读取输入、更新游戏状态、渲染画面、重复。但岩田聪设计的游戏使用了一种基于优先级的任务调度系统。玩家输入响应被赋予最高优先级,因为它直接影响操作手感;碰撞检测次之;音效处理再次之;画面渲染被放在最低优先级,因为它允许偶尔的延迟而不破坏游戏体验。这套架构让他在硬件性能有限的情况下,始终能保证游戏的操作响应灵敏度。1980年春天,Commodore日本分公司在东京设立了一个小型办事处。说是办事处,实际上更像是一个仓库兼展示间。它位于秋叶原边缘的一栋老旧商业楼的四楼,没有电梯,楼道里堆满了装运纸箱。但里面摆着的东西让岩田聪挪不动步:一台Commodore PET 2001,一台刚发布不久的VIC-20,以及几台用于拆解演示的裸机主板。

他通过东工大一位副教授的介绍,获得了一个无薪实习的机会——帮忙翻译英文技术文档、调试展示用机器、偶尔为来访的潜在客户演示计算机的基本操作。这份工作没有薪水,但它的价值不体现在工资上。岩田聪第一次亲手拆开了一台Commodore PET。他看到了那块MOS 6502中央处理器,看到了那八块1千比特容量的动态随机存取存储器芯片,看到了那块占据主板面积将近一半的只读存储器——里面固化了一套BASIC解释器和操作系统。他拿着螺丝刀,一块一块地拆下主板上的芯片,用万用表测量关键引脚的电压,然后对照英文技术手册确认每块芯片的功能和地址映射。他在Commodore的展示间里度过了很多个下午。他用那台PET上的BASIC语言写程序:一个在屏幕上移动的光标,一个响应键盘输入的方块,一个用字符组成的简单迷宫。每一次,他都会撞上同一个瓶颈:内存限制。

PET的BASIC解释器在加载后留给用户程序的内存空间只有大约3千字节,其中还包括了显示缓冲区和系统变量。他不得不反复压缩代码,用单字母变量名代替描述性名称,用直接地址代替变量引用,用最短的语法结构完成最多的操作。他在这个过程中学会了一个原则:在受限的系统上编程,最重要的不是写出优雅的代码,而是理解每一行代码的真实成本。一条BASIC语句编译后占用多少字节?一个整数变量在内存中占据多少空间?一个循环展开后节省了几个时钟周期?这些问题在拥有充足内存的现代计算机上几乎不需要考虑,但在VIC-20那5千字节的用户可用内存里,每一字节都意味着一个功能的有无,一个敌人的增减,一个音效的存废。这种在极度受限条件下编程的经验,后来成为他理解任天堂硬件设计哲学的关键。任天堂的游戏机从来不是当时市面上性能最强的硬件。

红白机使用的理光图像处理单元比世嘉SG-1000的德州仪器视频显示处理器弱,Game Boy的液晶屏比雅达利Lynx的彩色背光屏落后,Wii的中央处理器比PlayStation 3的Cell处理器慢了一整个数量级。但岩田聪理解这些限制背后的逻辑:硬件成本每降低一千日元,就意味着潜在用户群扩大了一百万家庭。他不需要在顶配硬件上写程序,他需要在有限硬件上写出让玩家感觉不到限制的程序。这种能力,来自他在Commodore展示间里用那台只有几千字节内存的PET反复打磨代码的下午。1980年秋天,HAL研究所找到了他。HAL研究所——这个名字来源于《2001太空漫游》中那台名为HAL 9000的计算机,IBM三个字母各往前移一位——是一家刚刚在东京成立的小型游戏开发公司。创始人是一群对电子游戏充满热情的年轻人,其中一些人在大学期间就开始接外包项目为街机厂商写程序。

他们通过岩田聪在Commodore展示间认识的一位熟人得知,有一个东工大的学生能用BASIC和汇编语言写游戏,而且据说他写的代码“几乎不需要调试”。他们约在秋叶原一家咖啡店见面。岩田聪带着他的笔记本去了——就是那本记录了他两年多来街机基板分析、游戏算法拆解和玩家行为观察的笔记本。他翻开笔记本,给对方看了他画的《Galaxian》硬件架构推测图,《太空侵略者》的难度曲线分析,《吃豆人》的幽灵AI状态转移表。对方翻了几页,合上笔记本,问他:“你能不能从下周开始,每周来三天?”

他接到的第一个商业级需求,是一个棒球游戏。日本人对棒球的要求是苛刻的。棒球是国民运动,每个日本孩子都在电视上看过巨人队的比赛,在学校操场上挥过球棒。他们对棒球游戏的心理模型不是抽象的数字模拟,而是具体的、身体性的投球动作、挥棒时机和跑垒节奏。如果游戏里的投球轨迹不符合物理直觉,他们会立刻感觉到不对;如果击球的时机窗口太宽或太窄,他们会觉得游戏不公平;如果守备队员的跑位看起来愚蠢,他们会失去对游戏系统的信任。而所有这些都需要在极其有限的硬件资源上实现。HAL研究所当时正在为任天堂的街机基板开发游戏,那块基板使用的Z80中央处理器主频只有几兆赫兹,内存容量以千字节计。岩田聪需要在这样的硬件上模拟出投球的速度变化、击球的多种结果、守备队员的跑位AI和跑垒者的判断逻辑,同时还要保证画面每秒刷新六十次,操作响应延迟不超过三帧。他同时在东工大修一门编译原理课。

课程要求学生在学期末完成一个项目:为一个简化版的高级语言编写编译器前端,包括词法分析器和语法分析器。岩田聪选择了用C语言实现一个递归下降语法分析器,能够将类BASIC语言的源代码转换成抽象语法树。这个项目需要他处理大量的字符串操作、指针运算和内存分配。他在东工大的计算机中心里写编译器,在HAL研究所的地下室里写棒球游戏。两套代码在同一个大脑里并行运行。有一天深夜,他在调试编译器的词法分析器时,发现了一个内存泄漏问题——他在循环中分配了临时字符串缓冲区,但在某些分支条件下没有释放。他花了一个小时找到并修复了这个问题,然后突然意识到,他在棒球游戏里也遇到了类似的问题。投球轨迹的计算需要在每帧分配临时变量来存储中间结果,但他在某些情况下重复分配了内存而没有释放,导致游戏在运行一段时间后帧率下降。他回到HAL研究所,重新检查了棒球游戏的内存管理代码,在投球轨迹计算函数的末尾添加了显式的内存释放操作。游戏帧率立刻稳定了。他在笔记本上写下:“编译器设计和游戏开发共享同一套底层逻辑。它们都是资源管理问题。”

1981年春天,任天堂的硬件工程师上村雅之访问了东工大。上村雅之是任天堂红白机硬件架构的核心设计者之一,他当时正在为即将发布的红白机寻找第三方开发者。他参观了东工大的计算机实验室,看到了那台PDP-11小型机和上面运行的操作系统原型。岩田聪的导师向上村介绍了他的论文方向——实时系统中的资源调度算法——然后顺便提了一句,这个学生还在外面一家小公司写游戏。上村找到了岩田聪,两人在实验室里谈了将近两个小时。上村问了他一个具体的问题:“如果你在设计游戏机硬件,你会在图像处理单元里内置哪些功能?”

岩田聪没有立即回答。他想了想,然后从书包里拿出那个笔记本,翻到一页画满了方框和箭头的地方。那页上是他对《Galaxian》硬件精灵系统的分析,旁边用红笔标注了几个关键发现:精灵数量上限、每行精灵数量限制、精灵颜色与背景颜色的独立控制。他指着其中一个方框说:“背景卷动。如果你能让硬件自动处理背景卷动,程序员就不需要每帧都重新计算整个屏幕的坐标。这可以节省大量的中央处理器时间。”

上村看了那页笔记,问他是怎么得出这些结论的。岩田聪告诉他,他是在秋叶原的街机厅里,通过观察屏幕上的画面变化,一款一款游戏分析出来的。他没有用任何测试仪器,只有眼睛和笔记本。上村后来在任天堂内部的技术讨论中提到过这次对话。他没有当场给岩田聪任何承诺,但他记住了这个东工大学生。三年后,当HAL研究所陷入财务危机时,上村会向山内溥社长提起这个名字。1982年,岩田聪的毕业论题目是“实时系统中资源调度算法的性能分析”。导师是计算机科学系以严格著称的森下教授。论文的核心问题是:当一个系统必须在严格的时间限制内响应多个并发请求时,如何分配有限的资源才能保证所有请求都在截止时间前完成?岩田聪在论文中使用的案例,全部来自他在HAL研究所的实际开发经验。

他分析了棒球游戏中投球、击球和守备动作的响应时间分布,用排队论模型计算了不同优先级分配策略下的丢帧概率,最后提出了一套基于动态优先级的调度算法:当游戏画面中有多个精灵同时移动时,距离玩家角色最近的精灵获得最高优先级,因为它对玩家的操作体验影响最大。这篇论文在答辩时引起了一些争议。几位教授认为,用游戏作为计算机科学论文的案例,不够“严肃”。计算机科学应该研究操作系统、编译器、数据库——那些“真正”的软件系统。游戏是娱乐产品,它的技术含量不足以支撑一篇学术论文。森下教授替岩田聪挡了回去。他说:“一个系统是否值得研究,不取决于它的应用领域,而取决于它提出的技术问题的难度。这篇论文讨论的是实时系统在多资源约束下的调度问题,案例来自游戏开发,但结论适用于任何需要在严格时间限制内处理并发请求的系统。”

答辩结束后,岩田聪在走廊里追上森下教授,向他道谢。森下摆摆手,说了一句让他终生难忘的话:“你选的案例没有问题。问题是,你毕业后真的打算去做游戏吗?”

岩田聪说:“是的。”

森下沉默了一会儿。他不是一个对游戏行业有偏见的人,但他是一个对学生的前途有责任感的老师。1982年的日本,电子游戏产业还在主流社会的边缘地带。它不是一个东工大计算机科学系优秀毕业生应该选择的职业方向。大公司——日立、东芝、富士通、NEC——才是体面的去处。“那就去吧,”森下说。“但记住,你在这里学到的东西,不是让你用来写更好的游戏的。是让你用来理解那些游戏为什么好。”

1983年春天,岩田聪从东京工业大学毕业。他没有参加任何大型企业的就职说明会。没有投递简历给日立或富士通。没有像他大多数同学那样,穿着崭新的深蓝色西装,在就职仪式上齐声背诵社训。他拿着毕业证书,坐电车去了秋叶原,走进了HAL研究所那间位于一栋老旧商业楼地下室里的办公室。HAL研究所当时还是一家很小的公司。员工不到十个人,办公室的墙上贴着《2001太空漫游》的电影海报,桌上堆满了各种游戏机的开发板和英文技术手册。他们的主要业务是为任天堂开发游戏,第一款商业产品就是岩田聪参与的那个棒球游戏。1983年7月,任天堂红白机正式发售,包含岩田聪贡献代码的那个棒球游戏作为首发阵容的一部分,摆上了秋叶原电器店的货架。那个傍晚,他站在秋叶原的街头。电气街口的霓虹灯刚刚亮起,电器店门口排着等待购买红白机的顾客,街机厅里传出的电子合成旋律和电器店橱窗里播放的红白机演示音效在空气中交织。

他手里拿着HAL研究所的正式录用通知书,口袋里装着东工大的毕业证书。他在这条街上花了五年时间。从大一那年蹲在街机厅里透过散热格栅看基板,到在Commodore展示间里用几千字节内存写BASIC程序,到在东工大实验室里用门级电路搭建中央处理器,到在HAL研究所地下室里用汇编语言写棒球游戏的投球轨迹计算。现在,他写的代码正在那些电器店的屏幕上运行,即将被某个陌生人买回家,插上卡带,按下开始键。他转身走进了HAL研究所的地下室。桌子上放着一块新的开发板,上面贴着任天堂的标签。旁边是一张手写的需求清单,列出了下一个项目的技术要求:一个横向卷轴动作游戏,主角需要能够在平台上跳跃、攻击敌人、收集道具。内存限制比棒球游戏更紧,但玩法要求更复杂。岩田聪坐下来,拿起笔。他在笔记本上写下了新项目的第一行注释。不是技术规格,不是算法描述,而是一句话。这句话来自他在操作系统课上学的实时系统响应时间约束,来自他在街机厅里观察玩家身体反应时记录下的规律,来自他在Commodore展示间里反复压缩代码时建立的对用户感知的理解。“玩家按下按钮之后,角色必须在三帧之内做出反应。”

他翻开那个从大一就开始用的笔记本,翻到最后一页空白处,画下了新项目的第一个方框。窗外,秋叶原的霓虹灯在夜色中明灭,街机厅里的电子合成旋律还在继续。这个从北海道走出来的年轻人,刚刚做完了人生中最重要的一个选择。他选择了那个在主流社会看来仍属边缘的行业,选择了那个需要在地下室里用汇编语言一行一行抠内存的职业,选择了那个在东工大教授们眼中“不够严肃”的研究领域。他带着计算机科学教给他的操作系统原理和体系结构,带着五年街机基板逆向工程积累的产业直觉,带着那个从高中时代就一直在追问的问题——玩你程序的人,在玩的时候笑了吗——走进了HAL研究所的地下室。

1983年7月,任天堂红白机正式发售,两个月内售出超过50万部。包含岩田聪贡献代码的那个棒球游戏作为首发阵容的一部分,摆上了秋叶原电器店的货架。

在1983年春天这个夜晚,他只是一个刚刚从大学毕业的年轻人,坐在一间地下室里,面前是一块开发板和一个新的游戏需求,脑子里装着一整套关于计算机系统如何运作的理论,心里想的是如何让那个即将在屏幕上跳跃的小人,让玩家感到快乐。他拿起螺丝刀,拆开了那块开发板的外壳,开始研究它的芯片布局。就像五年前在秋叶原的街机厅里,透过散热格栅看《太空侵略者》的基板一样。