第 6 章

HAL研究所的地下室初创

第6章 HAL研究所的地下室初创

时间倒回三年之前,回到1980年的秋天。神田和泉町那栋公寓楼的走廊窄得只能容一人通过。岩田聪侧着身子,把装满印刷电路板和软盘的背包抱在胸前,爬上四楼,推开那扇没挂牌子的门。房间里六张铁制办公桌挤在一起,每张桌上都摊着拆开的康懋达VIC-20主机,烙铁搁在陶瓷烟灰缸改成的支架上,焊锡松香的气味混着泡面调料包的味精味,从清晨弥漫到深夜。池田光博从最里面那张桌子后抬起头,指了指角落里空着的第七张桌子。桌面放着一台已经拆开外壳的VIC-20,旁边堆着复印的英文技术手册,纸张边缘卷起,上面用铅笔密密麻麻标着日文注释。岩田聪刚刚过完二十岁生日,以东京工业大学计算机科学系三年级学生的身份,正式成为HAL研究所的第六名兼职程序员。HAL研究所这个名字,是池田光博在注册公司前夜想出来的。H在I之前,A在B之前,L在M之前——每个字母都领先IBM一步。这个命名带着一种不动声色的野心,也带着一种只有程序员才能会心一笑的幽默感。

但在1980年2月21日公司正式成立时,除了这个野心勃勃的名字和岩崎技研工业公司注入的一笔启动资金,池田光博手里几乎什么都没有。没有自有办公楼,没有正式员工编制,没有已经签下的稳定客户。他只有一个在东京千代田区租下的公寓房间,以及人脉网络中能找到的大学生程序员。这些学生分散在东京几所工科大学,白天上课,晚上和周末挤进这个公寓,为报酬微薄的外包项目写代码。岩田聪是其中年纪最轻的一个,但他带到这张桌子上的,远不止年轻。他带来的是东京工业大学计算机科学系三年系统训练积累下来的全部知识储备,以及从札幌南高中时代就开始积累的、超过五年的实操经验。他知道如何把一段程序从两百字节压缩到一百二十字节,不是靠删减功能,而是靠重新设计数据结构。他理解VIC-20的6502处理器在什么指令周期下会产生什么时序,不需要反复查阅手册。他能在没有调试器的情况下,仅凭屏幕上的异常像素闪烁,推断出内存堆栈的哪一层出了问题。

这些能力,在学术界或许只是技术素养,在神田和泉町这间公寓里,却直接等同于生存。HAL研究所早期的生存模式,比任何商业教科书上描述的都要原始。池田光博凭借个人关系,从一些小型计算机制造商和软件分销商那里承接外包项目。这些项目通常是给某种家用电脑开发一个演示程序,或者给某个外设编写驱动程序,有时甚至只是把一份英文技术文档翻译成日文并配上示例代码。报酬低,周期短,要求刁钻。项目完成后,客户不一定按时付款,下一笔订单什么时候来也没有保障。在这样一个连正式雇佣合同都没有的草台班子里,技术的可靠程度直接决定了团队能否吃上下个月的泡面。岩田聪很快就在这种环境中确立了自己的位置。不是通过自我标榜,而是通过解决别人解决不了的问题。有一次,团队接了一个给VIC-20开发图形显示程序的外包项目。客户要求在一个几乎没有硬件图形加速能力的平台上,实现流畅的横向卷轴效果。

VIC-20的视频芯片只能显示二十二列二十三行的文本模式,或者最多一百七十六乘一百八十四像素的位图模式,可用内存扣掉系统占用后只剩大约三点五KB。要在这种限制下实现平滑卷轴,意味着必须精确控制字符映射表的每一帧刷新,在显示中断的间隙里偷出修改视频内存的时间窗口。团队里的其他兼职程序员尝试了几天,得到的画面要么撕裂,要么闪烁,要么移动速度慢得毫无意义。岩田聪没有立刻动手写代码。他先把自己关在公寓角落里,在笔记本上画了两天的时间图。他需要计算6502处理器的每条指令占用多少时钟周期,VIC-20的视频芯片在每一帧的哪几个微秒读取字符映射表,哪几个微秒读取字符定义数据,以及系统中断服务例程会在什么时刻打断主程序。他把这些时间节点画成一张横向展开的甘特图,然后在中断服务例程的间隙里,找到了一段只有几十个微秒的空窗期。如果在这段空窗期内一次性更新视频芯片的滚动寄存器,画面就不会撕裂。

