# Engine 0.2.1 → 0.3.3：旧游戏依赖升级与兼容迁移指南

> [!IMPORTANT]
> 目标是**将已有游戏项目自身的 Engine 依赖从 0.2.1 升到 0.3.3，让原游戏继续运行**。
> 不重新创建游戏，不重做玩法，不把升级 `@forgeax/game` 或修改资产库后端当作迁移前置。
> 其他源版本不在本次实测范围内。

验证日期：2026-09-28。适用于使用 `assets/` Pack 源码、`forge.json#roots` 的
Engine 0.2.1 项目。目标 Engine commit 为
`4ad48ef03d8f8f1bb74f5bf7cde71c4799d51060`。下面命令按 macOS/Linux 编写；
Node 前置要求为 ≥22.13.0；实测平台为 macOS arm64、Node 24、pnpm 11.7.0。
Windows 按相同检查点使用 PowerShell，
不能把本次结果描述为 Windows 已验证。

## 一、兼容结论与升级范围

| 对象 | 需要做什么 | 已确认的边界 |
|:--|:--|:--|
| 游戏 Engine 依赖 | 升至精确 `0.3.3`，同步分包、DevKit 和锁文件 | 只更新全局 CLI 或重复插件 `init` 不会升级游戏依赖 |
| Engine Skills | 用 0.3.3 SDK 更新受管来源，保留用户定制 | 旧生成副本可能阻止覆盖，要先辨认并备份 |
| 原玩法和项目配置 | 保留 root GUID，按实际诊断调整代码 | 本次旧游戏无须修改玩法源码；不代表所有旧 API 都兼容 |
| 已导入的 EA 原生 Pack | 保留来源、依赖文件和 GUID，重新构建与运行 | 实测 Pack 无须修改资产源码，3D 显示和玩法通过 |
| 其他 Pack、GLB、材质、纹理、音频等 | 优先保留文件，重建输出并逐项目验证 | 未逐一测试所有格式，不能保证全部零改动 |
| 资产库后端和新下载 | 由后端维护版本声明、查询与交付兼容性 | 不属于本地游戏依赖迁移，也不是运行已有本地资产的前置 |
| 主插件和第三方扩展 | 仅在继续使用对应连接器/扩展时适配 | 见可选集成章节，不混入纯 Engine 主流程 |

**已有本地资产与资产库重新搜索是两回事。** 已保存的旧 EA Pack 在本次具体游戏中
可继续构建和使用，无须为了升级重新下载、改 GUID 或转为 GLB。旧导入记录的
Engine 0.2.1 是历史来源，不应伪改成 0.3.3。兼容结论来自新引擎构建及真实画面，
不来自文件名、ZIP 标签或服务端查询结果。

后端适配由资产库维护者负责。本地迁移不要求 Agent 修改后端或重新搜索全部旧资产。
如果后端 `engineVersions` 尚未更新，0.3.3 筛选无候选不等于本地旧资产无法运行。
新下载应选声明兼容的版本；元数据缺失表示未知，仍需正常导入、构建和 Preview
验证。明确声明不兼容的版本不能强行导入。

> [!WARNING]
> 保留旧资产源码不等于复用所有旧构建产物。0.3.3 的网格二进制生产端输出 v5，
> 读取端支持 v4/v5，不接受 v2/v3；应保留源码及 `.meta.json`，用新版导入器/Cook
> 重建。这里的版本是网格二进制格式，不是 `.pack.json` schema。
> 新版使用 Reverse-Z；普通材质深度比较语义由 Engine 转换，直接读取/写入深度的
> 自定义 WGSL/RHI 代码须对照新版渲染包声明核对，不能照搬旧深度约定。

## 二、交给其他 Agent 的执行要求

提供旧游戏目录和本指南即可开始纯 Engine 迁移；使用可选插件/新资产下载时，
再提供对应的精确版本和获授权服务配置。

```text
将这个已有游戏项目的 Engine 依赖从 0.2.1 升级到 0.3.3。
在独立副本或分支操作，保留原玩法、资产源码、依赖文件和 GUID。
按指南更新 Engine 依赖、锁文件和受管 Skills，使用 Engine 正式 CLI。
根据新类型/Skills、编译错误和运行日志修复必要的 API 或组件注册问题。
不要创建替代游戏，不换资产，不把后端改造作为本地迁移前置。
完成项目检查、类型检查、原游戏测试、构建、GUID 读回和真实 Preview 验证。
验证原有核心操作及重置；报告修改文件和未通过项，不能只凭构建成功验收。
```

## 三、旧游戏依赖迁移

### 1. 固定起点，保护原项目

确认 `@forgeax/engine` 为 `0.2.1`、`forge.json` 为 schema 3，存在原
`roots.engine/frontend`。记录依赖、锁文件、正在使用的导入 GUID、资产来源和哈希。
更早布局或缺少这些输入时，先报告范围差异，不直接套用流程。

