Skip to content

扩展包格式与安装说明(格式版本 1)

本文描述 Phase 4 已实现的物理扩展包契约。扩展包只提供数据和资源文件,不包含需要 Unity 重新编译的 C# 类型。

搜索位置

运行时只扫描以下目录的直接子目录,不递归搜索:

  • 随游戏发布:StreamingAssets/Content/Packs/<扩展包目录>/
  • 用户安装:Application.persistentDataPath/Content/Packs/<扩展包目录>/

目录名不参与身份判断;pack.json 中的 packId 才是稳定身份。

text
Packs/
  sample-pack/
    pack.json
    catalog.json
    assets/
      cards/
        sample.png

pack.json

json
{
  "formatVersion": 1,
  "packId": "sample_pack",
  "packVersion": "1.0.0",
  "schemaVersion": 2,
  "loadOrder": 100,
  "dependencies": [],
  "overrides": [],
  "catalogFile": "catalog.json",
  "catalogSha256": "catalog.json 的 SHA-256 小写十六进制"
}
  • formatVersion:当前只接受 1
  • packId:全局唯一稳定 ID,使用小写字母开头,可包含小写字母、数字、点、下划线和连字符。
  • packVersion:必须和 catalog.jsoncontentVersion 一致。
  • schemaVersion:必须和目录中的内容 schema 一致;当前运行时接受 1–2,建议只产出 2。
  • loadOrder:只用于多个“依赖已经就绪”的扩展包之间排序;依赖拓扑优先于数值。
  • dependencies:依赖扩展包的 packId。缺失依赖、重复 ID 和依赖环都会中止加载。
  • catalogFile:相对于扩展包目录的文件路径,不允许 .. 或绝对路径逃出扩展包目录。
  • catalogSha256:按 catalog 原始 UTF-8 文件字节计算,不是对格式化后的 JSON 计算。

catalog.json

catalog 使用与基础内容相同的 schema,但可以只携带本包新增或替换的定义。例如:

json
{
  "schemaVersion": 2,
  "contentVersion": "1.0.0",
  "characters": [
    {
      "characterId": "sample_hero",
      "displayName": "示例角色",
      "initialHealth": 20,
      "baseDamage": 3,
      "moveSteps": 2,
      "enabled": true
    }
  ],
  "assets": [
    {
      "assetKey": "sample.hero.art",
      "assetKind": "artwork",
      "relativePath": "assets/cards/sample.png",
      "sha256": "可选的资源文件 SHA-256"
    }
  ]
}

资源路径同样必须留在本扩展包目录内。声明了 sha256 时,运行时会验证文件内容;所有声明的外部资源都必须存在。

显式覆盖

新增定义不得与基础内容或较早加载的包发生稳定 ID 冲突。确实需要替换时,必须逐条声明:

json
"dependencies": ["sample_base"],
"overrides": [
  { "definitionKind": "card", "definitionId": "fireball_01" },
  { "definitionKind": "asset", "definitionId": "card.fireball.art" }
]

可组合的定义种类包括 cardpoolstatusdeckrarityassetclasscharacterequipment。当前格式不允许扩展包替换基础 GameSettings

启动校验与失败策略

合并完成后,运行时在建立 Content Registry 之前统一检查:

  • 已启用卡牌、牌库、卡池、职业、角色和装备之间的引用;
  • 行为所有者、稳定 ID、Trigger 和行为图节点能力;
  • 外部文件是否存在、目录是否越界、声明的 SHA-256 是否匹配。

任一已发现扩展包无效时,本次内容初始化整体失败并阻止进入战斗。这是当前版本的故障隔离边界;尚未提供“禁用单个坏包后继续”的 UI。