文明6 Mod教程(2)创建人物

Mod 相关文件类型

文明 6 的 mod 主要由以下文件构成

  1. xml: 最主要的文件
  2. artdef: 模型定义
  3. xlp: 图像资源变量名
  4. dds: 贴图

本质上, 后面 3 个其实也是 xml 文件, 只是后缀名不同, 语法格式是相同的

创建新的单位

设计目标

设计一个单位, 名称为职业军队 ProfessionalArmy, 替代步兵, 造价和维护费低于步兵, 速度更快, 强于步兵

新建 project

与修改文本类似, 这次新建一个 unit project, 命名为 UNIT_ProfessionalArmy

删除无用的 GettingStarted.html, 无视不重要的 .Art.xml 文件

重要的是下面几个文件

  1. Units.artdef: 模型定义
  2. UNIT_ProfessionalArmy_Gameplay.xml: 参数设置
  3. UNIT_ProfessionalArmy_Icons.xml: 图标设置
  4. UNIT_ProfessionalArmy_Text.xml: 文本设置

单位参数设置

原版单位结构

作为参考, 打开含有原版单位参数的文件 Sid Meier’s Civilization VI\Base\Assets\Gameplay\Data\Units.xml

文明 6 的单位命名一般以 UNIT 开头, 步兵为 UNIT_INFANTRY

第一项在 Types 标签下, 代表单位的名称

<Row Type="UNIT_INFANTRY" Kind="KIND_UNIT"/>

第二项在 UnitAiInfos 标签下, 代表单位的信息

<Row UnitType="UNIT_INFANTRY" AiType="UNITAI_COMBAT"/>
<Row UnitType="UNIT_INFANTRY" AiType="UNITAI_EXPLORE"/>
<Row UnitType="UNIT_INFANTRY" AiType="UNITTYPE_MELEE"/>
<Row UnitType="UNIT_INFANTRY" AiType="UNITTYPE_LAND_COMBAT"/>

这段代码表示步兵是战斗单位, 探索单位, 近战单位, 地面战斗单位

第三项是 UnitReplaces, 即单位替换 (步兵没有)

例如重装步兵替换了枪兵

<UnitReplaces>
<Row CivUniqueUnitType="UNIT_GREEK_HOPLITE" ReplacesUnitType="UNIT_SPEARMAN"/>
</UnitReplaces>

第四项在 TypeTags 标签下, 代表单位类型

<Row Type="UNIT_INFANTRY" Tag="CLASS_MELEE"/>

这段代码表示步兵是近战单位

最关键的第五项在 Unit 标签下, 代表单位的具体参数

<Row UnitType="UNIT_INFANTRY" Cost="430" Maintenance="6" BaseMoves="2" BaseSightRange="2" ZoneOfControl="true" Domain="DOMAIN_LAND" Combat="75" FormationClass="FORMATION_CLASS_LAND_COMBAT" PromotionClass="PROMOTION_CLASS_MELEE" AdvisorType="ADVISOR_CONQUEST" Name="LOC_UNIT_INFANTRY_NAME" Description="LOC_UNIT_INFANTRY_DESCRIPTION" PurchaseYield="YIELD_GOLD" PrereqTech="TECH_REPLACEABLE_PARTS"/>

包括:

  1. 花费的生产力 Cost,
  2. 维护费 Maintenance,
  3. 基础移速 BaseMoves,
  4. 基础视野 BaseSightRange,
  5. 是否有控制区 ZoneOfControl,
  6. 空中或地面单位 Domain,
  7. 近战力 Combat,
  8. 编队类型 FormationClass,
  9. 晋升类型 PromotionClass,
  10. 顾问提示类型 AdvisorType,
  11. 名称 Name,
  12. 描述 Description,
  13. 购买力范围 PurchaseYield,
  14. 生产所需科技 PrereqTech,
  15. 淘汰科技 MandatoryObsoleteTech (如有),
  16. 特质类型 TraitType (如果是文明独有的),
  17. 战略资源消耗 StrategicResource (如有),
  18. 远程攻击力 RangedCombat (如有),
  19. 远程攻击范围 Range (如有)

在 xml 中, 下面两种写法是等效的

<TagA RowA="A" RowB="B"/>

<TagA>
<RowA>A</RowA>
<RowB>B</RowB>
</TagA>

第六项在 UnitUpgrades 标签下, 表示单位的升级目标