如果事先把下一帧要显示的字符数据预先计算好,放在内存中连续排列的地址空间中,更新时就可以用一条块传送指令完成,而不是逐个字符写入。这个方法需要重新设计整个程序的架构,但换来的结果是:当他最终把代码加载到VIC-20上运行时,屏幕上的画面以稳定的每秒六十帧速度平滑滚动,没有任何可见的闪烁或撕裂。池田光博站在他身后,看了整整一分钟。然后他说,以后这类问题,都先交给岩田处理。语气平淡,毫无戏剧性,但在这个勉强维持运转的初创团队里,这句话确立了一种事实上的分工秩序。不是因为岩田聪比别人更聪明——团队里每个人都是东京各工科大学的尖子生——而是因为他处理问题的方式从根本上就不同。其他人拿到一个任务,通常会先去查阅现有的代码库,找一个类似的实现,修改后适配到当前项目。这是工程实践中的常规做法,节省时间,降低风险。

但岩田聪的做法是:先把问题拆解到最基础的层面,弄清楚硬件在每一个时钟周期里做什么,软件在每一层抽象中如何映射到底层,然后从零开始构建一个针对这个特定问题的最优解。他不是在修修补补,而是在重新设计。这种做法的代价是前期投入时间更长,在项目初期看起来进展缓慢,但一旦完成,代码的效率和可靠性往往远超预期。这种工作方式,在岩田聪加入HAL研究所的头几个月里,逐渐形成了一种对他个人而言至关重要的路径依赖。在资源极度受限的环境中,技术能力最强的人自然会成为解决问题的最终依赖。团队成员遇到困难时,会先自己尝试,尝试失败后就去找岩田。岩田接过问题,拆解,重建,然后交出解决方案。这个循环每运转一次,他在团队中的技术核心地位就加固一层。但其他人也开始形成一种习惯:把最难的部分留给岩田,自己只处理那些常规的、不太可能失败的任务。这不是推卸责任,而是一种在高压环境下自然形成的分工方式。

问题是,当这种分工方式固化之后,岩田聪手中积累的就不再只是技术难题,而是整个团队生存所依赖的最关键节点。1981年夏天,HAL研究所接到了一个规模远超以往的项目:为刚刚进入日本市场的MSX家用电脑平台开发一款完整的游戏。MSX的标准规格由微软日本和ASCII公司联合制定,采用Z80处理器,主频三点五八兆赫,标准内存配置从八KB到六十四KB不等,视频芯片支持三十二列二十四行的文本模式,或者二百五十六乘一百九十二像素的位图模式,最多十六色。相比VIC-20,MSX的硬件规格有了明显提升,但客户的要求也相应提高:他们想要的不是简单的演示程序,而是一款有完整玩法、有图形界面、能在零售渠道销售的游戏产品。这是HAL研究所成立以来接到的第一个真正意义上的游戏开发项目,不再是某个厂商外包的驱动程序或演示代码,而是以自己的名义署名发行的商业软件。

池田光博接下了这个项目,但他心里清楚,以HAL目前的团队规模和技术储备,要按时交付一款合格的商业游戏,绝非易事。六个兼职大学生中,有人擅长图形设计,有人擅长音效处理,有人擅长用户界面,但能够把所有这些模块整合起来、同时保证程序在MSX的硬件限制下高效运行的人,只有岩田聪。他找到岩田,把项目说明书放在那张铁桌上。说明书上列出的要求很清楚:一个太空射击游戏,包含多个关卡,每种关卡有不同的敌人编队和背景卷轴速度,需要支持键盘和手柄两种输入方式,需要保存最高分数,还需要在游戏结束后显示一个简单的结束画面和排名表。以当时的家用电脑游戏标准来看,这是一个相当完整的规格清单。以HAL研究所现有的资源来看,这几乎是一个不可能完成的任务。MSX的可用内存扣掉系统占用后不到三十二KB,游戏程序、图形数据、音效数据和分数记录都要挤在这三十二KB里。如果按照常规的编程方式,每个功能模块各自占用一块内存,各自设计数据结构,内存很快就会耗尽。

