下载 App
《变成黑洞》经费已至,敬请期待
日期:2026-10-17 ~ 2026-10-18 本期构建序号:19 → 56(共 38 次构建) 代码规模:8469 行 / 14 个文件


一、本期进展
这一期的主线只有一件事:把「视野」这件事从头重做一遍。 围绕它牵出了一连串问题——阶段错乱、渲染预算、特效不跟随、性能卡顿。 下面按「主线 → 连带修复 → 工程债」的顺序说。
1. 视野重构:从「按玩家体型」到「固定广阔」
起点:用户反馈「所有球体都太大了,手机横屏看不清主次」,并给了参考图。
原来的镜头是按玩家体型定标的(zoom = 短边 / (玩家半径 × 7)), 问题在于:玩家越大,镜头越远,但球在屏幕上的占比永远不变—— 所以永远只能看到自己那一阶,宇宙的层次感完全没了。
这一期改了六轮才定下来:
| 轮次 | 用户反馈 | 改动 |
|---|---|---|
| 1 | 「球体太大了」 | 引入 CameraPlayerRadius(玩家占短边比例) |
| 2 | 「视野忽大忽小」 | 删掉「按附近最大天体自适应」——那是抖动的真凶 |
| 3 | 「固定拉到最远」 | 占比降到 0.12% |
| 4 | 「这个比例很好」 | 回到参考图比例(6%) |
| 5 | 「各阶都要同屏」 | 改为按最大阶(红巨星 r=310)定标,跨阶视野恒定 |
| 6 | 「玩家食物太小」 | 加最小渲染尺寸 + 暖色描边 |
最终形态:所有阶段共用同一个缩放(实测 zoom 恒为 0.128), 一块手机屏幕里能同时看到碎石到黑洞的全部 12 阶。
教训:这六轮里,前五轮都是我在调一个数字,没有一开始就问清楚 「你要的是固定视野还是可伸缩视野」。 如果第二轮就问清楚,能省掉三轮往返。
2. 视角拉远后暴露的连带问题
视野一改,所有基于"屏幕尺寸"的假设全部失效。这一期修了一大批:
① 食物刷在视野外 旧的生成环带按「半对角线 × 系数」算,而横屏视口是扁的(半高远小于半宽), 大量食物被丢到屏幕上下很远的死角,永远不进画面。 改成按可见矩形外扩,并让大部分直接生在可见范围内。
② 景观天体怼在出生点 12 阶景观天体原本摆在视野外(免得干扰玩家)。 为了「各阶同屏」把它们挪进视野后,一颗红巨星可能正好落在出生点旁边—— 实测开局 90 帧内就被吞。加了出生安全区 + 恢复出生保护期。
③ 硬编码阈值全部失效 黑洞渲染里有一句 local isBig = sr > 30(「太小时只画核心」)。 固定视野后黑洞屏幕半径只有约 15px,这个条件永远不成立—— 吸积盘、光子环、透镜弧全被跳过,黑洞退化成纯黑圆。
用户反馈「我的黑洞怎么成这样了」就是这一条。 改成 sr > 6,并给盘加了按屏幕尺寸缩放(diskBoost)。
3. 黑洞渲染:两次独立的 bug
黑洞在这一期出了两次问题,原因完全不同:
| 问题 | 根因 |
|---|---|
| 退化成纯黑圆 | 硬编码阈值 sr > 30 在固定视野后失效 |
| 多个黑洞长得不一样 | 盘粒子预算是全局共享的,一个黑洞吃掉约 1770 点,总预算 2400 → 第二个黑洞被截断 |
第二个问题尤其隐蔽:我上一轮为了修第一个问题把预算从 720 提到 2400, 那时场上只有一个黑洞,够用。但这一期新增了 3 个外围黑洞后, 只有第一个是完整的,后面的退化成光秃秃的黑圆。
修法是新增 Core.SetRingBudget(holes),按本帧可见的黑洞数量动态分配。
4. 阶段错乱:一个反复出现的坑
用户反馈:「触发红巨星特效然后变成类地行星」。
排查发现根因在快照还原:RestoreSnapshot 重建天体时用 NewEntity(x, y, r), 而这个函数会按半径反推阶段。但半径非单调:
红巨星 310 → 中子星 102.9 → 黑洞 114.8反推必然错位。实测数据:
复活后 stage=2 kind=neutron 期望kind=meteor r=102.9
复活后 stage=2 kind=blackhole 期望kind=meteor r=116.1
...
不一致实体数 = 7一个 stage=2(陨石)的天体,因为半径是 102.9,被画成了中子星。
修法:快照里一并存 stage,还原时直接恢复,不再靠半径反推。
教训:「按半径反推阶段」这个坑,这个项目已经踩过至少四次。 半径非单调是根本原因,凡是「从半径倒推阶段」的地方都是隐患。 这次排查时我还发现 SupernovaEvents 里有同样的写法(目前是死代码,未触发)。
5. NPC 进化判定:只升一阶
根因:NPC 进化只升一阶,但它的成长方式和玩家不同。
- 玩家每口最多长 8%(MaxGainPerRadius),永远不可能一口跨多阶
- NPC 是「面积相加」(grow = small.r² × 系数),一口可能长很多
结果:一口从陨石涨到半径 150,但 stage 只跳到「小行星」—— 渲染按 stage 取贴图,就显示成被放大的小陨石。
修法:改成循环补齐,一直升到半径对应的正确阶段为止。
6. 特效不跟随主体
用户反馈:「球体都走了,然后特效在原地放」。
根因:SetAnimSubject 存的是坐标快照,不是实体引用。 进化动画要播 1.8~2.6 秒,期间 NPC 早飞走了。
修法:
- 改为存实体引用(animEnt),AnimAnchor 逐帧读实时坐标
- 快照保留作兜底(主体中途被吞噬时用)
- 动画播完自动释放引用(否则残留死引用,特效飘在空处)
实测验证:主体从 (-2690,1926) 移到 (-2670,1910),快照停在原地不动, 说明渲染确实在跟随实时坐标。
7. 黑洞特效重做:从「两条粗线」到粒子喷流
用户反馈「黑洞特效不够帅,两条粗线没意思」。
原来的极向喷流画的是两个实心梯形,读起来就是两条粗线。改成:
- 粒子流喷流:26 个光点沿轴分布,越远越细越淡,带等离子体扰动 + 随时间向外流动,芯部偏白、外缘偏蓝
- 新增吸积盘:坍缩后新生盘开始旋转,与喷流同时出现
这样「变成黑洞」读起来是**「一个系统诞生了」**,而不是「炸了一下」。
8. 外围刷新:12 阶全部多刷
用户要求「12 阶多刷一些,刷在地图边沿」。
新增 11 个外围刷新档位(第 2~12 阶),全部刷在星域外围环带。
排查中发现两个坑:
| 坑 | 说明 |
|---|---|
| 回收半径会吃掉外围天体 | 回收半径约 5788,星域半径 6000——刷在边界附近的天体下一帧就被回收 |
| 计数逻辑按半径归档 | 中子星(115)和黑洞(125)都比红巨星(320)小,按半径区间归档会全部错位;而且碎石档没有 absMax,会吞掉所有统计名额 |
修法:环带夹在回收半径之内;计数改成按 stage 归档(每档唯一)。
9. 性能与卡顿
用户反馈:「BGM 卡住,尤其玩家黑洞相对而行时」。
我先确认了一件事:BGM 播放后代码里再没有任何操作,音频引擎有独立线程。 所以卡顿只可能是主线程被长耗时帧占满。
找到的确切风险:上一轮修「多黑洞渲染不一致」时, 我把光点上限无条件抬到了 12000。而每个光点是一次径向渐变填充, 是全场最贵的绘制操作。
收紧:
- 单个黑洞盘预算 1900 → 1300 点
- 总上限 12000 → 4200
- 每环点数 210/200/180 → 140/134/120(约 -33%)
诚实说明:我本地测不出这个问题(3 个大天体同屏均值 2.0ms, 黑洞对撞均值 2.6ms)。桌面软渲染和手机 GPU 表现不同—— 我这边"不卡"不代表真机不卡。这次是按风险收紧,不是按复现修复。
10. 世界与难度
| 项 | 改动 |
|---|---|
| 星域半径 | 6000 → 20000(面积 11 倍) |
| 通关阈值 | 世界半径 × 0.78 → × 0.5(通关需要玩家 r=10000) |
| 第 6~12 阶难度 | 每阶口数 ×3(全程约 1210 口 → 3445 口) |
连带修的问题:星域放大后,通关要求玩家 r=10000, 而固定视野下 10000 的屏幕半径是短边的 2.4 倍——球会撑爆屏幕。 新增 CameraPlayerMaxFrac = 0.18(玩家超过短边 18% 后镜头拉远,前期不受影响)。
顺手删掉一道有害的钳制:相机里有一道「视野不能超出星域」的钳制。 验证后发现:世界半径 = 玩家半径 × 45,随玩家同步扩张, 边界永远远在视野之外(实测 r=10000 时视野半高 27800、到边界 440000)。 这道钳制从不真正需要,却会把 zoom 压得比玩家占比上限还小。
另一个真 bug:第 12 阶(黑洞)根本没有独立的成长系数—— GrowthPerStage 查表越界会夹到最后一格,黑洞一直在用中子星的系数。 第一次改的时候只改了兜底值,实测黑洞通关要 10777 口(远超预期), 补上独立系数后才是 2242 口。
11. 视觉辨识度
用户反馈「背景光点干扰,容易看错食物」。
根因是背景有三层光点,前景尘埃最像食物——它离玩家最近、带失焦散景, 而且有一个暖色变体 (235,215,190),和食物的暖灰几乎同色。
| 层 | 改前 | 改后 |
|---|---|---|
| 星点三层亮度 | 70/120/175 | 42/72/105 |
| 前景尘埃亮度 | 40/52 | 20/26 |
| 前景尘埃颜色 | 冷色 + 暖色变体 | 统一冷色 |
同时给食物加暖橙描边,形成稳定规则:暖色 = 能吃,冷色 = 背景。
12. 工程债:模块化拆分
Game.lua 2880 行、Renderer.lua 2559 行,构建每次告警。本期拆成:
| 文件 | 行数 | 职责 |
|---|---|---|
| Game.lua | 1508 | 玩家 / 成长 / 碰撞 / 快照 / 相机 / 接口 |
| GameEcology.lua | 1029 | 天体行为(感知 / 互吞 / 引力积分) |
| CosmicEnvironment.lua | 873 | 天体构造 / 生成 / 环境视觉 |
| Renderer.lua | 613 | 每帧编排(只调模块,不再自己画) |
| RenderBodies.lua | 521 | 天体本体绘制 |
| RenderTransitions.lua | 501 | 进化 / 撞击动画 |
| RenderCore.lua | 366 | 绘制原语(球体光照 / 粒子环 / 光点) |
| RenderBackground.lua | 339 | 星空 / 星云 / 尘埃 |
| SphereProjection.lua | 116 | 球面 UV 投影试做 |


