Jump to content

Modding:Festival data

From Stardew Valley Wiki

← Index

This page explains how the game stores and uses festival data. This is an advanced guide for mod developers.

Data file

Each festival has a data file located at Data/Festivals/<season><day of month>. 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 game also has a data file located at Data/Festivals/FestivalDates which contains the names and dates of festivals. Mod authors who wish to add a custom festival will need to add an entry to it as well.

Raw data

The festival data file can be unpacked for editing. For example, here's the raw data from Data/Festivals/fall27 as of 1.6.15 for reference:

Data 
{
  "name": "Spirit's Eve",
  "conditions": "Town/2200 2350",
  "set-up": "spirits_eve/-1000 -1000/farmer 12 54 1/changeToTemporaryMap Town-Halloween/viewport -1000 -1000/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/viewport player clamp true unfreeze/globalFadeToClear",
  "Abigail_spouse": "You'll have to tell me what's beyond, I can't go on... spiders...$s",
  "Leah_spouse": "I may have had a little too much pumpkin ale...",
  "Maru_spouse": "I'm confused... you go on ahead and let me figure this out.",
  "Penny_spouse": "Oh... These vapors... Hmmm... You look nice tonight.$l",
  "Haley_spouse": "I get scared easily... I think I'm just going to stay right here.$s",
  "Sebastian_spouse": "It would be interesting to have one of these on the farm.",
  "Sam_spouse": "Hey, I was wondering when you'd show up!$h",
  "Harvey_spouse": "Hi... I was hoping you'd find me here...$l",
  "Elliott_spouse": "Mmph... I believe I've eaten a few too many slices of pumpkin pie.",
  "Abigail": "I can't go on... spiders...$s",
  "Robin": "Well, winter's almost here. It's a great time to stockpile wood and stone.",
  "Demetrius": "I haven't seen Maru in hours... I hope she's alright.",
  "Maru": "I think I've already been this way... no, wait...$s#$e#I'm lost...$s",
  "Sebastian": "I have no idea how these skeletons are walking... creepy.#$e#It's pretty cool though.",
  "Pierre": "??",
  "Caroline": "I get scared very easily. I'll leave the haunted maze to the younger people.",
  "Linus": "Good show, old friend.",
  "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.",
  "George": "Hmm... smoked turkey haunch? I guess this festival isn't all bad.$h",
  "Evelyn": "I wish Gus would include a vegetarian option. Some zucchini skewers, maybe?",
  "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.",
  "Clint": "One of my iridium-infused maces would make quick work of these things.",
  "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.",
  "shop_y2": "BO 113 5000 1 O 746 750 5 BL 746 2000 1 BO 47 350 -1 F 2870 4000 -1",
  "set-up_y2": "spirits_eve/-1000 -1000/farmer 12 54 1/changeToTemporaryMap Town-Halloween2/viewport -1000 -1000/loadActors Set-Up/advancedMove Pam true 1 10000 4 2500/advancedMove Jodi true 4 12300 3 3000/advancedMove Harvey true 3 9000 4 2000 3 500 2 2500/advancedMove Vincent true 2 11000 3 1250 2 500 1 1000/advancedMove Sebastian true 2 13500 3 1400 2 500 1 1200/advancedMove Willy true 4 12000 3 1550 4 10500 1 1750/advancedMove Emily true 2 6500 3 1000 2 4000 1 1250/advancedMove Leah true 2 4000 1 3000 4 2250 1 500 2 800 0 5 -4 0 3 1100 2 3500 3 600 -4 0 0 -4 4 500 3 4000 2 1500 3 2500 4 1500 3 1750 2 500 0 4 4 0 1 800 2 3000 3 1500 2 3250 1 500 4 0 0 -5 4 2500/advancedMove Robin true 4 8500 2 0 1 500 4 6250 3 650 -2 0 3 400 4 500/advancedMove Abigail true 4 7500 1 500 2 0 1 400 4 5500 2 0 0 -3 4 500 3 6250 2 500 0 3 -2 0 3 500 4 3750 3 400 -2 0 3 500/advancedMove Alex true 2 8000 1 1000 2 650 3 1250 2 5500 1 1500 2 750 3 1500 2 500/advancedMove Kent true 4 3800 1 400 3 0 1 400 4 9600 3 500 -2 0 3 500 4 7000 3 400 -1 0 3 400/positionOffset Clint 16 -24/positionOffset Willy 5 -15/positionOffset George 0 -12/positionOffset Evelyn 0 -16/addTemporaryActor Mummy 16 32 9 62 2 false Monster/advancedMove Mummy true 2 5000 1 0 1 800 2 4000 3 2000 2 500 1 2500 2 4000 3 500 4 500 0 -1 4 1500 1 3000 2 4000 3 800 -1 0 3 1500 2 3750 0 1 2 2000/addTemporaryActor Wilderness_Golem 16 24 18 59 2 false Monster/advancedMove Wilderness_Golem true 2 5000 3 2500 2 4000 1 2000 2 1000 3 500 -1 0 3 1000 2 6000 0 1 2 4000 3 3000 2 500 1 2500 4 650 0 -1 -1 0 3 2000 3 5000 3 3000 2 2000 1 1500 2 0 1 3000/addTemporaryActor Stone_Golem 16 24 16 61 2 false Monster/advancedMove Stone_Golem true 2 3500 0 1 2 0 1 500 2 4000 1 800 4 500 0 -1 4 2000 1 2500 2 500 3 3000 -2 0 3 3000/advancedMove Leo true 2 5000 1 3000 2 3500 1 4000/addTemporaryActor Mummy 16 32 11 60 1 false Monster/playerControl halloween/viewport player clamp true unfreeze/globalFadeToClear",
  "Abigail_spouse_y2": "Have you ever fought any of these monsters before?$0#$e#Even... the s-spiders?$2",
  "Leah_spouse_y2": "I probably had too much pumpkin ale before jumping into the maze.$2#$e#You go on ahead. I'll catch up.$0",
  "Maru_spouse_y2": "Grab a plate and sit down with the family!$1",
  "Penny_spouse_y2": "*phew* I got lost in the maze...$3#$e#I was worried I might get trapped and everyone would go home without me!$12",
  "Emily_spouse_y2": "*giggle* I knew you'd find your way here.$0",
  "Haley_spouse_y2": "Hah! None of this is real.$h#$b#.... right, @? It's not real... right?$12",
  "Alex_spouse_y2": "Hey, you made it past the creepy hands.$1#$e#I think I hear someone calling for help nearby.$0",
  "Sebastian_spouse_y2": "Hey, could you... give me a hand? Hehehe...$h#$e#These gravestones would look nice on the farm, don't you think?$0",
  "Sam_spouse_y2": "My little brother and I made it pretty far in here but we got stuck.#$e#You go on ahead... find that treasure for us!",
  "Harvey_spouse_y2": "I was wondering when I'd see you.$1#$e#Don't mind me. I'm just taking a quick breather.$0",
  "Elliott_spouse_y2": "I shudder to think what would happen if these got loose...%noturn$2#$e#Fear not, my dear! I would run the cursed wretch through, before it could lay a finger on you.",
  "Shane_spouse_y2": "I talked Marnie into letting me take Jas into the maze. I think she's old enough.$0#$e#We're going very slow, though. Go ahead without us!$1",
  "Abigail_y2": "Did you see the decorations on our house? I don't like it...$2",
  "Robin_y2": "Are you looking forward to things slowing down soon? Winter is around the corner.$0",
  "Demetrius_y2": "Did you know... a study in the Journal of Anthropological Physiology found that the cadence, tempo, and key of music can have a measurable impact on cortisol levels?#$e#Er... Is there vanilla ice cream to go with the blackberry cobbler?$0",
  "Maru_y2": "After I finish this food, I'm going head-first into that maze!$0",
  "Sebastian_y2": "This is my spot.$0",
  "Pierre_y2": "Ah, it's farmer @! I have quite the selection of wares tonight. Take a look!$0",
  "Caroline_y2": "I should make a plate of food for my husband. He's been manning the shop all night.$0",
  "Linus_y2": "Haha! Another fine creation, my old friend.$1",
  "Alex_y2": "I think I heard a girl screaming... She needs my help!$0",
  "George_y2": "If I wasn't in this blasted chair, I'd be running circles around everyone in that maze!$0",
  "Evelyn_y2": "Dear, can you pass the zucchini fritters please?$0",
  "Lewis_y2": "Good evening, @. Once again, we've been graced with a haunted maze, constructed in secret by the eccentric who lives out in the forest.$0#$e#I've heard it's larger this year. Good luck if you dare to venture inside...",
  "Clint_y2": "I already made it through the maze... now it's time to kick back with a pumpkin ale!#$e#...I'm trying my best to ignore the spider infestation behind me.$0",
  "Emily_y2": "Ooooh. You found the secret entrance too!$1",
  "Penny_y2": "I was in the maze for a while but then I got hungry.$0#$e#My Mom seems to be enjoying herself.$0",
  "Pam_y2": "Pass another bottle of pumpkin ale over here!... *hic*$1",
  "Haley_y2": "Have you seen my sister?$2#$e#Emily! Can you hear me?$2",
  "Jodi_y2": "Sam took Vincent into the maze. I hope they're okay...$0",
  "Kent_y2": "These things don't look so tough.$0",
  "Sam_y2": "Am I Sam? Heh, heh, heh...$11",
  "Leah_y2": "Is it this way? Or maybe over here?$0",
  "Marnie_y2": "I hope Jas is okay in there.$2#$e#Did you have a successful year farming, @?",
  "Elliott_y2": "Oh pitiful wretch... in what fetid grotto lies your kingdom?%noturn$0#$e#Sometimes, one must stare into the abyss to stir a languid muse...",
  "Gus_y2": "Carving pumpkins is a talent of mine. I usually do most of the Jack-O-Lanterns for everyone in town.#$b#All I ask in return is to keep the seeds... sprinkle a little cinnamon sugar on those puppies and you've got yourself a golden snack!$h",
  "Dwarf_y2": "This place is very strange...$0",
  "Wizard_y2": "The trials continue... Every magician must have an apprentice...",
  "Harvey_y2": "I'm afraid to say I'm quite puzzled on this one...$0",
  "Shane_y2": "You gotta stay close to me, Jas. Don't run off!%noturn$0",
  "Sandy_y2": "I heard it's raining back home. Is that why you came here?$h#$e#I kind of miss the rain, actually...$s",
  "Jas_y2": "Let's go this way!%noturn$1",
  "Willy_y2": "I'd watch yer back, lad... something terrible's in that maze...^I'd watch yer back, miss... something terrible's in that maze...",
  "Vincent_y2": "Did we beat the maze? Where's my prize?$0",
  "Marlon_y2": "I caught more monsters this year. Mind your distance near the cages.",
  "Leo_y2": "This is a maze inside of a maze... My head is spinning...$0",
  "Krobus_y2": "Wh-what are you doing here?$0"
}