岩田聪把项目说明书合上,放在桌角,转头看向窗外。神田和泉町的街道窄而拥挤,自行车和轻型货车在公寓楼下交错穿行,引擎声和铃声混在一起传上来。他看了一会儿,然后转回身,翻开那个从大一就开始用的笔记本,翻到第一页空白处,开始画图。他画的是内存映射图。MSX的整个内存空间从左到右展开,系统占用区、程序区、数据区、栈区、视频内存区、系统变量区,每一块都标上起始地址和终止地址。然后在程序区和数据区之间,他画了一个重叠的箭头,表示这两个区域可以共享同一块物理内存,只要在时间上错开使用。接着在视频内存区的旁边,他写下了一个数字:十六KB。如果使用字符模式而不是位图模式,背景图可以用字符映射表来实现,每一帧只需要更新几百个字节的映射表,而不是几万个字节的位图数据。敌人可以用硬件精灵来实现——MSX的视频芯片支持最多三十二个硬件精灵,每个精灵八乘八像素,可以独立移动而不需要软件重绘。

如果把游戏设计成强制使用字符模式和硬件精灵的组合,那么程序的内存占用可以压缩到大约二十KB,剩下的十二KB用来存储关卡数据、音效序列和分数记录,刚刚够用。这个设计决策,在当时看来只是一个技术上的权宜之计。但它所体现的思维方式,和岩田聪在札幌南高中用HP-65计算器编写棒球游戏时如出一辙:先理解硬件机制的全部细节,然后反过来设计游戏规则,让规则适配硬件,而不是让硬件疲于追赶规则。这种思维方式,在HAL研究所的早期项目中反复出现,逐渐成为团队默认的技术哲学。不是因为大家都认同这种方法论,而是因为只有这种方法能在资源限制下产出可交付的产品。然而,当项目推进到代码编写阶段,另一个问题浮现出来。岩田聪负责程序核心架构和关键模块,其他人负责图形绘制、音效制作和关卡设计。

但图形设计师画出来的敌人精灵,单个就占用了四KB的数据空间,因为设计师想要更精细的像素图案,使用了十六乘十六像素的精灵,每个精灵需要二百五十六字节的存储空间,加上不同颜色的版本和不同的动画帧,空间迅速膨胀。音效师制作了八种不同的音效,但每种音效使用的波形数据都独立存储,重复率极高。关卡设计师设计了五关,每关的敌人编队数据都单独存储,很多编队模式实际上是重复的,只是出现的顺序不同。岩田聪看着这些数据,算了一笔账。如果按照这个方案完全实现,程序和数据加起来会超过四十五KB,超过MSX可用内存的百分之四十以上。他必须找每个人谈,告诉他们需要压缩自己的部分。但他没有直接下命令。他拿着笔记本,走到每个人的桌前,把内存分配到KB的数字画出来,让每个人看到如果不压缩,整个项目就会失败。然后他逐一提出具体的压缩方案:精灵可以使用八乘八像素模式,通过组合多个精灵来形成更大的角色,这样单个精灵的存储空间从二百五十六字节降到六十四字节;

音效波形可以拆分成基本波形单元,不同的音效通过组合和调整这些基本单元来生成,而不是每种音效都存储完整波形;关卡编队可以拆分成模板,每一关只是在模板序列上调整参数,而不是存储全新的编队数据。没有人反对。不是因为岩田聪有权威——在这个只有七个人的公寓里,没有人有权威——而是因为他提出的每一个数字都是可验证的,每一个压缩方案都是可实现的。他从不要求别人做自己做不到的事情。在高压环境下,技术人员之间的沟通往往充满摩擦:设计师想要更好的效果,程序员想要更小的数据,双方各执一词,最后要么妥协出一个平庸的中间方案,要么形成长久的隔阂。但岩田聪的方式是:把问题还原成数字,让每个人看到同一个数字,然后在这个数字面前共同寻找方案。他不站在任何一边,他站在数字的那一边。这款MSX射击游戏最终在1981年底完成交付。

