BWIKI 全站将于 9 月 3 日(全天)进行维护,期间无法编辑任何页面或发布新的评论。
模组:Content Patcher 制作指南/修改数据
← 模组:目录
带有 "Action": "EditData"
的补丁可以编辑数据素材中的字段和条目。多个内容包可以编辑同一个素材。
基本概念
游戏中有许多类型的数据,Content Patcher 将其转化成一些常用概念。
只有理解了本页所述的概念,您才能理解其余部分,所以请不要跳过该部分!
数据素材
数据素材(Data Asset)包括从游戏中加载的时间地点,角色对话等数据。例如 Data/Objects
包括游戏内所有物品的数据。每种数据的格式都在模组:目录上有阐述。
以下是三种主要的数据素材:
类型 |
用法 |
---|---|
字典 |
字典(Dictionary)是包含许多键值对的列表。其中的键必须有唯一 ID。同一个字典中的键值对必须写在一对花括号 {
//格式是 "键": "值" (所有引号必须用英文的半角符号)
"504": "Sneakers/A little flimsy... but fashionable!/50/1/0/0/Sneakers",
"505": "Rubber Boots/Protection from the elements./50/0/1/1/Rubber Boots",
"506": "Leather Boots/The leather is very supple./50/1/1/2/Leather Boots"
}
|
列表 |
列表(List)是一组没有明确键的非唯一值。列表中的键值对必须写在一对方括号 [
{
"ID": 0,
"Name": "Cotton Candy",
"DisplayName": "Cotton Candy",
"Description": "A large pink cloud of spun sugar.",
"Price": 50,
"ItemTags": [ "Sweet", "Candy" ]
},
// 篇幅有限,其他数据省略
]
虽然列表没有键,但 Content Patcher 通常会指定一个字段作为唯一标识符(请参阅编辑列表)。 |
模型 |
模型(Model)是一种预定义的数据结构。对于内容包来说,它和字典相同,只是您不能添加新字段(只能编辑已有字段)。 |
条目和字段
条目(Entry)是目标数据中的顶层数据块(即字典中的键值对或列表中的值)
例如,Data/Objects
中,"MossSoup": { ...}
和 "PetLicense": { ... }
是两个独立的条目:
{
"MossSoup": {
"Name": "Moss Soup",
"Type": "Cooking",
"Category": -7,
"Price": 80,
"ContextTags": [ "color_green" ]
...
},
"PetLicense": {
"Name": "Pet License",
"Type": "Basic",
"Category": 0,
"Price": 0,
...
},
...
}
字段(Field)是条目中的一个子块。在前面的示例中: - "MossSoup": { ... }
是一个条目; - "Name": "Moss Soup"
是 "MossSoup": { ... }
这个条目中的一个字段。
使用目标字段改变目标条目
在上一部分中,我们说条目是“目标数据中的一个顶层数据块”。而目标字段可以让您改变目标数据的含义。
例如,假设我们将目标字段设置为上面的 ContextTags
字段。那么您会看到的数据是这样的:
[ "color_green" ]
这意味着ContextTags
中的每一个值都是一个条目,所以您可以添加/替换/删除上下文标记,而无需编辑对象数据的其他部分。
(目标字段章节会详细介绍这一点)
用法
概述
EditData
由 Changes
下的模型组成,其中包含(见下面的示例):
- 必填字段
-
您必须同时指定这两个字段:
字段 用途 Action
操作类型。此操作类型设置为 EditData
。Target
要编辑的目标游戏素材名称(或多个由逗号分隔的素材名),例如 Characters/Dialogue/Abigail
。该字段支持令牌,不区分大小写。至少有下列一项:
字段
用途
Fields
您要更改的现有条目的单个字段。该字段的键和值都支持令牌。每个字段的键是以
/
分隔的字符串索引(从 0 开始),或对象的字段名。Entries
您要添加/替换/删除的用 ID 索引的数据文件中的条目。如果您只想改某些字段,使用
Fields
以获取与其他模组最佳的兼容性。要添加条目,只需要指定一个不存在的键;要删除条目,可以把它的值设为null
(例如"some key": null
)。该字段的键和值都支持令牌。对于列表的值,查看下面的
MoveEntries
。MoveEntries
(只支持列表素材)更改列表素材(如
Data/MoviesReactions
)中的条目顺序。(在非列表素材中使用会出错,因为那些素材没有顺序)请参阅移动列表条目。
TextOperations
更改现有字符串条目或字段的值;请参阅文本操作。
要更改条目,请使用格式
["Entries", "条目对应的值"]
并将"条目对应的值"
替换为上文您想指定的Entries
。如果该条目不存在,它会自动新建。文本操作会把它当做一个空字符串生效。要更改字段,请使用格式
["Fields", "条目对应的值", "字段对应的值"]
并用上文您想为Fields
指定的键替换"条目对应的值"
和"字段对应的值"
。如果条目不存在,这个文本操作会报错;如果该字段不存在,在条目是一个对象时它会自动新建,条目是一个分隔字符串时会报错。目前只能针对顶层字段。 - 可选条目:
-
条目 用途 TargetField
(可选)以列表或字典为目标时,值中的字段会被设为根作用域;请参阅目标字段。该字段支持令牌。 When
(可选)仅在给定的条件匹配时应用这个内容补丁。 LogName
(可选)在日志中显示的补丁名称。这有助于查找错误。如果省略,则默认为类似 EditData Data/Achievements
的名称。Update
(可选)补丁字段的更新频率。请参阅补丁更新频率。 LocalTokens
(可选)一组仅在此补丁中生效的局部令牌。 - 高级字段:
-
字段 用途 Priority
(可选)当多个补丁编辑同一数据素材时,此字段控制它们应用的顺序。可用的值有 Early
(更早),Default
(默认),还有Late
(更晚)。默认值为Default
。补丁(包括所有模组)按以下顺序生效:
- 优先级从早到晚;
- 按照模组加载顺序(基于依赖关系等因素);
- 按照补丁在
content.json
中列出的顺序。
如果需要更具体的顺序,可以使用简单的偏移量,如
"Default + 2"
或者"Late - 10"
。默认值为 -1000(Early
),0(Default
)和 1000(Late
)。此字段不支持令牌,不区分大小写。
警告优先级会让您的更改难以排除故障。推荐做法:
- 如果可以的话,只使用上述无偏移的优先级(例如外观覆盖设为
Late
) - 不需要为您自己的补丁设置优先级,因为您可以自己在 content.json 排列好补丁应用的顺序。
TargetLocale
(可选)素材名称中要匹配的地区代码,例如设置 "TargetLocale": "fr-FR"
将会只编辑法语的素材(例如Data/Achievements.fr-FR
)。可以为空,若为空则将只编辑没有地区代码的基本素材。如果省略,则将应用于所有素材,不论其是否存在本地化。
编辑字典
字典最简单的编辑方法是创建或覆盖一个条目。例如,以下操作会将一个 ID 为 {{ModId}}_Pufferchick
的物品添加到 Data/Objects
中:
{
"Format": "2.7.0",
"Changes": [
{
"Action": "EditData",
"Target": "Data/Objects",
"Entries": {
"{{ModId}}_Pufferchick": {
"Name": "{{ModId}}_Pufferchick",
"DisplayName": "Pufferchick",
"Description": "An example object.",
"Type": "Seeds",
"Category": -74,
"Price": 1200,
"Texture": "Mods/{{ModId}}/Objects"
}
},
}
]
}
您还可以编辑条目中的字段。当条目是字符串时,该值会被假定为一个以 /
分隔的字段列表(每个字段从零开始编号),否则字段是给定条目中的直接条目。
例如,这将编辑一个条目的描述字段:
{
"Format": "2.7.0",
"Changes": [
{
"Action": "EditData",
"Target": "Data/Objects",
"Fields": {
"MossSoup": { //ID为"MossSoup"的条目
"Description": "Maybe a pufferchick would like this."
}
}
},
]
}
您可以通过把字段设为 null
的方式删除某个条目。例如,下列事件删除了一个事件,同时使用新的条件重新创建它:
{
"Format": "2.7.0",
"Changes": [
{
"Action": "EditData",
"Target": "Data/Events/Beach",
"Entries": {
"733330/f Sam 750/w sunny/t 700 1500/z winter/y 1": null,
"733330/f Sam 750/w sunny/t 700 1500/z winter": "事件脚本"
}
}
]
}
当一个值存在嵌套的条目时,您可以用目标字段来编辑特定的那一个。
编辑列表
您可以用同样的方法编辑列表。
在游戏原版的数据素材中,列表没有键,但在 Content Patcher 中,他们仍有一个“键”来实现 Entries
和 MoveEntries
。也就是说,编辑列表和编辑字典差不多。
对于模型列表({ ... }
块),键是每个模型的 Id
字段。例如,Data\LocationContexts
就展示了 ID 为 spring1
的 Music
条目:
{
"Default": {
"SeasonOverride": null,
"DefaultMusic": null,
"DefaultMusicCondition": null,
"DefaultMusicDelayOneScreen": true,
"Music": [
{
"Id": "spring1",
"Track": "spring1",
"Condition": "SEASON Spring"
}
...
]
}
}
为了在内容包中编辑该音乐条目,您必须使用它的 ID:
{
"Format": "2.7.0",
"Changes": [
{
"Action": "EditData",
"Target": "Data/LocationContexts",
"TargetField": [ "Default", "Music" ],
"Entries": {
"spring1": {
"Id": "spring1",
"Track": "spring1",
"Condition": "SEASON Spring, YEAR 2"
}
}
}
]
}
编辑简单字符串列表的方法和上述完全相同,只是字符串本身就是键。请参阅编辑对象上下文标签示例。
移动列表条目
列表的顺序通常非常重要(例如,游戏会使用 Data\MoviesReactions
的第一个条件适合的条目来匹配 NPC 反应。)您可以用 MoveEntries
字段来更改顺序。例如,此示例逐一使用 MoveEntries
操作来移动 Abigail
条目:
{
"Format": "2.7.0",
"Changes": [
{
"Action": "EditData",
"Target": "Data/MoviesReactions",
"MoveEntries": [
{ "ID": "Abigail", "BeforeID": "Leah" }, //移动字段让阿比盖尔在莉亚前面
{ "ID": "Abigail", "AfterID": "Leah" }, //移动字段让阿比盖尔在莉亚后面
{ "ID": "Abigail", "ToPosition": "Top" }, //移动字段让它位于最顶层
{ "ID": "Abigail", "ToPosition": "Bottom" }, //移动字段让它位于最底层
]
},
]
}
新条目默认增加到列表底部。
编辑模型
模型是一种预定义的数据结构。对于内容包来说,除了不能添加新条目(只能编辑已有条目)以外,它与字典相同。
组合操作
您可以在同一个补丁中执行任意数量的操作。例如,您可以添加一个新条目,然后同时将其移动到正确的顺序。它们将按照 Entries
、Fields
、MoveEntries
、TextOperations
的顺序被应用。
目标字段
更改通常适用于顶层条目,但 TargetField
让您可以选择一个子字块编辑。这会影响所有编辑补丁(例如 Fields
、Entries
、TextOperations
等)。
格式
TargetField
是一个字段名称列表,用于“深入”到数据中(见以下示例)。列表中的每个值都在前一个值的范围内,可以是其中之一:
类型 | 作用 |
---|---|
ID | 数据内的字典键或者列表键(例如:下面示例中的 "Goby" )。
|
字段名 | 数据模型中的字段名。 |
列表值 | 简单字符串或数值列表的目标值。 |
列表索引 | 值在列表中的位置(如 #0 表示第一个值)。前缀必须是 # ,否则会被视为 ID。这种用法很容易出错,因为它取决于列表的顺序,尽可能使用 ID 或者字段名代替。
|
示例
编辑对象上下文标签示例
Data/Objects
中有以下条目:
"Goby": {
"Name": "Goby",
"Type": "Fish",
"ContextTags": [ "color_brown", "fish_river", "season_fall", "season_spring", "season_summer" ]
...
},
如果我们要更改上下文标签,而非重新定义整个条目,或者丢失其他模组的更改,可以使用 "TargetField": [ "Goby", "ContextTags" ]
。
新补丁生效后内容如下:
[ "color_brown", "fish_river", "season_fall", "season_spring", "season_summer" ]
然后我们即可像数据素材一样在列表中添加/替换/删除条目。
{
"Format": "2.7.0",
"Changes": [
{
"Action": "EditData",
"Target": "Data/Objects",
"TargetField": [ "Goby", "ContextTags" ],
"Entries": {
"season_winter": "season_winter", //添加值
"season_spring": null, //删除值
"color_brown": "color_green" //替换值
}
},
]
}
编辑深嵌套字段
上面的示例编辑了模型顶部的字段,但我们可以深入到任意深度的字段。
例如,考虑 Data/Objects
中的条目:
"791": {
"Name": "Golden Coconut",
"GeodeDrops": [
{
"Id": "Default",
"RandomItemId": [ "(O)69", "(O)835", "(O)833", "(O)831", "(O)820", "(O)292", "(O)386" ],
"StackModifiers": [
{
"Id": "PineappleSeeds",
"Condition": "ITEM_ID Target (O)833",
"Modification": "Set",
"Amount": 5
},
...
],
...
}
]
}
假设我们想把菠萝种子的数量从 5 个改为 20 个,那么我们得先厘清该条目的层次结构:
- 条目:
791
- 字段:
GeodeDrops
- 含 ID 的列表值:
Default
- 字段:
StackModifiers
- 含 ID 的列表值:
PineappleSeeds
- 字段:
Amount
- 字段:
- 含 ID 的列表值:
- 字段:
- 含 ID 的列表值:
- 字段:
我们只需要“深入”这个层次结构,编辑我们需要的字段:
{
"Format": "2.7.0",
"Changes": [
{
"Action": "EditData",
"Target": "Data/Objects",
"TargetField": [ "791", "GeodeDrops", "Default", "StackModifiers", "PineappleSeeds" ],
"Entries": {
"Amount": 20
}
}
]
}