Format

field key explanation
name The festival name. This is used in display text like the calendar tooltip or the festival-is-ready message.
conditions When and where the festival takes place. The format is <location>/<start time> <end time>, where <location> is the internal location name and the times are specified in 26-hour format (i.e., 600 for 6am to 2600 for 2am).
mainEvent 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.
shop The items the festival shop sells. See shop format below.
set-up The event script that's run when the player first enters the festival. This includes moving the player to the festival map.
Set-Up_additionalCharacters NPCs to spawn when the festival loads. This is specified as four space-delimited fields in the form <NPC name> <tile X> <tile Y> <facing direction>, repeated for each NPC to add with a / between each NPC. The <facing direction> can be one of up or 0, down or 2, left or 3, and right or 1. These are additional to the NPCs spawned via the map file. For example, this adds Abigail and Leah side-by-side facing down:
"Set-Up_additionalCharacters": "Abigail 15 6 down/Leah 16 6 down"
startedMessage A tokenizable string for a custom festival-started notification message.
MainEvent_additionalCharacters, or
Main-Event_additionalCharacters for the Festival of Ice
NPCs to spawn when the festival's mainEvent script is run. Just like mainEvent, this is absent for events that do not have a prompt to start a new scene. The format is identical to Set-Up_additionalCharacters, above.
<NPC name>_roommate The dialog line the named NPC will say when the player talks to them, if they're roommates with the player. This field doesn't work on the Flower Dance festival and doesn't support #$e# breaks. If not specified, the <NPC name>_spouse will be used next.
<NPC name>_spouse The dialog line the named NPC will say when the player talks to them, if they're married to the player. This field doesn't work on the Flower Dance festival and doesn't support #$e# breaks.
<NPC name> The dialog line the named NPC will say when the player talks to them, if <NPC name>_spouse doesn't exist or apply.
locationDisplayName The location name in the festival-started message (e.g., "The Luau has begun on the beach") by default shows the internal name for non-vanilla festival locations. You can add this field to set the display name.