它没有在市场上引起轰动——MSX平台的用户基数本身就不大,再加上HAL研究所没有任何市场营销能力,发行完全依赖客户方的渠道——但它的完成本身,对这个初创团队来说,意味着一次完整的商业项目历练。他们学会了如何从客户需求出发,在技术和资源限制下制定可执行的方案,如何在团队内部协调不同职能之间的矛盾,以及最重要的:如何按期交付一个可以运行的产品,而不是一个永远停留在理想中的方案。但这次成功交付,也暴露了HAL研究所生存模式中一个根本性的脆弱环节。整个项目的核心架构、关键模块、性能优化和最终集成,全部依赖岩田聪一个人。他不仅是技术核心,也是事实上的项目经理,还是团队内部协调冲突的沟通枢纽。如果他在,项目可以推进;如果他不在——哪怕只是生病几天,或者因为学业压力暂时无法分身——整个团队的生产力就会急剧下降。这不是因为其他人能力不足,而是因为整个工作流程的结构,已经围绕着他一个人形成了路径依赖。池田光博看到了这个问题。

1982年初,他开始尝试招募更多正式员工,建立更稳定的开发团队,让技术能力不再过度集中在一个人身上。但招募并不顺利。在那个年代,日本的电子游戏产业仍处于草莽阶段,有经验的游戏程序员凤毛麟角,大多数计算机专业毕业生的首选仍然是大型电子制造企业或金融系统公司。一个小型软件工作室,蜗居在公寓里,没有福利保障,没有职业发展路径,甚至连正式雇佣合同都没有——这样的工作机会,对绝大多数人来说,没有任何吸引力。这就是HAL研究所面临的深层困境:它需要更多人来分散技术风险,但它没有能力提供吸引人的条件;它需要从兼职作坊向正规公司转型,但转型所需的资金、人才和市场机会,都还没有出现。它活下来了,在神田和泉町那间公寓里,靠着一个创始人的关系网、六个大学生的技术热情,以及岩田聪不合比例地投入的时间和能力,活下来了。但活下来,和成为一个可持续的商业实体,是两回事。1982年春天,岩田聪进入东京工业大学的最后一个学年。

他需要在毕业去向和HAL研究所之间做出选择。按照当时东京工业大学计算机科学专业毕业生的常规路径,他完全可以进入一家大型企业,获得稳定的收入、清晰的职业前景,以及在当时日本经济高速增长的背景下几乎可以预期的终身雇佣保障。他的父亲岩田弘志,前室兰市市长,虽然没有直接施压,但显然期望儿子走一条更稳妥的路。HAL研究所没有任何东西能与这些条件竞争:没有稳定收入,没有发展路径,没有哪怕是一份正式的雇佣合同。但岩田聪没有犹豫太久。他选择留在HAL研究所。这个选择,在当时看来几乎是不理性的。但在这个选择的背后,有一层逻辑,只有他自己能完全理解。在HAL研究所,他面对的不是一个写代码的岗位,而是一个可以让他从架构设计、底层优化、团队协作到项目管理全面介入的实战空间。这个空间,任何大企业都不会给他。大企业有成熟的流程、明确的分工和层层叠叠的管理层级。一个刚毕业的大学生,无论多么有才华,都只能在自己的岗位上执行既定的规范。

