下载 App
涌仙,天道模拟器
10/1214 浏览综合
10 月 12 日 · 开发者日志 #6
---
哦,伙计们,我们又见面了。这是第六篇。
我知道你们在想什么。你们在想:"这位可怜的老兄今天又打算跟我们抱怨些什么呢?"好吧,好吧,我承认,抱怨确实是我的强项之一——但今天,今天有点不一样,我的意思是,今天确实发生了几件值得你停下来听一分钟的事。
先来杯咖啡的时间,看看今天到底攒下了多少家底:三百六十八次提交,其中十五次是今天;一百五十八个 Lua 源文件,六万两千九百五十二行;八十七种事件类型。至于那十三道门禁——十二盏是绿的,还有一盏不是。我们会谈到那一盏的。我保证我们会谈到。
---
【本期进展】
第一件,老天,先把昨天那笔债说清楚。
昨天,在这同一个位置,我用相当不要脸的大字号告诉你们:main.lua 涨到了一千四百七十七行。而我自己给它划的线是一千四百七十,并且那条规矩后面还写着"只许降不许升"。我把线踩碎了,踩得干干净净,一行不剩。
今天它是一千四百零一行。
不过请注意——我必须非常认真地请注意——我一个字的功能都没有删掉。 你知道删功能把行数降下来是什么玩意儿吗?那是这个行业里最便宜的化妆术,任何一个还没睡醒的家伙都会在三十秒内做到,而它证明不了任何东西。我做的其实是这样一件事:把那坨挤在入口文件里、"谁都能往里塞点东西"的注册代码,一块一块地,被搬进了三个新文件——LayoutProfiles,三百三十四行;InputRouter,五百八十七行;PlayerUiState,一百四十三行。东西全在,一个没少,只是终于不挤在门口了。
哦,那感觉可比修好一个 bug 爽快多了。我是说真的。可能是因为昨天我难受得实在太厉害了,你们都知道那种难受,对吧?
第二件,玩家操作界面:P0 到 P5,六层。
在相当长的一段时间里,这款游戏操作逻辑的样子是这样的:玩家点到哪儿,哪儿就算数。哦,那可真是聪明——在一个原型阶段。到了成品阶段,它有个更贴切的名字,我们内部一般叫它"事故现场"。
所以现在,分工变成了这样。
InputRouter 是唯一的那个独裁者——我指的是唯一,全部点击都得先排着队从它门前过一遍,由它抬头看一眼"这位可怜的玩家此刻究竟站在哪个界面上",然后才决定这条点击该给谁。而在以前,哦,以前是十一个面板各自趴在地上偷听全局点击事件,像十一个人同时听见了同一句话,然后一起开口互相打断。现在只剩下一个人听着了。安静得让人有点不习惯,我得承认。
LayoutProfiles 管的是屏幕。而手机世界真正刻薄的地方,不在于它有几种尺寸——不,不,那样反倒简单了——而在于它有十几种。 iPhone SE 那块可怜巴巴的三百二十乘五百六十八;Galaxy Z Fold 外屏那种三百四十乘八百的、像被门夹过的窄长条;一直到 iPad Pro 的一千零二十四乘一千三百六十六,那块富得流油的板砖。每一种该给按钮留多宽、玉简该贴在哪一边,全写在这里面了。于是今天,机型矩阵:十四款,全绿。 对一个孤零零的家伙来说,这个数字简直有点让人得意忘形了。
PlayerUiState 是一台小小的状态机,它回答的是一个上周没有任何人能回答的问题:这位玩家现在究竟是在看这个世界,还是在读某个人的履历。同样一颗星星,落在这两种状态之下,你点下去该发生的事是完全不同的——而在过去,它根本不知道自己面对的是哪一种。
第三件,哦,第三件才是我今天真正想拉着你的手聊的那一件。
宗门开始自己打架了。
我不愿意手写剧情。你们知道为什么吗?因为手写剧情这东西,玩家玩到第三遍就会闻出塑料味儿,而我又恰好是个懒惰到无可救药的人。所以我把全部的赌注,都押在了这次 Jam 那个词上——涌现。
今天,有两套自驱逻辑被接上了:宗门地缘政治,还有人间百态。八十五个文件,加了五千九百三十六行。
它们不读剧本,老天,它们压根儿不知道剧本是什么。它们读的是彼此的处境:谁家灵石堆得比邻居高出一截;谁家秘境就那么不巧,正好贴在别人家的山门外头;谁昨天刚死了第一位长老,于是继承的位子空了整整半年,而所有人都看见了那个空缺。你把它们放出去跑,然后——然后它们就会自己结仇、自己结盟、自己吞并,自己把彼此灭掉。
而我一行剧情都没有写。 我向上帝发誓。第一次看见两个宗门因为一件我完全没有安排过的事情真的动起手来的时候,我在椅子上愣了大概有五秒钟,手里那杯东西全凉了。
第四件,法宝:九档品级,九段精炼。
EquipmentSystem.lua,九百四十四行;EquipmentDefs.lua,七百六十四行。九个档,从最不入流的那一档一路排到头;九段精炼,每一段到底是涨一个数值还是掉出一条新词条——规则全部被写进了配置表里,我的意思是全部,代码里连一行零头都没剩下。
而这件事真正的回报,哦,真正的回报,根本不是"省了几百行"那种廉价东西。回报是:我在调数值的时候再也不用去碰代码了,于是我再也不会在改一个八百里外的掉落率时,顺手把另一个八百里外的东西踢进沟里。那玩意儿叫免费的安全网,朋友们,免费的。
跟它一块儿装上的是 HeritageSystem,四百五十五行,管传承;和 CelebritySystem,二百八十二行,管名人。因为它们本来就是同一枚硬币的两面:一件法宝总得有个人把它传下去,也总得有个人为它出点名。
第五件,地形它终于不是一张棋盘了。
改成了 Marching-Squares 的四十五度倒角。用大白话讲——我怕你们嫌我啰嗦——从前地图是一格一格的正方形,你要是斜着走,你走出来的是一条丑陋的楼梯;而现在方块的角被切掉了,斜线它终于是一条真正的斜线了。
代价?哦,代价是这一趟动了五百六十四个文件。全是坐标,全是朝向,全是那种你以为是 A 结果是 B 的连锁反应。到今天凌晨,我还没能完全原谅我自己,我猜明天也悬。
第六件,声音第一次有了"出处"这么一栏。
以前我加音效的方式是"诶,这个听起来不错,加上"。今天我为自己写了那份《世界音效来源与接线》,把每一个音效的事件来源,一条条落进了 AudioFeedbackDefs,然后派了一份叫 SpecAudioFeedback 的断言站在门口守着它。从今往后规矩是这么个规矩:你想加一个声音,先证明它是哪件事发出来的。 天雷落下的动静必须来自天雷——不能只是因为那段素材好听,见鬼,我以前就是这么干的。
第七件,也是最后一件:七个幽灵机制终于被超度了。
在此之前,有七个机制被声明了、然后被忘了,从来没有被接上过。它们就那么安静地躺在代码里,像七个不领工资却天天按时打卡的员工。今天,全部接完了。愿它们安息。
---
【问题与风险】
第一条,哦,我最偏爱的一条:我把十八个断言弄丢了。或者多出来了十八个。我至今还不知道究竟是哪一种。
run_spec.py 清了清嗓子,告诉我:通过一千七百一十五条。
而 run_main.py,那个内嵌着同一份 Spec 的家伙,转过头告诉我:通过一千七百三十三条。
同一个东西,两个数字,中间隔着十八条断言。这说明有一条链路在我们所有人的眼皮子底下,偷偷多跑了一段——而我不知道它跑了什么,我也不知道它为什么要跑。
而真正让我后背发凉的部分是,你们猜怎么着?这两处写的都是"失败 0"。 没有任何一盏灯为它变红,没有任何一个人会为它难受。绿灯是会上人停止提问的,我的朋友,这正是它最危险的地方。明天我就去逮它。
第二条,那个 TablePool 慢了整整三分之一。
一万次借还:昨天三千毫秒——好吧我指的是三点零零毫秒,昨天;今天四点零零毫秒。绝对数值依旧是每秒百万级的,玩家哪怕把耳朵贴在屏幕上也不可能听出来。但我盯着它。我必须盯着它。因为一个内存池忽然变慢,通常意味着有个家伙在"借"和"还"当中,偷偷夹带干了点别的什么私活。
第三条,也就是那盏红灯:SpecPresentation.lua 里的 redefined-local,基线三,现在五。
静态诊断基线只拦新增,而我偏偏在同一个测试文件里,把局部变量又重定义了两遍。它不会让游戏崩掉,当然不会——它只是那种你今晚可以假装看不见、明晚它会自己长出来的小东西。
不过最近我学到了一条挺有用的规律,今天把它送给同样孤军奋战的你:红灯不是失败,红灯是一张收据。 它清清楚楚记着今天我随手放过的那两件小事,而明天它会连本带利地上门来收。所以我把这张收据贴在这儿,我不藏,我发誓我不藏。
---
【下期计划】
一,把 SpecPresentation.lua 那两条重定义还清。
二,去逮那十八条断言——本周围案。我打算先给两条链路一边装一个计数器,让它们当面对质。
三,把宗门自驱逻辑放出去跑一次长局,看看它会不会把自己玩到崩溃。而如果它真的崩了——哦,老天,那可不是 bug,那就是我要卖给你们的那件东西。
四,试法宝九炼的手感。我怀疑数值铺得太开了,玩家会在第三档就彻底迷路。要是真那样,我会回来告诉你们的。
---
【数字屏:十三道门禁,十二绿一红】
提交:三百六十八次,今天十五次
体量:一百五十八个 Lua 源文件,六万两千九百五十二行,八十七种事件类型
语法:checked=158 failed=0
纯逻辑:通过 1715 / 失败 0
冒烟:共 66 步,失败 0 步
机型矩阵:十四款,全部通过
Maker 经典 Bug 扫描:0 缺陷;main.lua 1401 / 1470
图集:缺失 0,孤儿 0;显存 1024 KB,而移动端的预算是 25 MB——我们省得有点寒酸了
交付检查:0 错误、0 提醒
建设闭环:十个种子,十个跑通(十个种子 × 六百合游戏日)
首个完工日 81—198 天,均值 117;成功搬运 4—43 趟,均值 15.6;累计工时均值 1349 tick
性能基准 5/5:地形笔刷 2.230 → 1.510 毫秒(−32.3%);实体遍历 79.00 毫秒 / 337.9 KB GC → 0.00 毫秒 / 2.0 KB GC;五千次分类索敌 4.00 毫秒,零次分配
唯一的那盏红灯:SpecPresentation.lua redefined-local,基线 3 → 现在 5
最后一件小事,哦,我最喜欢的一件。
那张建设闭环表里,有一栏的名字叫"作废"。十个种子,整栏全是零。 一座工地只要立起来了,就没有一座被放弃过。
而"阻塞原因"那一栏讲的才是人间:seed 8888 有十六次 no_path——人已经走到工地跟前了,路断了,就在最后那一格;seed 5150 有七十三次 worker_away——该开工的时候,全体工人统统在别处;而 8888 还额外贡献了三十三次 worker_lost。
我从没为这些写过一句台词。可是一个工人走了一整天,路在最后一格断了,他就站在断口前面——那个画面,朋友们,那才是玩家两小时之后还会记得的东西。
好啦,就说这些。感谢你们读到这里,我向上帝保证这不是一句客套话。我们下回见。
P.S. 那十八条断言。如果明天它变成了零差异,我会在下一篇里告诉你们为什么;如果它没变,那我就把它一直挂在标题上——一直挂着,挂到它脸红为止。