Any other entry is 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

All fields in the festival data allow annual variants. These work by adding _y<year variant> to the end of key, where the <year variant> is an incrementing number starting at 1 with no upper limit. For example, two entries set-up_y1 and set-up_y2 will alternate (set-up_y1 in year 1, set-up_y2 in year 2, set-up_y1 in year 3, etc). If year variants are defined for a key, the original key is ignored (e.g., set-up will never be used if set-up_y* entries are defined).

ⓘ
It is recommended to use the year variants for the Set-Up_additionalCharacters and MainEvent_additionalCharacters fields, even if you don't wish to spawn your custom NPC in different locations on odd and even years.
These keys are global to the festival data, and if any 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 <item type> <item ID> <cost> <count available>, which is repeated for each item. Field formats:

field explanation
<item type> The item type. The valid values are B or Boots (boots), BL or Blueprint (blueprint), BBL, BBl or BigBlueprint (big blueprint), BO or BigObject (bigcraftable object), F (furniture), H or Hat (hat), O or Object (object), R or Ring (ring), or W or Weapon (weapon).
<item id> The item's spritesheet index.
<cost> The purchase price in gold. For seeds, this is modified based on the profit margin.
<count available> How many of that item can be purchased from the shop, or -1 for unlimited.

Shop data may also be stored in Data/Shops and accessed via a map tile action, as non-festival shops are.

Map

Many festivals use a separate map file located in the Maps folder. The map to use is specified in the data file's set-up field using the changeToTemporaryMap command.

Spawned NPCs

ⓘ
This is fragile and not recommended for custom NPCs or festivals.
Consider using the data file's Set-Up_additionalCharacters field instead.

NPCs can be added to festivals using map tile indexes on a specific layer. This is enabled in the data file's set-up field using the loadActors <layer name> command. For each tile which exists on the layer, the tile index is mapped to the NPC's FestivalVanillaActorIndex field in the Data\Characters asset, 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 1. That matches Abigail's entry ("FestivalVanillaActorIndex": 0), with an offset of 1 so she's facing right. When the festival is loaded, Abigail 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.

See also

Modding:Passive Festival data for information about passive festivals.