发布于 更新于 约 4 分钟读完 · 1,545 字

本文目录 13 节
  1. 事实记录(不可修改区)
  2. 交付 vs 诉求
  3. 四次方向被推翻
  4. 1. 「没有公网服务器」——错误前提裁掉两个月 ❗
  5. 2. 「iOS 本地网络权限死结」——复述了一个已被推翻的猜想 ❗
  6. 3. Cloudflare 免费信令——完整做完,整套没上线
  7. 4. 「Minecraft 式局域网发现」——正确设限,不算推翻
  8. 可迁移的技术做法
  9. 砍数据结构前,先把「谁会读它」逐字段列出来
  10. 用「同一状态下的 A/B」代替前后两次测量
  11. 反馈里的”偶尔”往往不是随机
  12. 尚未验证(上线了,但没有证据)
  13. 关联文档

2026-08-20 zombie-world 联机重构与局内货币 · 全链路复盘

两日一轮: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 个反馈 bug4 个(第 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:

改前改后
原始 JSON9135 字节3263(−64%)
压缩后3282 字节1127(−66%)
每客机80 KB/s28 KB/s

关键纪律:白名单而不是黑名单;砍完必须端到端实跑对账(数量、得分、抽样字段精度)—— 砍漏一个字段的表现是”房主看得见客机看不见”,极难查。

用「同一状态下的 A/B」代替前后两次测量

第一次测瘦身效果时前后两次的敌人数不一样,得出”0% 改进”的假结论。 改成在同一帧上同时跑新旧两种打包,才拿到可信的 −64%。 性能优化的对照必须同状态,不能同场景。

反馈里的”偶尔”往往不是随机

“偶尔自动切枪,没能复现”——查下来是解锁新武器时无条件 p.weapon = i, 每局只在跨过连击阈值时发生几次,所以像随机。 用户说”偶尔/没能复现”时,先找”低频但确定”的触发条件,别先假设是竞态。


尚未验证(上线了,但没有证据)

  • 真实玩家的连接成功率与延迟(实测的 127ms 是本机绕代理经新加坡到香港,不代表国内直连)
  • 局域网 P2P 传输层(代码保留、无界面入口、仍无真机结论)
  • 4 人同时在线(只测到 3 人)
  • 货币数值的有趣性(只验了稀缺性:十波下来”买完剩下”始终贴着 0)

关联文档

类型/协作工具链主题/游戏开发主题/复盘