<Row Unit="UNIT_LINE_INFANTRY" UpgradeUnit="UNIT_INFANTRY"/>
<Row Unit="UNIT_INFANTRY" UpgradeUnit="UNIT_MECHANIZED_INFANTRY"/>

在原版的升级线中, 线列步兵可以升级为步兵, 步兵可以升级为机械化步兵

编写职业化军队

仿照步兵, 编写职业化军队的 UNIT_ProfessionalArmy_Gameplay.xml 文件

<?xml version="1.0" encoding="utf-8"?>
<GameData>
<!-- Almost all gameplay types should first be added to the types table. -->
<!-- This serves as a central way to reference any type -->
<Types>
<Row Type="UNIT_PROFESSIONAL_ARMY" Kind="KIND_UNIT" />
</Types>

<UnitAiInfos>
<Row UnitType="UNIT_PROFESSIONAL_ARMY" AiType="UNITAI_COMBAT"/>
<Row UnitType="UNIT_PROFESSIONAL_ARMY" AiType="UNITAI_EXPLORE"/>
<Row UnitType="UNIT_PROFESSIONAL_ARMY" AiType="UNITTYPE_MELEE"/>
<Row UnitType="UNIT_PROFESSIONAL_ARMY" AiType="UNITTYPE_LAND_COMBAT"/>
</UnitAiInfos>

<UnitReplaces>
<Row CivUniqueUnitType="UNIT_PROFESSIONAL_ARMY" ReplacesUnitType="UNIT_INFANTRY"/>
</UnitReplaces>

<TypeTags>
<Row Type="UNIT_PROFESSIONAL_ARMY" Tag="CLASS_MELEE"/>

</TypeTags>

<!-- Define the actual unit here. For examples of additional properties and values, look at Units.xml in /Base/Assets/Gameplay/Data/-->
<Units>
<Row UnitType="UNIT_PROFESSIONAL_ARMY" Cost="215" Maintenance="3" BaseMoves="3" BaseSightRange="2" ZoneOfControl="true" Domain="DOMAIN_LAND" Combat="80" FormationClass="FORMATION_CLASS_LAND_COMBAT" PromotionClass="PROMOTION_CLASS_MELEE" AdvisorType="ADVISOR_CONQUEST" Name="LOC_UNIT_PROFESSIONAL_ARMY_NAME" Description="LOC_UNIT_PROFESSIONAL_ARMY_DESCRIPTION" PurchaseYield="YIELD_GOLD" PrereqTech="TECH_REPLACEABLE_PARTS"/>
</Units>

<UnitUpgrades>
<Row Unit="UNIT_LINE_INFANTRY" UpgradeUnit="UNIT_PROFESSIONAL_ARMY"/>
<Row Unit="UNIT_PROFESSIONAL_ARMY" UpgradeUnit="UNIT_MECHANIZED_INFANTRY"/>
</UnitUpgrades>
</GameData>

文本标签

对于 LOC_UNIT_PROFESSIONAL_ARMY_NAME 和 LOC_UNIT_PROFESSIONAL_ARMY_DESCRIPTION 两个文本标签, 需要在 UNIT_ProfessionalArmy_Text.xml 中编写

开发环境已经提供了模板, 不过是英文 en_US 的, 照着写中文 zh_Hans_CN 即可

<?xml version="1.0" encoding="utf-8"?>
<GameData>
<LocalizedText>
<!-- The name of the unit. -->
<Row Tag="LOC_UNIT_PROFESSIONAL_ARMY_NAME" Language="zh_Hans_CN">
<Text>职业化军队</Text>
</Row>

<!-- It's description. -->
<Row Tag="LOC_UNIT_PROFESSIONAL_ARMY_DESCRIPTION" Language="zh_Hans_CN">
<Text>强大的现代近战单位,替代步兵,造价和维护费更低,战斗力和移动速度更强</Text>
</Row>
</LocalizedText>
</GameData>

图标

单位图标可以用游戏自带的, 也可以用自己的

在文件 Sid Meier’s Civilization VI\Base\Assets\UI\Icons\Icons_Units.xml 中保存了游戏自带的单位图标

标签 IconDefinitions 下定义了游戏内所有单位的图标

<Row Name="ICON_UNIT_INFANTRY"                 Atlas="ICON_ATLAS_UNITS" Index="71"/>

步兵的图标序号是 71, 代表其图标为游戏自带画册 ICON_ATLAS_UNITS 的 71 号