1983年春天,岩田聪正式从东京工业大学毕业。他不再是HAL研究所的兼职大学生,而是这家公司事实上的全职技术骨干。就在同一年,他推出了自己的第一款商业游戏。HAL研究所也开始承接一个新的项目:为任天堂正在开发的一款新主机开发游戏。这款主机后来被命名为Family Computer,在日语中简称为Famicom,在海外市场被称为红白机。它的硬件架构比VIC-20和MSX都要复杂,性能更强,但限制也更严格:CPU是理光基于6502核心定制的RP2A03,主频一点七九兆赫,可用内存只有两KB,视频内存两KB,支持最多六十四个硬件精灵,但每个精灵只有八乘八或八乘十六像素,同屏最多只能显示八个精灵,超过八个就会出现闪烁。两KB内存。

这个数字,岩田聪在池田光博的办公室里看到时,第一反应不是畏惧,而是沉默地计算。他在笔记本上写下了内存分配的数字:程序代码必须压缩到一点五KB以内,剩下零点五KB用于变量和堆栈。视频数据必须全部存储在视频内存中,不能占用主内存。硬件精灵的数据必须精确排列,每个字节都要反复利用。音效数据必须通过程序生成,不能预存波形。当他把这些数字算完,抬起头来,窗外的神田和泉町已是黄昏,公寓楼下的自动售货机亮起灯,街上行人匆匆。他合上笔记本,对自己说了一句:可以做到。这不是盲目的自信。这是他在HAL研究所三年里,反复验证过的一种能力:在看起来不可能的限制中,找到一条可行的路径。从VIC-20的三点五KB内存到MSX的三十二KB,再到红白机的两KB,每一次都必须重新思考程序的结构,每一次都必须从拆解硬件开始,重建整个设计方案。

这种重复的极限压缩,已经不再是一种技术训练,而是变成了一种本能:面对任何新平台,第一件事不是写代码,而是画出全部可用资源的边界,然后在边界内部寻找最优解。但即将到来的项目,和HAL之前接过的所有外包都不一样。任天堂不是一家小型软件分销商,而是一家拥有自有硬件平台、严苛质量标准和庞大市场野心的公司。自1983年起,HAL研究所开始与任天堂合作,参与开发任天堂各平台游戏。红白机不是一款开放性家用电脑,而是一台封闭的、专为游戏设计的消费电子产品。为它开发游戏,意味着必须通过任天堂的审核,遵守任天堂的技术规范,接受任天堂的发行控制。对于HAL研究所这样一个靠外包和草莽韧性活下来的小型团队来说,这是一个通向更大市场的机会,但也意味着,他们必须从作坊式的敏捷,转向正规军的纪律。这种纪律不是写在员工手册里的条文,而是刻在硬件限制和开发规范中的铁律:代码必须通过任天堂的审核,产品必须符合任天堂的质量标准,交期必须遵守任天堂的发行排期。

任何一环的失误,都可能导致整个项目被取消,而HAL研究所没有足够的储备来承受一次被取消的代价。岩田聪坐在那张铁桌前,翻开笔记本,在空白页上画下了新项目的第一个方框。他的面前是红白机那两KB内存的技术限制,他的身后是HAL研究所三年来的生存轨迹,他的脚下是神田和泉町那间公寓里焊锡和泡面交织的气味。他写下的第一行字,不是技术架构,不是项目计划,而是那句他已经反复验证过的设计准则:玩家按下按钮之后,角色必须在三帧之内做出反应。在红白机每秒六十帧的刷新率下,三帧就是五十分之一秒。在这个时间内,程序必须完成输入检测、逻辑计算、物理更新、图像绘制和音效触发,在只有两KB内存的机器上,一遍又一遍,不能有任何差错。这是HAL研究所在公寓地下室年代积累下来的全部经验,即将面对一次真正严苛的检验。而这一次,不再是能不能交付的问题,而是能不能在任天堂制定的游戏规则中,活下来,并且活成一个真正的商业实体。

池田光博在公寓里接洽客户的声音从隔壁传来,岩田聪没有抬头。他继续在笔记本上画着方框,一个接一个,像在搭建一座只有他自己能看见全貌的桥梁。桥的这一端是七个人挤在公寓里写代码的草莽岁月,桥的那一端,是一台即将改变整个电子游戏产业的灰色机器,和它那严苛到近乎苛刻的两KB内存。