手机彻底没电是在七月十八日凌晨三点。
林浩按了十三次电源键,屏幕始终漆黑。他把它放在窗台上,对著月光——月光很亮,但没用。钙鈦矿电池需要的是太阳光中的紫外线,月光太弱了。他试了檯灯,试了手电筒,都没用。那0。0%的电量像一道深渊,把所有未来的可能性都吸了进去。
他站在窗前,看著手里这块黑色砖头。2028年的技术结晶,现在成了一块废铁。小艺休眠了,或者说,死了。在电量归零的瞬间,那个温和的女声,那些精確的数据,那些超越时代的洞察,全都沉默了。
他唯一剩下的,是记忆。是之前看过的那些资料,那些架构图,那些算法思路。但记忆会模糊,会出错,会遗漏细节。他不能再问“小艺,这个函数怎么写”,不能再问“这个参数的最佳值是多少”,不能再问“如果遇到这个bug该怎么解”。
他只能靠自己了。
林浩把手机收进抽屉最底层,用几本书盖住。然后他坐回电脑前,打开一个空白的文本文档。
標题:“浩宇1。0引擎重构备忘录”。
他开始写,用最朴实的语言,把自己还记得的东西都记下来。
“1。高並发战斗引擎核心思路:事件驱动+协程+无锁队列。但2002年没有协程库,用状態机模擬。无锁队列用cas实现,但2002年的c++编译器不支持原子操作,用互斥锁+內存屏障替代。”
“2。网络同步优化:客户端预测+服务端矫正。关键:状態快照差分压缩。算法思路:將游戏状態编码为位图,只同步变化的部分。压缩用简单的游程编码(rle),2002年cpu能承受。”
“3。物理引擎简化:2d刚体碰撞,用分离轴定理(sat)检测。但《传奇》是格子移动,不需要连续物理。改为格子碰撞+射线检测,性能更高。”
“4。技能系统:用脚本驱动,但2002年没有好的脚本引擎。改为配置表+硬编码。每个技能是一个状態机,有前摇、施法、后摇三个阶段。”
“5。ai系统:行为树,但太复杂。改为有限状態机(fsm),五个状態:閒置、追击、攻击、逃跑、死亡。”
他写了三页。停下来时,天已经蒙蒙亮。窗外有鸟叫声,清脆的,一声接一声。
他看了一眼时间:凌晨五点。他睡了两个小时,够了。
阿坤和王磊是早上八点来的。两人都带著黑眼圈,但眼神清醒。阿坤背著一个鼓鼓囊囊的书包,里面是他从学校图书馆借的数学书:《计算几何》《图论导论》《数值分析》。王磊提著一个塑胶袋,里面是二十包泡麵,十根火腿肠,一箱矿泉水。
“这是接下来一周的粮草。”王磊把塑胶袋放在墙角。
“我推演了状態同步的数学模型。”阿坤拿出草稿纸,上面是密密麻麻的公式,“但有个问题:如果网络延迟超过300毫秒,预测纠正会导致明显的画面抖动。2002年,很多玩家还在用56k猫,延迟可能到500毫秒。”
林浩接过草稿纸看。阿坤的推导很严谨,但思路还是传统的那一套:降低延迟,优化算法。这解决不了根本问题。
“我们换一个思路。”林浩说,“不追求零延迟,而是让玩家感受不到延迟。”
“怎么做?”
“客户端不只做预测,还做预渲染。”林浩在白板上画,“服务端同步的不仅是当前状態,还有未来几帧的预测状態。客户端收到后,不是立即纠正,而是平滑过渡到预测状態。这样即使有延迟,画面也是流畅的,只是有轻微的『飘移感。对《传奇》这类游戏来说,可以接受。”
阿坤盯著白板,手指在空中比划,心算。过了一会儿,他说:“需要服务端做状態预测,计算量会增加30%。”
“但客户端体验会好很多。”林浩说,“玩家不会因为延迟高就骂娘,只会觉得『这游戏有点飘,但能玩。在2002年,这已经是降维打击了。”
王磊插话:“服务端扛得住吗?我们只有一台二手ibm伺服器。”
“所以需要优化。”林浩说,“阿坤,你来设计预测算法,要准,但不要太复杂。王磊,你来优化服务端架构,用事件驱动,避免线程切换开销。我负责把整个引擎的手工重构出来。”
“手工重构?”王磊皱眉,“什么意思?”
“意思是我要用手抄代码。”林浩说,“把我脑子里的架构,一行行写成2002年能运行的c++代码。没有现成的库,没有参考文档,只有记忆。我会先写核心框架,你们基於框架实现具体模块。”
阿坤和王磊对视了一眼。他们从林浩的语气里听出了什么——一种破釜沉舟的决心,一种不成功便成仁的狠劲。
“从哪开始?”阿坤问。
“从最核心的战斗引擎开始。”林浩说,“今天,我要写出战斗引擎的骨架。阿坤,你继续完善数学模型,今晚我要看到完整的预测算法偽代码。王磊,你搭建测试环境,我要能在一台机器上跑起十个客户端模擬器,模擬不同网络延迟下的表现。”
“十个客户端……”王磊苦笑,“咱们就三台电脑。”
“用虚擬机。2002年有vmware了,虽然慢,但能用。”