在文件 Sid Meier’s Civilization VI\Base\Assets\UI\Icons\Icons_UnitPortraits.xml 中保存了游戏自带的单位头像

标签 IconDefinitions 下定义了游戏内所有单位的头像

<Row Name="ICON_UNIT_INFANTRY_PORTRAIT"                     Atlas="ICON_ATLAS_UNIT_PORTRAITS_2" Index="5"/>

对于不同地域的同一个单位, 单位头像是不一样的

对应的编写 UNIT_ProfessionalArmy_Icons.xml 文件

<?xml version="1.0" encoding="utf-8"?>
<GameData>
<!-- For simplicity sake, we're going to reuse existing icons. -->
<IconDefinitions>
<!-- This is the unit icon for the unit. -->
<Row Name="ICON_UNIT_PROFESSIONAL_ARMY" Atlas="ICON_ATLAS_UNITS" Index="71"/>

<!-- This is the portrait of the unit. -->
<Row Name="ICON_UNIT_PROFESSIONAL_ARMY_PORTRAIT" Atlas="ICON_ATLAS_UNIT_PORTRAITS_2" Index="5"/>

<!-- Ethnic specific portrait of the unit. This changes based on the leader. -->
<Row Name="ICON_ETHNICITY_ASIAN_UNIT_PROFESSIONAL_ARMY_PORTRAIT" Atlas="ICON_ATLAS_ASIAN_UNIT_PORTRAITS" Index="1"/>
<Row Name="ICON_ETHNICITY_MEDIT_UNIT_PROFESSIONAL_ARMY_PORTRAIT" Atlas="ICON_ATLAS_MEDITERRANEAN_UNIT_PORTRAITS" Index="1"/>
<Row Name="ICON_ETHNICITY_SOUTHAM_UNIT_PROFESSIONAL_ARMY_PORTRAIT" Atlas="ICON_ATLAS_SOUTH_AMERICAN_UNIT_PORTRAITS" Index="1"/>
<Row Name="ICON_ETHNICITY_AFRICAN_UNIT_PROFESSIONAL_ARMY_PORTRAIT" Atlas="ICON_ATLAS_AFRICAN_UNIT_PORTRAITS" Index="1"/>
</IconDefinitions>
</GameData>

单位模型设置

在文件 Sid Meier’s Civilization VI\Base\ArtDefs\Units.artdef 中定义了游戏内的单位模型

搜索 UNIT_INFANTRY, 将其所在的 Element 标签赋值到 Units.artdef 对应位置并替换 UNIT_INFANTRY 为 UNIT_PROFESSIONAL_ARMY 即可

image-56f1b4358939fc0e9.png

导出 mod

设置好 mod 信息, 由于是通过模板制作的 mod, FontEnd Actions 和 In-Game Actions 是编写好的, 如果有其他额外内容, 需要自行设置加载顺序

如果出现了类似以下的报错: Error 1 The “GeneratePantryPaths” task was not given a value for the required parameter “AssetsPath”. E:\steam\steamapps\common\Sid Meier’s Civilization VI SDK\ModBuddy\Extensions\Application\Civ6.targets 104 6 Unit_Dies

请参考专栏

按照上一篇笔记的方法导出 mod, 加载进游戏

由于模型设置的偷懒, 导致显示为了工人, 其实修改一下即可

image-7fc912c30628334f3.png

image-6c5b8727be6f9577b.png

Mod 的本质

由于官方提供了足够的接口, 编写文明 6 的 mod 相比来说更加容易上手

实际上, 文明 6 的 mod 本质上就是通过官方给的接口, 修改 sql 数据库, 间接达到修改游戏内容的目的

游戏在启动的时候会创建数据库, 通过游戏自带的 xml 文件给数据库中填预设好的数据 (如文明, 单位等等)

第三方 mod 在游戏启动后加载, 并在特定时候加载 xml 文件, 覆盖游戏数据库, 达到增加或修改游戏内容的目的

SQL 替代 XML

实际上许多简单的 mod 不需要大费周章的使用 ModBuddy 开发, 例如 “修改城市间距最小为 5” 这个需求, 就可以通过 sql 文件完成

update GlobalParameters set Value=5 where Name="CITY_MIN_RNGE";

如果使用 xml, 将会是如下写法

<?xml ... ?>
<GameInfo>
<GlobalParameters>
<Replace Name="CITY_MIN_RNGE" Value=5/>
</GlobalParameters>
</GameInfo>