非 Git 项目使用下面的独立副本；Git 项目可用新分支/worktree，自行设置 `GAME`
及项目外的 `backup_dir`。下文连续使用这些变量：

```sh
SOURCE_GAME="/absolute/path/to/existing-game"
GAME="$(mktemp -d /tmp/engine-game-migration.XXXXXX)"
backup_dir="$(mktemp -d /tmp/engine-game-upgrade.XXXXXX)"
rsync -a --exclude node_modules --exclude dist "$SOURCE_GAME/" "$GAME/"
```

保留完整资产依赖，不只拷贝顶层 Pack。备份可能含私有配置，不要上传；
不要读取或复制项目外的凭证到项目。

### 2. 获取精确 Engine SDK 0.3.3，不安装主插件

安装独立 SDK 与 pnpm，避免全局旧 `forgeax` 抢先执行：

```sh
ENGINE_TARGET_VERSION="0.3.3"
tool_dir="$(mktemp -d /tmp/engine-sdk-tool.XXXXXX)"
npm install --prefix "$tool_dir" --no-save --ignore-scripts \
  "@forgeax/engine-sdk@$ENGINE_TARGET_VERSION" "pnpm@11.7.0"
SDK_ROOT="$tool_dir/node_modules/@forgeax/engine-sdk/sdk"
SDK="$SDK_ROOT/bin/forgeax.mjs"
PNPM="$tool_dir/node_modules/pnpm/bin/pnpm.cjs"
node -p "require('$tool_dir/node_modules/@forgeax/engine-sdk/package.json').version"
node "$PNPM" --version
(cd "$SDK_ROOT" && PATH="$tool_dir/node_modules/.bin:$PATH" node ./bin/forgeax.mjs project init --json)
```

版本应为 SDK `0.3.3`、pnpm `11.7.0`。按 init 返回的 `onboarding.read` 阅读 SDK
入口、SDK Skill 和能力目录，只选择本次迁移需要的能力。最后一条在 SDK 根目录准备当前
Node/平台组合的载体，成功后才继续；新载体直接初始化游戏可能报
`sdk-not-initialized`。游戏参数 `--install=false` 不替代 SDK 根目录准备。

### 3. 更新依赖，备份旧 Engine-owned Skills

在工作副本的 `package.json` 将 `@forgeax/engine` 的精确版本改为 `0.3.3`。
下一步 SDK 会同步需要的 Engine 分包及 `@forgeax/engine-devkit`，核对其版本一致。
不要批量把所有 `@forgeax/*` 包都改为 0.3.3；主插件和扩展有各自版本。

若旧 `skills/forgeax-engine-*` 与 `.agents/skills/forgeax-engine-*` 是
未定制的 SDK 生成副本，移到备份后再安装；不同内容会触发
`project-skill-source-conflict`，SDK 不会静默覆盖。

> [!CAUTION]
> 先核对 `.forgeax/skill-install-manifest.json` 的 `sdkVersion`、登记目录和所有权，
> 并确认没有用户定制。下面的比较只证明两个副本相同，不能单独证明未定制。
> 定制内容需人工迁移；用户自有 Skill、链接和第三方目录不能批量移动。

仅对满足上述条件的目录执行：

```sh
cd "$GAME"
for dir in skills/forgeax-engine-*; do
  diff -qr "$dir" ".agents/skills/${dir##*/}" || exit 1
done
mkdir -p "$backup_dir/skills" "$backup_dir/.agents/skills"
for dir in skills/forgeax-engine-*; do
  [ -d "$dir" ] || continue
  mv "$dir" "$backup_dir/skills/"
done
for dir in .agents/skills/forgeax-engine-*; do
  [ -d "$dir" ] || continue
  mv "$dir" "$backup_dir/.agents/skills/"
done
```

符号链接先核对为 SDK 登记且指向项目来源的链接，不直接套用目录示例。
保留备份到真实验收完成。

### 4. 用 SDK 同步原项目，重新生成锁文件

```sh
cd "$GAME"
node "$SDK" project init --root "$GAME" --install=false --json
node "$SDK" project skill verify --json
node "$PNPM" install --no-frozen-lockfile --ignore-scripts --registry=https://registry.npmjs.org
node "$PNPM" install --frozen-lockfile --ignore-scripts --registry=https://registry.npmjs.org
```

这一步同步原项目依赖与 Skills，不是 `project new`，不生成替代游戏。
`--install=false` 是已验证参数，`--no-install` 不是。旧项目默认 init
可能在写入依赖后因旧锁文件报 `ERR_PNPM_OUTDATED_LOCKFILE`；先 init、再解算、
最后 frozen 校验。核对声明、锁文件与已安装 Engine/DevKit 均为 0.3.3。

