Changes

m
→‎Year variants: Minor wording change on the coordination problem warning.
Line 1: Line 1:  
← [[Modding:Index|Index]]
 
← [[Modding:Index|Index]]
  −
{{stub}}
      
This page explains how the game stores and uses festival data. This is an advanced guide for mod developers.
 
This page explains how the game stores and uses festival data. This is an advanced guide for mod developers.
   −
==Overview==
+
==Data file==
Festivals are complex events with both content and code components.  For the majority of festivals, there exist special map files with location data for villager placements.  These are located within Content/Maps like other map files. For scripted events that play during the festival (such as Lewis judging the farmer's grange display), the event is usually handled in code.
+
Each festival has a data file located at <samp>Content/Data/Festivals/&lt;season&gt;&lt;day of month&gt;</samp>. The game uses this asset to determine whether there's a festival today (if the asset exists), where and when it happens, and NPC placement/dialogue/behavior.
 
  −
The Night Market is a special festival, as it is handled differently than other festivals.  While there are separate Night Market maps, the NPC data does not exist on these.  Instead, NPCs dynamically enter and leave the festival via schedule data.  The raw data for the schedule destinations of each NPC during the Night Market can be found below.
     −
==Raw Data==
+
===Raw data===
 +
The festival data file can be [[Modding:Editing XNB files#unpacking|unpacked for editing]]. For example, here's the raw data from <samp>Content/Data/Festivals/fall27</samp> as of {{version|1.5.4}} for reference:
 
{{collapse|Data|content=<syntaxhighlight lang="json">
 
{{collapse|Data|content=<syntaxhighlight lang="json">
 
{
 
{
   Winter 15:
+
   "name": "Spirit's Eve",
Abigail: Beach 30 34
+
  "conditions": "Town/2200 2350",
Shane: Beach 20 24
+
  "shop": "BO 113 5000 1 O 746 750 5 BL 746 2000 1 BO 47 350 -1 F 2870 4000 -1",
Penny: Beach 35 36
+
  "set-up": "spirits_eve/-1000 -1000/farmer 12 54 1/changeToTemporaryMap Town-Halloween/loadActors Set-Up/advancedMove Maru true 0 2 2 0 0 3 -11 0 0 -7 5 0 0 2 4 0/advancedMove Alex true -4 0 4 4000 4 0 4 5000/advancedMove Jas true 1 1500 4 1000/advancedMove Pam true 0 1 1 5000 0 -1 1 5000/advancedMove Shane true -7 0 0 2 2 9000 0 -2 7 0 4 9000/advancedMove Demetrius true 3 18000 4 3000/addTemporaryActor Skeleton 16 32 30 59 2 false Monster/advancedMove Skeleton true 0 1 3 4000 2 0 0 -1 4 2000 -1 0 3 1000 2 2000 0 -1 4 4000 -1 0 0 1 2 5000/addTemporaryActor Skeleton 16 32 35 58 2 false Monster/playerControl halloween",
Linus: Beach 19 4
+
  "Abigail_spouse": "You'll have to tell me what's beyond, I can't go on... spiders...$s",
Leah: Beach 41 35
+
  "Leah_spouse": "I may have had a little too much pumpkin ale...",
Jas: Beach 19 24
+
  "Maru_spouse": "I'm confused... you go on ahead and let me figure this out.",
Harvey: Beach 37 31
+
  "Penny_spouse": "Oh... These vapors... Hmmm... You look nice tonight.$l",
Emily: Beach 25 36
+
  "Haley_spouse": "I get scared easily... I think I'm just going to stay right here.$s",
Clint: Beach 37 33
+
  "Sebastian_spouse": "It would be interesting to have one of these on the farm.",
   Winter 16:
+
  "Sam_spouse": "Hey, I was wondering when you'd show up!$h",
Vincent: Beach 19 24
+
   "Harvey_spouse": "Hi... I was hoping you'd find me here...$l",
Sebastian: Beach 10 39
+
  "Elliott_spouse": "Mmph... I believe I've eaten a few too many slices of pumpkin pie.",
Robin: Beach 13 31
+
  "Abigail": "I can't go on... spiders...$s",
Maru: Beach 11 33
+
  "Robin": "Well, winter's almost here. It's a great time to stockpile wood and stone.",
Marnie: Beach 37 31
+
  "Demetrius": "I haven't seen Maru in hours... I hope she's alright.",
Lewis: Beach 40 34
+
  "Maru": "I think I've already been this way... no, wait...$s#$e#I'm lost...$s",
Haley: Beach 27 34
+
  "Sebastian": "I have no idea how these skeletons are walking... creepy.#$e#It's pretty cool though.",
Demetrius: Beach 11 32
+
  "Pierre": "??",
Caroline: Beach 24 32
+
  "Caroline": "I get scared very easily. I'll leave the haunted maze to the younger people.",
   Winter 17:
+
  "Linus": "Good show, old friend.",
Sam: Beach 11 34
+
  "Alex": "There's something weird over there. But how do I get to it?#$e#There's gotta be a secret passage somewhere around here.",
Jodi: Beach 20 24
+
  "George": "Hmm... smoked turkey haunch? I guess this festival isn't all bad.$h",
George: Beach 11 39
+
  "Evelyn": "I wish Gus would include a vegetarian option. Some zucchini skewers, maybe?",
Evelyn: Beach 12 39
+
  "Lewis": "Good evening, @. Have you ventured into the haunted maze yet? It's quite spooky.#$e#That strange man who lives in the tower set it all up himself. He wouldn't let anyone near while he was working on it.",
Elliot: Beach 38 36
+
  "Clint": "One of my iridium-infused maces would make quick work of these things.",
Alex: Beach 27 24
+
  "Emily": "Do you like the jack-o-lanterns? I carved them myself.",
 +
  "Penny": "The vapor from this cauldron... it's making my head spin, but I can't seem to leave...$u",
 +
  "Pam": "I'll come to any event with free grub! You won't see me in the haunted maze, though.",
 +
  "Haley": "Eek! I'm too scared.$s",
 +
  "Jodi": "Vincent's upset that I won't let him go into the haunted maze... but he's just a little boy!",
 +
  "Kent": "Hey, @. Nice evening, isn't it?",
 +
  "Sam": "That's odd... It's just a dead end up ahead.#$e#I could've sworn there was someone ahead of me when I went through the maze, though. Where'd they go?",
 +
  "Leah": "Mm, hi. Sorry... mouth full of blackberries.",
 +
  "Marnie": "Hi, @. Have you had a productive fall?#$e#It's starting to get quite cold... crops won't hold out for much longer.",
 +
  "Elliott": "Why, hello @. It's chilly, isn't it?",
 +
  "Gus": "It's a lot of fun to cook with pumpkin. Such an interesting fruit.",
 +
  "Dwarf": "You say it's raining up above? *gasp*#$e#Rain... It's almost mythical to us. Some of us live our entire lives without ever experiencing it.",
 +
  "Wizard": "The affairs of mundane folk matter little to me, but the elementals like a chance to see you up close.#$e#It was for them that I created this silly maze.",
 +
   "Harvey": "Oh! You found me...$8#$b#The truth is, I got too scared so I came here to hide. Don't tell anyone.$s",
 +
  "Shane": "Why is there no more pumpkin ale?",
 +
  "Sandy": "I heard it's raining back home. Is that why you came here?$h#$e#I kind of miss the rain, actually...$s",
 +
  "Jas": "But Aunt Marnie! I wanna go in the maze! I'm not scared!$s",
 +
  "Vincent": "Mother won't let me go in the maze. *sob*$s",
 +
  "Marlon": "Don't get too close to the cage.",
 +
  "Leo": "%Leo's unblinking eyes are glued to the screen. You're unable to get his attention."
 
}
 
}
 
</syntaxhighlight>}}
 
</syntaxhighlight>}}
    +
===Format===
 +
{| class="wikitable"
 +
|-
 +
! field key
 +
! explanation
 +
|-
 +
| <samp>name</samp>
 +
| The festival name. This is used in display text like the calendar tooltip or the festival-is-ready message.
 +
|-
 +
| <samp>conditions</samp>
 +
| When and where the festival takes place. The format is <samp>{{t|location}}/{{t|start time}} {{t|end time}}</samp>, where {{t|location}} is the internal location name and the times are specified in 26-hour format (''i.e.,'' 600 for 6am to 2600 for 2am).
 +
|-
 +
| <samp>mainEvent</samp>
 +
| The main event script. This is triggered when the player asks the festival host (usually Lewis) to begin the festival. This is absent for events that do not have a prompt or where speaking to Lewis does not trigger a new scene.
 +
|-
 +
| <samp>shop</samp>
 +
| The items the festival shop sells. See ''[[#Shop format|shop format]]'' below.
 +
|-
 +
| <samp>set-up</samp>
 +
| The [[Modding:Event data|event script]] that's run when the player first enters the festival. This includes moving the player to the festival map. This field supports [[#Year variants|year variants]].
 +
|-
 +
| <samp>Set-Up_additionalCharacters</samp>
 +
| NPCs to spawn when the festival loads. This is specified as four space-delimited fields in the form <samp>{{t|NPC name}} {{t|tile X}} {{t|tile Y}} {{t|facing direction}}</samp>, repeated for each NPC to add with a <code>/</code> between each NPC. The {{t|facing direction}}</samp> can be one of <samp>up</samp> or <samp>0</samp>, <samp>down</samp> or <samp>2</samp>, <samp>left</samp> or <samp>3</samp>, and <samp>right</samp> or <samp>1</samp>. These are additional to the NPCs spawned via the [[#Map|map file]]. For example, this adds Abigail and Leah side-by-side facing down: <syntaxhighlight lang="javascript">"Set-Up_additionalCharacters": "Abigail 15 6 down/Leah 16 6 down"</syntaxhighlight>This field supports [[#Year variants|year variants]].
 +
|-
 +
| <samp>MainEvent_additionalCharacters</samp>, or<br><samp>Main-Event_additionalCharacters</samp> for the [[Festival of Ice|Festival of Ice]]
 +
| NPCs to spawn when the festival's <code>mainEvent</code> script is run. Just like <code>mainEvent</code>, this is absent for events that do not have a prompt to start a new scene. The format is identical to <code>Set-Up_additionalCharacters</code>, above.<br>This field supports [[#Year variants|year variants]].
 +
|-
 +
| <samp>{{t|NPC name}}_roommate</samp>
 +
| The [[Modding:Dialogue#Format|dialog line]] the named NPC will say when the player talks to them, if they're roommates with the player. This field supports [[#Year variants|year variants]], doesn't work on the Flower Dance festival, and doesn't support <samp>#$e#</samp> breaks. If not specified, the <samp>{{t|NPC name}}_spouse</samp> will be used next.
 +
|-
 +
| <samp>{{t|NPC name}}_spouse</samp>
 +
| The [[Modding:Dialogue#Format|dialog line]] the named NPC will say when the player talks to them, if they're married to the player. This field supports [[#Year variants|year variants]], doesn't work on the Flower Dance festival, and doesn't support <samp>#$e#</samp> breaks.
 +
|-
 +
| <samp>{{t|NPC name}}</samp>
 +
| The [[Modding:Dialogue#Format|dialog line]] the named NPC will say when the player talks to them, if <samp>{{t|NPC name}}_spouse</code></samp> doesn't exist or apply. This field supports [[#Year variants|year variants]].
 +
|}
 +
 +
Any other entry is [[Modding:Event data|event data]] for a cutscene during the festival. In some cases like the [[Luau]], these are linked together when played in the game.
 +
 +
===Year variants===
 +
Several fields allow annual variants (documented in the table above). These work by adding <samp>_y{{t|year variant}}</samp> to the end of key, where the {{t|year variant}} is an incrementing number starting at 1 with no upper limit. For example, two entries <samp>set-up_y1</samp> and <samp>set-up_y2</samp> will alternate (<samp>set-up_y1</samp> in year 1, <samp>set-up_y2</samp> in year 2, <samp>set-up_y1</samp> in year 3, etc). If year variants are defined for a key, the original key is ignored (''e.g.,'' <samp>set-up</samp> will never be used if <samp>set-up_y*</samp> entries are defined).
 +
{{note box|'''It is recommended to use the year variants for the <samp>Set-Up_additionalCharacters</samp> and <samp>MainEvent_additionalCharacters</samp> fields, even if you don't wish to spawn your custom NPC in different locations on odd and even years.'''<br>These keys are global to the festival data, and if <strong>any</strong> mod appends to them, the game will use those keys instead of the non-variant keys. This will cause any NPCs not using the year variant keys to fail to spawn.}}
 +
 +
===Shop format===
 +
The shop data for a festival is stored as four space-separated values in the format <samp>{{t|item type}} {{t|item ID}} {{t|cost}} {{t|count available}}</samp>, which is repeated for each item. Field formats:
 +
 +
{| class="wikitable"
 +
|-
 +
! field
 +
! explanation
 +
|-
 +
| {{t|item type}}
 +
| The item type. The valid values are <samp>B</samp> or <samp>Boots</samp> (boots), <samp>BL</samp> or <samp>Blueprint</samp> (blueprint), <samp>BBL</samp>, <samp>BBl</samp> or <samp>BigBlueprint</samp> (big blueprint), <samp>BO</samp> or <samp>BigObject</samp> (bigcraftable object), <samp>F</samp> (furniture), <samp>H</samp> or <samp>Hat</samp> (hat), <samp>O</samp> or <samp>Object</samp> (object), <samp>R</samp> or <samp>Ring</samp> (ring), or <samp>W</samp> or <samp>Weapon</samp> (weapon).
 +
|-
 +
| <samp>{{t|item id}}</samp>
 +
| The item's spritesheet index.
 +
|-
 +
| <samp>{{t|cost}}</samp>
 +
| The purchase price in gold. For seeds, this is modified based on the [[Multiplayer#Profit margins|profit margin]].
 +
|-
 +
| <samp>{{t|count available}}</samp>
 +
| How many of that item can be purchased from the shop, or <samp>-1</samp> for unlimited.
 +
|}
 +
 +
==Map==
 +
Many festivals use a separate [[Modding:Maps|map file]] located in the <samp>Content/Maps</samp> folder. The map to use is specified in the [[#Data file|data file]]'s <samp>set-up</samp> field using the <samp>changeToTemporaryMap</samp> command.
 +
 +
===Spawned NPCs===
 +
{{note box|'''This is fragile and not recommended for custom NPCs or festivals.'''<br />Consider using the [[#Data file|data file]]'s <samp>Set-Up_additionalCharacters</samp> field instead.}}
 +
 +
NPCs can be added to festivals using map tile indexes on a specific layer. This is enabled in the [[#Data file|data file]]'s <samp>set-up</samp> field using the <samp>loadActors {{t|layer name}}</samp> command. For each tile which exists on the layer, the tile index is mapped to the NPC's index in the <samp>Data\NPCDispositions</samp> asset multiplied by four, with an offset which determines the facing direction (0 = up, 1 = right, 2 = down, or 3 = left).
 +
 +
For example, let's say the layer has a tile with tilesheet index 61. That's the NPC at index <samp>61 / 4 = 15</samp> in <samp>Data\NPCDispositions</samp>, ''i.e.,'' the 16th NPC, ''i.e.,'' Leah. The offset is <samp>61 % 4 = 1</samp>, so she's facing right. When the festival is loaded, Leah will be added to that tile position facing right.
 +
 +
==Hardcoded logic==
 +
Several vanilla events have hardcoded scripted logic in the game code. For example, Lewis judging the farmer's grange display at the [[Stardew Valley Fair]] is handled in the game code, not the content assets documented here.
 +
 +
The [[Night Market]] is also handled differently from other festivals. While there are separate Night Market maps, the NPC data doesn't exist on these. Instead, NPCs dynamically enter and leave the festival via schedule data.
    
[[Category:Modding]]
 
[[Category:Modding]]
 +
 +
[[ru:Модификации:Фестивали]]
16

edits