二、问题与风险
已解决的问题
① 视野改了六轮,前三轮是无效往返
用户说「再大一点」我就调一个数,没有意识到真正的问题是 「固定 vs 可伸缩」这个架构选择。第 5 轮「各阶都要同屏」才暴露出来。
② 硬编码阈值在视野改变后集体失效
sr > 30、radius + 400、900 世界距离…… 这些都是按当时的视野尺度硬编码的。视野一改,全部失效。
③ 「按半径反推阶段」第四次踩坑
半径非单调(红巨星 310 → 中子星 102.9)是根本原因。 RestoreSnapshot、SupernovaEvents、GetStageIndex 都是隐患点。
现存风险
真机性能仍未实测:本地软渲染均值 2~3ms,但手机 GPU 画径向渐变比桌面贵得多。 BGM 卡顿问题用户反馈已修,但我无法验证。
Game.lua 仍超 1500 行(1508),构建会告警。
通关极其肝:全程 3445 口,其中黑洞阶段占 2242 口(65%)。 配合星域半径 20000,一局会很长。
星域扩大后食物变稀疏:从 6000 扩到 20000 是 11 倍面积, 同样数量的天体摊在 11 倍面积上。外围刷新档位的 max 可能需要上调。
未实施的建议(只给了方案,本期未动):
- 引力玩法改进:引力前 4 阶缺席、完全没有视觉表现。 建议「第 1 阶就生效 + 加引力场可视化」,但未实施。
- 宇宙真实性补全:做了差距分析(引力自洽性、双星、潮汐),未实施。
- 切后台暂停、音量开关、排行榜。
双星配置仍未接通:Config.Gameplay.Binary 定义了参数,零引用。


三、下期计划
- 真机性能实测 —— 这是唯一能证伪「卡顿已修」的事
- 拆分 Game.lua(仍超阈值)
- 引力可视化 —— 核心玩法现在完全看不见
- 星域扩大后的食物密度平衡


四、一点感想
这一期最值得记的,不是修了多少 bug,而是两类反复出现的问题。
第一类:硬编码阈值。 sr > 30 让黑洞退化成黑圆、radius + 400 让红巨星怼在脸上、 900 世界距离 让屏幕外的 NPC 震屏—— 它们在当时都是"看起来合理"的数字,但一旦上游条件变化就全部失效。
第二类:「按半径反推阶段」。 这个项目已经踩了四次。每次的表现都不一样(黑洞显示成恒星、 复活后阶段错位、陨石直接变中子星),但根因是同一个:半径非单调。
这两类问题的共同点是:它们不会立刻报错,而是在某个特定条件下 悄悄给出错误结果。比崩溃更难发现。


文档最后更新:2026-10-18








