BWIKI 全站将于 9 月 3 日(全天)进行维护,期间无法编辑任何页面或发布新的评论。
模组:NPC数据
← 目录
此页面概述了创建自定义NPC的方法。这是面向模组开发者的高级指南。
在阅读本页前,请参阅模组:编辑 XNB 文件以了解基础概念。
需编辑的文件
若想创建新的NPC,则需要编辑一些文件。然而,这并不需要编程经验,而可以使用Content Patcher来完成。
主要数据
Data/Characters素材文件包含了关于NPC的大部分布局,包括其名字、社交信息(例如人格、生日、可否恋爱)、外貌、配偶房屋和露台、节日行为等。
此素材文件为一个“字符串 → 数据模型”查询,其中:
- 键是NPC的唯一字符串ID,例如Example.ModId_NpcName,会被用作内部Name(而非DisplayName)。
- 值是包含如下字段的数据模型:
基本信息
字段 | 效果 |
---|---|
DisplayName | 此NPC在游戏中显示的姓名。可用模板字符串。 |
Language | (可选) 此NPC使用的语言。可以取此两者之一:Default(玩家能够理解的默认语言)或 Dwarvish(矮人语,只有玩家找到矮人语教程才能理解)。默认为Default。 |
Gender | (可选) 此NPC的性别特征。可用的取值为 Female、Male 或 Undefined 之一。默认为Undefined。 |
Age | (可选) 此NPC的年龄段。可用的取值为Child、Teen 或 Adult。默认为Adult。
此字段会影响对话台词的生成(例如,孩子可能会说"stupid",而成人则会说"depressing")、一般对话(例如,孩子可能会对翻垃圾桶的人说 "Eww... What are you doing?" 而青年则会说 "Um... Why are you digging in the trash?")、冬日星盛宴的礼物选择。孩子也不会发起“送货”任务。 |
Manner | (可选) 用于衡量此NPC是否有礼貌,这会影响某些对话台词。可用的取值为Neutral、Polite 或 Rude。默认为Neutral。 |
SocialAnxiety | (可选) 用于衡量NPC内向外向程度,这会影响某些通用的对话台词。可用的取值为Neutral、Outgoing 或 Shy。默认为Neutral. |
Optimism | (可选) 用于衡量NPC的乐观程度。可用的取值为Neutral、Negative 或 Positive。默认为Neutral。 |
BirthSeason | (若不可社交,则可选) NPC的生日所在季节(大小写敏感)。可用的取值为:spring、summer、fall、winter。默认为none。 |
BirthDay | (若不可社交,则可选) NPC的生日在当季哪天。默认为0。 |
HomeRegion | (可选) NPC所生活的世界区域(取值为Desert、Town 或 Other)。例如,只有生活区域为 Town(镇上)的NPC会被计入“介绍”任务。同样地,冬日星盛宴的神秘朋友只可能为镇上的NPC,夏威夷宴会的友谊加成也仅对镇上的NPC有效。默认为Other。 |
IsDarkSkinned | (可选) 此NPC是否为深色皮肤,这会影响孩子为深色皮肤的概率。默认为false。 |
社交功能
字段 | 效果 | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
CanSocialize | (可选) 指示是否开启社交功能的游戏状态查询(例如生日、送礼、友谊、“社交”选项卡)。默认为true。 | ||||||||||
CanBeRomanced | (可选) 此NPC是否可以约会和求婚。这会开启此NPC的婚恋功能(例如社交选项卡中的“单身”字样、可赠予花束、可结婚)。默认为false。 | ||||||||||
CanReceiveGifts | (可选) 玩家是否可以给此NPC送礼。默认为true。
若希望给此NPC送礼,还需同时开启CanSocialize字段,并在Data/NPCGiftTastes设置相应的条目。仅开启此字段是不够的。 | ||||||||||
CanCommentOnPurchasedShopItems | (可选) 当商店把玩家售出的商品售卖给此NPC时,此NPC是否会对齐有所评论。若为空(或被忽略),且此NPC的HomeRegion字段为Town,则此字段默认为true。
若希望开启此功能,还需同时开启CanSocialize字段。仅开启此字段是不够的。 | ||||||||||
CanGreetNearbyCharacters | (可选) 此NPC是否可以在接近玩家、接近其他NPC或被其他NPC问候时显示对话气泡。默认为true。 | ||||||||||
CanVisitIsland | (可选) 一个模组:游戏状态查询,用于指示此NPC是否可以造访姜岛度假村(若已解锁)。默认为true。
若希望开启此功能,还需同时开启CanSocialize字段。仅开启此字段是不够的。 | ||||||||||
LoveInterest | (可选) 无用。 | ||||||||||
Calendar | (可选) 此NPC的生日是否显示在日历上。可用的取值为:
默认为AlwaysShown。 | ||||||||||
SocialTab | (可选) 决定此NPC(若已解锁)出现在社交选项卡上的方式。可用的取值未:
默认为UnknownUntilMet。 | ||||||||||
SpouseAdopts | (可选) 一个游戏状态查询,用于指示玩家是否需要领养孩子,而不是和配偶生孩子。若为空且玩家和此NPC同性,则默认为true;若为空且玩家和此NPC性别相反,则默认为false。
其中Target玩家(参见模组:游戏状态查询#目标玩家)指代与此NPC结婚的玩家。 | ||||||||||
SpouseWantsChildren | (可选) 一个游戏状态查询,用于指示此NPC是否会询问玩家要孩子。默认为true。
其中Target玩家(参见模组:游戏状态查询#目标玩家)指代与此NPC结婚的玩家。 | ||||||||||
SpouseGiftJealousy | (可选) 一个游戏状态查询,用于指示此NPC是否会嫉妒玩家给其他NPC送礼。默认为true。
其中Target玩家(参见模组:游戏状态查询#目标玩家)指代与此NPC结婚的玩家,Target物品指代玩家送出的物品(参见模组:游戏状态查询#仅用于物品)。 | ||||||||||
SpouseGiftJealousyFriendshipChange | (可选) 触发SpouseGiftJealously后,对友谊点数的影响,默认为-30。 | ||||||||||
SpouseRoom | (可选) 用于设置农舍中的配偶房间(若可用)。若此NPC可结婚且省略此字段,则默认使用阿比盖尔的配偶房间。
此字段为包含如下字段的数据模型:
欲配置配偶在其房间中站立的位置,可以在Paths层放置红色的圆形道路地块(地块索引7)。 | ||||||||||
SpousePatio | (可选) 农场的NPC的室外活动区(若有)。默认为none。
此字段为包含如下字段的数据模型:
| ||||||||||
SpouseFloors SpouseWallpapers |
(可选) NPC和玩家结婚后,NPC可能随机使用的地板和强制。若省略,则NPC会随机选取一个地板(0-39)或墙纸(0-111)。 | ||||||||||
IntroductionsQuest | (可选) 是否将此NPC加入 介绍 任务中。若为null或被忽略,且该NPC为小镇居民(HomeRegion字段为Town),则此字段默认为true。 | ||||||||||
ItemDeliveryQuests | (可选) 一个游戏状态查询,指示此NPC是否能够给出“送货”任务。若为 null(或被忽略),且该NPC为小镇居民(HomeRegion字段为Town),则此字段默认为true。
若要启用此字段,该NPC必须可社交(CanSocialize字段为true)。 | ||||||||||
PerfectionScore | (可选) 在完美度的“与所有人达成最高友谊”中是否将此NPC计算在内。默认为true。
若要启用此字段,该NPC必须可社交(CanSocialize字段为true)。 | ||||||||||
EndSlideShow | (可选) 此NPC以何种方式出现在“完美”过场动画中。可用的取值为:
默认为MainGroup。 | ||||||||||
FriendsAndFamily | (可选) 此NPC的密友和亲人,为一个字典,其键为相应NPC的内部名称,其值为用于对话的相应称呼(例如 'mom'),此称呼可以为模板字符串,也可省略。默认为none。
此字段会影响NPC表达对家庭成员喜欢/不喜欢的通用对话,且可能影响inlaw_<NPC>对话。此字段无需太过详尽。 |
翻垃圾桶
字段 | 效果 |
---|---|
DumpsterDiveEmote | (可选) 此NPC看见玩家翻垃圾桶时,头上出现的表情对应的ID。参见表情ID。若忽略,或为null,则会根据NPC的年龄生成默认值:孩子会显示悲伤(28),青少年会显示疑惑(8),成年人会显示愤怒(12)。 |
DumpsterDiveFriendshipEffect | (可选) 此NPC看见玩家翻垃圾桶时的好感度变化。默认为-25。 |
节日
字段 | 效果 | ||||
---|---|---|---|---|---|
FlowerDanceCanDance | (可选) 玩家是否可以邀请此NPC为花舞节舞伴。可用的取值为true(总是可以)、false(总不可以)、null(仅当该NPC可恋爱时可以) 。默认为null。
若该NPC可以跳舞,则应当指定跳舞贴图以及FlowerDance_Decline对话文本。您也可以设置FlowerDance_Accept对话,但这不是必需的(若省略,则会生成默认的“我接受”对话)。 | ||||
WinterStarParticipant | (可选) 一个游戏状态查询,指示此NPC是否可以在冬日星盛宴上送出或接受礼物。若为null(或忽略),且该NPC为小镇居民(HomeRegion为Town),则默认为true。 | ||||
WinterStarGifts | 在冬日星盛宴上,此NPC可能送给玩家的礼物。
此字段为包含如下字段的数据模型所组成的列表。会随机选取任何一个匹配的列表项。
|
生成规则
字段 | 效果 | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
UnlockConditions | (可选) 一个游戏状态查询,指示此NPC是否应当被添加进世界。相应的检查会在加载存档或每天结束时触发。仅用于当NPC丢失时加回此NPC。若返回false,也不会移除已经添加的NPC。默认为true。 | ||||||||||||
SpawnIfMissing | (可选) 当NPC丢失时,是否添加此NPC(若UnlockConditions中的游戏状态查询通过,且HomeLocation字段可用)。默认为true。 | ||||||||||||
Home | (可选) 此NPC每天生成和返回的默认地点。
此字段为包含如下字段的数据模型所组成的列表。若该列表有多项,则会使用第一个匹配的项。
|
外观和贴图
字段 | 效果 | ||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
TextureName | (可选) 此NPC的肖像和全身贴图的素材名称,但只要最后一段。例如,此字段设为Abigail,代表自动使用Portraits/Abigail(肖像)和Characters/Abigail(全身)。默认为内部NPC名称。 | ||||||||||||||||||
Appearance | (可选) 待使用的肖像/全身贴图。
可以列出任意数量的外观选项,其会按照Precedence数值依次排序(较低的数值优先级较高),然后会筛选匹配的那些选项。若能匹配多个选项,则会根据其Precedence的相对权重随机选取一个。此随机数的结果在同一天内保持不变,因此在下一天到来之前,此NPC都将作出相同的选择。若无法加载某个肖像/全身贴图(或没有匹配的列表项),则会基于TextureName使用默认素材。 每当NPC切换地点,会重新检查此字段。 此字段为包含如下字段的数据模型所组成的列表:
注意: 即使您使用此字段,也必须指定TextureName的默认贴图集。 | ||||||||||||||||||
MugShotSourceRect | (可选) 此NPC全身贴图集中的16x24像素区域,用于在日历、社交菜单和其他场景中设置此NPC的头像图标。默认为此NPC第一个全身贴图的一部分。 | ||||||||||||||||||
Size | (可选) 此NPC单张全身贴图在贴图集中的像素尺寸。为包含X和Y字段的数据模型。默认为(16, 32)。
注意: 若尺寸大于16x32,则会引发一些问题,例如生成出错、寻路出错、完美过场动画中无法对齐等。 | ||||||||||||||||||
Breather | (可选) 当此NPC呼吸时,其全身贴图是否会起伏。默认为true。 | ||||||||||||||||||
BreathChestRect | (可选) 贴图集中的一个矩形像素区域,该区域会被反复缩放以模拟呼吸。该矩形以所在单张贴图的左上角为基准。若忽略,则会自动计算。对于多数NPC,应当忽略此字段,除非此NPC尺寸非标准。 | ||||||||||||||||||
BreathChestPosition | (可选) 绘制呼吸起伏时,施加的点像素偏移。若忽略,则会自动计算。对于多数NPC,应当忽略此字段,除非此NPC尺寸非标准。 | ||||||||||||||||||
Shadow | (可选) 此选项用于绘制NPC下方的阴影,若忽略,则使用默认的阴影。
此字段为包含如下字段的数据模型:
| ||||||||||||||||||
EmoteOffset | (可选) 对NPC的表情气泡施加的点像素偏移。默认为0。 | ||||||||||||||||||
ShakePortraits | (可选) 肖像贴图索引组成的列表,该列表中的肖像贴图在显示时会颤动一下。默认为none。 | ||||||||||||||||||
KissSpriteIndex | (可选) 可婚NPC亲吻玩家的贴图在Texture中的索引。默认为28。 | ||||||||||||||||||
KissSpriteFacingDirection | (可选) 此NPC在其KissSpriteIndex中是面向左(true)还是右(false)。此贴图会据此自动翻转以面向玩家。默认为true。 |
礼物日志特殊动画
字段 | 效果 |
---|---|
HiddenProfileEmoteSound | (可选) 用于礼物日志的隐藏动画。此字段给出了点击贴图时播放的声音提示ID。默认为drumkit6。 |
HiddenProfileEmoteDuration | (可选) 用于礼物日志的隐藏动画。此字段给出了动画播放的时长,单位为毫秒。默认为4000(4秒)。 |
HiddenProfileEmoteStartFrame | (可选) 用于礼物日志的隐藏动画。此字段给出了隐藏动画第一帧在此NPC全身贴图表中的索引。若省略,且为原版NPC,则会播放此NPC的默认动画;若为自定义NPC,则播放其面部朝向为下的走路动画。 |
HiddenProfileEmoteFrameCount | (可选) 用于礼物日志的隐藏动画。此字段给出了隐藏动画的总帧数。其中第一帧由HiddenProfileEmoteStartFrame给出,随后每一帧都是前一帧后面的贴图。默认为 1 。
若未设置HiddenProfileEmoteStartFrame,则此字段无效。 |
HiddenProfileEmoteFrameDuration | (可选) 用于礼物日志的隐藏动画。每一帧的持续时长,单位为毫秒。默认为200。
若未设置HiddenProfileEmoteStartFrame,则此字段无效。 |
高级
字段 | 效果 |
---|---|
CustomFields | 此项目的自定义字段。 |
FormerCharacterNames | (可选) 可能出现在存档文件中的NPC曾用名。若匹配成功,则游戏会进行重命名,并升级对应的数据(例如友谊)。
只有一个名称满足如下条件时才会被视为曾用名:
例如: "FormerCharacterNames": [ "SomeOldName" ]
曾用名可以具有任何格式,但必须全局唯一。不能和Data/Characters中其他NPC的ID或FormerCharacterNames字段发生冲突,无论他们是原版还是自定义NPC。 |
FestivalVanillaActorIndex | (可选,专用) 此NPC在Maps/characterSheet地块表中的索引,若可用。在原版游戏中,这用于将NPC放置在节日地图上;自定义NPC不应使用此字段,而应使用节日数据中的<layer>_additionalCharacters字段。 |
礼物喜好
- 主要礼物数据
- Data/NPCGiftTastes素材包含了NPC的礼物喜好(例如,最爱什么、讨厌什么),以及NPC收到礼物时的反应。参见模组:礼物喜好数据以获取更多信息。
- 上述素材文件每行对应一个NPC,例如:
Abigail: "I seriously love this! You're the best, @!/66 128 220 226 276 611/Hey, how'd you know I was hungry? This looks delicious!//What am I supposed to do with this?/-5 -75 -79 16 245 246/What were you thinking? This is awful!/330/You brought me a present? Thanks.//"
- 上述例子可以分解为5个“对话+物品ID”对,分别对应于最爱、喜欢、不喜欢、讨厌和一般。若对话字段为空,则游戏会使用通用的对话文本。参见模组:物品数据以获取物品ID。
- 礼物对话
- 当您送礼给某个NPC时,其会按如下顺序选择对话:
- 在生日当天,使用AcceptBirthdayGift对应的对话,否则使用默认对话,例如NPC.cs.4274 ("You remembered my birthday? I'm impressed. Thanks.$h");
- AcceptGift_*对话;
- Data/NPCGiftTastes中的对话,且为默认肖像(可以被$h等肖像指令覆盖)。
全身贴图
NPC的全身贴图(Overworld Sprite)储存在Characters/NpcName中,包含NPC的移动和动画帧。每个帧都必须为16x32像素。感谢Discord用户TheLimeyDragon#1993,其为我们提供了一个示例贴图指南。贴图集中的某些特定位置是专门用于特定动作的:
- 前16个帧是处理NPC的正常移动的(往4个方向移动,每个方向4帧);
- 女性角色的第40-47帧、男性角色的44-47帧必须为花舞节动画(若参加跳舞);
- 可婚女性角色的36-38帧、可婚男性角色的48-50帧有特殊用途(包含婚礼贴图);
- 亲吻时的贴图/面部朝向视具体NPC而定:
角色 亲吻帧 面部朝向 阿比盖尔和艾米丽 33 左 亚历克斯 42 右 艾利欧特 35 左 海莉 28 右 哈维 31 左 莉亚 25 右 玛鲁 28 左 潘妮 35 右 山姆 36 右 塞巴斯蒂安 40 左 谢恩 34 左 任何其他NPC 28 右
肖像
对话肖像存储在Portraits/NpcName。每张贴图都应为64x64像素。开头的6张代表专用的表情(参见模组:对话#肖像指令),在这6张之后可以添加任意多的自定义肖像。第一张肖像是对话的默认肖像。
日程
日程文件指定了NPC在不同时间的行程。为允许自定义对话,您应当向Strings文件夹中的独立的日程文件添加字符串。参见模组:行程数据以获得更多信息。
对话
NPC对话和事件数据存储在几个不同文件中,参见模组:对话。
睡眠动画
当NPC睡觉时,会循环播放Data/animationDescriptions中<lowercase NPC name>
_sleep指定的睡眠动画(若存在)。例如,如下的内容包添加了名为"Pufferbob"的NPC的睡眠动画:
{
"Format": "2.7.0",
"Changes": [
{
"Action": "EditData",
"Target": "Data/animationDescriptions",
"Entries": {
"pufferbob_sleep": "50/50/50" // note: make name lowercase
}
}
]
}
次要素材
- 参见模组:事件数据以了解NPC的过场动画。
- 参见模组:节日数据以了解节日中NPC的位置(由Set-Up_additionalCharacters和MainEvent_additionalCharacters字段指定)和对话。
- 参见模组:电影院数据以了解NPC的电影和影院零食喜好。
示例
完整实现
如下代码展示了如何创建一个名为Dobson的NPC,包括全部社交功能:
注意{{ModId}}
是Content Patcher中的关键字,会按照唯一字符串ID惯例被自动替换为您的模组ID。
- 创建一个空的Content Patcher内容包。按照惯例,我们需要将此文件夹命名为[CP] Dobson。
- 创建如下文件
- assets/dialogue.json为日常对话文件。
- assets/marriageDialogue.json为结婚对话文件(若可用)。
- assets/sprites.png为全身贴图文件。
- assets/portraits.png为肖像贴图文件。
- assets/schedule.json为日程文件。
- 编辑content.json以载入上述文件:
{ "Format": "2.7.0", "Changes": [ { "Action": "Load", "Target": "Characters/{{ModId}}_Dobson", "FromFile": "assets/sprites.png" }, { "Action": "Load", "Target": "Portraits/{{ModId}}_Dobson", "FromFile": "assets/portraits.png" }, { "Action": "Load", "Target": "Characters/Dialogue/{{ModId}}_Dobson", "FromFile": "assets/dialogue.json" }, { "Action": "Load", "Target": "Characters/Dialogue/MarriageDialogue{{ModId}}_Dobson", "FromFile": "assets/marriageDialogue.json" }, { "Action": "Load", "Target": "Characters/schedules/{{ModId}}_Dobson", "FromFile": "assets/schedule.json" }, { "Action": "EditData", "Target": "Data/Characters", "Entries": { "{{ModId}}_Dobson": { "DisplayName": "Dobson", // this can use {{i18n:}} to support translations "BirthSeason": "Summer", "BirthDay": 7, "HomeRegion": "Town", "Gender": "Male", "Age": "Adult", "Manner": "Rude", "SocialAnxiety": "Neutral", "Optimism": "Positive", "CanBeRomanced": true, "Home": [ { "Id": "Default", "Location": "BusStop", "Tile": { "X": 4, "Y": 5 } } ] } } }, { "Action": "EditData", "Target": "Data/NPCGiftTastes", "Entries": { "{{ModId}}_Dobson": "You're giving this to me? This is amazing!/207 232 233 400/Thank you! This is a very interesting specimen./-5 -79 422/...What is this?/80 330/This is disgusting./2/That was very thoughtful of you./-4/ " } }, { "Action": "EditData", "Target": "Data/EngagementDialogue", "Entries": { "{{ModId}}_Dobson0": "I can't believe I am about to be married!$h", "{{ModId}}_Dobson1": "I hope I don't get cold feet" } } ] }
做好了!若您加载了您的游戏,则此NPC会出现。若希望添加此NPC的事件,请添加相应的事件文件。
动态外观
Data/Characters中的Appearance字段允许NPC具有任意数量的自定义肖像贴图和全身贴图(以及任意的使用条件),而不会产生重载NPC贴图的性能开销。
例如,下述代码添加了前文提及的Dobson的室内/室外贴图:
// add base indoor/outdoor sprites
{
"Action": "Load",
"Target": "
Characters/{{ModId}}_Dobson_Indoor,
Characters/{{ModId}}_Dobson_Outdoor,
Portraits/{{ModId}}_Dobson_Indoor,
Portraits/{{ModId}}_Dobson_Outdoor
",
"FromFile": "assets/{{Target}}.png"
},
// apply any overlays needed
{
"Action": "EditImage",
"Target": "Characters/{{ModId}}_Dobson_Indoor, Portraits/{{ModId}}_Dobson_Indoor",
"FromFile": "assets/overlays/{{Target}}_married.png",
"When": {
"Spouse": "Dobson"
}
},
// add appearance to NPC
{
"Action": "EditData",
"Target": "Data/Characters",
"Entries": {
"{{ModId}}_Dobson": {
...,
"Appearance": [
{
"Id": "Outdoors",
"Indoors": false,
"Portrait": "Portraits/{{ModId}}_Dobson_Outdoor",
"Sprite": "Characters/{{ModId}}_Dobson_Outdoor"
},
{
"Id": "Default",
"Portrait": "Portraits/{{ModId}}_Dobson_Indoor",
"Sprite": "Characters/{{ModId}}_Dobson_Indoor"
}
]
}
}
}
另请参阅
- 请查看模组:目录#另请参阅以了解像素艺术指南。