基础格式与文件结构
1. 概述
本游戏采用 XML 文件作为数据定义的主要形式,允许开发者和模组作者通过结构化的文本文件创建、修改和扩展游戏内容。游戏启动时将扫描特定目录下的 XML 文件,并根据其类型和内容载入游戏。
2. 文件系统结构
游戏会从两个主要目录读取数据:Data/ 和 Mods/。这两个目录下包含一系列“包”(Packages),每个包代表一个独立的数据集合,可以是一个核心游戏模块,也可以是一个用户创建的模组。
文件目录结构示例:
├── Data/
│ ├── Pack1/ # 数据包示例 1
│ │ ├── About/ # 包信息目录
│ │ ├── Define/ # 数据定义目录
│ │ └── Translation/ # 翻译文件目录 (当前版本未实装)
│ └── Pack2/ # 数据包示例 2
│ ├── About/
│ ├── Define/
│ └── Translation/
└── Mods/
├── Mod1/ # 模组包示例 1
│ ├── About/
│ ├── Define/
│ └── Translation/
└── Mod2/ # 模组包示例 2
├── About/
├── Define/
└── Translation/
目录说明:
Data/: 包含游戏的核心内容和官方扩展数据包。Mods/: 包含用户自定义的模组数据包。PackN/,ModN/: 每个子文件夹被视为一个独立的“包”。包名应当具有唯一性。About/: 存放包的元数据(Metaproperties)。Define/: 存放各种游戏对象的具体定义。Translation/: 存放多语言翻译数据(当前版本未实装)。
3. XML 文件类型
当前游戏版本主要识别并处理以下三种类型的 XML 文件:
- About 文件: 包含包的基本信息和加载依赖关系。
- Define 文件: 包含游戏内的各种数据定义,如物品、角色、属性等。
- Translation 文件: 用于多语言本地化(当前版本未实装)。
4. About XML 文件
About 文件是每个包的门户,它提供了包的基本信息以及游戏加载时所需的依赖和排序数据。
- 文件位置: 每个包的
About/文件夹下。 - 文件命名: 建议命名为
About.xml。 - 根元素: 必须以
<About>为根。 - 数量限制: 一个包中只能包含一个 About XML 文件。
典型 About 文件示例:
<?xml version="1.0" encoding="utf-8"?>
<About>
<!-- 包的显示名称,用于用户界面 -->
<name>核心</name>
<!-- 包的详细描述,解释其功能或内容 -->
<description>这是一个基础核心模块,除非有完整的代替,否则应该永远作为启动项</description>
<!-- 包的版本号 -->
<version>0.1</version>
<!-- 包的唯一标识符,必须在所有包中全局唯一 -->
<packID>core</packID>
<!-- 加载排序和依赖关系定义 -->
<sort>
<!-- 定义本包加载前必须加载的包的packID列表 -->
<necessary></necessary>
<!-- 定义本包应该优先于哪些包加载,填写那些包的packID列表 -->
<before></before>
<!-- 定义本包应该在哪些包之后加载,填写那些包的packID列表 -->
<after></after>
</sort>
</About>
元素说明:
<name>: (String) 包的显示名称,会显示在游戏的用户界面中。<description>: (String) 包的详细描述,用以解释其功能或内容。<version>: (String) 包的版本号,遵循语义化版本控制(如1.0.0)或简单版本号(如0.1)。<packID>: (String, 必填) 包的唯一标识符。这个 ID 在整个游戏的数据包和模组中必须是全局唯一的,用于识别包及其依赖关系。<sort>: (Object) 包含加载排序和依赖关系的定义。<necessary>: (Array of String) 定义了本包加载前必须加载的包的packID列表。如果这些包未能加载,本包将无法加载。<before>: (Array of String) 定义了本包应该优先于哪些包加载。列表中填写其他包的packID。<after>: (Array of String) 定义了本包应该在哪些包之后加载。列表中填写其他包的packID。
加载机制:
游戏启动时,会首先读取所有 About.xml 文件,构建一个包的依赖图。然后根据 necessary, before, after 标签中定义的规则,确定包的加载顺序。
- 如果多个包定义了相同的
packID,游戏启动时会报错或仅加载其中一个。 - 如果
necessary的包缺失,则当前包无法加载。 before和after标签用于调整加载顺序,以解决同名 Define 数据覆盖问题或确保特定功能的前提条件。
5. Define XML 文件
Define 文件是游戏内容的核心,用于定义游戏中的各种对象、属性和规则。
- 文件位置: 每个包的
Define/文件夹下。 - 文件命名: 可以根据内容自由命名,例如
Items.xml,Characters.xml等。 - 根元素: 其中的每个 XML 文件必须以
<Define>为根。 - 内容: 可以包含任意数量和类别的各种数据定义。
核心约定:
- 基本属性: 所有的顶级定义都必须包含以下三个属性:
defName: (String, 必填) 定义的唯一名称。这个名称在 该类型的数据定义中 必须是全局唯一的。例如,所有ImageDef都有唯一的defName,所有WeaponDef也有唯一的defName,但ImageDef和WeaponDef可以有相同的defName(如TestGunItem和TestGun)。label: (String) 定义的显示名称,用于游戏用户界面。description: (String) 定义的详细描述,用于游戏用户界面或工具提示。
- 覆盖机制: 如果不同包(或同一包内不同文件)中同一类型的数据定义了相同的
defName,则后加载的定义会覆盖先加载的定义。这允许模组轻松地修改或替换原版游戏内容。 - 引用机制: 当一个定义的数据字段需要引用其他数据定义时,可以通过以下两种方式:
- 引用
defName: 直接填写被引用定义的defName。游戏会在加载时解析这些引用。 - 嵌套定义(匿名定义): 直接在引用位置定义一个新的对象,该对象通常没有
defName,是当前定义的私有或匿名部分。
- 引用
典型 Define 文件示例:
<?xml version="1.0" encoding="utf-8"?>
<Define>
<!-- 图片定义 -->
<ImageDef>
<defName>TestGunItem</defName> <!-- 唯一标识符 -->
<path>Resources\Item\TestGun.png</path> <!-- 图片路径 -->
</ImageDef>
<!-- 属性定义 -->
<AttributesDef>
<defName>TestGun</defName> <!-- 唯一标识符 -->
<attack>10</attack>
<defense>3</defense>
<attackSpeed>3</attackSpeed>
<attackRange>10</attackRange>
<attackTargetCount>1</attackTargetCount>
</AttributesDef>
<!-- 武器定义 -->
<WeaponDef>
<defName>TestGun</defName> <!-- 全局唯一标识符 -->
<label>测试枪</label> <!-- 显示名称 -->
<description>一把测试用的枪</description> <!-- 详细描述 -->
<!-- 引用属性定义,通过defName="TestGun"引用AttributesDef中定义的属性 -->
<attributes>TestGun</attributes>
<type>Ranged</type>
<textures>
<!-- 引用ImageDef中的图片定义 -->
<li>TestGunItem</li>
</textures>
<!-- 引用子弹定义,通过defName="yellowBullet"引用BulletDef -->
<bullet>yellowBullet</bullet>
</WeaponDef>
<!-- 子弹定义 -->
<BulletDef>
<defName>yellowBullet</defName>
<label>黄色子弹</label>
<description>一颗黄色的子弹</description>
<!-- 嵌套定义属性,此处的属性是当前子弹特有的匿名属性,没有defName -->
<attributes>
<health>1</health>
<moveSpeed>20</moveSpeed>
</attributes>
<!-- 嵌套定义纹理绘制顺序,包含多个匿名绘制状态定义 -->
<drawingOrder>
<idle_down>
<textures>
<li>yellowBullet</li>
</textures>
</idle_down>
<walk_down>
<textures>
<li>yellowBullet</li>
</textures>
</walk_down>
</drawingOrder>
</BulletDef>
</Define>
示例解析:
ImageDef: 定义了一个图像资源。defName为TestGunItem,表示这是图像定义的唯一标识。path指定了图像文件在文件系统中的相对路径。
AttributesDef: 定义了一组属性集。defName为TestGun。- 包含了攻击、防御等具体数值。
WeaponDef: 定义了一个武器对象。defName为TestGun。label和description提供显示文本。<attributes>TestGun</attributes>: 这里通过defName引用了AttributesDef中名为TestGun的属性集。<textures><li>TestGunItem</li></textures>: 引用了ImageDef中名为TestGunItem的图像定义。<textures>标签下的<li>元素表示一个列表项。<bullet>yellowBullet</bullet>: 引用了BulletDef中名为yellowBullet的子弹定义。
BulletDef: 定义了一个子弹对象。defName为yellowBullet。<attributes>: 这里没有引用已有的AttributesDef,而是直接在此嵌套定义了一组属性。这些属性是yellowBullet特有的,不与其他定义共享defName。<drawingOrder>: 同样采用嵌套定义的方式,为不同的动画状态(如idle_down,walk_down)定义了各自的纹理列表。
6. Translation XML 文件 (当前版本未实装)
此类型文件未来将用于实现游戏的多语言本地化。
- 文件位置: 每个包的
Translation/文件夹下。 - 根元素: 预期的根元素将是
<Translation>或类似的元素。 - 内容: 届时将包含键值对形式的翻译文本,用于替换游戏中硬编码的字符串或 Define 文件中的
label和description。