Difference between revisions of "Modding:NPC data"

From Stardew Valley Wiki
Jump to navigation Jump to search
(→‎Portraits: remove broken hotlinked image (images should be uploaded to the wiki with an open license instead))
 
(27 intermediate revisions by 7 users not shown)
Line 1: Line 1:
← [[Modding: Index | Index]]
+
← [[Modding:Index|Index]]
  
Esta página proporciona una descripción general de lo que se necesita para crear un NPC personalizado. Esta es una guía avanzada para desarrolladores de mods.
+
This page provides an overview of what's needed to create a custom NPC. This is an advanced guide for mod developers.
  
'' 'Antes de leer esta página' '', consulte [[Modding: Editando archivos XNB]] para conocer los conceptos básicos.
+
'''Before reading this page''', see [[Modding:Editing XNB files]] for the basic concepts.
  
== Archivos para editar ==
+
==Files to edit==
Para crear un nuevo NPC, debe editar varios archivos diferentes. Sin embargo, no necesita ninguna experiencia en programación y se puede hacer con {{nexus mod | 1915 | Content Patcher}}.
+
To create a new NPC, you need to edit a number of different files. However, you don't need any programming experience and it can be done with [[Modding:Content Patcher|Content Patcher]].
  
=== Información básica ===
+
===Basic info===
El activo <tt> Data \ NPCDispositions </tt> contiene información básica de tu personaje, incluido su nombre, fecha de nacimiento, relaciones con otros personajes, personalidad y si pueden tener una fecha.
+
The <samp>Data\NPCDispositions</samp> asset contains basic information for your character, including their name, birthday, relations to other characters, personality, and whether they can be dated.
  
El archivo tiene una fila por NPC como esta:
+
The file has one row per NPC like this:
<syntaxhighlight lang = "yaml">
+
<syntaxhighlight lang="yaml">
   Abigail: "adolescente / grosera / extrovertida / neutral / femenina / datable / Sebastian / Town / otoño 13 / Caroline 'mamá' Pierre 'papá' / SeedShop 19 / Abigail"
+
   Abigail: "teen/rude/outgoing/neutral/female/datable/Sebastian/Town/fall 13/Caroline 'mom' Pierre 'dad'/SeedShop 1 9/Abigail"
 
</syntaxhighlight>
 
</syntaxhighlight>
  
La clave (antes de los dos puntos) es el nombre interno que identifica de forma única a ese NPC. Este nombre no se muestra al jugador, pero se usará cuando se haga referencia al NPC en otros archivos. El valor contiene los siguientes campos:
+
The key (before the colon) is the internal name which uniquely identifies that NPC. This name isn't shown to the player, but will be used when referencing the NPC in other files. The value contains the following fields:
  
