扩展包格式与安装说明(格式版本 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.pngpack.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.json的contentVersion一致。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" }
]可组合的定义种类包括 card、pool、status、deck、rarity、asset、class、character 和 equipment。当前格式不允许扩展包替换基础 GameSettings。
启动校验与失败策略
合并完成后,运行时在建立 Content Registry 之前统一检查:
- 已启用卡牌、牌库、卡池、职业、角色和装备之间的引用;
- 行为所有者、稳定 ID、Trigger 和行为图节点能力;
- 外部文件是否存在、目录是否越界、声明的 SHA-256 是否匹配。
任一已发现扩展包无效时,本次内容初始化整体失败并阻止进入战斗。这是当前版本的故障隔离边界;尚未提供“禁用单个坏包后继续”的 UI。