陈明的电话是早上九点打来的。
林浩正在吃早饭,一碗白粥,一碟咸菜。电话铃声尖锐地响起来,母亲在厨房喊:“浩子,接电话!”
他放下筷子,走到客厅。老式电话机是红色的,听筒很重。他拿起:“餵?”
“林浩吗?我是搜狐的陈明。”
“陈编辑,您好。”
“哎,別这么客气。”陈明的声音听起来心情不错,“你那个游戏,数据太好了。上线一周,日均点击破五万,用户平均停留时间超过八分钟。这在flash游戏里是现象级的。”
“谢谢。”林浩说,语气平静。
“我们领导看了数据,说想跟你长期合作。你手头还有新项目吗?”
“在做一个消除类的,物理引擎的。”
“物理引擎?”陈明顿了顿,“flash还能做物理引擎?”
“简化版的,刚体碰撞,重力模擬。”
“行,你做出来咱们再谈。”陈明说,“另外,有件事……方便透露你的联繫方式吗?有几个圈內人,看了你的游戏,想认识你。”
林浩沉默了两秒:“暂时不方便。有什么事可以通过您转达。”
“理解,理解。”陈明笑了,“搞技术的都这样,喜欢低调。那我给你个邮箱,你有新作品或者想合作,隨时联繫。”
掛了电话,林浩回到饭桌。粥已经凉了,他几口喝完,收拾碗筷。
母亲从厨房出来,擦著手:“谁呀?”
“搜狐的编辑,说游戏数据不错。”
“哦……”母亲似懂非懂地点点头,“那你继续做,妈支持你。”
回到房间,林浩打开电脑。先登录闪客帝国,后台消息99 。私信、评论、好友申请,大部分是夸游戏的,小部分是求合作的,还有几个是质疑他抄袭的——说他肯定不是新人,是哪个大佬的马甲。
他一条条看,但不回復。他现在不需要这些虚名,他需要人。
真正能做事的人。
《细胞吞噬》的火爆证明了他的设计能力,但一个人的力量是有限的。他需要团队,需要能写代码、能做美术、能搞运营的人。而2002年,这样的人大多散落在全国各地,有些还在上大学,有些在网吧打工,有些可能还没发现自己有这方面的天赋。
他需要一个方法,找到他们。
林浩打开论坛,进入“技术交流”板块。这里比作品区冷清得多,帖子不多,回復也少。大部分是初学者问基础问题,偶尔有几个技术討论帖,但深度有限。
他新建一个帖子。標题:“悬赏题:用50行代码实现粒子流体模擬”。
正文:
“语言:actionscript 2.0。
工具:flash mx。
要求:在550x400的舞台上,实现至少100个粒子的流体模擬效果。粒子之间要有简单的相互作用(排斥/吸引),与边界碰撞。代码不超过50行(不包括空行和注释)。
奖励:最佳实现者,可获得horizon工作室的实习邀请,及1000元奖金。
截止时间:三天。
提交方式:在本帖回覆中贴出核心代码及效果截图。
注意:只接受原创代码,谢绝抄袭。”
他点了发布。
这个题目的难度,在2002年的flash圈,是顶尖的。粒子系统本身就不简单,还要模擬流体,还要在50行內实现——这是故意设置的极限挑战。能解出来的,要么是天才,要么是经验丰富的老手。
而他真正的目的,不是看谁能解出来,而是看解题的思路、代码的风格、对问题的理解深度。
帖子发了十分钟,第一个回復出现了:
“沙发!大佬又出现了!”
“50行?开玩笑吧?”
“粒子流体是什么?新人求科普。”
“horizon工作室?没听过,新成立的吗?”
“1000元奖金!真的假的?”
质疑的居多。2002年,一千元奖金对普通网友来说很有吸引力,但更多人怀疑是骗局。
林浩不解释。他关掉页面,开始做自己的事。第二个游戏《方块大崩塌》已经完成了80%,他需要完善物理引擎,调整碰撞检测的精度。
工作到中午,他刷新了一下帖子。回复数:47。大部分是灌水,只有三个贴了代码。
第一个,id“flash小王子”,贴了八十多行代码,实现的是简单的粒子隨机运动,没有相互作用,没有流体效果。下面有人回覆:“这跟流体有关係?”
第二个,id“代码诗人”,贴了六十行,实现了一个漂亮的粒子拖尾效果,但依然不是流体模擬。代码写得挺优雅,但跑题了。
第三个,id“半夏”,只贴了三十行代码。林浩仔细看了一遍,眼睛微微眯起。
这三十行代码,实现了一个简化版的sph(光滑粒子流体动力学)算法。虽然极度简化——只考虑了密度和压力,忽略了粘性、表面张力——但在2002年的flash平台上,能用三十行代码写出这个,已经非常惊人。
更重要的是,代码风格极其乾净。变量命名规范,逻辑清晰,注释精准。没有多余的语句,没有炫技的写法,就是最纯粹、最高效的实现。
林浩点进“半夏”的主页。註册时间:2002年3月。发帖数:3。都是技术提问帖,问得很深,但没人回答。最后登录时间:昨天。
没有作品,没有简介,没有个人信息。像个幽灵。
林浩记下了这个id。他继续往下翻,后面又出现了几个尝试,但都不如“半夏”的惊艷。
下午,他接到了陈明的第二个电话。
“林浩,你那个悬赏题,在圈里炸了。”陈明的声音有些兴奋,“好多人问我horizon工作室是什么来头,是不是国外的工作室。还有人猜你是暴雪的人,或者ea的。”
“他们怎么说题目的难度?”
“都说难。有几个认识的圈內高手试了,说50行內几乎不可能,除非用极端的取巧方法。不过有个人做到了,id叫『半夏』,你看到了吗?”
“看到了。”
“那个人……有点意思。我打听了一下,好像是中科大的学生,数学系的,今年大二。平时独来独往,不混圈子,就喜欢研究算法。”
中科大,数学系。林浩心里有数了。这种背景,能写出那样的代码不奇怪。
“能联繫上吗?”
“我试试,但不保证。那人据说很孤僻,连宿舍同学都不怎么说话。”陈明顿了顿,“你真要招人?工作室成立了?”
“在筹备。”
“需要投资吗?我认识几个投资人,对游戏行业有兴趣。”
“暂时不用,谢谢。”
掛了电话,林浩继续工作。但心里已经记下了“半夏”。数学天才,算法能力强,性格孤僻——这种人是技术核心的最佳人选,但管理起来有难度。
晚上,帖子回复数破百了。又出现了几个有价值的尝试,其中一个id“楚飞”的引起了林浩的注意。
这个人没贴完整代码,只贴了核心算法思路:
“不用sph,用格子法。把舞台分成20x20的网格,每个格子记录密度和速度。粒子只与同格子和相邻格子的粒子交互。复杂度从o(n2)降到o(n)。50行內可以实现,但效果会粗糙。”
下面有人回覆:“格子法不是做流体模擬的主流吧?”
楚飞回覆:“在flash上,性能是第一位。sph好看但慢,格子法糙但快。如果要我选,我选格子法,然后加视觉后处理弥补粗糙度。”
很务实。不追求理论完美,追求工程可行。这是优秀的工程思维。
林浩点进楚飞的主页。註册时间:2001年8月。发帖数:87。大部分是游戏修改、外掛製作、逆向工程相关的帖子。语气桀驁,经常懟人,但技术確实扎实。最新一个帖子是三天前,问:“有人一起做《传奇》私服吗?我负责技术。”
私服。灰色地带。但技术能力应该不差。
林浩记下了。楚飞,有工程能力,有实战经验,但走的是偏门。需要引导。
第三个引起他注意的id是“陆明”。这个人没直接解题,而是回了一篇长文,分析题目本身的合理性:
“楼主出这道题,表面是考技术,其实是考思维。50行限制是故意设置的,逼我们做取捨:要效果,还是要简洁?要物理正確,还是要视觉近似?我的选择是:放弃完整的流体模擬,改用元胞自动机思路。每个粒子只有几个状態,根据周围粒子状態更新。虽然不像流体,但会有类似流体的『涌现』行为。代码35行,附图。”
他贴了代码和截图。效果確实不像传统流体,但有一种奇异的、动態的图案变化,很美,很魔性。
下面有人回覆:“这不算流体模擬吧?”
陆明回覆:“楼主没定义什么是『流体模擬』。我认为,能表现出流体某些特性(连续、可变形、有內聚力)的模擬,都算。我的实现可能不物理,但有趣。”
有创意,不拘泥,懂得重新定义问题。这是產品思维。
林浩看陆明的主页。註册时间:2002年1月。发帖数:42。大多是设计、艺术、心理学相关的討论,偶尔有技术帖。最新一个帖子是分享自己做的“自动生成水墨画”的算法,用flash实现,效果惊艷。
艺术 技术。稀缺的组合。
三天后,悬赏帖的回覆数定格在203。林浩从头到尾看了一遍,最终选了五个人:半夏、楚飞、陆明,还有两个候补。
他给这五个人发了私信,內容一样:
“恭喜通过初选。请於6月25日下午两点,登录qq,加群:1234567。进行第二轮面试。如通过,可获得实习机会及奖金。horizon。”
然后他申请了一个新的qq號,建了一个群。群名:“horizon技术测试”。
做完这些,他靠在椅背上,长长地舒了口气。
第一步走完了。接下来,是真正的考验。
6月25日,下午一点五十。
林浩坐在电脑前,qq已经登录。群是空的,只有他一个人。窗外下著小雨,六月的雨很细很密,打在窗户上沙沙响。
一点五十五,第一个人加群。id:半夏。头像是一片空白。
通过。
半夏进群后没说话,静静地待著。
一点五十七,第二个人:楚飞。头像是《传奇》里的武士,手里拿把屠龙刀。
通过。
楚飞进群后发了个表情:/抽菸。
一点五十九,第三个人:陆明。头像是自己画的水墨画,一只鹤。
通过。
陆明:“大家下午好。”
两点整,另外两个候补也进来了。五个人到齐。
林浩在群里发言:“大家好,我是horizon。感谢各位参加第二轮测试。本轮测试是实时编程,我会出三道题,大家在两小时內完成。工具自备,语言不限,但需要能运行出结果。完成后將代码发到群文件。现在开始第一题。”
他复製粘贴了第一题:
“题一:在文本中查找所有邮箱地址。输入:一段包含文字、数字、符號、邮箱的文本。输出:所有邮箱地址的列表。要求:自己写正则表达式,不能用库函数。时间:20分钟。”
这题考基本功。正则表达式是文本处理的必备技能,能看出一个人的代码严谨性和边界情况处理能力。
群里安静下来。林浩看著屏幕右下角的时间,一分一秒地走。
十五分钟后,第一个提交:半夏。代码很简洁,正则写得完美,考虑了各种边界情况。测试用例全过。
十八分钟,楚飞提交。正则有点瑕疵,但整体能用。附了一句话:“这题没意思,考记忆力的。”
二十分钟,陆明提交。正则正確,但代码里加了个小功能:把找到的邮箱按域名分类统计。超出了题目要求,但很实用。
另外两个候补,一个超时,一个正则写错了。
“题二。”林浩发了第二题,“实现一个简单的伺服器,能响应get请求,返回请求的文件。要求:支持多线程,有基本的错误处理。时间:40分钟。”
这题难度上来了。2002年,很多人还没接触过网络编程。而且“多线程”在flash里不好实现,需要用到一些技巧。
群里沉默了很久。二十五分钟后,半夏提交。代码用的是java,实现了一个完整的、可运行的伺服器,支持多线程,错误处理完善。还附了一个测试脚本。
三十二分钟,楚飞提交。代码是c ,也实现了,但用了些奇技淫巧,绕过了多线程,用异步io模擬。附言:“flash做不了多线程,我换语言了,不算违规吧?”
林浩回覆:“不算。看结果。”
三十八分钟,陆明提交。代码是python——2002年python还不流行,但他用了。实现很简单,但巧妙地用单线程 事件循环模擬了並发。附言:“轻量级方案,適合资源有限的环境。”
另外两个候选人,一个没提交,一个提交的代码跑不起来。
“题三。”林浩发了最后一题,也是最难的一题,“设计一个游戏存档系统。要求:1.存档可加密,防修改。2.支持增量存档,节省空间。3.存档损坏可部分恢復。4.有版本兼容性设计(新版游戏能读旧版存档)。不需要实现,写设计文档,包括架构图、核心算法、关键数据结构。时间:60分钟。”
这题考系统设计能力。不只是写代码,而是思考一个完整系统的方方面面。
群里彻底安静了。只有雨声,从窗外传来。
林浩起身倒了杯水,站在窗边看雨。雨中的县城灰濛濛的,远处的山隱在雨雾里。他想起2028年,华为的架构设计评审会,会议室里坐满了顶尖的工程师,为了一个设计方案爭得面红耳赤。
而现在,他一个人在2002年,用qq群面试几个可能成为伙伴的年轻人。
命运真是奇妙。
五十分钟,半夏提交。文档极其专业,用latex写的,有完整的架构图、流程图、状態机。加密方案用了非对称加密 签名,增量存档用差异算法,版本兼容用適配器模式。每个设计都有理论依据和实现考量。
五十五分钟,楚飞提交。文档是纯文本,但思路清晰。加密方案用了简单的异或 校验和——他备註:“复杂加密在客户端没用,反正能被破解,不如做防篡改检测。”增量存档用简单的二进位差异,版本兼容方案很粗暴:每个版本留一个转换器。附言:“工程方案,追求简单有效。”
五十八分钟,陆明提交。文档图文並茂,手绘了架构图,虽然不专业但生动。他提出了一个有趣的想法:存档不上传伺服器,而是在本地用算法生成“种子”,伺服器只存种子。这样节省带宽,也保护隱私。版本兼容方案是“向后兼容,向前不兼容”——旧版不能读新版存档,但新版永远能读旧版。
时间到。
林浩回到电脑前,看著三份文档。三个完全不同的风格,三个完全不同的思路。
半夏是学者,追求理论正確和体系完整。
楚飞是黑客,追求实用和效率,不拘泥於规范。
陆明是创造者,总想跳出框架,找新路径。
都是人才。但horizon需要什么样的人?
他需要学者来建立技术体系,需要黑客来攻坚克难,需要创造者来打开局面。
他都要。
林浩在群里发言:“测试结束。感谢各位的参与。请半夏、楚飞、陆明三位留下,其他两位可以退群了,感谢你们的时间,稍后会有一百元参与奖金打到你们提供的帐户。”
那两个候补退了群。群里剩下四个人。
“现在进入面试环节。”林浩打字,“我会问几个问题,请诚实地回答。第一个问题:你们为什么学编程?”
片刻,楚飞先回答:“因为爽。能控制机器,能做別人做不到的事。最早是改游戏,后来是写外掛,现在是觉得……能做点更大的。”
陆明:“因为美。代码有一种结构之美,逻辑之美。我学画画,学音乐,但最后发现编程是最自由的创作方式。你能创造一个世界,哪怕只是虚擬的。”
半夏过了半分钟才回答:“因为问题在那里。数学问题,物理问题,现实问题……编程是解决问题的工具。我喜欢工具,喜欢用工具解决问题的过程。”
很真实的回答。
“第二个问题:你们对未来五年的中国网际网路,有什么判断?”
楚飞:“会火。游戏、社交、电商,都会火。但泡沫也会有,死掉的公司会比活下来的多。我要做活下来的那个。”
陆明:“会连接一切。现在电脑是电脑,手机是手机,以后都会连在一起。內容的形式会变,但人需要故事,需要美,需要连接。我要做创造连接的那个人。”
半夏:“技术会进步,但瓶颈在基础设施。网速、硬体、人才。谁能解决瓶颈,谁就能贏。我要做解决瓶颈的事。”
林浩看著这些回答,心里有数了。
“第三个问题:如果加入horizon,你们想要什么?钱?名?成长?还是別的?”
楚飞:“钱要,但不能只给钱。得让我做有意思的事,有挑战的事。如果天天写业务代码,给再多钱我也不干。”
陆明:“想和厉害的人一起,做有影响力的作品。钱够生活就行,但作品必须是我骄傲的。”
半夏:“想接触前沿问题,有资源做研究。如果有论文產出,希望能署名。钱……按市场价就行。”
都很纯粹。这是好事。
林浩最后问:“如果我说,horizon现在只有我一个人,没有办公室,没有投资,只有一台电脑和一个想法。你们还愿意加入吗?”
沉默。
然后楚飞:“你一个人做出了《细胞吞噬》?”
林浩:“是。”
楚飞:“那我加入。一个人能做出那种东西,比有团队但做垃圾的强。”
陆明:“我也加入。一个人反而自由,没有条条框框。”
半夏:“只要问题有趣,资源可以慢慢解决。”
林浩笑了。这是他在这个时空,第一次真正地笑。
“好。”他打字,“那么,欢迎加入horizon。接下来我说一下安排。”
“第一,我们是远程协作。你们在哪里都可以,按时完成任务就行。”
“第二,前期没有工资,但项目有收益后,按贡献分成。分成比例后续详谈。”
“第三,第一个项目:网吧游戏自动更新系统。我负责架构和核心代码,半夏负责算法和性能优化,楚飞负责客户端和逆向兼容,陆明负责ui和用户体验。”
“第四,一周后,我会发详细的需求文档和技术方案。这周,你们各自熟悉相关技术,准备好开发环境。”
“有问题吗?”
楚飞:“分成比例现在不能说?”
林浩:“可以私下聊。但原则是:公平,透明,多劳多得。”
陆明:“网吧更新系统……听起来不像游戏?”
林浩:“不是游戏。是工具,是入口。我们要先活下来,才能做想做的事。”
半夏:“技术栈?”
林浩:“服务端用java,客户端用c ,管理端用delphi。资料库用mysql。有困难吗?”
半夏:“没有。”
楚飞:“delphi……老古董了。不过也行。”
陆明:“我学得快。”
“好。”林浩说,“那么,今天就到这里。三位加我好友,我们单独聊细节。解散。”
群解散了。三个人分別发来好友申请。林浩一一通过,然后分別私聊,谈具体的分工、时间、收益分成。
等全部聊完,已经是晚上七点。窗外的雨停了,天边有晚霞,金红色的光从云缝里透出来。
林浩靠在椅背上,长长地舒了一口气。
团队有了雏形。虽然只有三个人,虽然还没见过面,虽然前路艰难。
但至少,他不再是独自一人了。
他打开抽屉,拿出那台黑色手机。电量:1.8%。又掉了。
“小艺。”他低声说。
屏幕亮起。
“我在。”
“记录:2002年6月25日,horizon初步团队组建完成。核心成员:半夏(算法)、楚飞(工程)、陆明(设计)。第一个项目:网吧游戏更新系统,正式启动。”
“已记录。恭喜。但电量已降至危险水平,建议在下次充电前,不再进行大规模查询。”
“我知道。”林浩说,“休眠吧。等需要的时候,我会叫你。”
屏幕暗了。
房间里安静下来。只有电脑风扇的嗡嗡声,和远处街道上偶尔传来的车声。
林浩坐在黑暗里,看著窗外的晚霞。
第一步,迈出去了。虽然很小,虽然很慢。
但方向对了。
他起身,打开灯,坐回电脑前。开始写第一个项目的需求文档。
键盘声响起。嗒。嗒嗒。嗒。
沉稳,坚定,像心跳。
这一次,不再是独奏。
是合奏的开始。