下载 App
《深渊寻金》【开发者日志】第五篇
10/1610 浏览
【开发者日志】第五篇:地牢开始记住你了
大家好,我们是新人团队 EmbersStudio,第五篇开发者日志来了[表情_可爱]
这一期我们没加新怪,也没堆一堆新特效,而是给地牢装了个“小账本”——每局结束之后,它会留下一条记录
当然,我们还在其他地方做了优化![[表情_星星眼]](https://img-tc.tapimg.com/market/images/49174c5480690cc48faea772549a81e0.png)
![[表情_星星眼]](https://img-tc.tapimg.com/market/images/49174c5480690cc48faea772549a81e0.png)
本期进展
近几天我们在做 Plan_5。上一期把游戏往「好看、好懂、好爽」的方向推,这一期给它加的是记忆:每局结束之后,地牢会留下一条记录,其作为存档记录的内容
后续会将存档记录内容的UI做完
后续会将存档记录内容的UI做完涌现日志
打完一局,不管是通关还是死掉,游戏都会自动生成一份涌现日志:最长连锁、平均连锁、规则总触发次数、触发最多的三张牌、本局发现的未预设组合、系统给这套牌自动起的 Build 名,再配一句叙事碎片![[表情_佛了]](https://img-tc.tapimg.com/market/images/94d512d1473ccfa646b123476fc2edd1.png)
![[表情_佛了]](https://img-tc.tapimg.com/market/images/94d512d1473ccfa646b123476fc2edd1.png)
实跑的一局长这样:
json{ "result": "victory", "floor_reached": 3, "duration_seconds": 303.9, "max_chain": 20, "average_chain": 9.14, "total_rule_triggers": 600, "top_rules": [ { "id": "bullet_echo", "name": "子弹回响", "count": 290 }, { "id": "gold_barrage", "name": "金币弹幕", "count": 113 }, { "id": "crit_bounty", "name": "暴击赏金", "count": 102 } ], "discovered_combos": 0, "build_name": "战斗流", "narrative_snippet": "本局涌现模式:战斗流,峰值 20 段。它已经在等下一次了。" }
这一局最长连锁到了 20 段,平均每段能连 9.1 次,规则一共真的执行了 600 次动作。三个数字放在一起,才看得出来这局有多疯——我们自己平时玩的时候,还以为连锁十几段就到顶了![[表情_流口水]](https://img-tc.tapimg.com/market/images/f0320a0494447e27b7123a94b6cbcecf.png)
![[表情_流口水]](https://img-tc.tapimg.com/market/images/f0320a0494447e27b7123a94b6cbcecf.png)
未预设组合:终于有了能验的判据
Day 3 到 Day 6 那一期,我们纠结过「涌现到底发生了没有」,当时只能靠自举闭环和批量仿真旁敲侧击。这一期总算给了直接判据,四条必须同时满足:
| # | 判据 | 为什么必须有 |
|---|---|---|
| 1 | 两张牌在 2 秒窗口内交替触发 ≥3 次 | 只触发一次不算「转起来」 |
| 2 | 这一对牌不完全落在任何一条预设组合里 | 否则我们只是在检测自己的白名单 |
| 3 | 本局真实执行深度 ≥8(上限 12) | 排除「碰巧交替」的浅连锁 |
| 4 | 这一对牌不完全落在事前登记的预期清单里 | 这条最容易被忽略,下面单独说 |
就拿第 4 条来说。只有前三条的时候,检测器测的其实是「不等于那 4 条预设白名单」——而 Plan_6 内部测试要用的经济流、弹幕流、治疗流都在这 4 条之外,可它们明明是我们自己设计的。所以我们补了一份预期清单:把「我知道但我没写进预设列表」的组合也登记进去,命中了就不算发现
数据源也换了个口径:只认真实执行(每次动作真的执行才算一次),不认屏幕上那个连锁数字。因为那个数字包含被闸门拦下的触发,拿它当证据会给出假信号——这一点 Day 3 到 Day 6 已经在仿真里栽过一次
Build 自动命名
一局结束,系统按触发最多的两张牌给这套牌起个名字。规划里给了一条公式(「A 的标签 + B 的标签 + 流派后缀」)和一张示例表(「暴击金币弹幕流」)。我们照着做的时候发现两者对不上——暴击赏金 的标签是「经济」,金币弹幕 是「战斗」,按公式只会得到「经济战斗流」
最后取了个折中:示例表优先,公式兜底,两个都产不出名字就老实写「未命名 Build」
存档与叙事
存档落在本地 save.json:图鉴解锁、最高记录(最高连锁 / 最高层数 / 总局数 / 总击杀)和最近 20 份涌现日志
写入用的是「先写临时文件、再删旧的、改名过去」——直接往正式文件里写,写一半断电会留下一份截断的 JSON,整份存档就废了;万一程序死在替换那一步,下次启动还能从临时文件把内容捞回来
叙事碎片分五档:房间墙上的文字、结算片段、死亡旁白、通关旁白、层间加载提示。文案全部集中在一个 JSON 里,同一局内不重复,不看也不影响玩法
墙上文字是 12 像素低对比的小字,放在普通房里的随机位置——Boss 房不放,那里已经有 Boss 血条在抢注意力了![[表情_酷]](https://img-tc.tapimg.com/market/images/edd50e702f508971043f5619f686740e.png)
![[表情_酷]](https://img-tc.tapimg.com/market/images/edd50e702f508971043f5619f686740e.png)
问题与风险
同一把尺子,几局量出三个数
原本规划里写得很清楚:「单局 0–3 个未预设组合。0 个说明触发深度不够,≥5 个说明判定过松」
照这套判据反复跑了六局(同一颗种子、同一套脚手架),拿到的是 0 个、3 个、9 个
六局里差别只在驱动脚本的时序——时序一动,中途抽到的牌就不一样,这个数就跟着跳。换句话说,它现在测的其实是「这一局恰好抽到了什么牌」,而不是一个稳定的性质
抛开随机性,结构上的问题是清楚的:
- 门槛在一局的执行密度面前太低了。 2 秒窗口 + 交替 3 次,在一局 600 次左右的真实执行里几乎随手就能撞到
- 判据只判「两张牌」。 一副六张牌的构筑有 15 个两两组合,一局下来命中几对几乎是必然。我们检测的是「两张牌有没有一起转过」,不是「一套牌有没有变成新东西」
所以这一段要在 Plan_6 收紧,能动的旋钮有三个:把交替次数抬到 4–5、把窗口缩到 1–1.5 秒、或者要求同一对组合在本局内重复命中多次
我们暂时没改,因为阈值一改,「涌现到底发生了没有」这个结论就跟着变。而且现在这个 0 / 3 / 9 的散布本身就是一条证据:在把尺子校准之前,我们调的其实不是机制,是噪音
组合 ID 里的链长档位是空转的
规划里给组合 ID 设计了一个链长档位后缀(@chain{深度向下取整到 5 的倍数}),本意是区分「同一个组合在不同强度下的表现」
实测攒下来的组合 ID,全部是 @chain10——因为真实执行深度的上限就是 12,档位只可能是 10。这一维完全没有区分度,要么改档位步长,要么换成「发现时的实际深度」
两个「一局时长」口径不一样
涌现日志里记的是游戏内计时(暂停、选牌、层间过渡都不走表),自测报告按帧数算
同一局在两个口径下能差出上百秒——早前带新手引导的一局里,两种口径差了 188 秒,因为引导那段阻塞窗口走的是挂钟时间
做平衡分析的时候必须确定是用哪个,不然「一局到底几分钟」这个就存疑了
图鉴这一期只留了接口
图鉴(规则牌 / 敌人 / 组合三层的解锁与展示)这一期没有实现,只留下了一份接口
这是我们主动砍的:先把日志和存档做实,图鉴是纯展示层,砍掉它对玩法零影响,接回来也不用改调用方
代价是「死亡不丢图鉴」这条验收目前只能算部分通过——组合那一层确实在往存档里写(几局累计落了 3 条),规则牌和敌人两层还没有生产者,结算界面上也就没有「图鉴解锁」的提示
自测会写真实存档
这一期新引入的小麻烦:三套整局自测都会真的打完一局,于是它们会把 save.json 里的记录和日志刷新一遍——跑一次自测就多一条通关记录
存档路径是可配的,但主场景目前固定用默认路径。下一步要给主场景加一个测试用的路径开关
下期计划
- 技能牌继续扩:牌池往上加,重点让多张牌抢同一个触发事件,调序才会真的改变结局
- 敌人继续扩增:增加更多敌人,丰富关卡内容,同时不同机制让游戏更丰富
![[表情_酷]](https://img-tc.tapimg.com/market/images/edd50e702f508971043f5619f686740e.png)
- 层间补给:清完普通房目前只有三选一技能,下一段会让层间也能换别的,并且花得上金币
- 结算计分:把整局表现折算成一个分数,让「这局打得怎么样」一眼能看懂,明确游戏的目标
- 一局时长与视听:把一局往 10–15 分钟推,同时继续补美术素材与音效
- 当然,还有各种 Bug 的修复
![[表情_吐舌头]](https://img-tc.tapimg.com/market/images/945b09ff7a33dc3966007a3e87896ebf.png)
开发过程截图

图 1:通关结算界面。 一次通关结束后的完整结算:到达层数、最长连锁、触发最多的规则牌、本局用时、Build 名称、涌现日志摘要、叙事碎片,最后是按钮

图 2:层间过渡结算。 只有标题、层数、最长连锁、触发最多的牌和用时,Build 与日志两块都隐藏。用来和上面那张对比,说明不是每层都铺满信息。这个后续还会调整![[表情_微笑]](https://img-tc.tapimg.com/market/images/0f170d4b1ecf80c267e5a44b5992a199.png)
![[表情_微笑]](https://img-tc.tapimg.com/market/images/0f170d4b1ecf80c267e5a44b5992a199.png)

图 3:房间墙上的文字。 上半张是放大后的原文,下半张是它在房间里的实际样子。12 像素低对比的小字,摆在普通房的随机位置,扫一眼很容易略过去![[表情_嫌弃]](https://img-tc.tapimg.com/market/images/3b98294830b76e0c70e2ce54eda41ab0.png)
![[表情_嫌弃]](https://img-tc.tapimg.com/market/images/3b98294830b76e0c70e2ce54eda41ab0.png)
文本 4:save.json 的内容(文本)。 展示 records 与一份 run_log,可以看到日志确实落盘了,而不是只在结算界面飘一下:
json{ "records": { "max_chain": 25, "max_floor": 3, "total_runs": 6, "total_kills": 474 }, "run_logs": [ { "run_id": "2026-10-14_05-12-49", "result": "victory", "duration_seconds": 303.9, "max_chain": 20, "total_rule_triggers": 600, "build_name": "战斗流", "discovered_combos": 0 } ] }
文本 5:某一次跑出来的未预设组合 ID(文本):
textchain_overload+crit_bounty@chain10 bullet_echo+chain_overload@chain10 chain_overload+gold_barrage@chain10
图 1 还录了一小段(日志5_通关录像.mp4,约 66 秒):第 3 层最后一个房间开始,一路打到通关,最后是结算面板。想直接看结论的话,视频最后 10 秒就是那张结算界面。
杂谈
游戏名在上期定了:《深渊寻金》,英文 Abyss Rush。这两个月它的代号一直是 RogueDungeon,这也一直是项目文件名称![[表情_吃瓜]](https://img-tc.tapimg.com/market/images/d07b262774c8a022a7dddbc39683da6b.png)
![[表情_吃瓜]](https://img-tc.tapimg.com/market/images/d07b262774c8a022a7dddbc39683da6b.png)
另外说件我觉得挺有意思的事。涌现日志里那个 Build 名字是系统自己拼的,我们一个字没写。同一套机制,它给出过「经济爆发流」这种听着挺唬人的名字,也给出过「战斗流」这种朴素的。我个人更待见朴素的那种,至少我一眼能看懂它想说什么![[表情_流口水]](https://img-tc.tapimg.com/market/images/f0320a0494447e27b7123a94b6cbcecf.png)
![[表情_流口水]](https://img-tc.tapimg.com/market/images/f0320a0494447e27b7123a94b6cbcecf.png)
最后一个小插曲。墙上那行字我们定的是 12 像素、低对比,扫一眼基本会略过。结果自己做回归的时候,我盯着屏幕找了半天才想起来它在哪
这大概说明它确实够低调了
这大概说明它确实够低调了