私有网络可用批准的镜像；元数据缺失时不盲目 `--offline`。
此时 Engine Skill verifier 应通过，不手改 manifest 或删除登记挂载来伪造通过。

### 5. 按实际诊断修复必要的代码

先用原玩法/资产检查、构建，无错误就不改玩法源码。出现不兼容时读取本项目的
`skills/forgeax-engine-*` 和 `node_modules/@forgeax/engine*` 声明：

| 现象 | 调整方向 | 不应做的事 |
|:--|:--|:--|
| 导入路径、类型或 API 编译失败 | 对照 0.3.3 声明修正实际使用的导入/调用 | 猜 API、用 `any` 隐藏错误或改变玩法语义 |
| 模块未找到、Engine 版本混用 | 检查 SDK 同步的分包、锁文件和安装状态 | 盲目升级用户非 Engine 依赖 |
| 自定义组件导致实例化失败 | 按目标组件契约注册受信组件，再实例化 | 删组件、改 GUID 掩盖失败 |
| 可构建但不可见、比例或材质异常 | 检查层级、相机、灯光、变换、资产依赖及浏览器日志 | 换成程序化替身 |
| 输入、UI 或生命周期失效 | 对照对应 Engine Skill 和类型调整绑定/清理 | 丢弃原控制方式和反馈来通过验收 |

这是问题诊断入口，不声称上述 API 都发生变化，也不是完整 API 前后映射。
自定义系统是否需要改造以本项目类型检查和运行证据为准。

## 四、构建与真实验收

```sh
cd "$GAME"
node "$SDK" project check --json
node "$PNPM" exec tsc --noEmit
node "$PNPM" test
node "$SDK" project build --json
node "$SDK" asset verify --json
```

保留原测试；没有测试时为受影响核心行为补测试，不能用 Empty 测试代替。
构建前 `.pack.ts` 可能报 `producer-not-run`，先构建再校验。
`dist/` 和生成索引可重建；root GUID、来源记录和资产源码不是可随意替换的缓存。

用原导入 scene GUID 和源码路径读回：

```sh
ASSET_GUID="<原导入的 scene GUID>"
ASSET_SOURCE="<项目内原生 .pack.ts/.pack.json 的路径>"
shasum -a 256 "$ASSET_SOURCE"
jq -er --arg guid "$ASSET_GUID" \
  '.[] | select(.guid == $guid) | [.kind, .sourcePath, .packageUrl, .cookReceiptUrl] | @tsv' \
  dist/pack-index.json
```

原生场景应仍为 `scene`，来源仍是原文件，且有 package/receipt。
比较迁移前后哈希或 Git diff；必要的源码改动必须说明原因。其他资产类型按
对应 catalog 验收，不机械要求都为 scene。

启动正式 Preview：

```sh
cd "$GAME"
node "$SDK" project preview --json
```

保持进程运行，只打开本次成功返回的地址，核对响应 `root` 为工作副本、
`mode=preview`、`serves=dist`；Engine 版本/commit 从项目检查和已安装包核对。
SDK 0.3.3 的该 CLI 响应没有 `build digest` 和 `instance ID`，不要求 Agent
凭空补齐；若使用可选 Game Plugin Preview 连接器，则另外记录连接器返回的身份。
实际查看原资产、材质、比例和方向，操作原游戏的核心循环、反馈及重置，
检查浏览器错误。旧端口 HTTP 200、`ready` 或构建成功不能代替可玩验收。

### 完成标准与失败边界

- [ ] Engine/DevKit 0.3.3，依赖与锁文件一致。
- [ ] Engine Skills 已刷新，原生 Skill verifier 通过。
- [ ] 项目检查、类型检查、游戏测试、构建和资产校验通过。
- [ ] 原 root/资产 GUID、来源与依赖文件保留，必要改动有理由。
- [ ] 新 Preview 身份明确，原画面和核心交互真实通过。
- [ ] 交付修改文件、验证结果、未验证平台和遗留问题。

| 失败 | 先定位 | 停止边界 |
|:--|:--|:--|
| `sdk-not-initialized` | SDK 根目录准备是否成功 | 准备未过不继续游戏迁移 |
| `project-skill-source-conflict` | 旧 Skill 所有权、定制与备份 | 不覆盖未弄清的用户内容 |
| `ERR_PNPM_OUTDATED_LOCKFILE` | init 后解算和 frozen 校验 | 不用旧依赖继续运行 |
| 构建过但资产/交互失败 | GUID、cook 产物、注册和浏览器日志 | 不声称通过、不用替身掩盖 |
| 资产库版本筛选为空 | 后端声明和查询条件 | 不把它等同于本地旧资产不可用 |

## 五、可选集成：主插件与资产库扩展

