2026-08-20 zombie-world 联机重构与局内货币 · 全链路复盘 · v1
两日一轮:4 个玩家反馈 bug → 局内货币系统 → 联机从「局域网 P2P」重构成 「自有服务器房间制」并上线。重点是四次方向被推翻,其中两次是自己的判断错。
事实记录(不可修改区)
- 项目:zombie-world(僵尸危机:方块头),B站 Toy
19242799980544,PUBLIC - 区间:11 个提交(
4c3f1fa→aa3477a),2026-08-19 ~ 08-20 - 提交审核 2 次,2 次均已过审上线(第二次线上构建
19242799980544-v8298) - 测试:47 → 91 条,全绿
- 新增线上依赖:房间服务器
wss://<自有域名>/zombie/ws(腾讯云香港,与主站同机) - 数据来源:本机实测 + 服务器实测 + 线上构建产物核对
- 没有真实玩家数据 —— 联机属于「已上线但没有证据」
交付 vs 诉求
| 用户提出的 | 实际交付 |
|---|---|
| 修 5 个反馈 bug | 4 个(第 5 个”没有货币系统”用户当时明说可以之后再设计) |
| 完善货币系统(局内 + 只卖消耗品) | 做了,已上线 |
| 联机「做成 Minecraft 那样的局域网联机」 | 没做成,也做不到;改成服务器房间制(2~4 人、任意网络) |
最后一条要写清楚:交付的不是用户字面要的那个功能。 它解决了用户真正抱怨的”进房太麻烦”,并顺带解决了”必须在同一个网络”。
四次方向被推翻
1. 「没有公网服务器」——错误前提裁掉两个月 ❗
见独立律档:约束型结论先复核律_文档写的不可能会过期_v1。
一句写在 README 里的约束,让所有联机设计在”怎么不用服务器”里打转两个月;
而服务器早就部署好并跑了 23 天,只是配了纯 IP + 纯 HTTP,https 页面连不了 ws://。
2. 「iOS 本地网络权限死结」——复述了一个已被推翻的猜想 ❗
同上律档实证二。结论就写在项目记忆里,没先读就下了判断。
3. Cloudflare 免费信令——完整做完,整套没上线
按”零成本零维护”的约束,设计并实现了 Worker + Durable Object 信令服务: 业务逻辑与平台解耦(纯函数进出)、22 条单测、本地两标签页端到端跑通、部署文档齐全。 容量与定价也查得很准(KV 免费层每天 1000 次写 = 500 局/天到顶,所以改用 DO)。
栽在最后一公里:dash.cloudflare.com 对命令行客户端返回 bot 挑战页
(Just a moment...),而 wrangler 的 OAuth 必须去那里换 token。
试了 4 次、3 种方式(含用浏览器扩展点授权页)都不可能成功。
→ 这是 可行性生死线前置律_移植先探一票否决约束_v1 的第三次验证, 且是新维度:前两次的生死线是”性能”和”权限等级”,这次是认证链路本身。
4. 「Minecraft 式局域网发现」——正确设限,不算推翻
用户要的观感在浏览器里做不到(无 UDP / 组播 / 监听端口,页面当不了服务器)。 第一时间说清楚能力边界的物理原因,并把问题拆成三格:
| Minecraft 的那一步 | 浏览器 |
|---|---|
| 局域网广播自己 | ❌ 做不到 |
| 客机自动列出附近的房间 | ❌ 同上 |
| 把 offer/answer 递过去 | ⚠️ 只有这格能改——鸡肋就出在这里 |
| 连上之后的数据通道 | ✅ 已经有了 |
拆格之后双方很快在”只能改中间那格”上达成一致。这次是对的,值得保留为模式。
可迁移的技术做法
砍数据结构前,先把「谁会读它」逐字段列出来
联机中转的快照体积直接等于带宽成本。原来的打包是”把实体的标量字段一股脑倒过去”, 于是纯服务端的 AI 状态(僵尸的绕障参数、BOSS 的五个技能冷却)也按 17 位浮点发了一遍。
改成按类型白名单 + 定点数,白名单照着渲染函数和客机本地逻辑逐字段对出来、 并在代码里注明”谁在读它”。同一份状态下 A/B:
| 改前 | 改后 | |
|---|---|---|
| 原始 JSON | 9135 字节 | 3263(−64%) |
| 压缩后 | 3282 字节 | 1127(−66%) |
| 每客机 | 80 KB/s | 28 KB/s |
关键纪律:白名单而不是黑名单;砍完必须端到端实跑对账(数量、得分、抽样字段精度)—— 砍漏一个字段的表现是”房主看得见客机看不见”,极难查。
用「同一状态下的 A/B」代替前后两次测量
第一次测瘦身效果时前后两次的敌人数不一样,得出”0% 改进”的假结论。 改成在同一帧上同时跑新旧两种打包,才拿到可信的 −64%。 性能优化的对照必须同状态,不能同场景。
反馈里的”偶尔”往往不是随机
“偶尔自动切枪,没能复现”——查下来是解锁新武器时无条件 p.weapon = i,
每局只在跨过连击阈值时发生几次,所以像随机。
用户说”偶尔/没能复现”时,先找”低频但确定”的触发条件,别先假设是竞态。
尚未验证(上线了,但没有证据)
- 真实玩家的连接成功率与延迟(实测的 127ms 是本机绕代理经新加坡到香港,不代表国内直连)
- 局域网 P2P 传输层(代码保留、无界面入口、仍无真机结论)
- 4 人同时在线(只测到 3 人)
- 货币数值的有趣性(只验了稀缺性:十波下来”买完剩下”始终贴着 0)
关联文档
- 本轮提炼的律:约束型结论先复核律_文档写的不可能会过期_v1
- 第三次验证的律:可行性生死线前置律_移植先探一票否决约束_v1
- 复盘纪律:复盘事实先行原则
- 同作者的另一个游戏项目:2026-07-29_LastStand_v0.7.1_纯修复版开发闭环复盘_v1
- 先对基线:开工前先对基线律_v1
- 同项目下一轮(分享会当天,含 iOS 触屏与投影发糊):2026-08-21_一小时分享会_从设计到投影现场_全链路复盘_v1