OCC: Planet Civilization · 未完成清单
盘点时间:2026-10-15 21:40(上一版停在 2026-10-14 17:10,之后一天内清掉了大半) 对照:玩法方案-Planet Civilization-v1(M1~M5)、背包与物品系统方案-v1(B1~B5) 已实装的行为与数值以 玩法系统现状 为准;本篇只列"方案要求了、但代码里还没有"的部分。 所有结论都在 2026-10-15 当晚对着工作区代码复核过(含 grep 验证),不是转述旧记录。
0. 一句话结论
M1~M4 与 B1~B3、B5 已经跑通,"打 → 拿 → 造 → 更强"的循环闭上了。 M5 的教程引导已在 2026-10-15 落地(16 步、Server-authoritative推进,见 玩法系统现状.md), 剩下的缺口集中在三处:M5 的其余部分(经济平衡 / 移动端)、 六处功能"做了但没接完"(玩家在界面上摸不到)、以及一处方案明确要求但没做的(战场死亡回家园)。
一、这一轮闭环掉的(相对上一版清单)
上一版列出的大块缺口,2026-10-15 已全部落地:
| 上一版的状态 | 现在 |
|---|---|
| M4 科技树"未开始",是最大的一块 | ✅ 已完成且超出:35 节点(生产线 9 + 战场线 26),含 4 条五级改造线;研究所 UI(U 键)+ 随身制造(J 键)科技门槛 |
| 精英 / Boss 只给积分不掉 tech 物品 | ✅ 精英掉结晶 1~3 + 废铁 2~4;Boss 掉合金 3~5 + 结晶 5(掉在倒地处,多人可捡) |
掉落物客户端不渲染、lootPick 从没发过 | ✅ 已修:loot.js 重写为三段动画(落地 → 悬浮 → 飞进机甲),Server-authoritative拾取 |
| 物流站槽位 UI 是 0 处引用 | ❌ 仍未接(见第三节 #1)—— 这是唯一的例外 |
| 背包 ↔ 仓库只单向 | ✅ 已双向(「全部存入 / 全部取出」都在) |
| 建造网格辅助线没生成 | ❌ 仍未生成(见第三节 #4) |
| 拆除返还 0 | ✅ 2026-10-16 起改为 100% 放回背包(建筑本体 + 库存里的东西);客户端面板右上角有入口、带二次确认 |
| 矿脉采完不重生 | ✅ 已有内存 TTL(战场 10 分钟 / 家园 20 分钟);⚠️ 重启即清 |
| 积分商城 vs 科技树边界 | ✅ 问题消失:积分系统整体下线(/api/shop/buy 返 404) |
| 星门是 Y 键全局可切 | ✅ 已改为点星门建筑 → 开银河星图;Y 键作为快捷方式保留 |
| 教程引导"❌ 完全没做" | ✅ 已做:16 步新手引导(基础操作 → 循环发展 → 自身强化),进度Server-authoritative、登录即对齐老玩家 |
| 建筑 GLB "单栋 8~11MB 未瘦身" | ✅ 已做(2026-10-16):tools/slim_assets.mjs 贴图 WebP + 顶点量化 + meshopt,29 个模型 243MB → 42MB(↓82.6%);发布包 314MB → 约 108MB |
| 焦土"名字叫焦土、长得像绿星球" | ✅ 已重做(2026-10-16):新增 public/src/theme.js per-world 主题 —— 灰烬焦土色带 + 碳化枯树/焦桩/灰堆 + 暗红烟尘天空 + 暖褐雾光 + 小地图同色;苗圃一字未改。详见「玩法系统现状」§1.v |
| 引导面板"位置不顺眼" | ✅ 已调(2026-10-16):从左下角挪到雷达卡片正下方(#left-col flex 列) |
| 中级材料(钢板等)没有产出的地方 | ✅ 已解三重死锁:钢板 / 电路板 / 机械部件 / 塑料 / 武器 Mk1 挂进指挥中心(随身制造同时可用) |
| 苗圃星"私有"只做了一半(能看到别人) | ✅ 已修:可见性三通道(broadcast / broadcastState / relayState)都按 sameWorld 判定;掉落物带世界归属 |
| 苗圃星"私有"的伤害没隔离(在苗圃被焦土的 Boss / 精英坦克打) | ✅ 已修(2026-10-16):npcTimer 的玩家名单 dirs 只收 NPC_WORLD;hit 过 sameWorld();npcHit / bossHit 校验世界。回归 tools/e2e/boss_crossworld.mjs(带对照组) |
| 掉落物只有一个方块、看不出是什么 | ✅ 已做:32 个程序化小模型(材料 / 中间品 / 弹药 / 装备 / 战利品 / 建筑箱),仍是一物一 draw call |
| 采集"采完不消失"(植被) | ✅ 已修:树/石头走可破坏物那套(1~5 血)、灌木本地 3 次;服务端补 code:'floraDepleted' |
| 纸飞机"怎么瞄都打不中" | ✅ 已修:瞄准目标优先 + 贴地基线用 player.R + 贴地弧线;命中半径按体积(Boss +8) |
二、方案里有、但仍然没做的
| 项 | 方案位置 | 现状 |
|---|---|---|
| 战场被击毁 → 回家园重生 | 玩法 §1.3(明确说要改动现有逻辑) | ❌ 仍是战场随机点重生 |
| 3 个固定着陆点 | 玩法 §1.3 | ❌ 没有,落地位置仍是随机(按落点续用规则续用坐标另算) |
profile.location | 玩法 §6.2 存档结构 | ❌ 没存"在哪个世界 / 坐标",靠 URL 参数与 lastWorld/lastPos 顶替 |
| 建筑上限 400 的"快满了"提示 | 玩法 §6.2 | ⚠️ 服务端有硬校验并拒建,前端没有预警提示 |
| 经济平衡(产出 / 消耗速率实测调参) | M5 | ❌ 没做(当前数值是设计值,未经实测校准) |
| 移动端适配 | M5 | ❌ 没做 |
| 老存档迁移的完整验证 | M5 | ⚠️ 部分:ensureWorlds 会自愈幽灵建筑、自动补 root 科技;但没有系统性迁移测试 |
三、做了但"没接完"的(最容易误判成"已经做好了")
这些的共同特征:服务端通了、协议也有、但玩家在界面上摸不到。
| # | 缺口 | 证据 | 影响 |
|---|---|---|---|
| 1 | 物流站槽位 UI | ioSet 在 public/src/ 里 0 处引用(只有服务端有分支) | 🔴 玩家设不了供需 ⇒ 物流永远跑不起来。e2e(sim.cjs)是直接改存档才跑通的 |
| 2 | 特种弹药不消耗 | paper-planes.js 攻击时不查也不扣背包弹药;ammoPref 只有"装填"的显示 | 装备了爆破弹也打不出爆炸;"制造弹药"这条线没有意义 |
| 3 | place() 仍不校验矿脉(故意的):2026-10-16 起采矿机改成“玩家设定矿种 + 在占地外扩 3 格内找矿”,面板会明说“周围 7×7 格内没有这种矿 —— 停产”,不再有“放了却不产、玩家不知道为什么”的困惑 | 乱放只是白耗电,且界面上写得清清楚楚 | |
| 4 | 建造网格辅助线没生成 | public/src/build.js 里有 gridHelper 对象并会 visible = true,但从没往里加过线 | 玩家看不到吸附格子(方案 §3.1 要求可见) |
| 5 | 建筑基座没做 | 只有幽灵预览的"底座投影圈"(绿/红),没有方案要求的"程序化基座自动贴合地形" | 坡地上的建筑会悬空 / 陷进去 |
| 6 | 背包扩容是免费的 | store.js 的 bagExpand 直接 expand(),自注"消耗「背包扩容模块」的方式见 B3,这里先直接提供接口" | 方案要求的"容量走生产循环"没接上,容量成了一个免费按钮 |
| 7 | 石料厂配方空 | RECIPES 里没有石料厂产出;"建材块"这个物品根本不存在(只在物品描述里被提到) | 石料厂建了不干活 |
| 8 | 无人机组装厂配方空 | 同上;且没有无人机损耗机制 | 缺"无人机被打掉 → 造新的补上"这条线 |
| 9 | 服务端不校验水 / 雪线 | place() 的拒绝理由里没有水 / 雪线(客户端 solve() 会挡) | 改过的客户端可以绕过;正常玩家无感 |
四、实现时有意留的简化(保留的取舍)
这些是当时主动选择不做的,不是遗漏;列出来是为了别被当成 bug。
| 项 | 方案原意 | 实际实现 | 为什么 |
|---|---|---|---|
| 客户端世界切换 | 抽 createWorldRuntime / disposeWorld 做热切换 | 整页重载 + 星门过渡层 | main.js 单例装配太重,全量重构风险高;而且两颗星球不能同时驻留显存(光植被 10.2 万实例)。方案自己也接受"切换几秒可接受" |
| 装备槽 | v1 只开 weapon + tool | ✅ 按方案做的 | armor / engine 结构留着但报"尚未开放" |
| 矿脉再生 | 采完进入再生倒计时 | 内存 TTL,不落盘 | 重启即重置。对原型够用;要持久化得进存档 |
| 无人机损耗 | 造无人机补损耗 | 没做损耗机制 | 缺"无人机被打掉"这条线,所以组装厂也就空着 |
| VIP / 付费 | —— | 不存在 | 积分商城下线后,项目没有任何付费点 |
五、测试基建的问题
问题仍在:多个 e2e 共用同一个 _data/state.json,且其中至少 8 个脚本会 stop / start 服务 (bag.cjs、bag_ui.cjs、build.cjs、labui.cjs、m3ui.cjs、posrule.cjs、sim.cjs、tech.cjs), 所以必须顺序跑;连跑时偶发互相打断。
好消息是根因的工具已经就位:服务端已支持 OCC_DATA 环境变量覆盖存档路径 (server/server.js 的 createStore(process.env.OCC_DATA ?? ...)), 但目前没有任何测试脚本用它(tools/e2e/*.cjs 里 0 处引用)。
⇒ 待办很小:给需要独立存档的脚本指定各自的 OCC_DATA,或统一加一条"先探测服务存活"的串行约定。
六、如果只能做一件事
做「物流站槽位 UI」(第三节 #1)。
理由:现在建造 → 生产 → 物流这条线,前两段是通的,第三段是断的 —— 玩家能建物流站,但没有任何界面能给它设供需,于是无人机永远不会起飞。 sim.cjs 之所以通过,是因为它绕开 UI 直接改了存档。
而且这一项成本极低:协议(ioSet)、服务端校验、无人机表现(logistics.js)、 三栏建筑面板(build.js)全都已就位,缺的只是"在建筑面板里加一列槽位编辑控件"。
紧随其后的两项(同样低成本、高可见度):
- 建造网格辅助线(第三节 #4)—— 方案要求可见,
gridHelper是空的,补线即可。 - 特种弹药消耗(第三节 #2)—— 让"制造弹药"这条线有意义。
五、被击毁物件的记录已按星球分开(2026-10-16 修)
已修(2026-10-16):记账 key 从裸 seed 改成 <worldId>:<seed>(server.js 的 worldKeyOf), /api/world/destroyed?world= 与 POST /api/world/destroy {world} 都带世界, broadcast({t:'destroy'}) / {t:'respawn'} 也带上世界(原来靠默认值只发战场,苗圃的人收不到重生通知)。
⚠️ 连带修掉一处改 key 时最容易漏的:respawnTimer 原来写的是 store.getDestroyed(WORLD_CONFIG.seed, …)(裸 seed)—— 改完 key 之后那本账永远不存在, 于是"到期的记录再也没人清、物件永远不重生"。现在由 store.sweepDestroyed() 遍历所有世界账本。 (教训:改 key 形状时,别只改写入点,把所有读同一份数据的定时器一起搜一遍。)
老存档里 data.worlds 的裸 seed 条目会变成孤儿 —— 无害:物件本来有 TTL,最多"重生一次"。 不做迁移是故意的:迁移代码只为少一次重生,不值那份复杂度。
回归:tools/e2e/destroy_scope.cjs(9/9)—— 在焦土打碎 3 个物件后, 苗圃的账本里看不到它们,反之亦然;并断言客户端启动请求确实带了 world=。
/api/world/destroyed 与 /api/world/destroy 记账的 key 只有 seed (store.markDestroyed(seed, ids) → data.worlds[String(seed)]), 而两颗星球的 seed 是同一个(WORLD_CONFIG.seed = 20261012, "同 seed 私有分片"是刻意的设计,见 world.js 的注释)。
⇒ 在焦土打碎一棵树,那批 id 在苗圃也被当成"已打掉" ⇒ 苗圃里会凭空少几棵树 / 石头(330 秒后自己回来)。 反方向同样成立(在苗圃砍树会让焦土少东西)。
与刚修的伤害隔离是同一个病因("两颗星球完全分离"只做了一半), 但这次没一起改,原因有两个:
- 它要动存档结构(key 从
seed变成seed + world)与客户端协议(fetchDestroyed/reportDestroy要带 world),
而且现有存档里的 worlds 条目会变成孤儿(无害,物件 330 秒 TTL 后会自然重生);
world.js那句"同一套地形可以分享布局"读起来像是有意共享的
—— 到底是"特性"还是"漏了",需要老大拍一下再动。
如果确认要修:markDestroyed / getDestroyed 的 key 改成 ${seed}:${worldId}, /api/world/destroyed?seed=&world= 与 POST /api/world/destroy 的 body 各加一个 world, broadcast({t:'destroy'}) 也要带上世界(现在靠默认值只发战场)。
相关文档
- 现状与数值:玩法系统现状
- 方案原文:玩法方案-Planet Civilization-v1、背包与物品系统方案-v1
- 架构与禁区:系统架构