Skip to content

Latest commit

 

History

History
363 lines (281 loc) · 14.7 KB

File metadata and controls

363 lines (281 loc) · 14.7 KB

路线图

何时阅读:决定下一步做什么;估排期;评估某 Phase 是否完成 关联文档../README.md · architecture.md · 各 modules/* · 各 features/*


总览

Phase 0 ─▶ Phase 1 ─▶ Phase 2 ─▶ Phase 3 ─▶ Phase 4 ─▶ Phase 5 ─▶ Phase 6 ─▶ Phase 7 ─▶ Phase 8 ─▶ Phase 9 (stretch)
脚手架      渲染骨架     体素单人     物理交互     P2P 通道     权威同步     多人 UI      渲染优化     多 Pass+存档   后处理/TURN/触屏
  ✅          ✅          ✅          ✅          ✅          ✅          ✅          ✅          ✅

每个 Phase 可独立验收:完成时可以演示一个具体的、可观察的功能。后续 Phase 只增不破。


Phase 0 · 脚手架 ✅

目标

创建项目骨架,让一个空 canvas + Hello World UI 在浏览器跑起来。

涉及文档

任务清单

  • 创建 Cargo.toml workspace + 五个 crate 的空骨架
  • start.html + trunk.toml 跑通 trunk serve(landing 页 index.htmldata-trunk rel="copy-file" 同步复制)
  • client::start 创建一个空 wgpu Surface 并清屏纯色
  • 集成 egui,绘制"Hello VoxWeb"在屏幕中央
  • 设置 console_error_panic_hook + tracing-wasm
  • CI:cargo check --target wasm32-unknown-unknown + cargo fmt --check
  • signaling/ TS 项目初始化(空 worker,仅返回 200)
  • 浏览器能力前置检测(wasm 加载之前):在 index.html / start.html 内联检测脚本(< 2 KB gz),检查 WebAssembly / WebGPU / OPFS / WebRTC / WebSocket / 指针锁;缺失项展示降级页面并阻止 wasm 加载;仅 WebRTC 缺失时提供"仅单机模式"入口(window.__VOXWEB_FORCE_LOCAL_ONLY = true)。详见 reference.md §浏览器能力前置检测features/persistence.md §十五。回填日期:2026-05-12(见 PHASE_0_DONE.md §回填)

验证

  • trunk serve → 浏览器打开 http://localhost:8080 → 看到纯色背景 + 居中文字
  • 控制台无错误
  • WASM gz 体积 < 1.5 MB
  • 不支持浏览器(如 Firefox stable 缺 WebGPU)访问时看到友好提示,且 .wasm 不被下载(Network 面板可验证)
  • ?force=1 query 可跳过检测进入游戏(开发模式用)

可能踩的坑

  • wgpu Surface 在 canvas 未挂载到 DOM 时初始化会失败 → 等 RAF 第一次回调再创建
  • egui 中文字体未注入 → 临时只显示英文

Phase 1 · 渲染骨架 ✅

目标

让一个 chunk(手工填充的几个方块)出现在屏幕上,相机能用 WASD + 鼠标控制视角。

涉及文档

任务清单

  • core::block + core::chunk 完整定义
  • render::vertex 实现 u32 压缩顶点(先实现编码 + WGSL 解码)
  • render::passes::opaque 单 Pass:纯色 + 顶点 packed
  • client::camera 第一人称相机(Fly 模式)
  • client::input 键盘 + 鼠标 movement
  • 指针锁集成(点击 canvas 进入;ESC 退出)
  • 手工填充一个 16×16×4 的方块阵列,渲染显示
  • HUD:FPS + 坐标显示

验证

  • 在浏览器内可以用 WASD + 鼠标自由飞行
  • 看到一片彩色方块(不同 BlockID 不同颜色)
  • 60 fps 稳定
  • 退出/进入指针锁正常

Phase 2 · 体素单人 ✅

完成日期:2026-05-12 · 详见 ../PHASE_2_DONE.md

目标

单机模式可玩:地形生成、动态加载、跨区块剔除。

涉及文档

任务清单

  • server::terrain Perlin 高度图地形生成
  • server::world Chunk 表 + tick
  • server::Server::handle_client_message 基础 dispatch(无网络,仅本地 enum 转换)
  • client::NetEndpoint::Local 实现内存通道
  • render::chunk_mesh 朴素逐面网格化(先不上贪婪算法)
  • 跨区块面剔除(generate_with_neighbors + 世界坐标回调)
  • client::mesh_jobs 优先级队列 + 分帧 budget
  • 渲染距离动态加载/卸载(玩家走远了 chunk 释放)
  • 大厅 UI:单机模式按钮 → 进入游戏

验证

  • 大厅点"单机模式"→ 进入游戏 → 看到连绵地形(草/泥/石分层)
  • 飞过去能持续看到新地形加载
  • 走远后回头,原地形仍在
  • 渲染距离调到 6 时仍 60 fps(中等设备)
  • 区块边界处无明显漏面或多余面

Phase 3 · 物理与交互 ✅

完成日期:2026-05-12 · 详见 ../PHASE_3_DONE.md

目标

玩家有物理身体,能跳、能挖、能放。

涉及文档

任务清单

  • client::physics AABB + 重力 + 跳跃 + 分轴碰撞
  • Walk / Fly 模式切换(双击空格)
  • client::raycast DDA 算法
  • HUD 选中方块线框
  • 鼠标左键挖(本地直接修改 + send Break)
  • 鼠标右键放(计算邻居位置 + send Place)
  • server::physics::validate_break/place 仲裁
  • BlockUpdate 闭环:本地 server 处理 → 客户端收到 → 重网格化
  • 1-9 键 hotbar(hotbar UI HUD 简化版)
  • ActionAck rollback 路径(即使本地一定通过,也要走完逻辑)

验证

  • 单机模式下走路、跳跃、攀爬上小山坡
  • 不会穿墙或卡住
  • 左键能挖任何方块
  • 右键能放(不在身体里)
  • 1-9 切换不同方块
  • 挖完一个方块下层方块面立即正确显示

Phase 4 · P2P 通道 ✅

完成日期:2026-05-13 · 详见 ../PHASE_4_DONE.md

目标

让两个浏览器 Tab 之间能传字节。先不接入服务端逻辑,只验证 WebRTC + 信令 + DataChannel 工作正常。

涉及文档

任务清单

  • signaling/ Cloudflare Workers + Durable Object 完整实现
  • wrangler dev --local 本地跑通
  • net::signaling Rust 端 WebSocket 客户端 + Closure 事件回调
  • net::peer PeerConnection + DataChannel(双通道)
  • net::room 状态机
  • net::NetEndpoint::Host / ::Remote 实装
  • 大厅"创建房间" / "加入房间" UI(Phase 1 实装的简化版扩展)
  • 调试:connecting UI 显示进度
  • 简单消息 ping-pong:Remote 发 Ping{client_time_ms},Host 回 Pong,HUD 显示 RTT

验证

  • 同一台机两个 Tab:A 创建房间 abc123,B 加入 abc123
  • 双方 connecting UI 走完流程,进入 InGame(暂时只显示空地形)
  • HUD 显示 RTT < 50ms(本地)
  • chrome://webrtc-internals 中看到双通道开启
  • 关掉 wrangler dev,已建连的两 Tab 仍能互发 Ping

Phase 5 · 主机权威同步

目标

两个 Tab 看到同一个世界。Host 是权威,Remote 通过快照 + tick 同步。

涉及文档

任务清单

  • core::protocol 完整消息定义 + bincode 配置(消息枚举 + PROTOCOL_VERSION + Recipient/OutboundMessage)
  • Hello/Welcome 握手(add_player 分配 eid,Welcome 含 seed + eid)
  • ChunkSnapshot 分片传输 + 接收端组装(ChunkAssembler)
  • ChunkRequest 按需区块请求(Remote 移动后请求 Host 补齐有效视距;有效视距不超过 Host 视距)
  • PlayerInput / PlayerTick 60Hz 收发
  • client::prediction 自身位置预测协调(InputHistory + reconcile_self)
  • client::interp 远端玩家位置插值(PlayerInterp, delay=100ms)
  • BlockUpdate 广播闭环(Remote 操作 → Host 仲裁 → 全员看到)
  • Action Ack 协调
  • PeerJoined / PeerLeft 玩家进出广播
  • 简单玩家身体渲染(PlayerPass:实心 AABB cube,颜色 entity_id 派生)
  • 基础 OPFS 持久化 — 整体延后到 Phase 8

验证

  • A 创建房间 → B 加入
  • B 看到 A 站立位置(box)
  • A 走动,B 看到平滑移动(不抖)
  • B 挖一个方块,A 看到方块消失
  • A 关闭 Tab → B 收到"主机断开",回到大厅
  • A 重新进入相同 room_id + seed → 看到上次挖掉的方块仍是空气

Phase 6 · 多人 UI/HUD ✅

完成日期:2026-05-21 · 详见 ../PHASE_6_DONE.md

目标

让多人体验完整:知道谁在线、能聊天、看到玩家名字。

涉及文档

任务清单

  • HUD 玩家列表 widget
  • T 键打开聊天框
  • 聊天历史 + 系统消息(Join/Leave)
  • 平时显示最近 5 条聊天浮窗(5 秒淡出)
  • 远端玩家头顶名牌(egui Painter billboard)
  • 距离衰减(> 32m 不显示)
  • EscMenu 完整设置:FOV / 灵敏度 / 渲染距离 / 插值延迟 / 显示统计
  • 设置存到 localStorage
  • Disconnected 页面 + "返回大厅"按钮

验证

  • 4 人同房间,HUD 右上角列表显示 4 行
  • 玩家头顶看到名字,距离够远会自动消失
  • T 打字、Enter 发送、其他玩家收到
  • 系统消息 "Bob 加入了房间" 准确出现
  • ESC 菜单调整 FOV,画面立即响应

Phase 7 · 渲染优化 ✅

完成日期:2026-05-31 · 详见 ../PHASE_7_DONE.md

目标

让渲染距离能开到 8-10 仍然 60 fps。

涉及文档

任务清单

  • 贪婪网格化算法(替换 Phase 2 的朴素逐面)
  • 顶点压缩(Phase 1 已写位段编码,此处确认全链路用上)
  • AO 计算(顶点级 4 等级)
  • mesh_jobs 优先级队列优化(玩家附近 critical / high 优先)
  • 视锥剔除(每帧根据 camera frustum 过滤 chunk)
  • 网格化分帧 budget tuning(默认 4ms/帧)
  • 性能 stat HUD(每个 Pass 耗时)

验证

  • 渲染距离 8、复杂地形、4 人房间、稳定 60 fps(M2 mac)
  • 贪婪合并后顶点数比 Phase 2 减少 80%+(HUD stat 显示)
  • 远处看不到 chunk 边界缝隙
  • AO 在角落产生柔和阴影

Phase 8 · 多 Pass + 存档完善 ✅

完成日期:2026-06-01 · 详见 ../PHASE_8_DONE.md

目标

渲染管线优雅化(多 Pass);存档体验完整。

涉及文档

任务清单

  • render::graph::RenderGraph + RenderPass trait
  • Depth Pre-Pass(可关)
  • Skybox Pass(程序化天空 + 太阳方向)
  • Transparent Pass(水/玻璃 alpha blend)
  • UI Pass 重构为 trait 实现
  • 透明方块网格独立 buffer + 距离排序
  • 存档完善
    • crates/server/src/world.rs 引入 LRU + pinned 集合(capacity 4096,runtime 可调)
    • 暂停菜单"立即保存"按钮 + 配额 UI(使用量、> 80% 警告、> 95% 暂停 dirty)
    • navigator.storage.persist() 启动时申请
    • 协议 migration 框架(storage_version + migrations[] 数组,本期含 identity)
    • 加载失败错误处理 + 删档功能(不再因版本不匹配强制删档)
  • (可选)Variant B Worker + sync handle 升级:若 Phase 8 Variant A 上线后出现可观察的"关 Tab 丢数据"投诉,新增 crates/client/src/storage_worker.rsFileSystemSyncAccessHandle;详见 features/persistence.md §十二

验证

  • 看到清晰的天空(地平线渐变 + 太阳)
  • 水透明,能看到下面的方块
  • Depth Pre-Pass 开/关切换不影响画面,但 stat 显示帧时变化
  • 存档使用量准确显示
  • 手动注入 10000 dirty chunk(控制台 voxwebDebug.fillDirty(10000))→ OPFS 占用 < 200 MB;启动重连 < 3s;运行内存 < 500 MB
  • 强制删档后重进世界为初始地形
  • 修改 world.json.storage_version 为 999 → 大厅显示"需升级 VoxWeb" 而非删档

Phase 9 · Stretch(不在硬性目标内)

可选增强项,按时间和需求选做:

9.1 后处理 Pass

  • 雾(distance fog,远处淡出)
  • 色调映射(HDR → LDR)
  • Bloom(v3)

9.2 TURN 中继 fallback

应用层字节中继 ✅(2026-05-21 实装,详见 networking/signaling.md §九)

  • ICE 失败 / 15s 协商超时 → Host 主动发 relay_request
  • 信令 Worker DO 维护 relayPairs,在 WS 上做二进制帧字节级转发
  • 客户端 HUD 显示「RELAY n」徽标
  • Per-peer 粒度:仅升级失败的对,其它直连不受影响

剩余项(仍为 stretch)

  • 信令服务下发 TURN 凭据(让 WebRTC 走 TURN,保留 unreliable 语义)
  • TURN/字节中继并存策略:先试 TURN,TURN 也失败再退到字节中继

9.3 触屏 / 移动端

  • 屏幕左右虚拟摇杆(左:移动,右:视角)
  • 简化 UI(按钮放大)
  • 跳跃/挖/放按钮

9.4 声音

  • 走路 / 挖方块音效(web-sys::AudioContext
  • BGM(可选)
  • 远端玩家位置感

9.5 其它

  • 可迁移主机(Host 退出时投票选新 Host + 同步状态)
  • 地形群系(沙漠/雪地/海洋)
  • 简易光照(顶级方块发光的 light propagation)
  • 录制 / 回放(世界历史命令日志)

进度追踪建议

每个 Phase 完成后:

  1. 在仓库根创建 PHASE_N_DONE.md,列出实际完成项 + 已知问题
  2. 更新本文档对应 Phase 标题加
  3. ../README.md 决策表新增"当前 Phase"行
  4. (可选)git tag phase-N

不在路线图中

  • Phase 100:完美主义级别的视觉效果(PBR 材质、屏幕空间反射、体积光)
  • Phase X:Mod 系统
  • Phase X:移动端原生 App(用 Tauri/Capacitor 包装)
  • Phase X:Steam / 应用商店发布
  • Phase X:服务端中央化(违背 P2P 设计)