奥维实验icon
奥维实验
耳内有灰
WASM 下完整链路玩家打开分享链接 (WASM)  → background_match 秒连 → ServerReady  → Server 实例启动  → serverCloud:Get(0, "wall_bricks_all")   ← 1 次读,全量加载  → SYNC_ALL → 客户端合并 → 壁上看到所有人的留言 ✅玩家点"发送"  → RemoteEvent → Server 入队  → FlushWriteQueue: Get → 合并 → Set   ← 写完即持久化  → broadcastBrickUpdate → 客户端立即看到 ✅玩家刷新页面 / 重新进入  → 新 Server 实例启动  → serverCloud:Get(0, "wall_bricks_all")   ← 读到上次写入的数据  → SYNC_ALL → 留言还在 ✅每个环节都是确定性的:预加载:1 次 Get,不依赖注册表,不会遗漏写入:RMW 写完 serverCloud:Set 返回即入云,不存在"队列没 flush"的窗口重进:新实例同一个 key 直接读,数据完整对比当前方案为什么 WASM 下会丢当前方案的断裂点:  serverCloud.list:Add("brick_31", data)  ← 数据入云了  registerBrickId(31)                      ← 异步,可能没写完  玩家刷新页面                              ← 服务器销毁  新服务器 → 读注册表 → 没有 31 → 不去加载 → 留言"消失"单 key 整包方案没有这个断裂点,因为数据和索引是同一个东西。旧代码处理serverCloud.list + 注册表的代码注释保留,不删。后面如果需要按交互类型做审计日志(谁在什么时间点了什么赞),list 的逐条记录模式更合适,可以从冷宫捞回来做"热数据整包 + 冷数据 list 归档"的双写。确认方向没问题的话,我就开始改 Server.lua。
耳内有灰
修改总结:main.lua 中 EnterGame() 的加载策略改为:优先从静态文件加载 — MapData.Load("data/default_map.json"),这个文件会随构建打包,所有用户(包括分享链接)都能读到静态文件不存在时回退 clientCloud — 保留原有的云端加载逻辑,方便本地开发调试clientCloud 也不可用时 — 显示友好提示"地图未就绪"保存逻辑也做了防护 — saveMapToCloud() 会检查 clientCloud 是否存在,不存在时跳过云端保存,避免报错。关键点:我之前的修改只在**“玩家入口”**(EnterGame())中添加了静态文件加载,编辑器仍然从 clientCloud 读取——所以分享链接上的编辑器看到的是不同用户的 clientCloud 数据。请你在分享链接上点击**“玩家入口”**按钮测试——那里才是从静态文件 default_map.json 加载地图的路径。不过,编辑器也应该在启动时自动加载静态地图作为默认内容。让我加上这个逻辑。问题原因是 MapData.Load() 使用 fileSystem:FileExists() 检查文件存在性——这个 API 检查的是原始文件系统路径,在 WASM 中无法找到已打包的资源文件。改用 cache:GetFile() 后,会从引擎的资源缓存中搜索,可以正确找到构建打包的文件。
耳内有灰
数据流编辑器创建角色 → CharStorage.Save() → characters/{id}.json (sandbox)                                            ↓游戏角色选择 ← CharStorage.ListAll() ← 扫描 characters/ 目录                                            ↓            ← CharStorage.Load(id)  ← 读取同一个 JSON 文件            ← cache:GetFile()       ← 回退到 assets (内置角色)编辑器和游戏现在共享同一个文件、同一个格式,断裂消除了。
耳内有灰
导入成功了!角色在画布上显示正确。关于走动动画,最快的测试方法不需要新功能——你已经有两张正面图(A 和 B 姿态),它们交替就是走路动画:现有素材直接用:帧 素材 说明行走 帧1 dad_front_idle.json (A) 姿态A行走 帧2 dad_front_idle_b.json (B) 姿态B操作步骤:底部切到 “行走” 状态确认 帧 1/2,点"导入" → 选"爸爸-正面站立A"切到 帧 2/2,点"导入" → 选"爸爸-正面站立B"点 “播放” 预览两帧 A/B 姿态交替就是最基础的像素走路动画。后续如果要批量自动化(比如一键导入 3 朝向 × 2 状态 × 2 帧 = 12 张),那时再加一个"批量导入"按钮,根据文件命名规则自动匹配到对应的 方向/状态/帧。但现在手动导入 2 帧就够验证效果了。
耳内有灰
这次的核心改动:新策略:每帧只创建一个纹理 handle之前 PreloadAll 在一帧内对 15 个纹理全部调用 nvgCreateImage,导致所有 handle 瞬间创建完毕,loading 界面 1-2 帧就跳过。新增的 PreloadStep() 函数:每次调用最多创建 一个 新的 nvgCreateImage handle已有 handle 的纹理只做轻量的尺寸复查(几乎零开销)15 个纹理 → 至少需要 15 帧才能全部创建完毕在 60fps 下约 0.25 秒,进度条会从 1/15 → 2/15 → … → 15/15 逐步更新请再次测试,这次应该能看到进度条从 0 逐步填满到 15/15。
耳内有灰
问题原因:拆除屋檐/柱子时调用的是旧版全局方法 mapData:UninstallRoof(),它只检查已弃用的 self.roofInstalled 全局字段。而实际屋檐数据存储在 wallParts[wk].roofInstalled 中。修复:从 piece.data.wallKey 解析出 anchorRow, anchorCol,改为调用 mapData:UninstallWallParts(row, col),这个方法会正确清除对应墙段的 pillarsInstalled 和 roofInstalled。