{| class = "wikitable"
+
{| class="wikitable"
| -
+
|-
! índice
+
! index
! campo
+
! field
! ejemplo
+
! example
! propósito
+
! purpose
| -
+
|-
 
| 0
 
| 0
| edad
+
| age
| <tt> adolescente </tt>
+
| <samp>teen</samp>
| Si el NPC es un <tt> niño </tt>, <tt> adolescente </tt> o <tt> adulto </tt>. Esto afecta las líneas de diálogo generadas (por ejemplo, un niño diría '' estúpido '' y un adulto diría '' deprimente ''), el diálogo genérico (por ejemplo, un niño respondería a un contenedor de basura buceando con '' 'Eww ... haciendo? '' "y un adolescente diría" '' Um ... ¿Por qué estás cavando en la basura? '' "), y el regalo que eligen como [[Fiesta de la Estrella de Invierno | un obsequio secreto] ]. Los niños también están excluidos de las misiones de entrega de artículos.
+
| Whether the NPC is a <samp>child</samp>, <samp>teen</samp>, or <samp>adult</samp>. This affects generated dialogue lines (''e.g.,'' a child would say ''stupid'' and an adult would say ''depressing''), generic dialogue (''e.g.,'' a child would respond to dumpster diving with "''Eww... What are you doing?''" and a teen would say "''Um... Why are you digging in the trash?''"), and the gift they choose as [[Feast of the Winter Star|a secret gift-giver]]. Children are also excluded from item delivery quests.
| -
+
|-
 
| 1
 
| 1
| modales
+
| manners
| <tt> grosero </tt>
+
| <samp>rude</samp>
| Si el NPC es <tt> cortés </tt>, <tt> grosero </tt> o <tt> neutral </tt>. Esto afecta a algunas líneas de diálogo genéricas.
+
| Whether the NPC is <samp>polite</samp>, <samp>rude</samp>, or <samp>neutral</samp>. This affects some generic dialogue lines.
| -
+
|-
 
| 2
 
| 2
| ansiedad social
+
| social anxiety
| <tt> saliente </tt>
+
| <samp>outgoing</samp>
| Si el NPC es <tt> extrovertido </tt>, <tt> tímido </tt> o <tt> neutral </tt>. Esto afecta a algunas líneas de diálogo genéricas.
+
| Whether the NPC is <samp>outgoing</samp>, <samp>shy</samp>, or <samp>neutral</samp>. This affects some generic dialogue lines.
| -
+
|-
 
| 3
 
| 3
| optimismo
+
| optimism
| <tt> neutral </tt>
+
| <samp>neutral</samp>
| Si el NPC es <tt> positivo </tt>, <tt> negativo </tt> o <tt> neutral </tt>. ''No usado.''
+
| Whether the NPC is <samp>positive</samp>, <samp>negative</samp>, or <samp>neutral</samp>. ''Unused.''
| -
+
|-
 
| 4
 
| 4
| género
+
| gender
| <tt> mujer </tt>
+
| <samp>female</samp>
| Si el NPC es <tt> hombre </tt>, <tt> mujer </tt> o <tt> indefinido </tt>. Esto afecta el diálogo, si los hijos en matrimonio se obtienen mediante adopción o embarazo, y las posiciones de los marcos reservados en la hoja de sprites.
+
| Whether the NPC is <samp>male</samp>, <samp>female</samp>, or <samp>undefined</samp>. This affects dialogue, whether children in marriage are obtained through adoption or pregnancy, and the reserved frames' positions on the spritesheet.
| -
+
|-
 
| 5
 
| 5
 
| datable
 
| datable
| <tt> datable </tt>
+
| <samp>datable</samp>
| Si el NPC es <tt> datable </tt> o <tt> no datable </tt>. Esto alterna las características de romance (por ejemplo, etiqueta 'única' en el menú social, regalo de ramo y matrimonio).
+
| Whether the NPC is <samp>datable</samp>, <samp>not-datable</samp>, or <samp>secret</samp>. The former two toggle the romance features (''e.g.,'' 'single' label in the social menu, bouquet gifting, and marriage), while <samp>secret</samp> is used exclusively for Krobus, who cannot be married but can be made a roommate.
| -
+
|-
 
| 6
 
| 6
| interés amoroso
+
| love interest
| <tt> Sebastián </tt>
+
| <samp>Sebastian</samp>
| ''No usado.''
+
| ''Unused.''
| -
+
|-
 
| 7
 
| 7
| región de origen
+
| home region
| <tt> Ciudad </tt>
+
| <samp>Town</samp>
| Si el NPC vive en el <tt> Desierto </tt>, <tt> Pueblo </tt> u <tt> Otro </tt>. Esto se usa para mejorar los puntos de amistad para todos los NPC en una región determinada, que actualmente solo se usa para el impulso de amistad [[Luau]] (que solo afecta a los NPC en la región <tt> Town </tt>).
+
| Whether the NPC lives in the <samp>Desert</samp>, <samp>Town</samp>, or <samp>Other</samp>. This is used when improving friendship points for all NPCs in a given region, which is currently only used for the [[Luau]] friendship boost (which only affects NPCs in the <samp>Town</samp> region).
| -
+
|-
 
| 8
 
| 8
| cumpleaños
+
| birthday
| <tt> otoño 13 </tt>
+
| <samp>fall 13</samp>
| La temporada y el día del cumpleaños del NPC.
+
| The season and day for the NPC's birthday.
| -
+
|-
 
| 9
 
| 9
| relaciones
+
| relationships
| <tt> Caroline 'mamá' Pierre 'papá' </tt>
+
| <samp>Caroline 'mom' Pierre 'dad'</samp>
| Esto afecta el diálogo genérico para revelar lo que le gusta y lo que no le gusta a los miembros de la familia. También puede afectar el diálogo inlaw_ <NPC>. Puede estar vacío si no corresponde (por ejemplo, <code> / fall 13 // SeedShop 1 9 / </code>).
+
| This affects generic dialogue for revealing likes and dislikes to family members. May also affect the inlaw_<NPC> dialogue. Can be empty if not applicable (''e.g.,'' <code>/fall 13//SeedShop 1 9/</code>).
| -
+
|-
 
| 10
 
| 10
| mapa y posición predeterminados
+
| default map & position
| <tt> SeedShop 1 9 </tt>
+
| <samp>SeedShop 1 9</samp>
| El nombre de la ubicación y [[Modding: Modder Guide / Game Fundamentals # Tiles | tile position]] donde el NPC comienza y termina cada día.
+
| The location name and [[Modding:Modder Guide/Game Fundamentals#Tiles|tile position]] where the NPC starts and ends each day.
| -
+
|-
 
| 11
 
| 11
| nombre para mostrar
+
| display name
| <tt> Abigail </tt>
+
| <samp>Abigail</samp>
| El nombre del NPC que se muestra al jugador.
+
| The NPC name shown to the player.
 
|}
 
|}
  
=== Sabores de regalo ===
+
===Gift tastes===
El activo <tt> Data \ NPCGiftTastes </tt> contiene sus preferencias de obsequio (p. Ej., Qué obsequios aman u odian) y sus respuestas cuando reciben uno. Consulte [[Modding: Gift taste data]] para obtener más información.
+
The <samp>Data\NPCGiftTastes</samp> asset contains their gift preferences (''e.g.,'' which gifts they love or hate), and their responses when they receive one. See [[Modding:Gift taste data]] for more info.
  
El archivo tiene una fila por NPC como esta:
+
The file has one row per NPC like this:
<syntaxhighlight lang = "yaml">
+
<syntaxhighlight lang="yaml">
   Abigail: "¡En serio me encanta esto! ¡Eres la mejor, @! / 66 128 220 226 276 611 / Oye, ¿cómo sabías que tenía hambre? ¡Esto se ve delicioso! // ¿Qué se supone que debo hacer con esto? / -5-75-79 16 245 246 / ¿Qué estabas pensando? ¡Esto es horrible! / 330 / ¿Me trajiste un regalo? Gracias.// "#! String
+
   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.// " #!String
 
</syntaxhighlight>
 
</syntaxhighlight>
  
La línea se puede dividir en 5 pares de diálogos + ID de elementos en este orden: Amor, Me gusta, Neutral, No me gusta, Odio. Si un campo de diálogo está vacío, el juego utilizará un texto de diálogo genérico. Consulte [[Modding: datos del objeto]] para conocer los ID de los artículos.
+
The line can be broken down into 5 pairs of dialogue + item IDs in this order: Love, Like, Dislike, Hate, Neutral. If a dialogue field is empty, the game will use a generic dialogue text. See [[Modding:Items]] for the object IDs.
  
==== Respuestas de regalos de cumpleaños ====
+
====Birthday gift responses====
El activo <tt> Strings \ StringsFromCSFiles </tt> contiene las respuestas genéricas dadas por los NPC a los regalos de cumpleaños según sus preferencias y modales. Estas cadenas compartidas se pueden personalizar para un NPC específico editándolas condicionalmente, como solo en el cumpleaños (no compartido) del NPC. Los siguientes criterios se utilizan para seleccionar entre las cadenas:
+
The <samp>Strings\StringsFromCSFiles</samp> asset contains the generic responses given by NPCs to birthday gifts based on their gift preferences and manners. These shared strings can be customized for a specific NPC by editing them conditionally, such as only on the NPC's (non-shared) birthday. The following criteria are used to select from among the strings:
  
{| class = "wikitable"
+
{| class="wikitable"
| -
+
|-
! sabor de regalo
+
! gift taste
! modales
+
! manners
! oportunidad
+
! chance
! cuerda
+
! string
| -
+
! english string
| rowpan = "4" | amar como
+
|-
| rowpan = "2" | maleducado
+
| rowspan="4" | love, like
 +
| rowspan="2" | rude
 
| 50%
 
| 50%
| <tt> NPC.cs.4274 </tt>
+
| <samp>NPC.cs.4274</samp>
| -
+
| <samp>"You remembered my birthday? I'm impressed. Thanks.$h"</samp>
 +
|-
 
| 50%
 
| 50%
| <tt> NPC.cs.4276 </tt>
+
| <samp>NPC.cs.4276</samp>
| -
+
| <samp>"Oh, is it my birthday today? I guess it is. Thanks. This is nice.$h/Oh, is it my birthday today? I guess it is. Thanks. This is nice.$h"</samp>
| rowpan = "2" | educado, neutral
+
|-
 +
| rowspan="2" | polite, neutral
 
| 50%
 
| 50%
| <tt> NPC.
+
| <samp>NPC.cs.4275</samp>
 +
| <samp>"A birthday gift? That's very kind of you! I love it.$h"</samp>
 +
|-
 +
| 50%
 +
| <samp>NPC.cs.4277</samp>
 +
| <samp>"You remembered my birthday! Thank you. This is great.$h"</samp>
 +
|-
 +
| rowspan="2" | dislike, hate
 +
| rude
 +
| 100%
 +
| <samp>NPC.cs.4278</samp>
 +
| <samp>"It's my birthday and you give me this? Is this some kind of joke?$s/It's my birthday and you give me this? Is this some kind of joke?$s"</samp>
 +
|-
 +
| polite, neutral
 +
| 100%
 +
| <samp>NPC.cs.4279</samp>
 +
| <samp>"Oh... It's for my birthday? ... Thanks.$s/Oh... It's for my birthday? ... Thanks.$s"</samp>
 +
|-
 +
| rowspan="2" | neutral
 +
| rude
 +
| 100%
 +
| <samp>NPC.cs.4280</samp>
 +
| <samp>"For my birthday? Thanks."</samp>
 +
|-
 +
| polite, neutral
 +
| 100%
 +
| <samp>NPC.cs.4281</samp>
 +
| <samp>"Oh, a birthday gift! Thank you./Oh, a birthday gift! Thank you."</samp>
 +
|}
 +
 
 +
The <samp>$h</samp> and <samp>$s</samp> are [[Modding:Dialogue#Portrait_commands|portrait commands]] that select the portrait image of the character to use.
 +
 
 +
===Overworld sprites===
 +
 
 +
[[File:Abigail-sprite-sheet.png|thumb|The sprite sheet for Abigail.]]
 +
 
 +
The overworld sprites are stored in <samp>Characters/NpcName</samp>, including movement and animation frames. Each frame is exactly 16x32 pixels. Here's an [https://cdn.discordapp.com/attachments/156109690059751424/729807097835028540/unknown.png example sprite guide], courtesy of TheLimeyDragon#1993 on Discord. Some positions are reserved for certain actions:
 +
<ul>
 +
<li>the first sixteen frames are generic movement (four frames per direction);</li>
 +
<li>frames 40–47 (female) and 44–47 (male) must be the Flower Dance dance, if they participate;</li>
 +
<li>frames 36–38 (female) 48–50 (male) are reserved for marriageable NPCs (Contains Wedding sprite);</li>
 +
<li>and the kissing sprite/direction varies depending on NPC:
 +
{| class="wikitable"
 
|-
 
|-
 
! character
 
! character
Line 173: Line 218:
  
 
===Portraits===
 
===Portraits===
The dialogue portraits are stored in <tt>Portraits/NpcName</tt>. Each frame is exactly 64x64 per portrait. The first six represent specific emotions (see [[Modding:Dialogue#Portrait commands]]), followed by any number of custom portraits. The first portrait is used when the dialogue doesn't specify one.
+
[[File:Modding - creating an XNB mod - example portraits.png|thumb|Abigail's portrait sprite sheet.]]
  
Here's an [https://cdn.discordapp.com/attachments/156109690059751424/729820558966915122/unknown.png example portrait guide], courtesy of TheLimeyDragon#1993 on Discord.
+
The dialogue portraits are stored in <samp>Portraits/NpcName</samp>. Each frame is exactly 64x64 per portrait. The first six represent specific emotions (see [[Modding:Dialogue#Portrait commands]]), followed by any number of custom portraits. The first portrait is used when the dialogue doesn't specify one.
  
 
===Schedule===
 
===Schedule===
Line 184: Line 229:
  
 
===Festivals===
 
===Festivals===
Festivals are tricky things. Everyone in the vanilla game is added to the festival map by placing tiles on the Set-Up and MainEvent map layers from a character tilesheet that draws from NPCDispositions to get exactly who to place. This is not ideal for custom NPCs, since you have no way of knowing where on the NPCDispositions data list your NPC goes when a player is using multiple custom NPCs. For this reason, it is recommended to use {{nexus mod|1820|TMXLoader}}, as it has a festival addition function to add your character to the Festival Maps, since it will draw upon your character's internal name instead of their position on the list. It's fairly easy to do, and there's an explanation on the {{nexus mod|1820|TMXLoader}} Nexus Description.
+
Custom NPCs should be added to festivals via the <samp>Set-Up_additionalCharacters</samp> and <samp>MainEvent_additionalCharacters</samp> fields in the [[Modding:Festival_data#Data_file|festival's data file]]. You may also want to visit [https://stardewmodding.wiki.gg/wiki/Custom_NPC_Tiles Custom NPC festival tile positions] to check the positions of various existing NPCs for compatibility purposes.
  
For adding them to festivals in 1.5 using Content Patcher, see [[Modding:Migrate to Stardew Valley 1.5#Festival changes]].
+
(Prior to Stardew Valley 1.5, {{nexus mod|1820|TMXL}} was the recommended tool for adding festival spots.)
 +
 
 +
===Movie theater===
 +
An NPC's taste in movies and concessions are stored in <samp>Data\MoviesReactions.xnb</samp> and <samp>Data\ConcessionTastes.xnb</samp>, respectively. See [[Modding:Movie theater data]] for details on how these function.
 +
 
 +
===Spouse room===
 +
If your NPC will be a marriage candidate, note that you can add a spouse room for them much more easily after game version 1.5.5. See [[Modding:Migrate_to_Stardew_Valley_1.5.5#Custom_spouse_rooms]] for details.
 +
 
 +
===Sleep animation===
 +
When the NPC goes to bed, they'll play the looping sleep animation set via <samp>{{t|lowercase NPC name}}_sleep</samp> in <samp>Data/animationDescriptions</samp>, if it exists. For example, this content pack adds a sleep animation for an NPC named 'Pufferbob':
 +
{{#tag:syntaxhighlight|
 +
{
 +
    "Format": "{{Content Patcher version}}",
 +
    "Changes": [
 +
        {
 +
            "Action": "EditData",
 +
            "Target": "Data/animationDescriptions",
 +
            "Entries": {
 +
                "pufferbob_sleep": "50/50/50" // note: make name lowercase
 +
            }
 +
        }
 +
    ]
 +
}
 +
|lang=json}}
 +
}
  
 
==Adding your NPC==
 
==Adding your NPC==
Line 192: Line 261:
  
 
<ol>
 
<ol>
<li>[https://github.com/Pathoschild/StardewMods/blob/develop/ContentPatcher/docs/author-guide.md#format Create an empty Content Patcher content pack]. By convention, we'll name the folder <tt>[CP] Dobson</tt>.</li>
+
<li>[https://github.com/Pathoschild/StardewMods/blob/develop/ContentPatcher/docs/author-guide.md#format Create an empty Content Patcher content pack]. By convention, we'll name the folder <samp>[CP] Dobson</samp>.</li>
 
<li>Create the following files:
 
<li>Create the following files:
* <tt>assets/dialogue.json</tt> containing the dialogue.
+
* <samp>assets/dialogue.json</samp> containing the dialogue.
* <tt>assets/marriageDialogue.json</tt> containing the marriage dialogue (if applicable).
+
* <samp>assets/marriageDialogue.json</samp> containing the marriage dialogue (if applicable).
* <tt>assets/sprites.png</tt> containing their overworld sprites.
+
* <samp>assets/sprites.png</samp> containing their overworld sprites.
* <tt>assets/portraits.png</tt> containing their portraits.
+
* <samp>assets/portraits.png</samp> containing their portraits.
* <tt>assets/schedule.json</tt> containing their schedule data.
+
* <samp>assets/schedule.json</samp> containing their schedule data.
 
</li>
 
</li>
<li>Edit the <tt>content.json</tt> to load the files:
+
<li>Edit the <samp>content.json</samp> to load the files:
 
{{#tag:syntaxhighlight|
 
{{#tag:syntaxhighlight|
 
{
 
{
Line 208: Line 277:
 
             "Action": "Load",
 
             "Action": "Load",
 
             "Target": "Characters/Dobson",
 
             "Target": "Characters/Dobson",
             "FromFile": "assets/sprites.png",
+
             "FromFile": "assets/sprites.png"
 
         },
 
         },
 
         {
 
         {
 
             "Action": "Load",
 
             "Action": "Load",
 
             "Target": "Portraits/Dobson",
 
             "Target": "Portraits/Dobson",
             "FromFile": "assets/portraits.png",
+
             "FromFile": "assets/portraits.png"
 
         },
 
         },
 
         {
 
         {
 
             "Action": "Load",
 
             "Action": "Load",
 
             "Target": "Characters/Dialogue/Dobson",
 
             "Target": "Characters/Dialogue/Dobson",
             "FromFile": "assets/dialogue.json",
+
             "FromFile": "assets/dialogue.json"
 
         },
 
         },
 
         {
 
         {
 
             "Action": "Load",
 
             "Action": "Load",
 
             "Target": "Characters/Dialogue/MarriageDialogueDobson",
 
             "Target": "Characters/Dialogue/MarriageDialogueDobson",
             "FromFile": "assets/marriageDialogue.json",
+
             "FromFile": "assets/marriageDialogue.json"
 
         },
 
         },
 
         {
 
         {
 
             "Action": "Load",
 
             "Action": "Load",
 
             "Target": "Characters/schedules/Dobson",
 
             "Target": "Characters/schedules/Dobson",
             "FromFile": "assets/schedule.json",
+
             "FromFile": "assets/schedule.json"
 
         },
 
         },
 
         {
 
         {
Line 235: Line 304:
 
             "Entries": {
 
             "Entries": {
 
                 "Dobson": "adult/rude/neutral/positive/male/datable//Town/summer 7//BusStop 19 4/Dobson"
 
                 "Dobson": "adult/rude/neutral/positive/male/datable//Town/summer 7//BusStop 19 4/Dobson"
             },
+
             }
 
         },
 
         },
 
         {
 
         {
Line 241: Line 310:
 
             "Target": "Data/NPCGiftTastes",
 
             "Target": "Data/NPCGiftTastes",
 
             "Entries": {
 
             "Entries": {
                 "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/ ",
+
                 "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/ "
             },
+
             }
 
         },
 
         },
 
         {
 
         {
Line 249: Line 318:
 
             "Entries": {
 
             "Entries": {
 
                 "Dobson0": "I can't believe I am about to be married!$h",
 
                 "Dobson0": "I can't believe I am about to be married!$h",
                 "Dobson1": "I hope I don't get cold feet",
+
                 "Dobson1": "I hope I don't get cold feet"
             },
+
             }
         },
+
         }
 
     ]
 
     ]
 
}
 
}
Line 263: Line 332:
 
[[Category:Modding]]
 
[[Category:Modding]]
  
 +
[[es:Modding:Datos de NPC]]
 
[[pt:Modificações:Dados do NPC]]
 
[[pt:Modificações:Dados do NPC]]
 +
[[ru:Модификации:О NPC]]

Latest revision as of 19:55, 2 March 2024

Index

This page provides an overview of what's needed to create a custom NPC. This is an advanced guide for mod developers.

Before reading this page, see Modding:Editing XNB files for the basic concepts.

Files to edit

To create a new NPC, you need to edit a number of different files. However, you don't need any programming experience and it can be done with Content Patcher.

Basic info

The Data\NPCDispositions asset contains basic information for your character, including their name, birthday, relations to other characters, personality, and whether they can be dated.

The file has one row per NPC like this:

   Abigail: "teen/rude/outgoing/neutral/female/datable/Sebastian/Town/fall 13/Caroline 'mom' Pierre 'dad'/SeedShop 1 9/Abigail"

The key (before the colon) is the internal name which uniquely identifies that NPC. This name isn't shown to the player, but will be used when referencing the NPC in other files. The value contains the following fields:

index field example purpose
0 age teen Whether the NPC is a child, teen, or adult. This affects generated dialogue lines (e.g., a child would say stupid and an adult would say depressing), generic dialogue (e.g., a child would respond to dumpster diving with "Eww... What are you doing?" and a teen would say "Um... Why are you digging in the trash?"), and the gift they choose as a secret gift-giver. Children are also excluded from item delivery quests.
1 manners rude Whether the NPC is polite, rude, or neutral. This affects some generic dialogue lines.
2 social anxiety outgoing Whether the NPC is outgoing, shy, or neutral. This affects some generic dialogue lines.
3 optimism neutral Whether the NPC is positive, negative, or neutral. Unused.
4 gender female Whether the NPC is male, female, or undefined. This affects dialogue, whether children in marriage are obtained through adoption or pregnancy, and the reserved frames' positions on the spritesheet.
5 datable datable Whether the NPC is datable, not-datable, or secret. The former two toggle the romance features (e.g., 'single' label in the social menu, bouquet gifting, and marriage), while secret is used exclusively for Krobus, who cannot be married but can be made a roommate.
6 love interest Sebastian Unused.
7 home region Town Whether the NPC lives in the Desert, Town, or Other. This is used when improving friendship points for all NPCs in a given region, which is currently only used for the Luau friendship boost (which only affects NPCs in the Town region).
8 birthday fall 13 The season and day for the NPC's birthday.
9 relationships Caroline 'mom' Pierre 'dad' This affects generic dialogue for revealing likes and dislikes to family members. May also affect the inlaw_<NPC> dialogue. Can be empty if not applicable (e.g., /fall 13//SeedShop 1 9/).
10 default map & position SeedShop 1 9 The location name and tile position where the NPC starts and ends each day.
11 display name Abigail The NPC name shown to the player.

Gift tastes

The Data\NPCGiftTastes asset contains their gift preferences (e.g., which gifts they love or hate), and their responses when they receive one. See Modding:Gift taste data for more info.

The file has one row per NPC like this:

   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.// " #!String

The line can be broken down into 5 pairs of dialogue + item IDs in this order: Love, Like, Dislike, Hate, Neutral. If a dialogue field is empty, the game will use a generic dialogue text. See Modding:Items for the object IDs.

Birthday gift responses

The Strings\StringsFromCSFiles asset contains the generic responses given by NPCs to birthday gifts based on their gift preferences and manners. These shared strings can be customized for a specific NPC by editing them conditionally, such as only on the NPC's (non-shared) birthday. The following criteria are used to select from among the strings:

gift taste manners chance string english string
love, like rude 50% NPC.cs.4274 "You remembered my birthday? I'm impressed. Thanks.$h"
50% NPC.cs.4276 "Oh, is it my birthday today? I guess it is. Thanks. This is nice.$h/Oh, is it my birthday today? I guess it is. Thanks. This is nice.$h"
polite, neutral 50% NPC.cs.4275 "A birthday gift? That's very kind of you! I love it.$h"
50% NPC.cs.4277 "You remembered my birthday! Thank you. This is great.$h"
dislike, hate rude 100% NPC.cs.4278 "It's my birthday and you give me this? Is this some kind of joke?$s/It's my birthday and you give me this? Is this some kind of joke?$s"
polite, neutral 100% NPC.cs.4279 "Oh... It's for my birthday? ... Thanks.$s/Oh... It's for my birthday? ... Thanks.$s"
neutral rude 100% NPC.cs.4280 "For my birthday? Thanks."
polite, neutral 100% NPC.cs.4281 "Oh, a birthday gift! Thank you./Oh, a birthday gift! Thank you."

The $h and $s are portrait commands that select the portrait image of the character to use.

Overworld sprites

The sprite sheet for Abigail.

The overworld sprites are stored in Characters/NpcName, including movement and animation frames. Each frame is exactly 16x32 pixels. Here's an example sprite guide, courtesy of TheLimeyDragon#1993 on Discord. Some positions are reserved for certain actions:

  • the first sixteen frames are generic movement (four frames per direction);
  • frames 40–47 (female) and 44–47 (male) must be the Flower Dance dance, if they participate;
  • frames 36–38 (female) 48–50 (male) are reserved for marriageable NPCs (Contains Wedding sprite);
  • and the kissing sprite/direction varies depending on NPC:
    character kissing frame facing direction
    Abigail and Emily 33 left
    Alex 42 right
    Elliott 35 left
    Haley 28 right
    Harvey 31 left
    Leah 25 right
    Maru 28 left
    Penny 35 right
    Sam 36 right
    Sebastian 40 left
    Shane 34 left
    any other NPC 28 right

Portraits

Abigail's portrait sprite sheet.

The dialogue portraits are stored in Portraits/NpcName. Each frame is exactly 64x64 per portrait. The first six represent specific emotions (see Modding:Dialogue#Portrait commands), followed by any number of custom portraits. The first portrait is used when the dialogue doesn't specify one.

Schedule

Their schedule file tells the game where the NPC starts and moves based on on the time. You need to add strings to a separate schedules file found in the Strings folder to allow custom dialogue. See Modding:Schedule data for more info.

Dialogue and events

The NPC dialogue and events are stored in several files; see Modding:Dialogue and Modding:Event data for more info.

Festivals

Custom NPCs should be added to festivals via the Set-Up_additionalCharacters and MainEvent_additionalCharacters fields in the festival's data file. You may also want to visit Custom NPC festival tile positions to check the positions of various existing NPCs for compatibility purposes.

(Prior to Stardew Valley 1.5, TMXL was the recommended tool for adding festival spots.)

Movie theater

An NPC's taste in movies and concessions are stored in Data\MoviesReactions.xnb and Data\ConcessionTastes.xnb, respectively. See Modding:Movie theater data for details on how these function.

Spouse room

If your NPC will be a marriage candidate, note that you can add a spouse room for them much more easily after game version 1.5.5. See Modding:Migrate_to_Stardew_Valley_1.5.5#Custom_spouse_rooms for details.

Sleep animation

When the NPC goes to bed, they'll play the looping sleep animation set via <lowercase NPC name>_sleep in Data/animationDescriptions, if it exists. For example, this content pack adds a sleep animation for an NPC named 'Pufferbob':

{
    "Format": "2.0.0",
    "Changes": [
        {
            "Action": "EditData",
            "Target": "Data/animationDescriptions",
            "Entries": {
                "pufferbob_sleep": "50/50/50" // note: make name lowercase
            }
        }
    ]
}

}

Adding your NPC

Here's how you'd create an example NPC we'll name Dobson:

  1. Create an empty Content Patcher content pack. By convention, we'll name the folder [CP] Dobson.
  2. Create the following files:
    • assets/dialogue.json containing the dialogue.
    • assets/marriageDialogue.json containing the marriage dialogue (if applicable).
    • assets/sprites.png containing their overworld sprites.
    • assets/portraits.png containing their portraits.
    • assets/schedule.json containing their schedule data.
  3. Edit the content.json to load the files:
    {
        "Format": "2.0.0",
        "Changes": [
            {
                "Action": "Load",
                "Target": "Characters/Dobson",
                "FromFile": "assets/sprites.png"
            },
            {
                "Action": "Load",
                "Target": "Portraits/Dobson",
                "FromFile": "assets/portraits.png"
            },
            {
                "Action": "Load",
                "Target": "Characters/Dialogue/Dobson",
                "FromFile": "assets/dialogue.json"
            },
            {
                "Action": "Load",
                "Target": "Characters/Dialogue/MarriageDialogueDobson",
                "FromFile": "assets/marriageDialogue.json"
            },
            {
                "Action": "Load",
                "Target": "Characters/schedules/Dobson",
                "FromFile": "assets/schedule.json"
            },
            {
                "Action": "EditData",
                "Target": "Data/NPCDispositions",
                "Entries": {
                    "Dobson": "adult/rude/neutral/positive/male/datable//Town/summer 7//BusStop 19 4/Dobson"
                }
            },
            {
                "Action": "EditData",
                "Target": "Data/NPCGiftTastes",
                "Entries": {
                    "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": {
                    "Dobson0": "I can't believe I am about to be married!$h",
                    "Dobson1": "I hope I don't get cold feet"
                }
            }
        ]
    }
    

That's it! If you load your game, the NPC should appear. If you want to create events, don't forget to add that file too.

Guidance on pixel art

If you'd like additional guidance on pixel art, See Modding:Index#See_also for some recommended guides.