# 微信小游戏导出、导入与首包 CDN ## 开发者工具入口 导出菜单为 `AIGame/WeChat/Export Base Package`,输出到 `AIClient/Build/WeChat/Base/`。 - `minigame/` 是开发者工具项目,包含 `game.js`、`game.json`。 - `webgl/` 是网站资源目录。打开它或父目录时若没有正确配置源码路径,会出现找不到 `game.json`。 - 导出后现在同时生成父目录 `project.config.json`,指定 `miniprogramRoot: "minigame/"`;因此可以打开 Base 或 minigame。 - 父目录入口沿用 SDK 编译配置及符号文件排除规则,保留已有 AppID;不改私有配置。 - `AIGame/WeChat/Open Exported MiniGame Folder` 定位正确的项目目录;旧包可以执行 `Repair Exported DevTools Project`。 ## 启动资源下载 404 当前首包 CDN 为 `https://www.xworld.ren/game/Friends/webgl/`,与生产热更新目录位于同一个网站目录。 导出菜单会通过 Unity API 写入 MiniGameConfig 的 CDN,并由 SDK 写入 `minigame/game.js` 的 `DATA_CDN`。 修改现有包配置可用 `AIGame/WeChat/Refresh Exported Config (No Build)`,无需重新编译 Player。 **导出只生成本地文件,不会自动上传网站;重新生成底包不等于必须重新上传全部资源。** 首次部署或缺少文件时,将 `AIClient/Build/WeChat/Base/webgl/` 中需要的资源上传到网站 `/game/Friends/webgl/`,保持相对路径,不要额外嵌套一层 webgl。 | 本地相对 webgl 的路径 | 对外 URL 路径 | | --- | --- | | `.webgl.data.unityweb.bin.txt` | `/game/Friends/webgl/.webgl.data.unityweb.bin.txt` | | `StreamingAssets/cdn/version.json` | `/game/Friends/webgl/StreamingAssets/cdn/version.json` | | `StreamingAssets/yoo/...` | `/game/Friends/webgl/StreamingAssets/yoo/...` | `base-package-report.txt` 会列出本次实际首包文件和完整下载地址。 2026-10-22 的包为 `1ddb5fcad4415dd3.webgl.data.unityweb.bin.txt`,10,084,442 字节;排查时对应生产 URL 返回 404,而现有 `/game/Friends/webgl/cdn/version.json` 返回 200。 SDK 根据 Unity data 文件内容计算哈希,并写入文件名和 `game.js` 的 `DATA_FILE_MD5`。重新构建后,如果哈希未变且现有 CDN 的完整 URL 可访问,直接复用,无需重复上传;哈希变化时才需要补充对应的新文件。未变的 YooAsset 业务资源包同样无需重复上传。场景或壳内资源/构建设置变化可能影响 Unity data,不能仅凭业务资源未修改就判断其哈希一定不变。 排查 404 时,先核对 `DATA_CDN` 与既有文件部署位置,再核对 `DATA_FILE_MD5` 对应的文件是否存在。404 本身不能证明资源内容发生了变化。修正路径或补齐缺失文件后,确认完整 URL 返回 200,再清理开发者工具缓存并编译。 Unity 首包的 `DATA_CDN` 与游戏进入 Boot 后使用的 YooAsset `version.json`/Art/DefaultPackage 是两阶段下载。当前 YooAsset 生产清单地址仍为 `/game/Friends/webgl/cdn/version.json`,资源根为 `/game/Friends/webgl/yoo/DefaultPackage`。 ## 验证 `AIClient/AgentScripts/VerifyWeChatExport.cs` 通过 Unity Pipeline 刷新并验证现有包配置,检查父目录入口、AppID、SDK 排除规则、私有配置与 webgl 资源保留、重复刷新幂等性。 回执及修改前备份在 `Tools/output/wechat_export/`。本次本地验证通过,服务器首包文件尚需发布。 ## YooAsset 默认构造函数被裁剪 2026-10-22 小游戏启动出现 `MissingMethodException: Default constructor not found for type YooAsset.WebNetworkFileSystem`。 YooAsset 3.0.6 的 `FileSystemParameters.CreateFileSystem` 使用 `Type.GetType` 和 `Activator.CreateInstance` 创建实例。 实际检查完整与 WebGL ManagedStripped 程序集,确认 WebNetwork/Builtin/Sandbox 三种文件系统在完整程序集中有默认构造函数,裁剪后类型仍存在、默认构造函数已移除。 `AIClient/Assets/AOT/link.xml` 仅保留项目使用的这三个文件系统的无参构造函数,不全量保留 YooAsset,也不降低全局裁剪级别。 该文件独立于 `Assets/HybridCLRGenerate/link.xml`,后续 HybridCLR Gen All 不会覆盖它。Unity 保留规则见[官方托管代码裁剪说明](https://docs.unity3d.com/cn/2022.3/Manual/ManagedCodeStripping.html)。 `AIClient/AgentScripts/VerifyYooAssetStripping.cs`:`Before` 记录裁剪前后构造函数;`BuildAndVerify` 执行正式 Export Base Package,检查新裁剪 DLL 中的构造函数及方法体、新生成的原生构造函数,并对比业务 bundle 与启动 data 的内容哈希。 回执目录为 `Tools/output/yooasset_stripping/`。底包构造函数修复需要新的 wasm 代码生效;未改动的业务资源包继续复用。 本次 20:06 正式导出与产物检查通过:三种文件系统无参构造函数及方法体均已保留,IL2CPP 已生成 WebNetworkFileSystem 构造函数;业务 bundle 内容哈希全部未变。启动 data 实测由 10,084,442 字节变为 10,084,535 字节,文件名变为 `c58ae17711192f12.webgl.data.unityweb.bin.txt`;需要将这个新增启动文件同步到现有 `/game/Friends/webgl/`,无需重传未变业务 bundle。未自动发布服务器,微信开发者工具运行尚待复测。 ## 主界面移动端修复产物(2026-10-22 20:49) 启动不再自动加载 测试场景/CaoCao。主界面角色预览材质通过 Prefab 依赖进入 Art,顶部和底部布局使用设备/微信安全区,详见 `UI_AutoGen_Overview.md`。 三个屏幕布局与按钮命中、GPU 抠底、实际启动器无 3D 预加载检查通过;8 组微信窗口/胶囊/旧接口/DPR 用例通过。原 Boot 场景已恢复。 新底包已导出到 `AIClient/Build/WeChat/Base/minigame/`,构建成功并确认原生/JS 安全区桥接均包含。新首包为 `e33b1380f2e627d5.webgl.data.unityweb.bin.txt`(14,785,194 字节)。本次业务 UI 和热更代码有实际修改,需部署对应 Art/DefaultPackage 更新;相对上一构建仅 3 个 Art bundle、1 个热更 rawfile 及相应清单变化。 `Tools/output/home_mobile/deployment.json` 列出需发布文件、本地路径与目标 URL(排除构建报告和日志),资源文件先于总版本清单发布。该适配包含新的 AOT 组件,应搭配新底包。文件目前只在本地构建/暂存,未上传 CDN,微信开发者工具/真机需重新编译复测。 ## 2026-10-22:小游戏网络与启动遮罩修复 - `WsClient` 原 WebGL 分支只有“不支持 ClientWebSocket”的占位。现在通过 `Assets/AOT/Scripts/Boot/WebSocketBridge.cs` 与 `Assets/Plugins/WebGL/GameWebSocket.jslib` 使用微信 `wx.connectSocket` / `SocketTask`;普通浏览器回退到 WebSocket。轮询收发在 Unity 主线程处理,包含连接超时、指数退避、手动重连和关闭清理。AOT 原生导入独立保留,避免热更 DLL 直接声明 P/Invoke。 - WebGL 的 `GameNet.Bind` 对本机或非 HTTPS/WSS 地址回退为 `https://game.xworld.ren` 和 `wss://game.xworld.ren/ws?pid={pid}&token={token}`,同时更新 BootContext,供业务 HTTP 使用。编辑器本机配置保留;自定义 HTTPS/WSS 远端地址保留。 - 截图中首次 `/login` 返回 401 后出现 `authed pid=...`,对应游客首次登录失败后自动注册成功,并非最终鉴权失败。ASTC 不支持后软件解压属于纹理兼容提示,与 WebSocket 占位错误不同。 - 原 Boot 固定两帧就隐藏遮罩,异步加载主界面时会暴露空白。现在等待热更通过 BootContext 通知主界面就绪;缺少 HUD 或超时保留可见错误提示,该信号不依赖登录或 WebSocket 成功。 - 验证:`node Tools/verify_game_websocket.js` 的 8 组实际 JS 桥接用例;`dotnet run --project Tools/Tests/WebSocket/WebSocket.csproj` 编译并执行实际 UNITY_WEBGL WsClient;Pipeline 的 `VerifyMiniGameNetwork.Endpoints` / `CheckUiReady` 与 `VerifyHomeMobileUi.CheckReady`。隔离场景验证完成后恢复原 Boot 场景。 - 新增 AOT / JS 桥接与上下文,必须搭配新底包和本次 DefaultPackage 热更,不能只刷新导出配置或只替换旧底包的热更 DLL。Art 未修改,无需重新构建或重复上传未变的 Art bundles。构建与发布清单见 `Tools/output/minigame_network/`;本地构建不自动上传 CDN。微信后台需配置 request 合法域名 `https://game.xworld.ren`、socket 合法域名 `wss://game.xworld.ren`。开发者工具和真机仍需运行复测。 本轮最终本地构建已成功(约 232 秒),底包目录 `AIClient/Build/WeChat/Base/minigame/`。首包数据 `06add2285b23eace.webgl.data.unityweb.bin.txt`(14,785,694 字节);DefaultPackage 清单 `0e3722bbb19457d47bac35bbd4b516a7`,热更文件 `d34a46086ecefa40084479f551820a4e.rawfile`(253,440 字节)。Art 仍为 `006c201e92439eb03ae12d84b86f8fa6`,未变。已验证 4 个平台桥接原生导入、IL2CPP 返回字符串释放、生成 framework 中的桥接、Raw DLL 内容和清单 MD5;原 Boot 场景恢复,编辑器停止且编译完成。`Tools/output/minigame_network/deployment.json` 给出逐文件来源/URL,先发布资源文件,再发布总版本清单;未上传远端,未做微信真机联调。 后续线上核对:新首包 `06add2285b23eace.webgl.data.unityweb.bin.txt` 已返回 200;但 `/cdn/version.json` 仍下发旧热更版本 `5d00808a861cf2d9d5696eaafea5b896`,新 DefaultPackage 清单返回 404,导致新壳继续运行旧 DLL。已将本次缺少的 4 个 DefaultPackage 文件和 `cdn/version.json` 按网站路径整理到 `Tools/output/minigame_network/upload_patch/`,共 254,085 字节。将目录内容上传到网站 `/game/Friends/webgl/`,先 `yoo/DefaultPackage`,最后 `cdn/version.json`;首包与 Art 无需重复上传。仅本地整理,未执行上传。 ## 2026-10-22:玩法 API 404 与预览紫色区域 线上新热更已生效,WebSocket 和主界面加载正常;`https://game.xworld.ren/game/state` 仍返回 404,且响应为 Kestrel。本仓库的完整玩法服务为 AIServer,Windows Server 上传/启动方式见 `AIServer/deploy/windows/README.md`。本地已生成并验证 `Tools/output/server_release/AIServer-Windows-x64.zip`,不含开发数据库,不自动替换旧服务;全部游戏域名路由需切到同一新后端,旧后端数据需要单独迁移。 实际 Art 材质仍保存旧抠底色 (0.07,0.02,0.09),而热更代码改为紫色清屏,导致矩形显现;现已改为读取运行时材质 `_Key`。旧/新颜色的 GPU discard 与前景保留、隔离预览截图通过。客户端修复仅更新热更代码,无需底包/Art 重打:上传 `Tools/output/server_release/Client-CDN-Patch.zip` 解压内容到 `/game/Friends/webgl/`,先 `yoo/DefaultPackage`,最后 `cdn/version.json`。新 packVersion `587e28dfd1f166d117eadd24afa8efa1`,仍搭配既有支持 WebSocket 的新底包。两个 ZIP 均未上传线上。 ## BuddyDefense 15888 部署地址(当前) 游戏服务已改为 `https://BuddyDefense.xworld.ren:15888` / `wss://BuddyDefense.xworld.ren:15888/ws?pid={pid}&token={token}`,CDN 资源路径维持既有部署。本轮 packVersion `d36750d301123c62fd6f673f324137a5`,发布文件 `Tools/output/server_release/Client-BuddyDefense-15888.zip`,仍先发布 yoo/DefaultPackage、最后发布 cdn/version.json。新常量会在编译时内联进热更 DLL,不增加运行时 AOT API 依赖;既有支持 WebSocket 的底包可直接更新热更,无需重打。 服务器包 `AIServer-BuddyDefense-15888.zip` 默认监听 `127.0.0.1:15888`。用户现有 Caddy 站点也监听 15888,需要加 `bind` 绑定服务器实际非环回网卡 IPv4,避免通配监听占用环回端口;`New-CaddySite.ps1` 在服务器运行可生成准确片段,保留 transport http 的 read_timeout/write_timeout 0。云服务器存在公网 NAT 时使用网卡私网地址绑定,域名 DNS 指向公网地址。更新已运行任务时先使用 Stop-Server.ps1,再安装新开机任务;更改 Caddy 后验证并 reload。需配置新域名的 DNS、证书及公网 TCP 15888 放行。当前本地验证正常,未部署远端。 客户端 ZIP 的网站发布辅助:将 `Publish-BuddyDefenseClient.ps1` 与 `Client-BuddyDefense-15888.zip` 放在同一目录,管理员 PowerShell 执行 `powershell.exe -ExecutionPolicy Bypass -File .\Publish-BuddyDefenseClient.ps1 -WebglRoot "网站中/game/Friends/webgl/对应的实际目录"`。也可先加 `-WhatIf` 检查。脚本校验清单 MD5,最后发布总版本;该目录属于静态资源站点,不是 AIServer 程序目录。发布后通过公网 `https://www.xworld.ren/game/Friends/webgl/cdn/version.json` 确认 packVersion 为 `d36750d301123c62fd6f673f324137a5`。新游戏域名的 DNS/TLS/15888 入口须先可访问。 ### 2026-10-23 任务面板打开异常 TMP 会在多段文字下生成同名的 TMP_SubMeshUI 字体渲染子节点;PrototypeFlow.Panel 原先索引全部 Transform 时抛出重复键异常。现按组件排除内部渲染节点,保留业务节点绑定与重名校验。19 个业务面板(含任务、签到、背包、好友)预览场景验证通过。 本次仅发布 DefaultPackage 热更:packVersion `613942741fd3be253c86145d7451031c`,Art 保持 `006c201e92439eb03ae12d84b86f8fa6`。将最新 `Tools/output/server_release/Client-BuddyDefense-15888.zip` 放到服务器发布脚本旁,继续使用 `Publish-BuddyDefenseClient.ps1 -WebglRoot "C:\XWorld\CDN\Friends\webgl"`,脚本先写资源后更新 cdn/version.json。无需重打底包。未由 Agent 上传线上,发布后重新进入小游戏验证点击任务。 ## SSH 一键发布 CDN(2026-11-04) 已接通服务器 `Administrator@159.75.128.109:22`,网站目录 `C:\XWorld\CDN\Friends\webgl`。当前发布使用 `Tools/publish_cdn.py` 与服务器端执行的 `Tools/Publish-CdnRelease.ps1`;旧 `Tools/cdn_publish.py upload` 使用旧通道布局,不用于当前网站发布。 Unity 菜单位于 **AIGame/CDN**: - `Check SSH Connection`:检查免密连接与目标目录。 - `Preview Upload Changes`:只读比较服务器与本地暂存文件,记录需上传的差异。 - `Upload Staged Resources`:发布已构建的资源。 - `Build And Upload (Art + HotUpdate)`:依次检查连接、构建当前 WebGL Art/热更新包并发布,不构建 Player。要求编辑器为 WebGL 目标且不在 Play Mode。 - `Prepare SSH Key`:首次生成专用密钥及服务器公钥安装脚本。 - `Open Publish Folder`:查看预览、日志、ZIP 与发布回执。 本机配置位于 `Tools/cdn_publish.local.json`,示例为 `Tools/cdn_publish.example.json`。专用密钥位于 `Tools/.cdn-deploy/`,两个本机路径均已加入 Git 忽略规则。Windows 私钥 ACL 限制为创建者与 SYSTEM;服务器 Administrator 默认公钥文件为 `C:\ProgramData\ssh\administrators_authorized_keys`。SSH 使用 BatchMode 与严格主机密钥检查,不处理账号密码;公钥安装脚本仅包含公钥。更换网络出口时需更新云防火墙来源白名单。公钥配置依据:https://learn.microsoft.com/en-us/windows-server/administration/openssh/openssh_keymanagement 。 命令行(仓库根目录): ```powershell python Tools/publish_cdn.py check python Tools/publish_cdn.py plan --compare python Tools/publish_cdn.py upload python Tools/publish_cdn.py upload --startup-export AIClient/Build/WeChat/Base python Tools/publish_cdn.py rollback --release <发布回执中的32位releaseId> ``` 发布从 `Tools/cdn_root/wechat/version.prod.json` 读取包版本;验证清单 MD5、YooAsset CRC、版本标记并计算每个文件 SHA256。服务器比较后仅传输差异 ZIP,验证包含未变服务器文件的完整发布集合,防止遗漏文件。服务器先写资源,最后原子替换 `cdn/version.json`;发布时检查原版本未被其他发布者更改。保留旧资源与服务器私有目录中的上一版版本清单,回滚拒绝覆盖后续不同版本。服务器发布后从公网重新读取总版本与包清单进行校验;如果公网检查失败,会明确报告“服务器已发布”,不自动重复提交。 `--startup-export` 是新底包构建后的可选步骤:从该导出目录的 `minigame/game.js` 精确选择当前启动 data,校验 DATA_CDN、DATA_FILE_SIZE 和 SDK 使用的 MD5 中间 16 位命名,仅将对应的 `.webgl.data.unityweb.bin.txt` 加入同一发布事务。服务器路径白名单不允许任意根目录文件;公网额外验证启动 data 的完整 SHA256。原底包和旧哈希资源保留,回滚只切换远端热更版本,不会切换本地微信底包。Unity 常规资源发布菜单仍不自动构建 Player 或附带首包。 本轮实际发布:`releaseId=05a167475cd6402291421c746379c7c4`;DefaultPackage `d0116d388c58c3c73593c02037d0e3ad`,Art `0fd7811b1c0988f4b728dadb59041f38`。306 个本地文件共 69.48 MiB,实际差异 27 个文件/12.70 MiB,包括 HomeCamp +0.30 EV 曝光与首页接入。服务器完整性验证及公网两份清单 MD5 通过。回执:`Tools/output/cdn_publish/release-05a167475cd6402291421c746379c7c4.json`。11 项本地发布事务测试通过,覆盖损坏/缺失上传、过期版本、路径穿越、无变更、旧资源保留与回滚。 此流程发布 Art 和热更新资源;如变更 AOT/JS 桥接或底包配置,仍需按微信导出流程生成并部署相应底包及启动数据。 ### HomeCamp 热更新兼容旧底包(2026-11-04) 微信开发者工具实际 Boot 日志已读取新版 `d0116d388c58c3c73593c02037d0e3ad`,但首页仍显示旧插画,原因是 `MissingMethodException: MethodNotFind YooAsset.SceneHandle::add_Completed`。10 月 22 日导出的 WebGL 底包裁剪了 `SceneHandle.Completed` 和 `UnloadSceneAsync`,因此不是 CDN 未上传或客户端未读取新版本。 `MainHudView.cs` 中的 HomeCampPresenter 改为在常驻 UiManager 上以协程轮询旧底包保留的句柄状态,卸载改用 Unity SceneManager(YooAsset 通过 sceneUnloaded 回收句柄)。下载期间隐藏或销毁首页仍能完成清理。无需重打底包。 `AIClient/AgentScripts/InspectHomeCampAot.cs` 通过 Pipeline 检查旧 ManagedStripped 与实际生成的热更 DLL,确认 SceneHandle/HandleBase 引用均存在;回执 `Tools/output/homecamp_aot_compatibility/aot_check.json`。兼容修复仅上传 5 个差异文件/0.25 MiB,Art 不变;新 DefaultPackage `5b9d783853bd29484ecf828fbf33af47`,发布回执 `Tools/output/cdn_publish/release-4fdfb222706a47879f1511dd532630cf.json`,服务器及公网清单验证通过。 微信开发者工具使用现有底包普通重新编译后,Boot 确认加载上述新版本;首次下载完成后显示降低曝光后的 3D HomeCamp,商店打开后返回营地正常,本轮无红色异常。开发者工具仍有 ASTC 软件解压和加载帧耗时提示;未进行微信真机性能验收。 ### 启动画面整理(2026-11-04,待构建新底包) 用户截图的第一段深棕底花屏对应 Unity Splash Logo:项目开启 show/showUnityLogo,底色为 `#231F20`,当前许可支持关闭。第二段来自旧 `BootPatchView.Create()` 运行时拼装的黑底 AIGame/方形进度条;LegacyRuntime 字体无法正常显示所用中文。这两段属于启动壳,不是远端 HomeCamp 资源。 本地已通过 Pipeline 关闭 Splash,并将启动界面改为 `Doc/UIPrefabCreater/UI_BootLoading.json` → `Assets/AOT/UI/UI_BootLoading.prefab`。它在初始化 YooAsset 前就要显示,因此随 Boot 场景直接引用并放在 AOT 目录,不进入业务 Art 加载链路。复用已有营地插画与 Common 九宫格,使用独立静态中文子集 `Assets/AOT/UI/BootChinese.asset`,保留插画比例并裁切铺满。状态仅展示易懂的加载提示;版本哈希留在日志,进度单调平滑增长,营地准备好后才到 100% 并淡出。 `GameplayBootstrap` 将 MainUiReady 推迟到 HomeCamp 结束加载后,避免先展示旧插画 HUD 再切换 3D。`AIGame/Boot/Build Loading Screen` 可重建字体/Prefab/Boot 引用;导出基础包会检查配置,Setup Boot Scene 也保留启动 Prefab 引用。JsonUIPrefabBuilder 的 TMP 组件新增可选 `fontAsset` 明确路径,既有 JSON 默认字体行为不变。 验证入口 `AIClient/AgentScripts/VerifyStartupPresentation.cs`;1080×1920 与 1080×2338 两组实际 Prefab 预览通过中文字符覆盖、文本溢出、铺满且不拉伸、进度不回退与完成淡出检查,原场景和 Game View 已恢复。截图及回执位于 `Tools/output/startup_presentation/`。本轮尚未构建 Player、替换小游戏底包或发布 CDN;需经明确授权后构建新底包、同步新的启动 data 并在微信端复测,旧壳不能仅靠热更替换启动画面。