<details>
<summary>仅继续使用 Game Plugin/MCP 或新资产下载时需要</summary>

纯 Engine CLI 迁移到上一节即可验收，不必安装/更新 `@forgeax/game`。
若继续用 `forgeax_run_current_game`，连接器必须支持 Engine 0.3.3：
核对精确插件包的 SDK 依赖，不因版本号较大或 `@latest` 就假定支持。
随后刷新绑定、主 Skill 与所选 Agent 注册；插件 `init/update` 不替代依赖迁移。

本次发布目标为 `@forgeax/game@0.3.10`，固定 Engine SDK `0.3.3`；
旧 `@forgeax/game@0.3.9` 使用 SDK `0.2.1`，不能作为本次升级载体。
共享时提供明确发布版本或本地候选路径，不混用来源；发布状态以 npm 查询为准。
需要继续搜索/下载时，用适配后的扩展保留原获授权 `--library`、`--base-url`
和项目外凭证，按要求重新 enable；本地候选加 `--local`。
只复用本地旧资产，不强制 enable 或重新下载。后端适配由资产库维护者处理。

扩展仍为 `extension.json` + Skill + CLI，见
[插件接入规范](plugin-integration-standard.md)。不新增 Asset3D MCP。
扩展作者核对实际 Engine 导入/构建接口及 Skill 指引，不需要重做接入架构。

> [!WARNING]
> 可选连接器存在跨包契约问题：SDK 0.3.3 verifier 要求六个宿主挂载，
> 主插件 Codex-only init 会修剪未选宿主，并把选中 Skill 安装为副本，之后可能报
> `skill-install-manifest-drift`。纯 SDK 阶段通过；插件绑定后的失败仍是未解决项，
> 不能忽略为通过或回填其他宿主规避。需要该阶段全绿时，维护者须统一契约。

</details>

## 六、本地实测与结论边界

验证样本：Engine 0.2.1 的 **Orbit Garden**，使用已导入的 EA 原生 Pack。
迁移只在独立副本进行，原件未修改；下面保留可玩验证的资产及 Preview 身份，
不公开验证机器的私人目录。

本次又在另一独立副本按本指南重放了**纯 SDK 迁移路径**：
工具目录仅安装 `@forgeax/engine-sdk@0.3.3` 和 pnpm 11.7.0，
没有安装或调用 `@forgeax/game`。SDK 准备、原项目 init、17 个 Engine Skill
校验、锁文件解算与 frozen 校验、项目检查、TypeScript、2 个原游戏测试、
构建和资产校验均通过；原 scene GUID 可读回，`assets/` 与原件逐文件比较无差异。
正式 `project preview` 返回该副本的 root、`mode=preview`、`serves=dist`，
HTTP 页面标题为 Orbit Garden。该副本未重做浏览器交互；这次命令路径证据与
下面已有的浏览器可玩证据分别记录，不把 HTTP 成功当作新一次可玩验收。

| 证据 | 已确认事实 |
|:--|:--|
| 本地旧 Pack | EA 资产 ID `6ab11aad68d1d3c08aaa7bf4`；未修改玩法或资产源码 |
| 来源/GUID | scene `74d076ea-2f6b-5d6b-9f07-639592d1d150` 可读回，仍来自原 `crate.pack.ts`，包含 package/receipt |
| 源文件一致性 | `assets/` 聚合哈希前后均为 `02c0223a188a2642a6c759e4a3f083d5fe82564b7d562c7dac06e451fd4892cb` |
| 静态与构建 | 项目检查、TypeScript、2 个原游戏测试、构建与资产校验通过；SDK 阶段 17 个 Engine Skill verify 通过 |
| 可见与可玩 | Engine 0.3.3 Preview 实际完成 `0/3 → 1/3 → 2/3 → 3/3 → R → 0/3`；浏览器错误/警告 0 |
| 既有可玩验收的连接器身份 | instance `99125cc9-804a-40a5-b3ba-ad7ce1175dd9`；digest `210c097fc3a6c82940c3e27db88f148e9d1f604c77c4f8dc5812a94c1eedc50a` |
| 已知限制 | 可选插件绑定后有 Skill verifier 契约冲突；迁移副本有 pnpm workspace-state 警告，但 frozen lockfile 校验和上述检查通过 |
| 资产库范围 | 旧 Pack 本地复建通过；未完成本轮新资产重新导入，不承诺后端全部资产兼容 |

**可对外说明：已验证一个 Engine 0.2.1 旧游戏及已导入的 EA 原生 Pack，
经过依赖和 Skills 迁移，可在 Engine 0.3.3 继续运行，资产无须重做。**
不能推断全部历史游戏、所有 Pack/格式、所有系统或新下载链路自动兼容。
商业许可仍需另行确认；本指南不是新版 Game Plugin 的发布证明。
