Jump to content

Modding:Migrate to Stardew Valley 1.7: Difference between revisions

From Stardew Valley Wiki
imported>Pathoschild
imported>Pathoschild
split changes backported into 1.6.16 to Modding:Migrate to Stardew Valley 1.6.16, update XNB impact
Line 15: Line 15:


===Is this the modapocalypse?===
===Is this the modapocalypse?===
Probably not. SMAPI and Content Patcher will automatically rewrite older mods for many of the changes, so they should still work as-is. Some mods may require an update.
Probably not. SMAPI and Content Patcher will automatically rewrite older mods for many of the changes, so they should still work as-is. Some mods may need an update.


===How to update your mod===
===How to update your mod===
Line 21: Line 21:


; For C# mods:
; For C# mods:
:# [[Modding:Migrate to Stardew Valley 1.6.9#How to update your mod|Update for Stardew Valley 1.6.9]] if you haven't already.
:# [[Modding:Migrate to Stardew Valley 1.6.16#How to update your mod|Update for Stardew Valley 1.6.16]] if you haven't already.
:# Rebuild the solution.
:# Rebuild the solution.
:# Fix any build errors and review any build warnings. You can search this page and [[Modding:Index#Migration guides|previous migration guides]] for relevant info as needed.
:# Fix any build errors and review any build warnings. You can search this page and [[Modding:Index#Migration guides|previous migration guides]] for relevant info as needed.
Line 29: Line 29:


; For [[Modding:Content Patcher|Content Patcher]] packs:
; For [[Modding:Content Patcher|Content Patcher]] packs:
:# [[Modding:Migrate to Stardew Valley 1.6.9#How to update your mod|Update for Stardew Valley 1.6.9]] if you haven't already.
:# [[Modding:Migrate to Stardew Valley 1.6.16#How to update your mod|Update for Stardew Valley 1.6.16]] if you haven't already.
:# Skim through this page, and check any section that might be relevant to the mod.
:# Skim through this page, and check any section that might be relevant to the mod.


Line 123: Line 123:
| ''(Optional)'' The [[Modding:Common data field types#Custom fields|custom fields]] for this entry.
| ''(Optional)'' The [[Modding:Common data field types#Custom fields|custom fields]] for this entry.
|}
|}
===[[Modding:Maps#Sitting on non-furniture chairs|<samp>Data/ChairTiles</samp>]]===
* Fixed support for tilesheet asset names containing a dot. (For example, a tileseet asset named <code>ExampleAuthor.ModName_Tilesheet</code> now correctly uses that as the data key instead of <code>ExampleAuthor</code>.)
===[[Modding:Recipe data|<samp>Data/CookingRecipes</samp>]]===
These cooking recipe keys were changed to match their object name (like all the other recipes):
{| class="wikitable"
|-
! old name
! new name
|-
| Cheese Cauli.
| Cheese Cauliflower
|-
| Cookies
| Cookie
|-
| Cran. Sauce
| Cranberry Sauce
|-
| Dish o' The Sea
| Dish O' The Sea
|-
| Eggplant Parm.
| Eggplant Parmesan
|-
| Vegetable Stew
| Vegetable Medley
|}
This has no effect on the display text, but mods which reference these recipe keys will need to be updated.


===[[Modding:Event data|<samp>Data/Events/*</samp>]]===
===[[Modding:Event data|<samp>Data/Events/*</samp>]]===
Line 325: Line 293:
</nowiki>}}
</nowiki>}}


===[[Modding:Lost items shop|<samp>Data/LostItemsShop</samp>]]===
===[[Modding:Monster data|<samp>Data/Monsters</samp>]]===
Added one new field:
Monster data has been completely rethought in Stardew Valley 1.7. In particular...
{| class="wikitable"
* For monster data in general:
|-
** <samp>Data/Monsters</samp> has been been overhauled into a data model asset, with translations moved into a new <samp>Strings/Monsters</samp> asset. This includes significant new features which weren't supported with the old format.
! field
** A new 'monster variant' concept lets multiple specific monsters share common data (e.g. <samp>Green Slime</samp> and <samp>Tiger Slime</samp> are variants of the new base <samp>Slime</samp> monster). This is particularly used for common drops.
! effect
** A new 'monster tag' system lets monster define custom tags like <samp>slime_is_prismatic</samp>, which can be used to filter monster drops.
|-
* For monster drops:
| <samp>RequireCondition</samp>
** A rethought monster drop system supports the full range of vanilla features like [[Modding:Game state queries|conditions]], [[Modding:Item queries|item queries]], [[Modding:Common data field types#Item ID|qualified item IDs]] for non-object drops, and monster-specific concepts like repeating drop chance and mutually-exclusive drops.
| ''(Optional)'' The [[Modding:Game state queries|game state queries]] which must match to add this item. The <samp>Target</samp> player is the one being checked.
 
This field should generally only be used with deterministic game state queries.
|}
 
If you specify multiple criteria fields, only one is applied in this order: <samp>RequireMailReceived</samp>, then <samp>RequireEventSeen</samp>, then <samp>RequireCondition</samp>.
 
===[[Modding:Passive Festival data|<samp>Data/PassiveFestivals</samp>]]===
Added one new field:
{| class="wikitable"
|-
! field
! effect
|-
| <samp>InLocations</samp>
| ''(Optional)'' The locations in which the festival happens. This affects various game logic like NPC dialogues, tent placement restrictions, weather, etc. If omitted, defaults to the keys in <samp>MapReplacements</samp>.
|}
 
===[[Modding:Monster data|<samp>Data/Monsters</samp>]]===
Monster data has been completely rethought in Stardew Valley 1.7. In particular...
* For monster data in general:
** <samp>Data/Monsters</samp> has been been overhauled into a data model asset, with translations moved into a new <samp>Strings/Monsters</samp> asset. This includes significant new features which weren't supported with the old format.
** A new 'monster variant' concept lets multiple specific monsters share common data (e.g. <samp>Green Slime</samp> and <samp>Tiger Slime</samp> are variants of the new base <samp>Slime</samp> monster). This is particularly used for common drops.
** A new 'monster tag' system lets monster define custom tags like <samp>slime_is_prismatic</samp>, which can be used to filter monster drops.
* For monster drops:
** A rethought monster drop system supports the full range of vanilla features like [[Modding:Game state queries|conditions]], [[Modding:Item queries|item queries]], [[Modding:Common data field types#Item ID|qualified item IDs]] for non-object drops, and monster-specific concepts like repeating drop chance and mutually-exclusive drops.
** All drops are now [[Modding:Common data field types#Item ID|qualified item IDs]]. The former 'resource IDs' (formatted as negative numbers like <samp>-4</samp>) are no longer supported; items are converted into their equivalent resource debris automatically where needed.
** All drops are now [[Modding:Common data field types#Item ID|qualified item IDs]]. The former 'resource IDs' (formatted as negative numbers like <samp>-4</samp>) are no longer supported; items are converted into their equivalent resource debris automatically where needed.
** Nearly all monster drops are now defined in <samp>Data/Monsters</samp> (with just a few hardcoded drops common to all monsters left).
** Nearly all monster drops are now defined in <samp>Data/Monsters</samp> (with just a few hardcoded drops common to all monsters left).
Line 568: Line 510:
|}
|}


===[[Modding:Special orders|<samp>Data/SpecialOrders</samp>]]===
==Changes for all mod authors==
<ul>
===Switch blocks===
<li>Added one new field:
'Switch blocks' are a new <code>${…}$</code> syntax which can be used in nearly all game text (not just dialogue). This extends the former 'gender-switch blocks' [[Modding:Migrate to Stardew Valley 1.6#Gender changes|added in 1.6.0]].
 
These are applied before most other commands or parsing, so you can safely use them in cases where characters like <samp>^</samp> have a different meaning (e.g. mail text).
 
The supported switch blocks are:
{| class="wikitable"
{| class="wikitable"
|-
|-
! field
! type
! effect
! syntax
! description
|-
|-
| <samp>CanBeCancelled</samp>
| gender
| ''(Optional)'' Whether the special order can be cancelled. In multiplayer, any player cancelling the special order will remove it for all players. Default false.
| <code>${male^female}</code><br /><code>${male^female^non-binary}</code>
|}
| Switch between text for male, female, and non-binary players. The non-binary value is only used if a mod overrides the player's gender, since the in-game UI only allows male or female.
 
You can also use <samp>¦</samp> instead of <samp>^</samp>, in which case any <samp>^</samp> characters are left as-is.


And improved one field:
For example:
{| class="wikitable"
<syntaxhighlight lang="json">
"Mon": "Hey ${lad^lass^kiddo}$!"
</syntaxhighlight>
|-
|-
! field
| randomize
! effect
| <code>${variant A &#124;&#124;&#124; …}$</code>
|-
| Defines an arbitrary number of variants from which to choose each day. After randomization, any leading or trailing whitespace is trimmed. This randomization is deterministic per day (e.g. reloading the save won't change which one is shown).
| <samp>Duration</samp>
| This can now be set to <samp>"Indefinite"</samp> for a special order with no expiry. It will remain active until it's completed or cancelled. Consider enabling <samp>CanBeCancelled</samp> if applicable.
|}
</ul>


===[[Modding:Tools|<samp>Data/Tools</samp>]]===
For example, let's say you did this:
Added one field:
<syntaxhighlight lang="js">
{| class="wikitable"
"Rainy_Night": "I ${love ||| like ||| adore ||| somewhat enjoy ||| enjoy}$ rain.$h"
|-
</syntaxhighlight>
! field
 
! effect
That would create five variants which each have an equal probability of being selected.
|-
| <samp>ContextTags</samp>
| ''(Optional)'' The custom [[Modding:Context tags|context tags]] to add for this item (in addition to the tags added automatically based on the other item data), specified as an array.
|}
|}


===[[Modding:Weapons|<samp>Data/Weapons</samp>]]===
Switch blocks can be arbitrary combined and nested. For example:
Added one field:
<syntaxhighlight lang="js">
"Rainy_Night": "${Hello there ||| Hey ${lad^lass^kiddo}$ }$!"
</syntaxhighlight>
 
===[[Modding:Context tags|Context tag]] changes===
Added new context tags:
{| class="wikitable"
{| class="wikitable"
|-
|-
! field
! context tag
! item types
! effect
! effect
|-
|-
| <samp>ContextTags</samp>
| <samp>is_galaxy_weapon</samp>
| ''(Optional)'' The custom [[Modding:Context tags|context tags]] to add for this item (in addition to the tags added automatically based on the other item data), specified as an array.
| [[Modding:Weapons|weapons]]
| Marks the tool as a galaxy weapon like the [[Galaxy Hammer|galaxy hammer]] or [[Galaxy Sword|galaxy sword]]. This is set for vanilla scythes through <samp>Data/Weapons</samp>. This affects logic which checks for galaxy weapons (e.g. [[Galaxy Soul|galaxy soul]] enchantments).
|}
|}


==Changes for all mod authors==
===[[Modding:Dialogue|Dialogue]] changes===
===Switch blocks===
<ul>
'Switch blocks' are a new <code>${…}$</code> syntax which can be used in nearly all game text (not just dialogue). This extends the former 'gender-switch blocks' [[Modding:Migrate to Stardew Valley 1.6#Gender changes|added in 1.6.0]].
<li>Added a new [[Modding:Dialogue#Special tokens|special token]] in dialogue strings:
 
These are applied before most other commands or parsing, so you can safely use them in cases where characters like <samp>^</samp> have a different meaning (e.g. mail text).
 
The supported switch blocks are:
{| class="wikitable"
{| class="wikitable"
|-
|-
! type
! token
! syntax
! description
! description
|-
|-
| gender
| <code>&#124;&#124;&#124;</code>
| <code>${male^female}</code><br /><code>${male^female^non-binary}</code>
| This is a shortcut for the [[#Switch blocks|randomize switch block]].
| Switch between text for male, female, and non-binary players. The non-binary value is only used if a mod overrides the player's gender, since the in-game UI only allows male or female.


You can also use <samp>¦</samp> instead of <samp>^</samp>, in which case any <samp>^</samp> characters are left as-is.
Delimits an arbitrary number of dialogue variants from which to choose each day. After randomization, any leading or trailing whitespace is trimmed. This randomization is deterministic per day (e.g. reloading the save won't change which one is shown).
 
For example:
<syntaxhighlight lang="json">
"Mon": "Hey ${lad^lass^kiddo}$!"
</syntaxhighlight>
|-
| randomize
| <code>${variant A &#124;&#124;&#124; …}$</code>
| Defines an arbitrary number of variants from which to choose each day. After randomization, any leading or trailing whitespace is trimmed. This randomization is deterministic per day (e.g. reloading the save won't change which one is shown).


For example, let's say you did this:
For example, let's say you did this:
<syntaxhighlight lang="js">
<syntaxhighlight lang="js">
"Rainy_Night": "I ${love ||| like ||| adore ||| somewhat enjoy ||| enjoy}$ rain.$h"
"Rainy_Night": "
</syntaxhighlight>
    I love rain.$h|||
 
    I like rain.$h|||
That would create five variants which each have an equal probability of being selected.
    I adore rain.$h|||
|}
    I hate rain.$s#$b#Just kidding. I love it!$h|||
 
    I enjoy rain.$h
Switch blocks can be arbitrary combined and nested. For example:
"
<syntaxhighlight lang="js">
"Rainy_Night": "${Hello there ||| Hey ${lad^lass^kiddo}$ }$!"
</syntaxhighlight>
</syntaxhighlight>


===[[Modding:Context tags|Context tag]] changes===
That would create five variants of the dialogue which each have an equal probability of being selected.
Added new context tags:
|}</li>
<li>Improved some [[Modding:Dialogue#Special tokens|special tokens]]:
{| class="wikitable"
{| class="wikitable"
|-
|-
! context tag
! token
! item types
! changes
! effect
|-
|-
| <samp>axe</samp><br /><samp>error_tool</samp><br /><samp>fishing_rod</samp><br /><samp>generic_tool</samp><br /><samp>hoe</samp><br /><samp>lantern</samp><br /><samp>melee_weapon</samp><br /><samp>milk_pail</samp><br /><samp>pan</samp><br /><samp>pickaxe</samp><br /><samp>raft</samp><br /><samp>shears</samp><br /><samp>slingshot</samp><br />[[Return Scepter|<samp>wand</samp>]]<br /><samp>watering_can</samp>
| <code>&#124;&#124;</code>
| [[Modding:Tools|tools]] and [[Modding:Weapons|weapons]]
| Whitespace around the token is now ignored, so you can split text into multiple lines:
| The C# type which implements the tool or melee weapon.
<syntaxhighlight lang="js">
 
"Wed8": "
Note that the vanilla scythes are <samp>melee_weapon</samp>.
    Isn't it expensive, coming to the desert so often like you do?#$e#You must really like to see me, huh? Hmmm... $h||
|-
    *sigh*... I do miss the beautiful flowers of Stardew Valley...$s
| <samp>fish_skip_minigame</samp>
"
| ''any''
</syntaxhighlight>
| If the player catches this item while fishing, it'll be caught directly without the fishing minigame. This matches the behavior when catching junk items like [[seaweed]] (which now have the context tag where needed).
|}</li>
|-
<li>Some dialogues were merged or renamed using the new features. The previous dialogue keys are now ignored by the game.
| <samp>ignore_gift_limits</samp>
| ''any giftable item''
| Whether this item ignores the gift limits when given as a gift (similar to [[Stardrop Tea|stardrop tea]]). Items with this tag don't count towards the daily/weekly limits, and can be given even if those limits have been reached.
|-
| <samp>is_galaxy_weapon</samp>
| [[Modding:Weapons|weapons]]
| Marks the tool as a galaxy weapon like the [[Galaxy Hammer|galaxy hammer]] or [[Galaxy Sword|galaxy sword]]. This is set for vanilla scythes through <samp>Data/Weapons</samp>. This affects logic which checks for galaxy weapons (e.g. [[Galaxy Soul|galaxy soul]] enchantments).
|-
| <samp>is_scythe</samp>
| [[Modding:Tools|tools]] and [[Modding:Weapons|weapons]]
| Marks the tool as a [[scythe]]. This is set for vanilla scythes through <samp>Data/Weapons</samp>.
|-
| <samp>spawns_butterflies</samp>
| [[Modding:Furniture|furniture]]
| Whether butterflies spawn around this furniture, similar to the [[Butterfly Hutch|butterfly hutch]].
|-
| <samp>upgrade_level_*</samp>
| [[Modding:Tools|tools]] and [[Modding:Weapons|weapons]]
| The tool upgrade level. These tags are added automatically based on the tool's current level. For example, a copper [[axe]] will have both <samp>upgrade_level_0</samp> (base axe) and <samp>upgrade_level_1</samp> (copper axe).
|}
 
===[[Modding:Console commands|Debug command]] changes===
Improved existing commands:


{| class="wikitable"
{| class="wikitable"
|-
|-
! command
! asset
! description
! former key
! changes
|-
|-
| <samp>jump</samp>
| <samp>Characters/Dialogue/{{t|NPC name}}</samp>
| Fixed error if the NPC doesn't exist.
| <samp><samp>Resort_{{t|number}}</samp><br /><samp>Resort_Bar_{{t|number}}</samp><br /><samp>Resort_Chair_{{t|number}}</samp><br /><samp>Resort_Dance_{{t|number}}</samp><br /><samp>Resort_Shore_{{t|number}}</samp><br /><samp>Resort_Towel_{{t|number}}</samp><br /><samp>Resort_Umbrella_{{t|number}}</samp><br /><samp>Resort_Wander_{{t|number}}</samp>
| Merged into their base key (e.g. <samp>Resort_{{t|random}}</samp> into <samp>Resort</samp>) using the new <code>&#124;&#124;&#124;</code> random-variant token.
|-
|-
| <samp>perfection</samp>
|rowspan="7"| <samp>Characters/Dialogue/MarriageDialogue</samp><br /><samp>Characters/Dialogue/MarriageDialogue{{t|NPC name}}</samp><br /><samp>Characters/Dialogue/MarriageDialogue{{t|NPC name}}Roommates</samp>
| Fixed error when run on a save which already has some requirements partly met.
| <samp>funLeave_{{t|NPC name}}</samp><br /><samp>funReturn_{{t|NPC name}}</samp><br /><samp>jobLeave_{{t|NPC name}}</samp><br /><samp>jobReturn_{{t|NPC name}}</samp><br /><br /><samp>patio_{{t|NPC name}}</samp><br /><samp>spouseRoom_{{t|NPC name}}</samp><br /><br /><samp>spring_{{t|NPC name}}</samp><br /><samp>summer_{{t|NPC name}}</samp><br /><samp>fall_{{t|NPC name}}</samp><br /><samp>winter_{{t|NPC name}}</samp>
|}
| Moved into <samp>MarriageDialogue{{t|NPC name}}</samp> and removed the NPC suffix (like <samp>spouseRoom_{{t|NPC name}}</samp> → <samp>spouseRoom</samp>).
 
|-
===[[Modding:Dialogue|Dialogue]] changes===
| <samp>Indoor_Day_0</samp><br /><samp>Indoor_Day_1</samp><br /><samp>Indoor_Day_2</samp><br /><samp>Indoor_Day_3</samp><br /><samp>Indoor_Day_4</samp>
<ul>
| Merged into <samp>Indoor_Day</samp>.
<li>Added a new [[Modding:Dialogue#Special tokens|special token]] in dialogue strings:
|-
{| class="wikitable"
| <samp>Indoor_Night_0</samp><br /><samp>Indoor_Night_1</samp><br /><samp>Indoor_Night_2</samp><br /><samp>Indoor_Night_3</samp><br /><samp>Indoor_Night_4</samp><br /><samp>Indoor_Night_{{t|NPC name}}</samp>
| Merged into <samp>Indoor_Night</samp>.
|-
| <samp>NoBed_0</samp><br /><samp>NoBed_1</samp><br /><samp>NoBed_2</samp><br /><samp>NoBed_3</samp>
| Merged into <samp>NoBed</samp>.
|-
| <samp>Outdoor_0</samp><br /><samp>Outdoor_1</samp><br /><samp>Outdoor_2</samp><br /><samp>Outdoor_3</samp><br /><samp>Outdoor_4</samp><br /><samp>Outdoor_{{t|NPC name}}</samp>
| Merged into <samp>Outdoor</samp>.
|-
|-
! token
| <samp>Rainy_Day_0</samp><br /><samp>Rainy_Day_1</samp><br /><samp>Rainy_Day_2</samp><br /><samp>Rainy_Day_3</samp><br /><samp>Rainy_Day_4</samp>
! description
| Merged into <samp>Rainy_Day</samp>.
|-
|-
| <code>&#124;&#124;&#124;</code>
| <samp>Rainy_Night_0</samp><br /><samp>Rainy_Night_1</samp><br /><samp>Rainy_Night_2</samp><br /><samp>Rainy_Night_3</samp><br /><samp>Rainy_Night_4</samp><br /><samp>Rainy_Night_5</samp><br /><samp>Rainy_Night_{{t|NPC name}}</samp>
| This is a shortcut for the [[#Switch blocks|randomize switch block]].
| Merged into <samp>Rainy_Night</samp>.
|}</li>
</ul>


Delimits an arbitrary number of dialogue variants from which to choose each day. After randomization, any leading or trailing whitespace is trimmed. This randomization is deterministic per day (e.g. reloading the save won't change which one is shown).
===Enchantment data===
[[Forge#Enchantments|Enchantments]] have been '''partly''' de-hardcoded into a new <samp>Data/Enchantments</samp> data asset. Mods can now easily add new enchantments, including enchantments applied through the [[forge]] using a [[Prismatic Shard|prismatic shard]] or a custom item ID.
 
However, this logic is still hardcoded:
* Forging [[Forge#Innate enchantments|innate enchantments]]. The innate enchantments are in data, but the logic to choose which to apply is still hardcoded.
* Forging [[diamond]]s into a weapon to fill all its [[Forge#Weapon forging|weapon stat slots]].
* Forging three [[Galaxy Soul|galaxy souls]] into galaxy weapons to transform them into infinity weapons. (The 'Galaxy Soul' enchantment is in data, but the transformation is hardcoded.)
* Several enchantments' effects when applied (though weapon buff effects are in data).


For example, let's say you did this:
This consists of a string → model lookup, where...
<syntaxhighlight lang="js">
* The key is the [[Modding:Common data field types#Unique string ID|unique string ID]] for the enchantment.
"Rainy_Night": "
* The value is a model with the fields listed below.
    I love rain.$h|||
    I like rain.$h|||
    I adore rain.$h|||
    I hate rain.$s#$b#Just kidding. I love it!$h|||
    I enjoy rain.$h
"
</syntaxhighlight>


That would create five variants of the dialogue which each have an equal probability of being selected.
|}</li>
<li>Added new dialogue keys:
{| class="wikitable"
{| class="wikitable"
|-
|-
! key
! field
! description
! effect
|-
|-
| ''passive festival dialogue''
| <samp>DisplayName</samp>
| Identical to [[Modding:Dialogue#Location dialogue|location dialogue]], but you can use the passive festival ID as the location name. Any passive festival dialogue has priority over location dialogue in the same location.
| A [[Modding:Tokenizable strings|tokenizable string]] for the enchantment's display name, shown in tooltips. This can contain <samp>{0}</samp> for the enchantment level, if applicable.
|}</li>
<li>Improved some [[Modding:Dialogue#Special tokens|special tokens]]:
{| class="wikitable"
|-
|-
! token
| <samp>ForgeWith</samp>
! changes
| ''(Optional)'' If set, this enchantment is applied to tools by [[Forge|forging]] an item with this qualified ID into it. Default none, in which case it won't be applicable through the forge.
|-
|-
| <code>&#124;&#124;</code>
| <samp>AppliesTo</samp>
| Whitespace around the token is now ignored, so you can split text into multiple lines:
| ''(Optional)'' The tools or weapons to which this enchantment can be applied. Defaults to all tools/weapons.
 
This is specified as an array of [[Modding:Context tags|context tag]] queries. The enchantment can be applied if at least one query matches.
<syntaxhighlight lang="js">
<syntaxhighlight lang="js">
"Wed8": "
"AppliesTo": [
     Isn't it expensive, coming to the desert so often like you do?#$e#You must really like to see me, huh? Hmmm... $h||
     "melee_weapon, !is_scythe", // any non-scythe melee weapon
     *sigh*... I do miss the beautiful flowers of Stardew Valley...$s
     "hoe, upgrade_level_4"      // any hoe upgraded to iridium or higher
"
]
</syntaxhighlight>
</syntaxhighlight>
|}</li>
<li>Some dialogues were merged or renamed using the new features. The previous dialogue keys are now ignored by the game.
{| class="wikitable"
|-
|-
! asset
| <samp>IsForge</samp>
! former key
| ''(Optional)'' Whether this is a [[Forge#Weapon forging|weapon stat enchantment]] applied through the [[forge]]. Default false.
! changes
|-
|-
| <samp>Characters/Dialogue/{{t|NPC name}}</samp>
| <samp>IsSecondary</samp>
| <samp><samp>Resort_{{t|number}}</samp><br /><samp>Resort_Bar_{{t|number}}</samp><br /><samp>Resort_Chair_{{t|number}}</samp><br /><samp>Resort_Dance_{{t|number}}</samp><br /><samp>Resort_Shore_{{t|number}}</samp><br /><samp>Resort_Towel_{{t|number}}</samp><br /><samp>Resort_Umbrella_{{t|number}}</samp><br /><samp>Resort_Wander_{{t|number}}</samp>
| ''(Optional)'' Whether this is an [[Forge#Innate enchantments|innate enchantment]] applied through the [[forge]] using a [[Dragon Tooth|dragon tooth]]. Default false.
| Merged into their base key (e.g. <samp>Resort_{{t|random}}</samp> into <samp>Resort</samp>) using the new <code>&#124;&#124;&#124;</code> random-variant token.
|-
|-
|rowspan="7"| <samp>Characters/Dialogue/MarriageDialogue</samp><br /><samp>Characters/Dialogue/MarriageDialogue{{t|NPC name}}</samp><br /><samp>Characters/Dialogue/MarriageDialogue{{t|NPC name}}Roommates</samp>
| <samp>IsVisible</samp>
| <samp>funLeave_{{t|NPC name}}</samp><br /><samp>funReturn_{{t|NPC name}}</samp><br /><samp>jobLeave_{{t|NPC name}}</samp><br /><samp>jobReturn_{{t|NPC name}}</samp><br /><br /><samp>patio_{{t|NPC name}}</samp><br /><samp>spouseRoom_{{t|NPC name}}</samp><br /><br /><samp>spring_{{t|NPC name}}</samp><br /><samp>summer_{{t|NPC name}}</samp><br /><samp>fall_{{t|NPC name}}</samp><br /><samp>winter_{{t|NPC name}}</samp>
| ''(Optional)'' Whether the enchantment should be shown in the tool/weapon's tooltip. Default true.
| Moved into <samp>MarriageDialogue{{t|NPC name}}</samp> and removed the NPC suffix (like <samp>spouseRoom_{{t|NPC name}}</samp> → <samp>spouseRoom</samp>).
|-
|-
| <samp>Indoor_Day_0</samp><br /><samp>Indoor_Day_1</samp><br /><samp>Indoor_Day_2</samp><br /><samp>Indoor_Day_3</samp><br /><samp>Indoor_Day_4</samp>
| <samp>MaximumLevel</samp>
| Merged into <samp>Indoor_Day</samp>.
| ''(Optional)'' The number of times this enchantment can be applied to the same tool to upgrade the enchantment level (e.g. for [[Forge#Weapon forging|weapon stat enchantments]]). A value of 1 means there's only one enchantment level, so it can't be upgraded by applying the enchantment again. Default 1.
|-
|-
| <samp>Indoor_Night_0</samp><br /><samp>Indoor_Night_1</samp><br /><samp>Indoor_Night_2</samp><br /><samp>Indoor_Night_3</samp><br /><samp>Indoor_Night_4</samp><br /><samp>Indoor_Night_{{t|NPC name}}</samp>
| <samp>EquipmentEffects</samp>
| Merged into <samp>Indoor_Night</samp>.
| ''(Optional)'' The buffs applied to the weapon when this enchantment is applied.
 
This consists of a list of models with the fields below. You can specify any number of entries; the first one which matches the tool will be applied.
{| class="wikitable"
|-
|-
| <samp>NoBed_0</samp><br /><samp>NoBed_1</samp><br /><samp>NoBed_2</samp><br /><samp>NoBed_3</samp>
! field
| Merged into <samp>NoBed</samp>.
! effect
|-
|-
| <samp>Outdoor_0</samp><br /><samp>Outdoor_1</samp><br /><samp>Outdoor_2</samp><br /><samp>Outdoor_3</samp><br /><samp>Outdoor_4</samp><br /><samp>Outdoor_{{t|NPC name}}</samp>
| <samp>Id</samp>
| Merged into <samp>Outdoor</samp>.
| A [[Modding:Common data field types#Unique string ID|unique string ID]] for this entry.
|-
| <samp>MinLevel</samp>
| ''(Optional)'' The minimum enchantment level for which these stats apply. Default 0 (i.e. any level).
|-
| ''other fields''
| See the <samp>Effects</samp> field [[Modding:Buffs|in <samp>Data/Buffs</samp>]], which is equivalent to this model.
|}
|-
!colspan="2"| advanced
|-
|-
| <samp>Rainy_Day_0</samp><br /><samp>Rainy_Day_1</samp><br /><samp>Rainy_Day_2</samp><br /><samp>Rainy_Day_3</samp><br /><samp>Rainy_Day_4</samp>
| <samp>CustomFields</samp>
| Merged into <samp>Rainy_Day</samp>.
| ''(Optional)'' The [[Modding:Common data field types#Custom fields|custom fields]] for this entry.
|-
|-
| <samp>Rainy_Night_0</samp><br /><samp>Rainy_Night_1</samp><br /><samp>Rainy_Night_2</samp><br /><samp>Rainy_Night_3</samp><br /><samp>Rainy_Night_4</samp><br /><samp>Rainy_Night_5</samp><br /><samp>Rainy_Night_{{t|NPC name}}</samp>
| <samp>ClassName</samp>
| Merged into <samp>Rainy_Night</samp>.
| ''(Optional, specialized)'' The name of the C# class to construct within the <code>StardewValley.Enchantments</code> namespace. The class must be a subclass of <samp>StardewValley.Enchantments.Enchantment</samp>, and have a constructor with no arguments. For example, given a value of <samp>BottomlessEnchantment</samp>, the game will create <code>StardewValley.Enchantments.BottomlessEnchantment</code> instances.
|}</li>
<li>Fixed <samp>{{t|location}}_{{t|x}}_{{t|y}}</samp> and <samp>{{t|location}}_{{t|dayOfWeek}}</samp> dialogue keys never used in 1.6.0+ if a player has at least two hearts with the NPC.</li>
<li>Fixed [[Modding:Dialogue#Location dialogue|location dialogues]] not recognizing the <samp>spring</samp> prefix (they only allowed <samp>summer</samp>, <samp>fall</samp>, and <samp>winter</samp>).</li>
<li>Fixed <samp>$r</samp> response IDs not tracked correctly if you reuse an NPC reaction key across multiple <samp>$r</samp> options.</li>
</ul>


===Enchantment data===
This should usually be omitted, in which case the game will create a generic <samp>Enchantment</samp> instance which uses the data in <samp>Data/Enchantments</samp> for its ID.
[[Forge#Enchantments|Enchantments]] have been '''partly''' de-hardcoded into a new <samp>Data/Enchantments</samp> data asset. Mods can now easily add new enchantments, including enchantments applied through the [[forge]] using a [[Prismatic Shard|prismatic shard]] or a custom item ID.
|}


However, this logic is still hardcoded:
===[[Modding:Event data|Event]] changes===
* Forging [[Forge#Innate enchantments|innate enchantments]]. The innate enchantments are in data, but the logic to choose which to apply is still hardcoded.
====Multilingual events====
* Forging [[diamond]]s into a weapon to fill all its [[Forge#Weapon forging|weapon stat slots]].
All vanilla events are now multilingual, with a single copy of each event script which uses translation keys. Translations from the old per-language event files were moved into a per-language <samp>Strings/Events</samp> file.
* Forging three [[Galaxy Soul|galaxy souls]] into galaxy weapons to transform them into infinity weapons. (The 'Galaxy Soul' enchantment is in data, but the transformation is hardcoded.)
* Several enchantments' effects when applied (though weapon buff effects are in data).
 
This consists of a string → model lookup, where...
* The key is the [[Modding:Common data field types#Unique string ID|unique string ID]] for the enchantment.
* The value is a model with the fields listed below.


For example:
{| class="wikitable"
{| class="wikitable"
|-
|-
! field
! files in 1.6.16
! effect
! files in 1.7
|-
|-
| <samp>DisplayName</samp>
| <pre>
| A [[Modding:Tokenizable strings|tokenizable string]] for the enchantment's display name, shown in tooltips. This can contain <samp>{0}</samp> for the enchantment level, if applicable.
Data/Events/Beach
|-
Data/Events/Beach.de-DE
| <samp>ForgeWith</samp>
Data/Events/Beach.es-ES
| ''(Optional)'' If set, this enchantment is applied to tools by [[Forge|forging]] an item with this qualified ID into it. Default none, in which case it won't be applicable through the forge.
Data/Events/Beach.fr-FR
|-
Data/Events/Beach.hu-HU
| <samp>AppliesTo</samp>
Data/Events/Beach.it-IT
| ''(Optional)'' The tools or weapons to which this enchantment can be applied. Defaults to all tools/weapons.
Data/Events/Beach.ja-JP
Data/Events/Beach.ko-KR
Data/Events/Beach.pt-BR
Data/Events/Beach.ru-RU
Data/Events/Beach.tr-TR
Data/Events/Beach.zh-CN
</pre>
|valign="top"| <pre>
Data/Events/Beach
</pre>
|}
 
[[Modding:Content Patcher|Content Patcher]] content packs should generally be unaffected, since their edits were applied to the active version of the file automatically (which will just become the base file in all languages).
 
In rare cases, a mod which directly targets a specific localized asset name like <code>Data/Events/Beach.fr-FR</code> may no longer work or break vanilla events (depending on how it edits them). That should be a very rare case, since the APIs for both Content Patcher and SMAPI were designed to discourage doing that.
 
====Forking deprecated====
All vanilla events which used forking now use [[#New event commands|goto labels]] instead.


This is specified as an array of [[Modding:Context tags|context tag]] queries. The enchantment can be applied if at least one query matches.
'''Forking still works like before''' for backwards compatibility, but mod events should prefer goto labels since...
<syntaxhighlight lang="js">
* they work more consistently and intuitively with other features like skip labels;
"AppliesTo": [
* it's the approach that the game will be applying and developing in future versions;
    "melee_weapon, !is_scythe", // any non-scythe melee weapon
* deprecated commands will be reported as an error if you use the [[#EventValidator|<samp>EventValidator</samp>]];
    "hoe, upgrade_level_4"      // any hoe upgraded to iridium or higher
* and there's no guarantee forking will always work in future versions.
]
 
</syntaxhighlight>
The [[#Deprecated commands|fork-related event commands are deprecated]].
 
====Precondition slash now required for numeric event IDs====
In Stardew Valley 1.6.0–16, the behavior of an event key with no <code>/</code> depended on whether the ID was numeric. A numeric event ID like <code>10040609</code> was treated as an event with no precondition, while a string event ID like <code>PlayerKilled</code> was treated as a manual script. In 1.7+, the behavior is now consistent: any event ID without a slash (like <code>10040609</code>) is treated as a manual script, and any with a slash (like <code>10040609/</code>) is treated as an event.
 
In other words:
 
{| class="wikitable"
|-
|-
| <samp>IsForge</samp>
! event key format
| ''(Optional)'' Whether this is a [[Forge#Weapon forging|weapon stat enchantment]] applied through the [[forge]]. Default false.
! behavior in 1.6.16
! &rarr;
! behavior in 1.7
|-
|-
| <samp>IsSecondary</samp>
| <samp>{{t|id}}</samp>
| ''(Optional)'' Whether this is an [[Forge#Innate enchantments|innate enchantment]] applied through the [[forge]] using a [[Dragon Tooth|dragon tooth]]. Default false.
| event if numeric, else manual script
| &rarr;
| manual script
|-
|-
| <samp>IsVisible</samp>
| <samp>{{t|id}}/{{o|preconditions}}</samp>
| ''(Optional)'' Whether the enchantment should be shown in the tool/weapon's tooltip. Default true.
| event
|-
| &rarr;
| <samp>MaximumLevel</samp>
| event
| ''(Optional)'' The number of times this enchantment can be applied to the same tool to upgrade the enchantment level (e.g. for [[Forge#Weapon forging|weapon stat enchantments]]). A value of 1 means there's only one enchantment level, so it can't be upgraded by applying the enchantment again. Default 1.
|}
 
====New event commands====
{| class="wikitable"
|-
! command
! description
|-
|-
| <samp>EquipmentEffects</samp>
| <samp>choose {{t|question}} [{{t|answer}} {{t|go to label}}]+</samp>
| ''(Optional)'' The buffs applied to the weapon when this enchantment is applied.
| Show a dialogue box to choose from a list of responses, then optionally skip to a label based on the selected answer.


This consists of a list of models with the fields below. You can specify any number of entries; the first one which matches the tool will be applied.
Arguments:
{| class="wikitable"
{| class="wikitable"
|-
|-
! field
! argument
! effect
! usage
|-
|-
| <samp>Id</samp>
| {{t|question}}
| A [[Modding:Common data field types#Unique string ID|unique string ID]] for this entry.
| The [[Modding:Common data field types#Translation key|translation key]] or literal text to show above the choices. This can be empty (<code>""</code>) to omit the question line.
|-
|-
| <samp>MinLevel</samp>
| {{t|answer}}
| ''(Optional)'' The minimum enchantment level for which these stats apply. Default 0 (i.e. any level).
| The [[Modding:Common data field types#Translation key|translation key]] or literal text for an answer to show.
|-
| ''other fields''
| See the <samp>Effects</samp> field [[Modding:Buffs|in <samp>Data/Buffs</samp>]], which is equivalent to this model.
|}
|-
|-
!colspan="2"| advanced
| {{t|go to label}}
|-
| If the player chooses this answer, jump to this label in the event (see the <samp>goto</samp> command for more info). This can be <code>""</code> or <code>_</code> to continue to the next command instead.
| <samp>CustomFields</samp>
| ''(Optional)'' The [[Modding:Common data field types#Custom fields|custom fields]] for this entry.
|-
| <samp>ClassName</samp>
| ''(Optional, specialized)'' The name of the C# class to construct within the <code>StardewValley.Enchantments</code> namespace. The class must be a subclass of <samp>StardewValley.Enchantments.Enchantment</samp>, and have a constructor with no arguments. For example, given a value of <samp>BottomlessEnchantment</samp>, the game will create <code>StardewValley.Enchantments.BottomlessEnchantment</code> instances.
 
This should usually be omitted, in which case the game will create a generic <samp>Enchantment</samp> instance which uses the data in <samp>Data/Enchantments</samp> for its ID.
|}
|}


===[[Modding:Event data|Event]] changes===
For example, here's a simple choice which doesn't affect anything:
====Multilingual events====
<pre>choose "Do you like apples?" "I love them." _ "I hate them." _/</pre>
All vanilla events are now multilingual, with a single copy of each event script which uses translation keys. Translations from the old per-language event files were moved into a per-language <samp>Strings/Events</samp> file.


For example:
Or you can change the course of the event based on the choice:
{| class="wikitable"
<pre>
|-
speak Abigail "Do you... like me?$l"/
! files in 1.6.15
choose "" "Yes!" happy "No." heartbroken/
! files in 1.7
|-
| <pre>
Data/Events/Beach
Data/Events/Beach.de-DE
Data/Events/Beach.es-ES
Data/Events/Beach.fr-FR
Data/Events/Beach.hu-HU
Data/Events/Beach.it-IT
Data/Events/Beach.ja-JP
Data/Events/Beach.ko-KR
Data/Events/Beach.pt-BR
Data/Events/Beach.ru-RU
Data/Events/Beach.tr-TR
Data/Events/Beach.zh-CN
</pre>
|valign="top"| <pre>
Data/Events/Beach
</pre>
|}


[[Modding:Content Patcher|Content Patcher]] content packs should generally be unaffected, since their edits were applied to the active version of the file automatically (which will just become the base file in all languages).
label heartbroken/
speak Abigail "Oh. I understand.$s"/
faceDirection Abigail left/
pause 3000/
end/


In rare cases, a mod which directly targets a specific localized asset name like <code>Data/Events/Beach.fr-FR</code> may no longer work or break vanilla events (depending on how it edits them). That should be a very rare case, since the APIs for both Content Patcher and SMAPI were designed to discourage doing that.
label happy/
 
speak Abigail "We should explore the mines together next time!$h"/
====Forking deprecated====
...
All vanilla events which used forking now use [[#New event commands|goto labels]] instead.
</pre>
 
|-
'''Forking still works like before''' for backwards compatibility, but mod events should prefer goto labels since...
| <samp>conditionSpeak {{t|npc}} [{{t|dialogue}} {{o|condition}}]+</samp>
* they work more consistently and intuitively with other features like skip labels;
| Make an NPC say a dialogue based on arbitrary conditions. The first dialogue with a matching dialogue is spoken; if none match, the command is skipped.
* it's the approach that the game will be applying and developing in future versions;
* deprecated commands will be reported as an error if you use the [[#EventValidator|<samp>EventValidator</samp>]];
* and there's no guarantee forking will always work in future versions.
 
The [[#Deprecated commands|fork-related event commands are deprecated]].
 
====Precondition slash now required for numeric event IDs====
In Stardew Valley 1.6.0–15, the behavior of an event key with no <code>/</code> depended on whether the ID was numeric. A numeric event ID like <code>10040609</code> was treated as an event with no precondition, while a string event ID like <code>PlayerKilled</code> was treated as a manual script. In 1.7+, the behavior is now consistent: any event ID without a slash (like <code>10040609</code>) is treated as a manual script, and any with a slash (like <code>10040609/</code>) is treated as an event.
 
In other words:


Arguments:
{| class="wikitable"
{| class="wikitable"
|-
|-
! event key format
! argument
! behavior in 1.6.15
! usage
! &rarr;
! behavior in 1.7
|-
|-
| <samp>{{t|id}}</samp>
| {{t|npc}}
| event if numeric, else manual script
| The internal name of the NPC who should speak (which can be [[Modding:Event data#Optional NPCs|marked optional]]).
| &rarr;
|-
| manual script
| {{t|dialogue}}
| The [[Modding:Common data field types#Translation key|translation key]] or literal text for the dialogue to speak. If omitted or empty, the command is skipped when the condition is matched.
|-
|-
| <samp>{{t|id}}/{{o|preconditions}}</samp>
| {{o|condition}}
| event
| One of:
| &rarr;
* a [[Modding:Game state queries|game state query]];
| event
* or <samp>ANSWERED {{t|response ID}}+</samp> as a shortcut for the <samp>PLAYER_HAS_DIALOGUE_ANSWER Current</samp> query;
* or omitted/blank to always match this dialogue if no previous one matched.
|}
|}


====New event commands====
For example, here Maru says a different line if the player suggested she tell the truth:
<pre>conditionSpeak Maru "I accidentally dropped one of the samples... I'm so sorry.$s" "ANSWERED 38" "@ came in and slammed the door so loud I dropped this sample.$u"</pre>
|-
| <samp>goto [{{t|target}} {{o|condition}}]+</samp>
| Skip forward or backward to a specific position in the event script. Each {{t|target}} can be:
 
{| class="wikitable"
{| class="wikitable"
|-
|-
! command
! target
! description
! description
|-
|-
| <samp>addAchievement {{t|achievement ID}}</samp>
| <samp>end</samp>
| Unlock an [[achievement]] for the current player. The {{t|achievement ID}} can be a [[Modding:Console commands#Statistics and achievements|platform achievement ID]] (like <samp>Achievement_LocalLegend</samp>) or internal ID (like <samp>17</samp> for Gourmet Chef).
| Jump to the last <samp>end</samp> event command in the script.
|-
|-
| <samp>addActor {{t|x}} {{t|y}} {{t|direction}}</samp>
| ''any other value''
| Add a character or player to the event. This is mostly equivalent to adding them through the [[Modding:Event data#Basic format|character positions field]], but can be done at any point in the script (e.g. for use with <samp>goto</samp> for event variations).
| Jump to the first <samp>label</samp> command with this name.
|-
| <samp>choose {{t|question}} [{{t|answer}} {{t|go to label}}]+</samp>
| Show a dialogue box to choose from a list of responses, then optionally skip to a label based on the selected answer.
 
Arguments:
{| class="wikitable"
|-
! argument
! usage
|-
| {{t|question}}
| The [[Modding:Common data field types#Translation key|translation key]] or literal text to show above the choices. This can be empty (<code>""</code>) to omit the question line.
|-
| {{t|answer}}
| The [[Modding:Common data field types#Translation key|translation key]] or literal text for an answer to show.
|-
| {{t|go to label}}
| If the player chooses this answer, jump to this label in the event (see the <samp>goto</samp> command for more info). This can be <code>""</code> or <code>_</code> to continue to the next command instead.
|}
|}


For example, here's a simple choice which doesn't affect anything:
You can list any number of label/[[Modding:Game state queries|condition]] pairs, and it will go to the first label with a matching condition. If a condition is omitted, it defaults to always true. If none of the conditions match, it continues to the next command normally.
<pre>choose "Do you like apples?" "I love them." _ "I hate them." _/</pre>


Or you can change the course of the event based on the choice:
For example, this event script uses <samp>goto</samp> to repeat a question until a specific answer is selected:
<pre>
<pre>
speak Abigail "Do you... like me?$l"/
.../
choose "" "Yes!" happy "No." heartbroken/
label question/
choose Abigail "Hey! Did you have your eye on someone?" "Abigail" correct "Penny" wrong "Alex" wrong/


label heartbroken/
label wrong/
speak Abigail "Oh. I understand.$s"/
speak Abigail "Oh?$u"/
faceDirection Abigail left/
pause 500/
pause 3000/
goto question/
end/


label happy/
label correct/
speak Abigail "We should explore the mines together next time!$h"/
speak Abigail \"I thought so!$l\"/
...
pause 500/
end
</pre>
</pre>
You can make <samp>goto</samp> conditional using [[Modding:Game state queries|game state queries]]. For example, this will go to the <samp>divorced</samp> label if you divorced Abigail, and continue to the next command if not:
<pre>goto divorced "PLAYER_NPC_RELATIONSHIP Current Abigail Divorced"/</pre>
|-
|-
| <samp>completeQuest {{t|id}}</samp>
| <samp>label {{t|label}}</samp>
| Mark a quest complete. If the quest has no reward to collect, this also removes it from the in-game journal.
| Set a named position in the event script, which you can go to using the <samp>goto</samp> command.
|-
| <samp>conditionSpeak {{t|npc}} [{{t|dialogue}} {{o|condition}}]+</samp>
| Make an NPC say a dialogue based on arbitrary conditions. The first dialogue with a matching dialogue is spoken; if none match, the command is skipped.


Arguments:
'''Note:''' you can't use <samp>end</samp> as a label name, since that automatically matches the <samp>end</samp> event command.
{| class="wikitable"
|-
! argument
! usage
|-
| {{t|npc}}
| The internal name of the NPC who should speak (which can be [[Modding:Event data#Optional NPCs|marked optional]]).
|-
| {{t|dialogue}}
| The [[Modding:Common data field types#Translation key|translation key]] or literal text for the dialogue to speak. If omitted or empty, the command is skipped when the condition is matched.
|-
| {{o|condition}}
| One of:
* a [[Modding:Game state queries|game state query]];
* or <samp>ANSWERED {{t|response ID}}+</samp> as a shortcut for the <samp>PLAYER_HAS_DIALOGUE_ANSWER Current</samp> query;
* or omitted/blank to always match this dialogue if no previous one matched.
|}
|}


For example, here Maru says a different line if the player suggested she tell the truth:
====Improved existing commands====
<pre>conditionSpeak Maru "I accidentally dropped one of the samples... I'm so sorry.$s" "ANSWERED 38" "@ came in and slammed the door so loud I dropped this sample.$u"</pre>
|-
| <samp>goto [{{t|target}} {{o|condition}}]+</samp>
| Skip forward or backward to a specific position in the event script. Each {{t|target}} can be:
 
{| class="wikitable"
{| class="wikitable"
|-
|-
! target
! command
! description
! description
|-
|-
| <samp>end</samp>
| <samp>splitSpeak</samp>
| Jump to the last <samp>end</samp> event command in the script.
| You should now specify each dialogue as a separate argument (though the old syntax will still work):
|-
<pre>// in 1.6.16
| ''any other value''
splitSpeak Sam "You think so?~Yeah... kids should play and have fun while they still have the chance."
| Jump to the first <samp>label</samp> command with this name.
|}


You can list any number of label/[[Modding:Game state queries|condition]] pairs, and it will go to the first label with a matching condition. If a condition is omitted, it defaults to always true. If none of the conditions match, it continues to the next command normally.
// in 1.7
splitSpeak Sam "You think so?" "Yeah... kids should play and have fun while they still have the chance."
</pre>


For example, this event script uses <samp>goto</samp> to repeat a question until a specific answer is selected:
This also now works with the new <samp>choose</samp> command too.
<pre>
|}
.../
label question/
choose Abigail "Hey! Did you have your eye on someone?" "Abigail" correct "Penny" wrong "Alex" wrong/


label wrong/
====Deprecated commands====
speak Abigail "Oh?$u"/
These event commands are deprecated. '''They still work just like before''' (except the ones at the bottom of the table), but if you use the [[#EventValidator|<samp>EventValidator</samp>]] it'll report them as an error.
pause 500/
goto question/


label correct/
{| class="wikitable"
speak Abigail \"I thought so!$l\"/
|-
pause 500/
! event command
end
! migration
</pre>
 
You can make <samp>goto</samp> conditional using [[Modding:Game state queries|game state queries]]. For example, this will go to the <samp>divorced</samp> label if you divorced Abigail, and continue to the next command if not:
<pre>goto divorced "PLAYER_NPC_RELATIONSHIP Current Abigail Divorced"/</pre>
|-
|-
| <samp>label {{t|label}}</samp>
| <samp>fork</samp><br /><samp>resetVariable</samp><br /><samp>switchEvent</samp>
| Set a named position in the event script, which you can go to using the <samp>goto</samp> command.
| Use the <samp>choose</samp> or <samp>goto</samp> commands instead. If you used dialogue containing the <samp>%fork</samp> token, it should be removed and replaced with equivalent event commands.
 
'''Note:''' you can't use <samp>end</samp> as a label name, since that automatically matches the <samp>end</samp> event command.
|}
 
====Improved existing commands====
{| class="wikitable"
|-
|-
! command
| <samp>question forkX</samp>
! description
| Use the <samp>choose</samp> command instead, and replace the event fork with a label.
|-
| <samp>gainSkill</samp>
| Added argument validation.
|-
| <samp>skippable</samp>
| Added an optional {{o|skip to label}} argument. If set, the event will jump to that label when the player clicks the skip button (see <samp>goto</samp> for more info). The last <samp>skippable</samp> command run before the player skips is applied.


This is meant to clean up or grant unlocks before the event ends. For example:
For example, this script:
<pre>
<pre>
skippable beforeEnd/
// main event
.../
question fork1 "#I believe in you!#Wow, you're really arrogant."/
label beforeEnd/
fork arrogant/
gainSkill Fishing 1/
speak Alex "Thanks, @. I'll remember that."/
addItem (T)TrainingRod/
...
end
 
// 'arrogant' event
emote Alex 12/
speak Alex "Hmmph... I think someone's a little jealous.$a"/
</pre>
</pre>


Technically you can jump to any point in the event (e.g. to cancel the skip). However, the skip action will still cancel any ongoing event behavior like ongoing player/NPC movements, so you should be careful doing this.
Becomes this script:
|-
<pre>
| <samp>splitSpeak</samp>
choose "" "I believe in you!" believe "Wow, you're really arrogant." arrogant/
| You should now specify each dialogue as a separate argument (though the old syntax will still work):
 
<pre>// in 1.6.15
label believe/
splitSpeak Sam "You think so?~Yeah... kids should play and have fun while they still have the chance."
speak Alex "Thanks, @. I'll remember that."/
...


// in 1.7
label arrogant/
splitSpeak Sam "You think so?" "Yeah... kids should play and have fun while they still have the chance."
emote Alex 12/
speak Alex "Hmmph... I think someone's a little jealous.$a"/
...
</pre>
</pre>


This also now works with the new <samp>choose</samp> command too.
Forks often duplicated the end of the script. In that case, you can have both variants just <samp>goto</samp> the common ending instead.
|-
|-
| <samp>spriteText</samp>
| <samp>question null</samp>
| The {{o|text}} argument can now be a [[Modding:Common data field types#Translation key|translation key]] to get the text from.
| Use <samp>choose</samp> with <samp>_</samp> labels instead. (Setting a label argument to <samp>_</samp> means it'll just continue to the next command instead.)
|}


====Deprecated commands====
For example, this command:
These event commands are deprecated. '''They still work just like before''' (except the ones at the bottom of the table), but if you use the [[#EventValidator|<samp>EventValidator</samp>]] it'll report them as an error.
<pre>question null "But what am I going to say to Vincent?#It's best to be honest with kids.#You did the right thing. Kids should have hope."/</pre>


{| class="wikitable"
Would become this command:
<pre>choose "But what am I going to say to Vincent?" "It's best to be honest with kids." _ "You did the right thing. Kids should have hope." _/</pre>
|-
|-
! event command
| <samp>quickQuestion</samp>
! migration
| Use the <samp>choose</samp> command instead. The {{t|question}} and {{t|answerX}} have matching <samp>choose</samp> arguments, while the {{t|answerX script}} arguments become labels.
|-
 
| <samp>fork</samp><br /><samp>resetVariable</samp><br /><samp>switchEvent</samp>
For example, this command:
| Use the <samp>choose</samp> or <samp>goto</samp> commands instead. If you used dialogue containing the <samp>%fork</samp> token, it should be removed and replaced with equivalent event commands.
<pre>quickQuestion #I'd like to help#Nah, I'll pass...(break)emote Willy 32\speak Willy "Aye... I thought you would.$h#$b#I'll leave this door unlocked for ya... you can come drop off the materials whenever you like."(break)emote Willy 28\speak Willy "Alright, suit yourself...$s#$b#If you have a change of heart, you can always come back and help out. I'll leave this door unlocked, anyhow."/</pre>
|-
| <samp>question forkX</samp>
| Use the <samp>choose</samp> command instead, and replace the event fork with a label.


For example, this script:
Becomes this script:
<pre>
<pre>
// main event
choose "" "I'd like to help" accept "Nah, I'll pass..." refuse/
question fork1 "#I believe in you!#Wow, you're really arrogant."/
 
fork arrogant/
label accept/
speak Alex "Thanks, @. I'll remember that."/
emote Willy 32/
...
speak Willy "Aye... I thought you would.$h#$b#I'll leave this door unlocked for ya... you can come drop off the materials whenever you like."/
goto resume/
 
label refuse/
emote Willy 28/
speak Willy "Alright, suit yourself...$s#$b#If you have a change of heart, you can always come back and help out. I'll leave this door unlocked, anyhow."/


// 'arrogant' event
label resume/
emote Alex 12/
speak Alex "Hmmph... I think someone's a little jealous.$a"/
</pre>
</pre>
|-
| <samp>cutscene bandfork</samp><br /><samp>elliottBookTalk</samp><br /><samp>question haleyDarkRoom</samp><br /><samp>question shaneCliffs</samp><br /><samp>question shaneLoan</samp>
| These commands are '''deleted''' and will no longer work. They're unlikely to be used by mod events, but see their relevant events for the new equivalents if needed.
|}


Becomes this script:
====Changed event keys====
<pre>
Events were generally unified and de-hardcoded in 1.7. In particular...
choose "" "I believe in you!" believe "Wow, you're really arrogant." arrogant/


label believe/
<ul>
speak Alex "Thanks, @. I'll remember that."/
<li>Several events were previously defined in the game's C# code, where they couldn't be changed by content packs. Most of these were moved into <samp>Data/Events/*</samp> with translations in <samp>Strings/Events</samp>:
...
{| class="wikitable"
 
! event
label arrogant/
! new asset name
emote Alex 12/
! new event ID
speak Alex "Hmmph... I think someone's a little jealous.$a"/
...
</pre>
 
Forks often duplicated the end of the script. In that case, you can have both variants just <samp>goto</samp> the common ending instead.
|-
|-
| <samp>question null</samp>
| [[Giant Stump|forest raccoon]] finished event
| Use <samp>choose</samp> with <samp>_</samp> labels instead. (Setting a label argument to <samp>_</samp> means it'll just continue to the next command instead.)
| <samp>Data/Events/Forest</samp>
 
| <samp>RaccoonFinish</code>
For example, this command:
<pre>question null "But what am I going to say to Vincent?#It's best to be honest with kids.#You did the right thing. Kids should have hope."/</pre>
 
Would become this command:
<pre>choose "But what am I going to say to Vincent?" "It's best to be honest with kids." _ "You did the right thing. Kids should have hope." _/</pre>
|-
|-
| <samp>quickQuestion</samp>
| [[Trash Bear|forest trash bear]] cleanup
| Use the <samp>choose</samp> command instead. The {{t|question}} and {{t|answerX}} have matching <samp>choose</samp> arguments, while the {{t|answerX script}} arguments become labels.
| <samp>Data/Events/Forest</samp>
 
| <samp>777111</samp>
For example, this command:
|-
<pre>quickQuestion #I'd like to help#Nah, I'll pass...(break)emote Willy 32\speak Willy "Aye... I thought you would.$h#$b#I'll leave this door unlocked for ya... you can come drop off the materials whenever you like."(break)emote Willy 28\speak Willy "Alright, suit yourself...$s#$b#If you have a change of heart, you can always come back and help out. I'll leave this door unlocked, anyhow."/</pre>
| [[Ginger Island#Gourmand Frog|island Gourmand crop inspection]]
 
| <samp>Data/Events/islandFarmCave</samp>
Becomes this script:
| <samp>GourmandInspection</samp>
<pre>
choose "" "I'd like to help" accept "Nah, I'll pass..." refuse/
 
label accept/
emote Willy 32/
speak Willy "Aye... I thought you would.$h#$b#I'll leave this door unlocked for ya... you can come drop off the materials whenever you like."/
goto resume/
 
label refuse/
emote Willy 28/
speak Willy "Alright, suit yourself...$s#$b#If you have a change of heart, you can always come back and help out. I'll leave this door unlocked, anyhow."/
 
label resume/
</pre>
|-
|-
| <samp>cutscene bandfork</samp><br /><samp>elliottBookTalk</samp><br /><samp>question haleyDarkRoom</samp><br /><samp>question shaneCliffs</samp><br /><samp>question shaneLoan</samp>
| [[The Summit#Cutscene|summit perfection cutscene]]
| These commands are '''deleted''' and will no longer work. They're unlikely to be used by mod events, but see their relevant events for the new equivalents if needed.
|}
 
====Changed event keys====
Events were generally unified and de-hardcoded in 1.7. In particular...
 
<ul>
<li>Several events were previously defined in the game's C# code, where they couldn't be changed by content packs. Most of these were moved into <samp>Data/Events/*</samp> with translations in <samp>Strings/Events</samp>:
{| class="wikitable"
! event
! new asset name
! new event ID
|-
| [[Giant Stump|forest raccoon]] finished event
| <samp>Data/Events/Forest</samp>
| <samp>RaccoonFinish</code>
|-
| [[Trash Bear|forest trash bear]] cleanup
| <samp>Data/Events/Forest</samp>
| <samp>777111</samp>
|-
| [[Ginger Island#Gourmand Frog|island Gourmand crop inspection]]
| <samp>Data/Events/islandFarmCave</samp>
| <samp>GourmandInspection</samp>
|-
| [[The Summit#Cutscene|summit perfection cutscene]]
| <samp>Data/Events/Summit</samp>
| <samp>Data/Events/Summit</samp>
| <samp>SummitPerfection</samp>
| <samp>SummitPerfection</samp>
Line 1,308: Line 1,122:
</li>
</li>
<li>[[Coral]] and [[Sea Urchin|Sea urchin]] now have the <samp>fish_talk_coral</samp> [[Modding:Context tags|context tag]] instead of a hardcoded <samp>_Coral</samp> translation key suffixes.</li>
<li>[[Coral]] and [[Sea Urchin|Sea urchin]] now have the <samp>fish_talk_coral</samp> [[Modding:Context tags|context tag]] instead of a hardcoded <samp>_Coral</samp> translation key suffixes.</li>
<li>Fixed the translation key suffix from a custom <samp>fish_talk_*</samp> [[Modding:Context tags|context tag]] being capitalized differently from the vanilla suffixes. (For example, <samp>fish_talk_some_example</samp> would incorrectly result in a <samp>someExample</samp> suffix instead of <samp>someExample</samp>.)</li>
</ul>
</ul>


===[[Modding:Game state queries|Game state query]] changes===
===[[Modding:Item queries|Item query]] changes===
Added new game state queries:
Added one new item query:
{| class="wikitable"
{| class="wikitable"
|-
|-
! Condition
! query
! effect
! effect
|-
|-
| <samp>IS_DEBRIS_WEATHER</samp><br /><samp>IS_GREEN_RAINING</samp><br /><samp>IS_LIGHTNING</samp><br /><samp>IS_RAINING</samp><br /><samp>IS_SNOWING</samp>
| <samp>SEASONAL_RACCOON_SEED</samp>
| Whether the weather in the [[Modding:Game state queries#Target location|given location]] sets the related [[Modding:Weather data#Save files|weather field]]. For example, <samp>IS_RAINING</samp> is true for the <samp>Rain</samp>, <samp>GreenRain</samp>, and <samp>Storm</samp> weathers.
|-
| <samp>LOCATION_MINE_DIFFICULTY {{t|location}} {{t|min}} {{o|max}}</samp>
| Whether the [[Modding:Game state queries#Target location|given location]] is in the [[The Mines|mines]] or [[Skull Cavern]], and its difficulty level is between {{t|min}} and {{o|max}} (default unlimited) inclusively. Difficulty 0 is the default difficulty, and modifiers like the [[Shrine of Challenge]] or some special orders each increase it by one.
|-
| <samp>LOCATION_MINE_LEVEL {{t|location}} {{t|min}} {{o|max}}</samp>
| Whether the [[Modding:Game state queries#Target location|given location]] is in the [[The Mines|mines]] or [[Skull Cavern]], and its floor level is between {{t|min}} and {{o|max}} (default unlimited) inclusively. The Skull Cavern implicitly starts at level 121 (e.g. Skull Cavern level 10 is mine level 130).
|-
| <samp>PLAYER_HAS_PREVIOUS_CONVERSATION_TOPIC {{t|player}} {{t|id}}+</samp>
| Whether the [[Modding:Game state queries#Target player|specified player(s)]] have previously had ''any'' of the specified [[Modding:Dialogue#Conversation topics|conversation topics]] active. This doesn't include current topics (unless they're a repeat of a previous one).
|-
| <samp>PLAYER_QUEST_ACTIVE {{t|player}} {{t|id}}+</samp><br /><samp>PLAYER_QUEST_COMPLETE {{t|player}} {{t|id}}+</samp>
| Whether the [[Modding:Game state queries#Target player|specified player(s)]] have ''any'' of the specified quest IDs open (<samp>PLAYER_QUEST_ACTIVE</samp>) or previously completed (<samp>PLAYER_QUEST_COMPLETE</samp>).
|}
 
===[[Modding:Item queries|Item query]] changes===
Added one new item query:
{| class="wikitable"
|-
! query
! effect
|-
| <samp>SEASONAL_RACCOON_SEED</samp>
| Get a [[Giant Stump#Note|seasonal raccoon seed]] for the current season.
| Get a [[Giant Stump#Note|seasonal raccoon seed]] for the current season.


Line 1,354: Line 1,144:
! field
! field
! effect
! effect
|-
| <samp>Color</samp>
| ''(Optional)'' For item types that support it (e.g. objects and clothes), a [[Modding:Common data field types#Color|tint color]] to apply to the produced item. Default none.
|-
|-
| <samp>Enchantments</samp>
| <samp>Enchantments</samp>
Line 1,365: Line 1,152:
"Enchantments": [ "Vampiric", "Attack", "Attack" ]
"Enchantments": [ "Vampiric", "Attack", "Attack" ]
</syntaxhighlight>
</syntaxhighlight>
|-
|}
| <samp>IsSpecial</samp>
| ''(Optional)'' Whether to mark the produced item as a special permanent item, which can't be destroyed or dropped. Default false.
|-
| <samp>ObjectIsQuestItem</samp>
| ''(Optional)'' Whether to mark the dropped item as a quest item. This enables special rules like not being able to gift the item, and the item getting auto-recovered when it's lost in some cases. Default false.
|-
| <samp>TempData</samp>
| ''(Optional)'' Set temporary item info that's not synchronized in multiplayer or written to the save file. This is somewhat specialized, and does nothing if there's no game logic or C# mod logic which reads it. Default none.


For example, this adds a custom flag:
===DialogueKeyValidator===
<syntaxhighlight lang="js">
The new <samp>DialogueKeyValidator</samp> class analyses [[Modding:Dialogue|dialogue entries]] to detect dialogue keys which don't match one of the predefined patterns.
"TempData": {
    "SomeExampleKey": "Example Value"
}
</syntaxhighlight>


A C# code can then check for the field on the dropped items:
This is mainly meant to implement unit tests. For example, to validate all dialogue keys in a data asset:
<syntaxhighlight lang="c#">
<syntaxhighlight lang="c#">
if (item.TryGetTempData("SomeExampleKey", out object value))
string assetName = "Characters/Dialogues/Abigail";
    ...;
var dialogues = Game1.content.Load<Dictionary<string, string>>(assetName);
</syntaxhighlight>
|}
</li>
<li>The <samp>ObjectColor</samp> field is obsolete and replaced by <samp>Color</samp>. Content packs which set it will still work (since the game will pass the value through to <samp>Color</samp> automatically).
</ul>


===[[Modding:Maps|Map property]] changes===
var validator = new DialogueKeyValidator();
<ul>
foreach ((string key, string dialogue) in dialogues)
<li>Added new map properties:
{
{| class="wikitable"
    if (!validator.IsKnownFormat(assetName, key))
|-
        Assert.Fail($"Validation failed for dialogue '{key}': key doesn't match one of the expected patterns.");
! action
}
! effect
</syntaxhighlight>
|-
| <samp>FarmHouseBed {{t|x}} {{t|y}} {{o|item ID}}</samp><br />''(valid in farm or farmhouse)''
| Sets the initial bed to place when creating the farmhouse or cabin. The arguments are:
* {{t|x}} {{t|y}}: the [[Modding:Maps#Tile coordinates|tile position]] at which to place it.
* {{o|item ID}}: if set, the qualified or unqualified [[Modding:Common data field types#Item ID|item ID]] for the bed furniture to place. This must match a [[Modding:Furniture|furniture item]] with item type <samp>Bed</samp>. Defaults to <code>(F)2048</code> ([[Single Bed|single bed]]).


If omitted, a [[Single Bed|single bed]] is placed at position (9, 8).
You can optionally extend the valid patterns by setting validator fields like <samp>MarriageDialogueKeyPatterns</samp>.
|}</li>
<li>Improved map properties:
{| class="wikitable"
|-
! action
! changes
|-
| <samp>FarmHouseFlooring</samp><br /><samp>FarmHouseFurniture</samp><br /><samp>FarmHouseStarterGift</samp><br /><samp>FarmHouseStarterSeedsPosition</samp><br /><samp>FarmHouseWallpaper</samp>
| Can now be set on the farmhouse map to override the farm map's equivalent property.
|-
| <samp>FarmHouseFurniture</samp>
| Fixed property only allowing numeric item IDs.
|}</li>
</ul>


===[[Modding:Quest data|Quest]] changes===
===EventValidator changes===
* The game now tracks completed quest IDs. You can check them using [[#Game state query changes|new game state queries]] or in C# via <code>Game1.player.questsCompleted</code>. The list is retroactively populated for pre-existing saves.
The [[Modding:Migrate to Stardew Valley 1.6.16|<samp>EventValidator</samp> class added in 1.6.16]] lets you detect issues in [[Modding:Event data|event scripts]] (mainly meant for unit tests).
* Added [[#Game state query changes|<samp>PLAYER_QUEST_ACTIVE</samp> and <samp>PLAYER_QUEST_COMPLETE</samp> game state queries]].
* Added [[#New event commands|<samp>completeQuest</samp> event command]] and [[#Trigger action changes|<samp>CompleteQuest</samp> trigger action]].
* Added <samp>QuestIds</samp> constants for C# mods.
* Added [[#Item spawn field changes|item spawn field to produce quest items]].
* Fixed intermittent crash when an item delivery quest for a non-Wizard NPC requests a cooking-type item.


===[[Modding:Schedule data|Schedule]] changes===
Stardew Valley 1.7 adds one token recognized by the <samp>EventArguments</samp> attribute:
<ul>
<li>Added new schedule keys:
{| class="wikitable"
{| class="wikitable"
|-
|-
! syntax
! token
! summary
! meaning
|-
|-
| <samp>roommate_{{t|festival ID}}_{{t|festival day}}</samp><br /><samp>roommate_{{t|festival ID}}</samp><br /><samp>roommate_{{t|season}}_{{t|day of month}}</samp><br /><samp>roommate_{{t|day of week}}</samp><br /><samp>roommateJob</samp>
| <samp>goToLabel</samp>
| Equivalent to the [[Modding:Schedule data#Marriage schedules|marriage schedules]], but only apply if the NPC is a roommate.
| An event label (see the <samp>goto</samp> and <samp>label</samp> event commands). This is equivalent to <samp>word</samp>, but is used by <samp>EventValidator</samp> to validate label references.
|}


If a roommate NPC has both <samp>roommate*</samp> and <samp>marriage*</samp> schedules, it'll use a <samp>roommate*</samp> schedule if any of them apply. If none apply, it'll default to <samp>marriage*</samp> schedules. You can avoid that by setting the fallback <samp>roommate</samp> schedule key.
===Content manager changes===
|-
1.7 adds a <samp>SourceCodeContentManager</samp> implementation of <samp>IContentManager</samp>. This is meant for internal unit tests, and isn't relevant for mod authors except as an example.
| <samp>marriage</samp><br /><samp>roommate</samp>
| A fallback schedule to use if a more specific schedule doesn't apply. If this is omitted and no other schedule applies, the NPC won't have a schedule that day.
|}</li>
</ul>


===[[Modding:Trigger actions|Trigger action]] changes===
===Monster changes===
<ul>
* The [[#Data/Monsters|monster data has been overhauled]].
<li>Added new trigger actions:
* The new <samp>monster.Tags</samp> field contains a set of metadata tags about the monster which can be checked in [[#Data/Monsters|<samp>Data/Monsters</samp>]]. It's safe to add new tags to the list for existing monster types.
{| class="wikitable"
* The former <samp>monster.objectsToDrop</samp> field (a list of string object IDs) has been replaced by <samp>monster.drops</samp> (an [[Modding:Migrate to Stardew Valley 1.6#Inventory class|item inventory]]).
|-
* Removed <samp>monster.getExtraDropItems()</samp>. Drops should be added in [[#Data/Monsters|<samp>Data/Monsters</samp>]] instead.
! action
! effect
|-
| <samp>CompleteQuest {{t|quest ID}}</samp>
| Complete all active quests with this ID in the player's journal.
|}</li>
</ul>


===Other changes===
===Other breaking API changes===
* Added validation for schedule <samp>offset</samp> command in end-of-route animations.
''(This section is meant as a quick reference if you have build errors; there's no need to read through it otherwise.)''
* Fixed crash when loading a save with missing building interiors.
* Fixed <samp>RejectItem_*</samp> dialogue disabling the NPC's normal dialogue after it's shown.
* Fixed [[Modding:NPC data|NPC <samp>FlowerDanceCanDance</samp> field]] ignored for non-datable NPCs with no dialogue.
 
==Changes for C# mod authors==
===Instance statics no longer affect mod assemblies===
In [[multiplayer]], split-screen mode works by swapping the values of static fields for each screen (called ''instanced statics''). In previous versions, Stardew Valley would scan all loaded assemblies for static fields marked with <code>[InstancedStatic]</code> attributes except a few ignored assemblies like MonoGame.
 
In Stardew Valley 1.7, the game now only does this for the main game assembly to improve performance. If a mod was using <code>[InstancedStatic]</code>, it should use SMAPI's built-in [[Modding:Modder Guide/APIs/Utilities#Per-screen data|per-screen data]] utility instead.
 
===AssetNameUtility===
The new <samp>AssetNameUtility</samp> class has methods for working with [[Modding:Common data field types#Asset name|asset names]]:


====Removed or renamed types====
These classes renamed in 1.7:
{| class="wikitable"
{| class="wikitable"
|-
|-
! method
! type
! usage
! migration
|-
|-
| <samp>Normalize</samp>
| <samp>BaseEnchantment</samp>
| A low-level method which normalizes path separators in an [[Modding:Common data field types#Asset name|asset name]]. For example:
| Renamed to <samp>Enchantment</samp>.
<syntaxhighlight lang="c#">
string assetName = AssetNameUtility.Normalize("Characters/\\/Abigail"); // produces "Characters/Abigail"
</syntaxhighlight>
 
Consider using SMAPI's <samp>PathUtilities.NormalizeAssetName</samp> instead, which is more thorough.
|-
|-
| <samp>TryParseTranslationKey</samp>
| <samp>AxeEnchantment</samp><br /><samp>BaseWeaponEnchantment</samp><br /><samp>FishingRodEnchantment</samp><br /><samp>HoeEnchantment</samp><br /><samp>MilkPailEnchantment</samp><br /><samp>PanEnchantment</samp><br /><samp>PickaxeEnchantment</samp><br /><samp>ShearsEnchantment</samp><br /><samp>WateringCanEnchantment</samp>
| Parses a [[Modding:Common data field types#Translation key|translation key]] into its component parts. For example:
| Obsolete. Enchantments now [[#Enchantment data|target tools via data]] instead.
<syntaxhighlight lang="c#">
if (AssetNameUtility.TryParseTranslationKey("Strings/UI:Confirm", out string assetName, out string fieldKey, out string error))
  ...;  // assetName: Strings/UI, fieldKey: Confirm, error: null
</syntaxhighlight>
 
This doesn't check whether the asset or key exists; see <samp>Game1.content.IsValidTranslationKey</samp> to do that.
|}
|}


===DialogueKeyValidator===
====Other API changes====
The new <samp>DialogueKeyValidator</samp> class analyses [[Modding:Dialogue|dialogue entries]] to detect dialogue keys which don't match one of the predefined patterns.
These class members changed in 1.7:


This is mainly meant to implement unit tests. For example, to validate all dialogue keys in a data asset:
{| class="wikitable"
<syntaxhighlight lang="c#">
|-
string assetName = "Characters/Dialogues/Abigail";
! type
var dialogues = Game1.content.Load<Dictionary<string, string>>(assetName);
! member
 
! migration
var validator = new DialogueKeyValidator();
|-
foreach ((string key, string dialogue) in dialogues)
|rowspan="9"| <samp>BaseEnchantment</samp><br /><small>(and its subclasses)</small>
{
| <samp>hideEnchantmentName</samp>
    if (!validator.IsKnownFormat(assetName, key))
| Replaced by <samp>EnchantmentManager.HideEnchantmentName</samp>.
        Assert.Fail($"Validation failed for dialogue '{key}': key doesn't match one of the expected patterns.");
|-
}
| <samp>hideSecondaryEnchantName</samp>
</syntaxhighlight>
| Replaced by <samp>EnchantmentManager.HideSecondaryEnchantName</samp>.
 
|-
You can optionally extend the valid patterns by setting validator fields like <samp>MarriageDialogueKeyPatterns</samp>.
| <samp>GetEnchantmentFromItem(…)</samp>
 
| Replaced by <samp>EnchantmentManager.GetEnchantmentFromItem</samp>.
===EventValidator===
|-
====Overview====
| <samp>GetAvailableEnchantments()</samp>
The new <samp>EventValidator</samp> class analyses [[Modding:Event data|event scripts]] to detect issues like...
| Removed.
* command names which don't match a registered command or alias;
<ul>
* command arguments which don't match those expected by the command;
<li>To check whether any enchantments can be applied to a tool through the [[forge]], use <samp>EnchantmentManager.CanForgeEnchant</samp>.</li>
* and custom rule violations based on the <samp>EventValidator.CommandValidators</samp> field (e.g. a default validator checks that <samp>goto</samp> commands match a valid label).
<li>There's no directly equivalent method in 1.7, but you can mimic the former logic if needed.
 
This is mainly meant to implement unit tests for events. For example, to validate all events in a data asset:
<syntaxhighlight lang="c#">
<syntaxhighlight lang="c#">
string assetName = "Data/Events/Farm";
static List<Enchantment> GetAvailableEnchantments()
var events = Game1.content.Load<Dictionary<string, string>>(assetName);
 
var validator = new EventValidator();
foreach ((string key, string script) in events)
{
{
     foreach (var issue in validator.Validator(assetName, key, script))
     var dataAsset = DataLoader.Enchantments(Game1.content);
        Assert.Fail($"Validation failed for event '{key}' > command '{issue.CommandText}': {issue.SuggestedError}.");
}
</syntaxhighlight>


====Command argument validation====
    List<Enchantment> enchantments = [];
Argument validation is enabled if the command's handler method has an <samp>EventArguments</samp> attribute, which defines the argument pattern using a special syntax. Each command can list multiple patterns, and it'll be considered valid if any of them matches. If the pattern is an empty string, the validator will ensure no arguments are provided.
    foreach ((string id, EnchantmentData data) in dataAsset)
    {
        if (data.ForgeWith == Object.prismaticShardQID)
            enchantments.Add(EnchantmentManager.CreateEnchantment(dataAsset, id));
    }


For example, the default <samp>showFrame</samp> command is defined like this:
    return enchantments;
}
</syntaxhighlight></li>
</ul>
|-
| <samp>GetAvailableEnchantmentsForItem(…)</samp>
| Removed.
<ul>
<li>To check whether any enchantments can be applied to a tool through the [[forge]], use <samp>EnchantmentManager.CanForgeEnchant</samp>.</li>
<li>There's no directly equivalent method in 1.7, but you can mimic the former logic if needed.
<syntaxhighlight lang="c#">
<syntaxhighlight lang="c#">
[EventArguments("int", "actor int bool?")]
static List<Enchantment> GetAvailableEnchantmentsForItem(Item? tool, Item? item)
public static void ShowFrame(Event @event, string[] args, EventContext context)
{
</syntaxhighlight>
    var dataAsset = DataLoader.Enchantments(Game1.content);
    var contextTags = tool?.GetContextTags();


An argument pattern consists of space-delimited ''tokens'', where each token defines the format for an argument. For example, <code>actor int bool?</code> has three tokens representing three arguments: an actor name, a positive integer, and an optional boolean.
    List<Enchantment> enchantments = [];
    foreach ((string id, EnchantmentData data) in dataAsset)
    {
        if (data.ForgeWith == Object.prismaticShardQID && (contextTags is null || EnchantmentManager.MatchesTags(contextTags, data.AppliesTo)))
            enchantments.Add(EnchantmentManager.CreateEnchantment(dataAsset, id));
    }


These are the tokens recognized by the validator:
    return enchantments;
{| class="wikitable"
}
</syntaxhighlight></li>
</ul>
|-
|-
! token
| <samp>GetName()</samp>
! meaning
| Removed. This inconsistently returned an ID, a display name, or <samp>"Unknown Enchantment"</samp> depending on the enchantment type. Use the new <samp>Id</samp> property or the pre-existing <samp>GetDisplayName()</samp> method instead.
|-
|-
!colspan="2"| generic argument types
| <samp>GetLevel()</samp>
| Removed. Use <samp>Level</samp> instead.
|-
|-
| <samp>bool</samp>
| <samp>GetType()</samp>
| A boolean value (<samp>true</samp> or <samp>false</samp>).
| This was sometimes to identify enchantments (like <code>enchantment.GetType() == expectedEnchantment.GetType()</code>). That's no longer reliable, since 1.7 introduces data-based enchantments which may not have their own C# type. You should use the new <samp>enchantment.Id</samp> property instead.
|-
|-
| <samp>float</samp>
| <samp>ResetEnchantments()</samp>
| A positive number with optional decimal point (like <samp>5</samp> or <samp>0.5</samp>).
| Removed. This is no longer needed since it no longer has a cached list of enchantment instances.
|-
|-
| <samp>-float</samp>
|rowspan="2"| <samp>Furniture</samp>
| A number with optional decimal point and optional negative sign (like <samp>5</samp>, <samp>-5</samp>, or <samp>-0.5</samp>).
| <samp>armchair</samp><br /><samp>bed</samp><br /><samp>bench</samp><br /><samp>bookcase</samp><br /><samp>chair</samp><br /><samp>couch</samp><br /><samp>decor</samp><br /><samp>dresser</samp><br /><samp>fireplace</samp><br /><samp>lamp</samp><br /><samp>longTable</samp><br /><samp>other</samp><br /><samp>painting</samp><br /><samp>rug</samp><br /><samp>sconce</samp><br /><samp>table</samp><br /><samp>torch</samp><br /><samp>window</samp>
| Removed. Replaced by the <samp>FurnitureType</samp> enum (e.g. <code>Furniture.rug</code> is now <code>FurnitureType.Rug</code>).
|-
|-
| <samp>int</samp>
| <samp>placementRestrictions</samp>
| A positive integer (like <samp>5</samp>).
| Removed. Replaced by <samp>CanPlaceIndoors</samp> and <samp>CanPlaceOutdoors</samp>.
|-
|-
| <samp>-int</samp>
|rowspan="2"| <samp>Monster</samp>
| An integer with optional negative sign (like <samp>5</samp> or <samp>-5</samp>).
| <samp>getExtraDropItems()</samp>
| Removed. Drops should be added to [[#Data/Monsters|<samp>Data/Monsters</samp>]] instead.
 
[[Modding:Modder Guide/APIs/Harmony|Harmony patches]] which can't be moved into data can target <samp>Monster.RollForDrops</samp> instead.
|-
|-
| <samp>string</samp>
| <samp>objectsToDrop</samp>
| A quoted sequence of arbitrary text like <samp>"some words here"</samp>. If the argument has no quotes, this is equivalent to the <samp>word</samp> token.
| Removed. Replaced by <samp>drops</samp>; see [[#Monster changes|''monster changes'']] and [[#Data/Monsters|''<samp>Data/Monsters</samp>'']].
|-
|-
| <samp>word</samp>
| <samp>Tool</samp>
| A simple sequence of letters, numbers, periods, and/or underscores (usually an ID or similar value). While the command will accept quotes, they're redundant and will be rejected by the validator.
| <samp>GetEnchantmentLevel&lt;T&gt;()</samp><br /><samp>GetEnchantmentOfType&lt;T&gt;()</samp><br /><samp>hasEnchantmentOfType&lt;T&gt;()</samp>
|-
| Removed. Replaced by <samp>GetEnchantmentLevel(id)</samp>, <samp>GetEnchantment(id)</samp>, and <samp>HasEnchantment(id)</samp> respectively. All vanilla enchantments have a constant for the ID like <samp>EnchantmentIds.GalaxySoul</samp>.
| <samp>remainder</samp>
| One or more arguments of any type.
|-
!colspan="2"| specific string formats
|-
| <samp>actor</samp>
| An actor name in the event format (like <samp>Abigail</samp> or <samp>Kent?</samp>).
|-
| <samp>assetName</samp>
| An [[Modding:Common data field types#Asset name|asset name]] like <samp>Data/Achievements</samp>.
|-
| <samp>direction</samp>
| A [[Modding:Event data#Directions|direction]] which can be specified as either a number (like <samp>0</samp>) or name (like <samp>up</samp>).
|-
| <samp>goToLabel</samp>
| An event label (see the <samp>goto</samp> and <samp>label</samp> event commands). This is equivalent to <samp>word</samp>, but is used by <samp>EventValidator</samp> to validate label references.
|-
| <samp>itemId</samp>
| An [[Modding:Common data field types#Item ID|item ID]] which can be qualified or unqualified (like <samp>(O)MossySoup</samp> or <samp>MossySoup</samp>).
|-
| <samp>translationKey</samp>
| A [[Modding:Common data field types#Translation key|translation key]] like <samp>Strings/Locations:SomeKey</samp>.
|-
!colspan="2"| custom formats
|-
| <samp>'...'</samp>
| The literal text or regex pattern to match, like <code>'continue'</code> or <code>'[\w-]+'</code>.
|}
|}


In addition, you can extend tokens with these indicators:
==Name translation changes for wiki maintainers==
* Suffix with <samp>+</samp> for repeating argument of that type. For example, <samp>int+</samp> would allow both <samp>5</samp> and <samp>5 6 7</samp>.
Some in-game item and monster names were retranslated in some languages for clarity or correctness.
* Suffix with <samp>?</samp> for an optional argument which can be omitted. All tokens after this token must also be optional. (You can have optional repeating arguments like <samp>int+?</samp>.)
 
* Infix with <samp>|</samp> for a parameter which can be one of multiple types. For example <samp>int|bool</samp> will allow either integer or boolean values.
This list is mostly provided to help wiki maintainers update pages, so it doesn't include names which only changed capitalization, changed <code>'</code> (straight apostrophe) to <code>’</code> (curly) in French, or aren't visible to vanilla players (like mine rocks).
 
''None yet.''


===Content manager changes===
==XNB impact==
The base game's 'content manager' API changed in Stardew Valley 1.7. This mainly affects <samp>LanguageCode</samp>, <code>Game1.content</code>, and other content manager fields. This does ''not'' affect mods which only use [[Modding:Modder Guide/APIs/Content|SMAPI's content API]].
<!--
 
Updated up to 1.7 alpha 2025-09-13.
 
-->
===Overview===
This section provides a summary of the XNB files which changed in Stardew Valley 1.7. This doesn't include new files (since they won't impact existing mods) or text changes in non-English files.
 
[[Modding:Using XNB mods|XNB mods]] are disproportionately affected, since...
# they replace the entire file;
# they're loaded through the MonoGame content pipeline which is less tolerant of format changes;
# they don't benefit from the compatibility rewrites [[Modding:Content Patcher|Content Patcher]] provides for its content packs.
 
Content Patcher packs are typically unaffected (and Content Patcher will try to rewrite content packs automatically). However if a content pack replaces an entire asset instead of editing, it's more likely to be affected like an XNB mod.
 
===Changed assets===
Compatibility is broadly grouped into four categories:
* "'''✘ broken'''": mods will remove new content or significant changes, or the mod's intended changes will no longer work. Effects may range from display bugs to crashes, depending how the game uses that specific content.
* "✘ will remove changes": mods will remove minor changes in 1.7 (e.g. typo fixes).
* "✓ mostly unaffected": mods will only be affected if they edit specific entries or fields.
* Blank: no expected impact for the vast majority of mods.


In particular:
<ul>
<li>The game now uses <samp>IContentManager</samp> instead of <samp>LocalizedContentManager</samp> in most places. That includes fields like <code>Game1.content</code>, methods like <code>Game1.content.CreateTemporary()</code>, etc. The new interface also includes full IntelliSense docs.</li>
<li>Moved three types:
{| class="wikitable"
|-
! type
! changes
|-
| <samp>LocalizedContentManager</samp>
| Moved from the <code>StardewValley</code> namespace into <code>StardewValley.ContentManagement</code>.
|-
| <samp>LocalizedContentManager.LanguageCode</samp><br /><samp>LocalizedContentManager.LanguageChangedHandler</samp>
| &#32;
* Moved from the <code>StardewValley</code> namespace into <code>StardewValley.ContentManagement</code>.
* Moved out of the nested type (e.g. change <code>LocalizedContentManager.LanguageCode</code> to just <code>LanguageCode</code> in your mod code).
|}</li>
<li>And changed some <samp>LocalizedContentManager</samp> members:
{| class="wikitable"
{| class="wikitable"
|-
|-
! type
!rowspan="2"| content asset
! member
!rowspan="2"| changes in 1.7
! changes
!colspan="2"| compatibility for pre-1.7 mods
|-
|-
|rowspan="8"| <samp>LocalizedContentManager</samp>
! XNB mods
| <samp>CurrentLanguageCode</samp><br /><samp>CurrentLanguageLatin</samp><br /><samp>CurrentLanguageString</samp><br /><samp>CurrentModLanguage</samp><br /><samp>GetDefaultLanguageCode()</samp><br /><samp>OnLanguageChange</samp><br /><samp>SetModLanguage(…)</samp>
! Content Patcher packs
| These are no longer static, so they need to be called through an instance like <samp>Game1.content</samp>. For example, change <code>LocalizedContentManager.GetDefaultLanguageCode()</code> in mod code to <code>Game1.content.GetDefaultLanguageCode()</code>.
 
Some of these are also renamed (see the next rows).
|-
|-
| <samp>CurrentCulture</samp>
| <samp>Characters/Dialogue/Abigail</samp>
| Removed (it was unused).
| &#32;
* [[#Dialogue changes|Merged resort dialogue keys]].
* Removed event dialogues moved into <samp>Strings/Events</samp>.
* Fixed invalid dialogue keys.
| '''✘ broken'''
| ✓ mostly unaffected
|-
|-
| <samp>CurrentLanguageCode</samp>
| <samp>Characters/Dialogue/Alex</samp><br /><samp>Characters/Dialogue/Clint</samp>
| Renamed to <samp>LanguageCode</samp>.
| &#32;
* [[#Dialogue changes|Merged resort dialogue keys]].
* Removed event dialogues moved into <samp>Strings/Events</samp>.
| '''✘ broken'''
| ✓ mostly unaffected
|-
| <samp>Characters/Dialogue/Demetrius</samp>
| Removed event dialogues moved into <samp>Strings/Events</samp>.
|
|
|-
|-
| <samp>CurrentLanguageLatin</samp>
| <samp>Characters/Dialogue/Dwarf</samp>
| Renamed to <samp>LanguageUsesLatinFont</samp>.
| Fixed invalid dialogue keys.
| '''✘ broken'''
| ✓ mostly unaffected
|-
|-
| <samp>CurrentLanguageString</samp>
| <samp>Characters/Dialogue/Elliott</samp>
| Renamed to <samp>LanguageString</samp>.
| &#32;
* [[#Dialogue changes|Merged resort dialogue keys]].
* Removed event dialogues moved into <samp>Strings/Events</samp>.
* Fixed invalid dialogue key.
| '''✘ broken'''
| ✓ mostly unaffected
|-
|-
| <samp>CurrentModLanguage</samp>
| <samp>Characters/Dialogue/Emily</samp>
| Renamed to <samp>LanguageModData</samp>.
| Removed event dialogues moved into <samp>Strings/Events</samp>.
|
|
|-
|-
| <samp>GetCurrentLanguage()</samp>
| <samp>Characters/Dialogue/Evelyn</samp>
| Removed. Use the <samp>LanguageCode</samp> property instead.
| &#32;
* Removed event dialogues moved into <samp>Strings/Events</samp>.
* Fixed invalid dialogue key.
| '''✘ broken'''
| ✓ mostly unaffected
|-
|-
| <samp>OnLanguageChange</samp>
| <samp>Characters/Dialogue/Haley</samp>
| Renamed to <samp>OnGlobalLanguageChanged</samp>.
| &#32;
|}</li>
* [[#Dialogue changes|Merged resort dialogue keys]].
<li>Added a <samp>SourceCodeContentManager</samp> implementation of <samp>IContentManager</samp>. This is meant for internal unit tests, and isn't relevant for mod authors except as an example.</li>
* Removed event dialogues moved into <samp>Strings/Events</samp>.
</ul>
| '''✘ broken'''
 
| ✓ mostly unaffected
===Item changes===
|-
* Added <samp>IItemDataDefinition.GetContextTags(itemData)</samp> method, so custom item data definitions can add [[Modding:Context tags|context tags]] from their data if applicable.
| <samp>Characters/Dialogue/Harvey</samp>
* Fixed <code>item.CopyFieldsFrom(other)</code> always setting the stack size for the copy to 1.
| &#32;
 
* Removed event dialogues moved into <samp>Strings/Events</samp>.
===Monster changes===
* Fixed invalid dialogue key.
* The [[#Data/Monsters|monster data has been overhauled]].
| '''✘ broken'''
* The new <samp>monster.Tags</samp> field contains a set of metadata tags about the monster which can be checked in [[#Data/Monsters|<samp>Data/Monsters</samp>]]. It's safe to add new tags to the list for existing monster types.
| ✓ mostly unaffected
* The former <samp>monster.objectsToDrop</samp> field (a list of string object IDs) has been replaced by <samp>monster.drops</samp> (an [[Modding:Migrate to Stardew Valley 1.6#Inventory class|item inventory]]).
* Removed <samp>monster.getExtraDropItems()</samp>. Drops should be added in [[#Data/Monsters|<samp>Data/Monsters</samp>]] instead.
 
===Utility fields & methods===
<ul>
<li>1.6.9 adds many new utility methods and fields. For example:
{| class="wikitable"
|-
|-
! type
| <samp>Characters/Dialogue/Jodi</samp>
! member
| Fixed invalid dialogue key.
! usage
| '''✘ broken'''
| ✓ mostly unaffected
|-
|-
|rowspan="3"| <samp>PassiveFestivalData</samp>
| <samp>Characters/Dialogue/Kent</samp>
| <samp>CoversDate(…)</samp>
| Removed event dialogues moved into <samp>Strings/Events</samp>.
| Get whether the festival is active on the given date.
|
|
|-
|-
| <samp>GetFestivalLocations()</samp>
| <samp>Characters/Dialogue/Leah</samp>
| Get the locations in which the passive festival happens (based on the <samp>InLocations</samp> or <samp>MapReplacements</samp> fields in [[Modding:Passive Festival data|<samp>Data/PassiveFestivals</samp>]]).
| &#32;
* [[#Dialogue changes|Merged resort dialogue keys]].
* Removed event dialogues moved into <samp>Strings/Events</samp>.
| '''✘ broken'''
| ✓ mostly unaffected
|-
|-
| <samp>TryGetLocationReplacement(…)</samp>
| <samp>Characters/Dialogue/Lewis</samp>
| Get the new location to load instead of a normal one when the passive festival is active. For example, the [[Night Market]] replaces <samp>Beach</samp> with <samp>BeachNightMarket</samp>.
| &#32;
* Removed event dialogues moved into <samp>Strings/Events</samp>.
* Fixed invalid dialogue key.
| '''✘ broken'''
| ✓ mostly unaffected
|-
|-
| <samp>Utility</samp>
| <samp>Characters/Dialogue/MarriageDialogue</samp><br /><samp>Characters/Dialogue/MarriageDialogue*</samp>
| <samp>TryGetPassiveFestivalDataForDayHere(…)</samp>
| &#32;
| Get the passive festival which occurs on a given date within the given location, if any. This is equivalent to <samp>Utility.TryGetPassiveFestivalDataForDay(…)</samp>, but also checks the given location against the passive festival's <samp>InLocation</samp> or <samp>MapReplacements</samp> field.
* [[#Dialogue changes|Merged some dialogue keys]].
|}</li>
* [[#Dialogue changes|Merged some keys from the base asset into NPC-specific assets]].
</ul>
| '''✘ broken'''
 
| ✓ mostly unaffected
===Other breaking API changes===
''(This section is meant as a quick reference if you have build errors; there's no need to read through it otherwise.)''
 
====Removed or renamed types====
These classes were removed or renamed in 1.7:
{| class="wikitable"
|-
|-
! type
| <samp>Characters/Dialogue/Maru</samp>
! migration
| &#32;
* [[#Dialogue changes|Merged resort dialogue keys]].
* Removed event dialogues moved into <samp>Strings/Events</samp>.
| '''✘ broken'''
| ✓ mostly unaffected
|-
|-
| <samp>BaseEnchantment</samp>
| <samp>Characters/Dialogue/Pam</samp>
| Renamed to <samp>Enchantment</samp>.
| Removed event dialogues moved into <samp>Strings/Events</samp>.
|
|
|-
|-
| <samp>AxeEnchantment</samp><br /><samp>BaseWeaponEnchantment</samp><br /><samp>FishingRodEnchantment</samp><br /><samp>HoeEnchantment</samp><br /><samp>MilkPailEnchantment</samp><br /><samp>PanEnchantment</samp><br /><samp>PickaxeEnchantment</samp><br /><samp>ShearsEnchantment</samp><br /><samp>WateringCanEnchantment</samp>
| <samp>Characters/Dialogue/Penny</samp>
| Obsolete. Enchantments now [[#Enchantment data|target tools via data]] instead.
| &#32;
* [[#Dialogue changes|Merged resort dialogue keys]].
* Removed event dialogues moved into <samp>Strings/Events</samp>.
| '''✘ broken'''
| ✓ mostly unaffected
|-
|-
| <samp>Events.DiaryEvent</samp>
| <samp>Characters/Dialogue/Pierre</samp><br /><samp>Characters/Dialogue/Robin</samp>
| Removed. This was unused.
| Removed event dialogues moved into <samp>Strings/Events</samp>.
|}
|
 
|
====Other API changes====
These class members changed in 1.7:
 
{| class="wikitable"
|-
|-
! type
| <samp>Characters/Dialogue/Sam</samp>
! member
| &#32;
! migration
* [[#Dialogue changes|Merged resort dialogue keys]].
* Removed event dialogues moved into <samp>Strings/Events</samp>.
| '''✘ broken'''
| ✓ mostly unaffected
|-
| <samp>Characters/Dialogue/Sebastian</samp>
| &#32;
* [[#Dialogue changes|Merged resort dialogue keys]].
* Removed event dialogues moved into <samp>Strings/Events</samp>.
* Fixed invalid dialogue key.
| '''✘ broken'''
| ✓ mostly unaffected
|-
|-
|rowspan="9"| <samp>BaseEnchantment</samp><br /><small>(and its subclasses)</small>
| <samp>Characters/Dialogue/Shane</samp>
| <samp>hideEnchantmentName</samp>
| Removed event dialogues moved into <samp>Strings/Events</samp>.
| Replaced by <samp>EnchantmentManager.HideEnchantmentName</samp>.
|
|
|-
|-
| <samp>hideSecondaryEnchantName</samp>
| <samp>Data/Boots</samp>
| Replaced by <samp>EnchantmentManager.HideSecondaryEnchantName</samp>.
| [[#Data/Boots|Overhauled format]].
| '''✘ broken'''
| '''✘ broken'''<br /><small>(until Content Patcher adds runtime migrations)</small>
|-
|-
| <samp>GetEnchantmentFromItem(…)</samp>
| <samp>Data/Buffs</samp>
| Replaced by <samp>EnchantmentManager.GetEnchantmentFromItem</samp>.
| [[#Data/Buffs|Added new data field to data model]].
| '''✘ broken'''
|
|-
|-
| <samp>GetAvailableEnchantments()</samp>
| <samp>Data/Buildings</samp><br /><samp>Data/Characters</samp>
| Removed.
| [[#Item spawn field changes|Added new item spawn field]].
<ul>
| '''✘ broken'''
<li>To check whether any enchantments can be applied to a tool through the [[forge]], use <samp>EnchantmentManager.CanForgeEnchant</samp>.</li>
|
<li>There's no directly equivalent method in 1.7, but you can mimic the former logic if needed.
|-
<syntaxhighlight lang="c#">
| <samp>Data/Events/*</samp><br /><samp>Data/Events/Festivals/*</samp>
static List<Enchantment> GetAvailableEnchantments()
| [[#Event changes|Major changes]] including [[#Multilingual events|multilingual events]], [[#Forking deprecated|event labels]], [[#Changed event keys|event key changes]], replacing dialogue commands with event commands, etc.
{
| '''✘ broken'''
    var dataAsset = DataLoader.Enchantments(Game1.content);
| ✓ mostly unaffected
 
    List<Enchantment> enchantments = [];
    foreach ((string id, EnchantmentData data) in dataAsset)
    {
        if (data.ForgeWith == Object.prismaticShardQID)
            enchantments.Add(EnchantmentManager.CreateEnchantment(dataAsset, id));
    }
 
    return enchantments;
}
</syntaxhighlight></li>
</ul>
|-
|-
| <samp>GetAvailableEnchantmentsForItem(…)</samp>
| <samp>Data/ExtraDialogues</samp>
| Removed.
| &#32;
<ul>
* [[#Event changes|Moved hardcoded events into <samp>Data/Events/*</samp>]].
<li>To check whether any enchantments can be applied to a tool through the [[forge]], use <samp>EnchantmentManager.CanForgeEnchant</samp>.</li>
* Moved <samp>SummitEvent_*</samp> translations into <samp>Strings/Events</samp> (with a new name & format).
<li>There's no directly equivalent method in 1.7, but you can mimic the former logic if needed.
| ✓ mostly unaffected
<syntaxhighlight lang="c#">
| ✓ mostly unaffected
static List<Enchantment> GetAvailableEnchantmentsForItem(Item? tool, Item? item)
{
    var dataAsset = DataLoader.Enchantments(Game1.content);
    var contextTags = tool?.GetContextTags();
 
    List<Enchantment> enchantments = [];
    foreach ((string id, EnchantmentData data) in dataAsset)
    {
        if (data.ForgeWith == Object.prismaticShardQID && (contextTags is null || EnchantmentManager.MatchesTags(contextTags, data.AppliesTo)))
            enchantments.Add(EnchantmentManager.CreateEnchantment(dataAsset, id));
    }
 
    return enchantments;
}
</syntaxhighlight></li>
</ul>
|-
|-
| <samp>GetName()</samp>
| <samp>Data/FishPondData</samp><br /><samp>Data/FruitTrees</samp>
| Removed. This inconsistently returned an ID, a display name, or <samp>"Unknown Enchantment"</samp> depending on the enchantment type. Use the new <samp>Id</samp> property or the pre-existing <samp>GetDisplayName()</samp> method instead.
| [[#Item spawn field changes|Added new item spawn field]].
| '''✘ broken'''
|
|-
|-
| <samp>GetLevel()</samp>
| <samp>Data/Furniture</samp>
| Removed. Use <samp>Level</samp> instead.
| [[#Data/Furniture|Overhauled format]].
| '''✘ broken'''
| '''✘ broken'''<br /><small>(until Content Patcher adds runtime migrations)</small>
|-
|-
| <samp>GetType()</samp>
| <samp>Data/GarbageCans</samp><br /><samp>Data/GiantCrops</samp>
| This was sometimes to identify enchantments (like <code>enchantment.GetType() == expectedEnchantment.GetType()</code>). That's no longer reliable, since 1.7 introduces data-based enchantments which may not have their own C# type. You should use the new <samp>enchantment.Id</samp> property instead.
| [[#Item spawn field changes|Added new item spawn field]].
| '''✘ broken'''
|
|-
|-
| <samp>ResetEnchantments()</samp>
| <samp>Data/Hats</samp>
| Removed. This is no longer needed since it no longer has a cached list of enchantment instances.
| [[#Data/Hats|Overhauled format]].
| '''✘ broken'''
| '''✘ broken'''<br /><small>(until Content Patcher adds runtime migrations)</small>
|-
|-
| <samp>Boots</samp>
| <samp>Data/Locations</samp>
| <samp>price</samp>
| [[#Item spawn field changes|Added new item spawn field]].
| Removed. This was never used, since boots prices are calculated dynamically.
| '''✘ broken'''
|
|-
|-
|rowspan="2"| <samp>Bush</samp>
| <samp>Data/Machines</samp>
| <samp>draw(SpriteBatch batch, int yDrawOffset)</samp>
| [[#Item spawn field changes|Added new item spawn field]].
| Removed. Set the <samp>drawOffset</samp> field and then call <samp>draw(SpriteBatch)</samp> instead.
| '''✘ broken'''
|
|-
|-
| <samp>yDrawOffset</samp>
| <samp>Data/Monsters</samp>
| Replaced by <samp>drawOffset</samp>, which is now public and a <samp>Point</samp>.
| [[#Data/Monsters|Overhauled format]].
| '''✘ broken'''
| '''✘ broken'''<br /><small>(until Content Patcher adds runtime migrations)</small>
|-
|-
| <samp>FishingRod</samp>
| <samp>Data/Movies</samp>
| <samp>lastCatchWasJunk</samp>
| [[#Item spawn field changes|Added new item spawn field]].
| Renamed to <samp>lastCatchSkippedMinigame</samp> to more accurately convey what it does.
| '''✘ broken'''
|
|-
|-
|rowspan="2"| <samp>Furniture</samp>
| <samp>Data/Objects</samp>
| <samp>armchair</samp><br /><samp>bed</samp><br /><samp>bench</samp><br /><samp>bookcase</samp><br /><samp>chair</samp><br /><samp>couch</samp><br /><samp>decor</samp><br /><samp>dresser</samp><br /><samp>fireplace</samp><br /><samp>lamp</samp><br /><samp>longTable</samp><br /><samp>other</samp><br /><samp>painting</samp><br /><samp>rug</samp><br /><samp>sconce</samp><br /><samp>table</samp><br /><samp>torch</samp><br /><samp>window</samp>
| &#32;
| Removed. Replaced by the <samp>FurnitureType</samp> enum (e.g. <code>Furniture.rug</code> is now <code>FurnitureType.Rug</code>).
* [[#Data/Objects|Added new data field to data model]] and [[#Item spawn field changes|new item spawn fields]].
* Added <samp>fish_talk_coral</samp> [[#New context tags|context tag]] for [[coral]] and [[Sea Urchin|sea urchin]].
| '''✘ broken'''
| ✓ mostly unaffected
|-
|-
| <samp>placementRestrictions</samp>
| <samp>Data/Pets</samp><br /><samp>Data/Shops</samp>
| Removed. Replaced by <samp>CanPlaceIndoors</samp> and <samp>CanPlaceOutdoors</samp>.
| [[#Item spawn field changes|Added new item spawn field]].
| '''✘ broken'''
|
|-
|-
|rowspan="2"| <samp>Monster</samp>
| <samp>Data/Weapons</samp>
| <samp>getExtraDropItems()</samp>
| &#32;
| Removed. Drops should be added to [[#Data/Monsters|<samp>Data/Monsters</samp>]] instead.
* [[#Item spawn field changes|Added new item spawn field]].
 
* Added <samp>is_galaxy_weapon</samp> [[#New context tags|context tag]] for galaxy weapons.
[[Modding:Modder Guide/APIs/Harmony|Harmony patches]] which can't be moved into data can target <samp>Monster.RollForDrops</samp> instead.
| '''✘ broken'''
| ✓ mostly unaffected
|-
|-
| <samp>objectsToDrop</samp>
| <samp>Data/WildTrees</samp>
| Removed. Replaced by <samp>drops</samp>; see [[#Monster changes|''monster changes'']] and [[#Data/Monsters|''<samp>Data/Monsters</samp>'']].
| [[#Item spawn field changes|Added new item spawn field]].
| '''✘ broken'''
|
|-
|-
|rowspan="3"| <samp>NPCDialogueResponse</samp><br /><samp>Response</samp>
| <samp>Strings/1_6_Strings</samp>
| <samp>id</samp><br /><samp>friendshipChange</samp><br /><samp>extraArgument</samp><br /><samp>hotkey</samp><br /><samp>responseText</samp>
| &#32;
| Fields changed to get-only properties.
* [[#Event changes|Moved hardcoded events into <samp>Data/Events/*</samp>]].
* Moved some translations into <samp>Strings/EnchanmentNames</samp>, <samp>Strings/Events</samp>, and <samp>Strings/Furniture</samp>.
| ✓ mostly unaffected
| ✓ mostly unaffected
|-
|-
| <samp>responseKey</samp>
| <samp>Strings/EnchantmentNames</samp>
| &#32;
| &#32;
* Field changed to get-only property.
* Added translations moved from <samp>Strings/1_6_Strings</samp>.
* Previously <samp>NPCDialogueResponse</samp> stored the NPC's reaction dialogue key in this field. You should now use <samp>npcReactionKey</samp> for that instead.
* Renamed two keys (<samp>Auto-Hook</samp> → <samp.AutoHook</samp>, <samp>Bug Killer</samp> → <samp>BugKiller</samp>).
| '''✘ broken'''
| ✓ mostly unaffected
|-
|-
| <samp>SetHotKey(…)</samp>
| <samp>Strings/Events</samp>
| Removed. Set the hotkey through the constructor instead.
| &#32;
|-
* Added translations for [[#Multilingual events|multilingual events]].
| <samp>Tool</samp>
* Added translations moved from NPC dialogue assets.
| <samp>GetEnchantmentLevel&lt;T&gt;()</samp><br /><samp>GetEnchantmentOfType&lt;T&gt;()</samp><br /><samp>hasEnchantmentOfType&lt;T&gt;()</samp>
| Removed. Replaced by <samp>GetEnchantmentLevel(id)</samp>, <samp>GetEnchantment(id)</samp>, and <samp>HasEnchantment(id)</samp> respectively. All vanilla enchantments have a constant for the ID like <samp>EnchantmentIds.GalaxySoul</samp>.
|}
 
===Other changes===
* Added <samp>PlatformAchievementIds</samp> constants.
* Added <samp>event.floorSprites</samp> field for temporary animated sprites that should be drawn on the ground (e.g. under NPC shadows).
* The game now uses forward slashes in all asset names (like <samp>Maps/Town</samp> instead of <samp>Maps\Town</samp>). This shouldn't affect most mods, since SMAPI already converted all asset names to forward slashes.
* Removed broken <samp>Lantern</samp> tool, <samp>Raft</samp> tool, and their related logic.
* Fixed <code>Event.TryGetEventCommandHandler</code> not loading commands if it's called before any other methods.
* Fixed machine auto-load leaving empty slots in chests when taking a secondary ingredient.
* Fixed issue where placing a storage furniture (e.g. a dresser or fish tank) on a table would discard any items inside it.
 
==Name translation changes for wiki maintainers==
Some in-game item and monster names were retranslated in some languages for clarity or correctness.
 
This list is mostly provided to help wiki maintainers update pages, so it doesn't include names which only changed capitalization, changed <code>'</code> (straight apostrophe) to <code>’</code> (curly) in French, or aren't visible to vanilla players (like mine rocks).
 
===Objects===
; Hungarian
: {| class="wikitable"
|-
! item
! old name
! new name
|-
| [[Artichoke Dip]]
| ''Articsóka mártás''
| ''Articsókamártás''
|-
| [[Blackberry Cobbler]]
| ''Szeder kosár''
| ''Szedres kosárka''
|-
| [[Bone Mill]]
| ''Csontőrlő''
| ''Csontdaráló''
|-
| [[Chocolate Cake]]
| ''Csokis torta''
| ''Csokitorta''
|-
| [[Cranberry Candy]]
| ''Vörös áfonyás cukorka''
| ''Vörös áfonyás üdítő''
|-
| [[Geode Crusher]]
| ''Geóda zúzó''
| ''Geódazúzó''
|-
| [[Maple Syrup]]
| ''Juharfaszirup''
| ''Juharszirup''
|-
| [[Tea Sapling]]
| ''Tea csemete''
| ''Teacsemete''
|-
| [[Woodcutter's Weekly]]
| ''Favágok hetilapja''
| ''Favágók hetilapja''
|}
 
; Russian
: {| class="wikitable"
|-
! item
! old name
! new name
|-
|rowspan="71" valign="top"| [[Aged Roe]] (flavored)
| ''Вяленая икра (Альбакор)''<!--Albacore-->
| ''Вяленая икра альбакора''
|-
| ''Вяленая икра (Анчоус)''<!--Anchovy-->
| ''Вяленая икра анчоуса''
|-
| ''Вяленая икра (Морской черт)''<!--Angler-->
| ''Вяленая икра Морского черта''
|-
| ''Вяленая икра (Рыба-капля)''<!--Blobfish-->
| ''Вяленая икра рыбы-капли''
|-
| ''Вяленая икра (Голубой дискус)''<!--Blue Discus-->
| ''Вяленая икра голубого дискуса''
|-
| ''Вяленая икра (Лещ)''<!--Bream-->
| ''Вяленая икра леща''
|-
| ''Вяленая икра (Сомик)''<!--Bullhead-->
| ''Вяленая икра сомика''
|-
| ''Вяленая икра (Карп)''<!--Carp-->
| ''Вяленая икра карпа''
|-
| ''Вяленая икра (Сом)''<!--Catfish-->
| ''Вяленая икра сома''
|-
| ''Вяленая икра (Голавль)''<!--Chub-->
| ''Вяленая икра голавля''
|-
| ''Вяленая икра (Гребешок)''<!--Clam-->
| ''Вяленая икра гребешка''
|-
| ''Вяленая икра (Сердцевидка)''<!--Cockle-->
| ''Вяленая икра сердцевидки''
|-
| ''Вяленая икра (Краб)''<!--Crab-->
| ''Вяленая икра краба''
|-
| ''Вяленая икра (Рак)''<!--Crayfish-->
| ''Вяленая икра рака''
|-
| ''Вяленая икра (Багрянник)''<!--Crimsonfish-->
| ''Вяленая икра Багрянника''
|-
| ''Вяленая икра (Дорада)''<!--Dorado-->
| ''Вяленая икра дорады''
|-
| ''Вяленая икра (Угорь)''<!--Eel-->
| ''Вяленая икра угря''
|-
| ''Вяленая икра (Камбала)''<!--Flounder-->
| ''Вяленая икра камбалы''
|-
| ''Вяленая икра (Пятнистый криворот)''<!--Ghostfish-->
| ''Вяленая икра пятнистого криворота''
|-
| ''Вяленая икра (Ледорыб)''<!--Glacierfish-->
| ''Вяленая икра Ледорыба''
|-
| ''Вяленая икра (Ледорыб-младший)''<!--Glacierfish Jr.-->
| ''Вяленая икра Ледорыба-младшего''
|-
| ''Вяленая икра (Бычок)''<!--Goby-->
| ''Вяленая икра бычка''
|-
| ''Вяленая икра (Палтус)''<!--Halibut-->
| ''Вяленая икра палтуса''
|-
| ''Вяленая икра (Сельдь)''<!--Herring-->
| ''Вяленая икра сельди''
|-
| ''Вяленая икра (Ледопип)''<!--Ice Pip-->
| ''Вяленая икра ледопипа''
|-
| ''Вяленая икра (Большеротый окунь)''<!--Largemouth Bass-->
| ''Вяленая икра большеротого окуня''
|-
| ''Вяленая икра (Лавовый угорь)''<!--Lava Eel-->
| ''Вяленая икра лавового угря''
|-
| ''Вяленая икра (Легенда)''<!--Legend-->
| ''Вяленая икра Легенды''
|-
| ''Вяленая икра (Легенда II)''<!--Legend II-->
| ''Вяленая икра Легенды II''
|-
| ''Вяленая икра (Змеезуб)''<!--Lingcod-->
| ''Вяленая икра змеезуба''
|-
| ''Вяленая икра (Крылатка)''<!--Lionfish-->
| ''Вяленая икра крылатки''
|-
| ''Вяленая икра (Омар)''<!--Lobster-->
| ''Вяленая икра омара''
|-
| ''Вяленая икра (Полуночный карп)''<!--Midnight Carp-->
| ''Вяленая икра полуночного карпа''
|-
| ''Вяленая икра (Ночной кальмар)''<!--Midnight Squid-->
| ''Вяленая икра ночного кальмара''
|-
| ''Вяленая икра (Мисс Морской черт)''<!--Ms. Angler-->
| ''Вяленая икра Мисс Морской черт''
|-
| ''Вяленая икра (Мидия)''<!--Mussel-->
| ''Вяленая икра мидий''
|-
| ''Вяленая икра (Карп-мутант)''<!--Mutant Carp-->
| ''Вяленая икра Карпа-мутанта''
|-
| ''Вяленая икра (Осьминог)''<!--Octopus-->
| ''Вяленая икра осьминога''
|-
| ''Вяленая икра (Устрица)''<!--Oyster-->
| ''Вяленая икра устриц''
|-
| ''Вяленая икра (Окунь)''<!--Perch-->
| ''Вяленая икра окуня''
|-
| ''Вяленая икра (Литорина)''<!--Periwinkle-->
| ''Вяленая икра литорин''
|-
| ''Вяленая икра (Щука)''<!--Pike-->
| ''Вяленая икра щуки''
|-
| ''Вяленая икра (Иглобрюх)''<!--Pufferfish-->
| ''Вяленая икра иглобрюха''
|-
| ''Вяленая икра (Радиоактивный карп)''<!--Radioactive Carp-->
| ''Вяленая икра Радиоактивного карпа''
|-
| ''Вяленая икра (Радужная форель)''<!--Rainbow Trout-->
| ''Вяленая икра радужной форели''
|-
| ''Вяленая икра (Барабулька)''<!--Red Mullet-->
| ''Вяленая икра барабульки''
|-
| ''Вяленая икра (Берикс)''<!--Red Snapper-->
| ''Вяленая икра берикса''
|-
| ''Вяленая икра (Лосось)''<!--Salmon-->
| ''Вяленая икра лосося''
|-
| ''Вяленая икра (Песковник)''<!--Sandfish-->
| ''Вяленая икра песковника''
|-
| ''Вяленая икра (Сардина)''<!--Sardine-->
| ''Вяленая икра сардины''
|-
| ''Вяленая икра (Скорпионовый карп)''<!--Scorpion Carp-->
| ''Вяленая икра скорпионового карпа''
|-
| ''Вяленая икра (Морской огурец)''<!--Sea Cucumber-->
| ''Вяленая икра морского огурца''
|-
| ''Вяленая икра (Морской еж)''<!--Sea Urchin-->
| ''Вяленая икра морского ежа''
|-
| ''Вяленая икра (Шэд)''<!--Shad-->
| ''Вяленая икра шэда''
|-
| ''Вяленая икра (Креветка)''<!--Shrimp-->
| ''Вяленая икра креветок''
|-
| ''Вяленая икра (Слаймджек)''<!--Slimejack-->
| ''Вяленая икра слаймджека''
|-
| ''Вяленая икра (Малоротый окунь)''<!--Smallmouth Bass-->
| ''Вяленая икра малоротого окуня''
|-
| ''Вяленая икра (Улитка)''<!--Snail-->
| ''Вяленая икра улиток''
|-
| ''Вяленая икра (Малек Багрянника)''<!--Son of Crimsonfish-->
| ''Вяленая икра Малька Багрянника''
|-
| ''Вяленая икра (Жуть-рыба)''<!--Spook Fish-->
| ''Вяленая икра жуть-рыбы''
|-
| ''Вяленая икра (Кальмар)''<!--Squid-->
| ''Вяленая икра кальмара''
|-
| ''Вяленая икра (Скат)''<!--Stingray-->
| ''Вяленая икра ската''
|-
| ''Вяленая икра (Рыба-камень)''<!--Stonefish-->
| ''Вяленая икра рыбы-камня''
|-
| ''Вяленая икра (Солнечник)''<!--Sunfish-->
| ''Вяленая икра солнечника''
|-
| ''Вяленая икра (Чудо-огурец)''<!--Super Cucumber-->
| ''Вяленая икра чудо-огурца''
|-
| ''Вяленая икра (Тигровая форель)''<!--Tiger Trout-->
| ''Вяленая икра тигровой форели''
|-
| ''Вяленая икра (Тиляпия)''<!--Tilapia-->
| ''Вяленая икра тиляпии''
|-
| ''Вяленая икра (Тунец)''<!--Tuna-->
| ''Вяленая икра тунца''
|-
| ''Вяленая икра (Лосось пустоты)''<!--Void Salmon-->
| ''Вяленая икра лосося пустоты''
|-
| ''Вяленая икра (Желтый судак)''<!--Walleye-->
| ''Вяленая икра желтого судака''
|-
| ''Вяленая икра (Лесоплюх)''<!--Woodskip-->
| ''Вяленая икра лесоплюха''
|-
| [[Bait]]
| ''Приманка''
| ''Наживка''
|-
| [[Basic Retaining Soil]]
| ''Обычная влагосохраняющая почва''
| ''Обычный аквагрунт''
|-
| [[Deluxe Retaining Soil]]
| ''Влагосохраняющая почва Делюкс''
| ''Аквагрунт Делюкс''
|-
| [[Dried Fruit]] (flavored)
| ''Сушеная морошка''<!--Salmonberry-->
| ''Сушеная малина''
|-
| [[Jellies and Pickles|Jelly]] (flavored)
| ''Джем из морошки''<!--Salmonberry-->
| ''Малиновый джем''
|-
| [[Juice]] (flavored)
| ''Сок сквоша''<!--Summer Squash-->
| ''Кабачковый сок''
|-
| [[Magic Bait]]
| ''Волшебная приманка''
| ''Волшебная наживка''
|-
| [[Quality Fertilizer]]
| ''Высококачественное удобрение''
| ''Улучшенное удобрение''
|-
| [[Quality Retaining Soil]]
| ''Высококачественная влагосохраняющая почва''
| ''Улучшенный аквагрунт''
|-
| [[Quality Sprinkler]]
| ''Высококачественный спринклер''
| ''Улучшенный спринклер''
|-
|rowspan="72" valign="top"| [[Roe]] (flavored)
| ''Икра (Альбакор)''<!--Albacore-->
| ''Икра альбакора''
|-
| ''Икра (Анчоус)''<!--Anchovy-->
| ''Икра анчоуса''
|-
| ''Икра (Морской черт)''<!--Angler-->
| ''Икра Морского черта''
|-
| ''Икра (Рыба-капля)''<!--Blobfish-->
| ''Икра рыбы-капли''
|-
| ''Икра (Голубой дискус)''<!--Blue Discus-->
| ''Икра голубого дискуса''
|-
| ''Икра (Лещ)''<!--Bream-->
| ''Икра леща''
|-
| ''Икра (Сомик)''<!--Bullhead-->
| ''Икра сомика''
|-
| ''Икра (Карп)''<!--Carp-->
| ''Икра карпа''
|-
| ''Икра (Сом)''<!--Catfish-->
| ''Икра сома''
|-
| ''Икра (Голавль)''<!--Chub-->
| ''Икра голавля''
|-
| ''Икра (Гребешок)''<!--Clam-->
| ''Икра гребешка''
|-
| ''Икра (Сердцевидка)''<!--Cockle-->
| ''Икра сердцевидки''
|-
| ''Икра (Краб)''<!--Crab-->
| ''Икра краба''
|-
| ''Икра (Рак)''<!--Crayfish-->
| ''Икра рака''
|-
| ''Икра (Багрянник)''<!--Crimsonfish-->
| ''Икра Багрянника''
|-
| ''Икра (Дорада)''<!--Dorado-->
| ''Икра дорады''
|-
| ''Икра (Угорь)''<!--Eel-->
| ''Икра угря''
|-
| ''Икра (Камбала)''<!--Flounder-->
| ''Икра камбалы''
|-
| ''Икра (Пятнистый криворот)''<!--Ghostfish-->
| ''Икра пятнистого криворота''
|-
| ''Икра (Ледорыб)''<!--Glacierfish-->
| ''Икра Ледорыба''
|-
| ''Икра (Ледорыб-младший)''<!--Glacierfish Jr.-->
| ''Икра Ледорыба-младшего''
|-
| ''Икра (Бычок)''<!--Goby-->
| ''Икра бычка''
|-
| ''Икра (Палтус)''<!--Halibut-->
| ''Икра палтуса''
|-
| ''Икра (Сельдь)''<!--Herring-->
| ''Икра сельди''
|-
| ''Икра (Ледопип)''<!--Ice Pip-->
| ''Икра ледопипа''
|-
| ''Икра (Большеротый окунь)''<!--Largemouth Bass-->
| ''Икра большеротого окуня''
|-
| ''Икра (Лавовый угорь)''<!--Lava Eel-->
| ''Икра лавового угря''
|-
| ''Икра (Легенда)''<!--Legend-->
| ''Икра Легенды''
|-
| ''Икра (Легенда II)''<!--Legend II-->
| ''Икра Легенды II''
|-
| ''Икра (Змеезуб)''<!--Lingcod-->
| ''Икра змеезуба''
|-
| ''Икра (Крылатка)''<!--Lionfish-->
| ''Икра крылатки''
|-
| ''Икра (Омар)''<!--Lobster-->
| ''Икра омара''
|-
| ''Икра (Полуночный карп)''<!--Midnight Carp-->
| ''Икра полуночного карпа''
|-
| ''Икра (Ночной кальмар)''<!--Midnight Squid-->
| ''Икра ночного кальмара''
|-
| ''Икра (Мисс Морской черт)''<!--Ms. Angler-->
| ''Икра Мисс Морской черт''
|-
| ''Икра (Мидия)''<!--Mussel-->
| ''Икра мидий''
|-
| ''Икра (Карп-мутант)''<!--Mutant Carp-->
| ''Икра Карпа-мутанта''
|-
| ''Икра (Осьминог)''<!--Octopus-->
| ''Икра осьминога''
|-
| ''Икра (Устрица)''<!--Oyster-->
| ''Икра устриц''
|-
| ''Икра (Окунь)''<!--Perch-->
| ''Икра окуня''
|-
| ''Икра (Литорина)''<!--Periwinkle-->
| ''Икра литорин''
|-
| ''Икра (Щука)''<!--Pike-->
| ''Икра щуки''
|-
| ''Икра (Иглобрюх)''<!--Pufferfish-->
| ''Икра иглобрюха''
|-
| ''Икра (Радиоактивный карп)''<!--Radioactive Carp-->
| ''Икра Радиоактивного карпа''
|-
| ''Икра (Радужная форель)''<!--Rainbow Trout-->
| ''Икра радужной форели''
|-
| ''Икра (Барабулька)''<!--Red Mullet-->
| ''Икра барабульки''
|-
| ''Икра (Берикс)''<!--Red Snapper-->
| ''Икра берикса''
|-
| ''Икра (Лосось)''<!--Salmon-->
| ''Икра лосося''
|-
| ''Икра (Песковник)''<!--Sandfish-->
| ''Икра песковника''
|-
| ''Икра (Сардина)''<!--Sardine-->
| ''Икра сардины''
|-
| ''Икра (Скорпионовый карп)''<!--Scorpion Carp-->
| ''Икра скорпионового карпа''
|-
| ''Икра (Морской огурец)''<!--Sea Cucumber-->
| ''Икра морского огурца''
|-
| ''Икра (Морской еж)''<!--Sea Urchin-->
| ''Икра морского ежа''
|-
| ''Икра (Шэд)''<!--Shad-->
| ''Икра шэда''
|-
| ''Икра (Креветка)''<!--Shrimp-->
| ''Икра креветок''
|-
| ''Икра (Слаймджек)''<!--Slimejack-->
| ''Икра слаймджека''
|-
| ''Икра (Малоротый окунь)''<!--Smallmouth Bass-->
| ''Икра малоротого окуня''
|-
| ''Икра (Улитка)''<!--Snail-->
| ''Икра улиток''
|-
| ''Икра (Малек Багрянника)''<!--Son of Crimsonfish-->
| ''Икра Малька Багрянника''
|-
| ''Икра (Жуть-рыба)''<!--Spook Fish-->
| ''Икра жуть-рыбы''
|-
| ''Икра (Кальмар)''<!--Squid-->
| ''Икра кальмара''
|-
| ''Икра (Скат)''<!--Stingray-->
| ''Икра ската''
|-
| ''Икра (Рыба-камень)''<!--Stonefish-->
| ''Икра рыбы-камня''
|-
| ''Икра (Осетр)''<!--Sturgeon-->
| ''Икра осетра''
|-
| ''Икра (Солнечник)''<!--Sunfish-->
| ''Икра солнечника''
|-
| ''Икра (Чудо-огурец)''<!--Super Cucumber-->
| ''Икра чудо-огурца''
|-
| ''Икра (Тигровая форель)''<!--Tiger Trout-->
| ''Икра тигровой форели''
|-
| ''Икра (Тиляпия)''<!--Tilapia-->
| ''Икра тиляпии''
|-
| ''Икра (Тунец)''<!--Tuna-->
| ''Икра тунца''
|-
| ''Икра (Лосось пустоты)''<!--Void Salmon-->
| ''Икра лосося пустоты''
|-
| ''Икра (Желтый судак)''<!--Walleye-->
| ''Икра желтого судака''
|-
| ''Икра (Лесоплюх)''<!--Woodskip-->
| ''Икра лесоплюха''
|-
| [[Salmonberry]]
| ''Морошка''
| ''Малина''
|-
| [[Summer Squash Seeds]]
| ''Семена сквоша''
| ''Семена кабачка''
|-
| [[Summer Squash]]
| ''Сквош''
| ''Кабачок''
|-
|rowspan="71" valign="top"| [[Targeted Bait]]
| ''Наживка: Альбакор''<!--Albacore-->
| ''Наживка на альбакора''
|-
| ''Наживка: Анчоус''<!--Anchovy-->
| ''Наживка на анчоуса''
|-
| ''Наживка: Морской черт''<!--Angler-->
| ''Наживка на Морского черта''
|-
| ''Наживка: Рыба-капля''<!--Blobfish-->
| ''Наживка на рыбу-каплю''
|-
| ''Наживка: Голубой дискус''<!--Blue Discus-->
| ''Наживка на голубого дискуса''
|-
| ''Наживка: Лещ''<!--Bream-->
| ''Наживка на леща''
|-
| ''Наживка: Сомик''<!--Bullhead-->
| ''Наживка на сомика''
|-
| ''Наживка: Карп''<!--Carp-->
| ''Наживка на карпа''
|-
| ''Наживка: Сом''<!--Catfish-->
| ''Наживка на сома''
|-
| ''Наживка: Голавль''<!--Chub-->
| ''Наживка на голавля''
|-
| ''Наживка: Гребешок''<!--Clam-->
| ''Приманка для гребешков''
|-
| ''Наживка: Сердцевидка''<!--Cockle-->
| ''Приманка для сердцевидок''
|-
| ''Наживка: Краб''<!--Crab-->
| ''Приманка для крабов''
|-
| ''Наживка: Рак''<!--Crayfish-->
| ''Приманка для раков''
|-
| ''Наживка: Багрянник''<!--Crimsonfish-->
| ''Наживка на Багрянника''
|-
| ''Наживка: Дорада''<!--Dorado-->
| ''Наживка на дораду''
|-
| ''Наживка: Угорь''<!--Eel-->
| ''Наживка на угря''
|-
| ''Наживка: Камбала''<!--Flounder-->
| ''Наживка на камбалу''
|-
| ''Наживка: Пятнистый криворот''<!--Ghostfish-->
| ''Наживка на пятнистого криворота''
|-
| ''Наживка: Ледорыб''<!--Glacierfish-->
| ''Наживка на Ледорыба''
|-
| ''Наживка: Ледорыб-младший''<!--Glacierfish Jr.-->
| ''Наживка на Ледорыба-младшего''
|-
| ''Наживка: Бычок''<!--Goby-->
| ''Наживка на бычка''
|-
| ''Наживка: Палтус''<!--Halibut-->
| ''Наживка на палтуса''
|-
| ''Наживка: Сельдь''<!--Herring-->
| ''Наживка на сельдь''
|-
| ''Наживка: Ледопип''<!--Ice Pip-->
| ''Наживка на ледопипа''
|-
| ''Наживка: Большеротый окунь''<!--Largemouth Bass-->
| ''Наживка на большеротого окуня''
|-
| ''Наживка: Лавовый угорь''<!--Lava Eel-->
| ''Наживка на лавового угря''
|-
| ''Наживка: Легенда''<!--Legend-->
| ''Наживка на Легенду''
|-
| ''Наживка: Легенда II''<!--Legend II-->
| ''Наживка на Легенду II''
|-
| ''Наживка: Змеезуб''<!--Lingcod-->
| ''Наживка на змеезуба''
|-
| ''Наживка: Крылатка''<!--Lionfish-->
| ''Наживка на крылатку''
|-
| ''Наживка: Омар''<!--Lobster-->
| ''Приманка для омаров''
|-
| ''Наживка: Полуночный карп''<!--Midnight Carp-->
| ''Наживка на полуночного карпа''
|-
| ''Наживка: Ночной кальмар''<!--Midnight Squid-->
| ''Наживка на ночного кальмара''
|-
| ''Наживка: Мисс Морской черт''<!--Ms. Angler-->
| ''Наживка на Мисс Морской черт''
|-
| ''Наживка: Мидия''<!--Mussel-->
| ''Приманка для мидий''
|-
| ''Наживка: Карп-мутант''<!--Mutant Carp-->
| ''Наживка на Карпа-мутанта''
|-
| ''Наживка: Осьминог''<!--Octopus-->
| ''Наживка на осьминога''
|-
| ''Наживка: Устрица''<!--Oyster-->
| ''Приманка для устриц''
|-
| ''Наживка: Окунь''<!--Perch-->
| ''Наживка на окуня''
|-
| ''Наживка: Литорина''<!--Periwinkle-->
| ''Приманка для литорин''
|-
| ''Наживка: Щука''<!--Pike-->
| ''Наживка на щуку''
|-
| ''Наживка: Иглобрюх''<!--Pufferfish-->
| ''Наживка на иглобрюха''
|-
| ''Наживка: Радиоактивный карп''<!--Radioactive Carp-->
| ''Наживка на Радиоактивного карпа''
|-
| ''Наживка: Радужная форель''<!--Rainbow Trout-->
| ''Наживка на радужную форель''
|-
| ''Наживка: Барабулька''<!--Red Mullet-->
| ''Наживка на барабульку''
|-
| ''Наживка: Берикс''<!--Red Snapper-->
| ''Наживка на берикса''
|-
| ''Наживка: Лосось''<!--Salmon-->
| ''Наживка на лосося''
|-
| ''Наживка: Песковник''<!--Sandfish-->
| ''Наживка на песковника''
|-
| ''Наживка: Сардина''<!--Sardine-->
| ''Наживка на сардину''
|-
| ''Наживка: Скорпионовый карп''<!--Scorpion Carp-->
| ''Наживка на скорпионового карпа''
|-
| ''Наживка: Морской огурец''<!--Sea Cucumber-->
| ''Наживка на морского огурца''
|-
| ''Наживка: Шэд''<!--Shad-->
| ''Наживка на шэда''
|-
| ''Наживка: Креветка''<!--Shrimp-->
| ''Приманка для креветок''
|-
| ''Наживка: Слаймджек''<!--Slimejack-->
| ''Наживка на слаймджека''
|-
| ''Наживка: Малоротый окунь''<!--Smallmouth Bass-->
| ''Наживка на малоротого окуня''
|-
| ''Наживка: Улитка''<!--Snail-->
| ''Приманка для улиток''
|-
| ''Наживка: Малек Багрянника''<!--Son of Crimsonfish-->
| ''Наживка на Малька Багрянника''
|-
| ''Наживка: Жуть-рыба''<!--Spook Fish-->
| ''Наживка на жуть-рыбу''
|-
| ''Наживка: Кальмар''<!--Squid-->
| ''Наживка на кальмара''
|-
| ''Наживка: Скат''<!--Stingray-->
| ''Наживка на ската''
|-
| ''Наживка: Рыба-камень''<!--Stonefish-->
| ''Наживка на рыбу-камень''
|-
| ''Наживка: Осетр''<!--Sturgeon-->
| ''Наживка на осетра''
|-
| ''Наживка: Солнечник''<!--Sunfish-->
| ''Наживка на солнечника''
|-
| ''Наживка: Чудо-огурец''<!--Super Cucumber-->
| ''Наживка на чудо-огурец''
|-
| ''Наживка: Тигровая форель''<!--Tiger Trout-->
| ''Наживка на тигровую форель''
|-
| ''Наживка: Тиляпия''<!--Tilapia-->
| ''Наживка на тиляпию''
|-
| ''Наживка: Тунец''<!--Tuna-->
| ''Наживка на тунца''
|-
| ''Наживка: Лосось пустоты''<!--Void Salmon-->
| ''Наживка на лосося пустоты''
|-
| ''Наживка: Желтый судак''<!--Walleye-->
| ''Наживка на желтого судака''
|-
| ''Наживка: Лесоплюх''<!--Woodskip-->
| ''Наживка на лесоплюха''
|-
| [[Wine]] (flavored)
| ''Вино из морошки''<!--Salmonberry-->
| ''Малиновое вино''
|}
 
===Furniture===
; Hungarian
: {| class="wikitable"
|-
! item
! old name
! new name
|-
| [[Artist Bookcase]]
| ''Művészi könyvespolc''
| ''Művészi könyvszekrény''
|-
| [[Birch Double Bed]]
| ''Birs dupla ágy''
| ''Nyírfa dupla ágy''
|-
| [[Birch Lamp End Table]]
| ''Nyírfa lámpás éjjeliszekrény''
| ''Nyírfa éjjeliszekrény lámpával''
|-
| [[China Cabinet]]
| ''Kínai vitrin''
| ''Porcelános vitrin''
|-
| [[Coffee Table]]
| ''Kávésasztal''
| ''Kávézó asztal''
|-
| [[Dark Bookcase]]
| ''Sötét könyvespolc''
| ''Sötét könyvszekrény''
|-
| [[Gray Joja Bookcase]]
| ''Szürke Joja könyvespolc''
| ''Szürke Joja könyvszekrény''
|-
| [[Gray Joja Coffee Table]]
| ''Szürke Joja kávésasztal''
| ''Szürke Joja kávézó asztal''
|-
| [[Joja Bookcase]]
| ''Joja könyvespolc''
| ''Joja könyvszekrény''
|-
| [[Joja Coffee Table]]
| ''Joja kávésasztal''
| ''Joja kávézó asztal''
|-
| [[Junimo Bookcase]]
| ''Junimo könyvespolc''
| ''Junimo könyvszekrény''
|-
| [[Large Wizard Bookcase]]
| ''Nagy varázsló könyvespolc''
| ''Nagy varázsló könyvszekrény''
|-
| [[Luxury Bookcase]]
| ''Luxus könyvespolc''
| ''Luxus könyvszekrény''
|-
| [[Mahogany Lamp End Table]]
| ''Mahagóni lámpás éjjeliszekrény''
| ''Mahagóni éjjeliszekrény lámpával''
|-
| [[Modern Bookcase]]
| ''Modern könyvespolc''
| ''Modern könyvszekrény''
|-
| [[Oak Lamp End Table]]
| ''Tölgyfa lámpás éjjeliszekrény''
| ''Tölgyfa éjjeliszekrény lámpával''
|-
| [[Retro Bookcase]]
| ''Retro könyvespolc''
| ''Retro könyvszekrény''
|-
| [[Short Bookcase]]
| ''Kicsi könyvespolc''
| ''Kicsi könyvszekrény''
|-
| [[Short Wizard Bookcase]]
| ''Alacsony varázsló könyvespolc''
| ''Alacsony varázsló könyvszekrény''
|-
| [[Small Wizard Bookcase]]
| ''Kicsi varázsló könyvespolc''
| ''Kicsi varázsló könyvszekrény''
|-
| [[Spirits Table]]
| ''Italosasztal''
| ''Italos asztal''
|-
| [[Walnut Lamp End Table]]
| ''Diófa lámpás éjjeliszekrény''
| ''Diófa éjjeliszekrény lámpával''
|-
| [[Wizard Bookcase]]
| ''Varázsló könyvespolc''
| ''Varázsló könyvszekrény''
|}
 
; Russian
: {| class="wikitable"
|-
! item
! old name
! new name
|-
| [[Corn Plant]]
| ''Кукуруза''
| ''Драцена''
|-
| [[Pierre's Sign]]
| ''Знак Пьера''
| ''Вывеска Пьера''
|}
 
===Hats===
; French
: {| class="wikitable"
|-
! item
! old name
! new name
|-
| [[Good Ol' Cap]]
| ''Veille casquette''
| ''Vieille casquette''
|}
 
; Russian
: {| class="wikitable"
|-
! item
! old name
! new name
|-
| [[Blobfish Mask]]
| ''Маска рыбы-пузыря''
| ''Маска рыбы-капли''
|-
| [[Bluebird Mask]]
| ''Маска сиалии''
| ''Маска синей птицы''
|-
| [[Cowgal Hat]]
| ''Шляпа девушки-ковбоя''
| ''Женская ковбойская шляпа''
|-
| [[Deluxe Pirate Hat]]
| ''Элитная пиратская шляпа''
| ''Роскошная пиратская шляпа''
|-
| [[Dinosaur Hat]]
| ''Шляпа-динозавр''
| ''Шапка динозавра''
|-
| [[Official Cap]]
| ''Кепка от униформы''
| ''Фуражка''
|-
| [[Panda Hat]]
| ''Шляпка Панды''
| ''Шапка панды''
|-
| Party Hat
| ''Шляпа тусовщика''
| ''Праздничный колпак''
|-
| [[Santa Hat]]
| ''Шляпа Санты''
| ''Шапка Санты''
|-
| [[Star Helmet]]
| ''Звездный шлем''
| ''Шапка со звездами''
|-
| [[Sunglasses]]
| ''Солнечные очки''
| ''Солнцезащитные очки''
|-
| [[Tiger Hat]]
| ''Тигриная шляпа''
| ''Тигриная шапка''
|}
 
===Pants===
; Russian
: {| class="wikitable"
|-
! item
! old name
! new name
|-
| Dinosaur Pants
| ''Динозавровы штаны''
| ''Динозавровые штаны''
|}
 
===Shirts===
; Hungarian
: {| class="wikitable"
|-
! item
! old name
! new name
|-
| Goodnight Shirt
| ''Jóéjt póló''
| ''Jó éjt póló''
|}
 
===Tools===
; Hungarian
: {| class="wikitable"
|-
! item
! old name
! new name
|-
| [[Advanced Iridium Rod]]
| ''Fejlett irídium horgászbot''
| ''Profi irídium horgászbot''
|-
| [[Milk Pail]]
| ''Tejesvödör''
| ''Tejes vödör''
|}
 
===Weapons===
; Hungarian
: {| class="wikitable"
|-
! item
! old name
! new name
|-
| [[Iridium Needle]]
| ''Irídium tű''
| ''Irídiumtű''
|-
| [[Iridium Scythe]]
| ''Irídium kasza''
| ''Irídiumkasza''
|}
 
; Russian
: {| class="wikitable"
|-
! item
! old name
! new name
|-
| [[Abby's Planchette]]
| ''Дощечка Эбби''
| ''Спиритическая планшетка Эбби''
|-
| [[Dark Sword]]
| ''Темный Меч''
| ''Темный клинок''
|-
| [[Dragontooth Club]]
| ''Драконозубья дубинка''
| ''Дубина из драконьего зуба''
|-
| [[Dragontooth Cutlass]]
| ''Драконозубья сабля''
| ''Сабля из драконьего зуба''
|-
| [[Dragontooth Shiv]]
| ''Драконозубья заточка''
| ''Заточка из драконьего зуба''
|-
| [[Dwarf Dagger]]
| ''Кинжал Дварфов''
| ''Дварфийский кинжал''
|-
| [[Dwarf Hammer]]
| ''Молот Дварфов''
| ''Дварфийский молот''
|-
| [[Dwarf Sword]]
| ''Меч Дварфов''
| ''Дварфийский меч''
|-
| [[Insect Head]]
| ''Жучья Голова''
| ''Жучиная голова''
|-
| [[Leah's Whittler]]
| ''Точилка Леи''
| ''Резец Леи''
|-
| [[Seb's Lost Mace]]
| ''Потерянная палица Себа''
| ''Потерянная булава Себа''
|-
| [[Wind Spire]]
| ''Башня Ветров''
| ''Пика ветров''
|}
 
===Monsters===
; Hungarian
: {| class="wikitable"
|-
! monster
! old name
! new name
|-
| [[Truffle Crab]]
| ''Kőrák''
| ''Szarvasgombarák''
|}
 
==XNB impact==
<!--
 
Updated up to 1.7 pre-alpha 2025-06-14.
 
-->
===Overview===
This section provides a summary of the XNB files which changed in Stardew Valley 1.7. This doesn't include new files (since they won't impact existing mods), text changes in non-English files, or the switch from <samp>\</samp> to <samp>/</samp> in asset names (since that's backwards compatible).
 
[[Modding:Using XNB mods|XNB mods]] are disproportionately affected, since...
# they replace the entire file;
# they're loaded through the MonoGame content pipeline which is less tolerant of format changes;
# they don't benefit from the compatibility rewrites [[Modding:Content Patcher|Content Patcher]] provides for its content packs.
 
Content Patcher packs are typically unaffected (and Content Patcher will try to rewrite content packs automatically). However if a content pack replaces an entire asset instead of editing, it's more likely to be affected like an XNB mod.
 
===Changed assets===
Compatibility is broadly grouped into four categories:
* "'''✘ broken'''": mods will remove new content or significant changes, or the mod's intended changes will no longer work. Effects may range from display bugs to crashes, depending how the game uses that specific content.
* "✘ will remove changes": mods will remove minor changes in 1.7 (e.g. typo fixes).
* "✓ mostly unaffected": mods will only be affected if they replace the entire asset, or edit specific entries or fields.
* Blank: no expected impact for the vast majority of mods.
 
{| class="wikitable"
|-
!rowspan="2"| content asset
!rowspan="2"| changes in 1.7
!colspan="2"| compatibility for pre-1.7 mods
|-
! XNB mods
! Content Patcher packs
|-
| <samp>Characters/Dialogue/*</samp>
| &#32;
* Removed now-unneeded <samp>%fork</samp> tokens.
* Fixed bugs & typos.
| ✘ will remove fixes.
|
|-
| <samp>Data/Boots</samp>
| [[#Data/Boots|Overhauled format]].
| '''✘ broken'''
| '''✘ broken'''<br /><small>(until Content Patcher adds runtime migrations)</small>
|-
| <samp>Data/Buffs</samp>
| [[#Data/Buffs|Added new data fields]].
| '''✘ broken'''
|
|-
| <samp>Data/CookingRecipes</samp>
| [[#Data/CookingRecipes|Changed several recipe keys]].
| '''✘ broken'''
| ✓ mostly unaffected<br /><small>(until Content Patcher adds runtime migrations)</small>
|-
| <samp>Data/Events/*</samp><br /><samp>Data/Events/Festivals/*</samp>
| &#32;
* Migrated to [[#Multilingual events|multilingual events]] and [[#Forking deprecated|event labels]].
* [[#Changed event keys|Changed some event keys]].
* Replaced most <samp>awardFestivalPrize</samp> commands with <samp>addItem</samp>.
* Significant changes to support above migrations (e.g. replacing dialogue commands with event commands).
| '''✘ broken'''
| ✓ mostly unaffected
|-
| <samp>Data/ExtraDialogues</samp>
| &#32;
* [[#Event changes|Removed hardcoded events]].
* Moved <samp>SummitEvent_*</samp> translations into <samp>Strings/Events</samp> (with a different name & format).
| ✓ mostly unaffected
| ✓ mostly unaffected
|-
| <samp>Data/Furniture</samp>
| &#32;
* [[#Data/Furniture|Overhauled format]].
* Removed <samp>Rotations</samp> field for [[Decorative Joja Door|decorative Joja door]].
| '''✘ broken'''
| '''✘ broken'''<br /><small>(until Content Patcher adds runtime migrations)</small>
|-
| <samp>Data/Hats</samp>
| &#32;
* [[#Data/Hats|Overhauled format]].
* Standardized asset name capitalization (<samp>Data/hats</samp> → <samp>Data/Hats</samp>).
| '''✘ broken'''
| '''✘ broken'''<br /><small>(until Content Patcher adds runtime migrations)</small>
|-
| <samp>Data/LocationContexts</samp>
| Changed weather conditions to fix re-randomization issue.
| ✘ will remove fixes.
| ✓ mostly unaffected.
|-
| <samp>Data/Locations</samp>
| Changed [[Legend]] condition to use new <samp>IS_RAINING</samp> [[Modding:Game state queries|query]] to support mods weathers.
| ✘ will remove fixes.
| ✓ mostly unaffected.
|-
| <samp>Data/LostItemsShop</samp>
| [[#Data/LostItemsShop|Added new field]].
| '''✘ broken'''
| '''✘ broken'''
|
|
|-
|-
| <samp>Data/Monsters</samp>
| <samp>Strings/Furniture</samp>
| [[#Data/Monsters|Overhauled format]].
| Added translations for catalogue descriptions (moved from <samp>Strings/1_6_Strings</samp>).
| '''✘ broken'''
| '''✘ broken'''<br /><small>(until Content Patcher adds runtime migrations)</small>
|-
| <samp>Data/Objects</samp>
| Added [[#Data/Objects|new fields]] and [[#New context tags|new context tags]].
| '''✘ broken'''
| '''✘ broken'''
|
|
|-
|-
| <samp>Data/SpecialOrders</samp>
| <samp>Strings/Locations</samp>
| [[#Data/SpecialOrders|Added new fields]].
| '''✘ broken'''
|
|-
| <samp>Data/Tools</samp>
| &#32;
* [[#Data/Tools|Added new fields]].
* Removed <samp>Lantern</samp> tool.
| '''✘ broken'''
|
|-
| <samp>Data/Weapons</samp>
| [[#Data/Weapons|Added new fields]].
| '''✘ broken'''
|
|-
| <samp>Data/Weddings</samp>
| Fixed Lewis skipping his matrimonial dialogue at the farmer's wedding.
| ✘ will remove fix
| ✓ mostly unaffected
|-
| <samp>Maps/Bus(people)</samp><br /><samp>Maps/busPeople</samp><br /><samp>Maps/Island_Secret</samp>
| Removed (these were unused).
|
|
|-
| <samp>Strings/Events</samp>
| Added the translations for [[#Multilingual events|multilingual events]].
| '''✘ broken'''
|
|-
| <samp>Strings/1_6_Strings</samp>
| &#32;
| &#32;
* [[#Event changes|Removed hardcoded events]].
* [[#Event changes|Moved hardcoded events into <samp>Data/Events/*</samp>]].
* Moved some translations into <samp>Strings/Events</samp> and <samp>Strings/Furniture</samp>.
* Moved some event translations into <samp>Strings/Events</samp>.
| ✓ mostly unaffected
| ✓ mostly unaffected
|-
| <samp>Strings/Furniture</samp>
| Added translations for catalogue descriptions (moved from <samp>Strings/1_6_Strings</samp>).
| '''✘ broken'''
|
|-
| <samp>Strings/Locations</samp>
| [[#Event changes|Removed hardcoded events]].
| ✓ mostly unaffected
| ✓ mostly unaffected
| ✓ mostly unaffected
| ✓ mostly unaffected
|-
|-
| <samp>Strings/Objects</samp>
| <samp>Strings/Objects</samp>
| Moved some translations into <samp>Strings/Furniture</samp>.
| Moved catalogue descriptions into <samp>Strings/Furniture</samp>.
| ✓ mostly unaffected
| ✓ mostly unaffected
| ✓ mostly unaffected
| ✓ mostly unaffected
|-
| <samp>Strings/StringsFromCSFiles</samp><br /><samp>Strings/Tools</samp>
| Removed some unused translations.
|
|
|-
|-
| <samp>Strings/UI</samp>
| <samp>Strings/UI</samp>
| Merged male/female variants of <samp>PondQuery_StatusRequestPending_*</samp> entries.
| [[#Fish pond changes|Merged some fish pond translation keys]].
| '''✘ broken'''
| '''✘ broken'''
| ✓ mostly unaffected
| ✓ mostly unaffected
|}
|}
<!--
===Removed unused assets===
Stardew Valley 1.7 deletes assets which weren't used by the game. Mods usually aren't affected by this.
TODO
-->


[[Category:Modding]]
[[Category:Modding]]
[[zh:模组:迁移至游戏本体1.6.16]]

Revision as of 22:32, 13 September 2025

←Index

This page is for mod authors. Players: see the mod compatibility list instead.

⚠ Stardew Valley 1.7 was announced, but has no planned release date.
There's no estimate for when the update will be released, so don't plan mod updates around the 1.7 release. Things will change before it's released!

This page helps mod authors prepare their mods for the upcoming Stardew Valley 1.7, and documents some of the changes and new functionality.

FAQs

SMAPI mod compatibility over time.

What's changing?

Stardew Valley 1.7 makes significant changes to many data assets to enable new game features and mod extensibility. See the sections below for more details.

Is this the modapocalypse?

Probably not. SMAPI and Content Patcher will automatically rewrite older mods for many of the changes, so they should still work as-is. Some mods may need an update.

How to update your mod

Here's a suggested 'quick start' guide to update a mod for Stardew Valley 1.7.

For C# mods:
  1. Update for Stardew Valley 1.6.16 if you haven't already.
  2. Rebuild the solution.
  3. Fix any build errors and review any build warnings. You can search this page and previous migration guides for relevant info as needed.
  4. Increment your mod version in manifest.json.
    (Some mods may be added to SMAPI's compatibility blacklist due to runtime errors. Incrementing the mod version will fix that if so.)
  5. Test to make sure the mod works.
  6. Skim through this page, and check any section that might be relevant to the mod.
For Content Patcher packs:
  1. Update for Stardew Valley 1.6.16 if you haven't already.
  2. Skim through this page, and check any section that might be relevant to the mod.
For content packs which use another framework:
See the documentation for the framework mod. Often you won't need to update the content pack if the framework mod itself was updated.

Data asset changes

Data/Boots

This has been overhauled into a data model asset, with translations moved into a new Strings/Boots asset. This also includes new fields like ContextTags and CustomFields which weren't available in the old format.

The data asset now consists of a string → model lookup, where...

field effect
basic info
Name The internal item name (not shown in-game).
DisplayName
Description
A tokenizable string for the item's in-game display name and description.
ContextTags (Optional) The custom context tags to add for this item (in addition to the tags added automatically based on the other item data), specified as an array.
equipment effects
AddDefense
AddImmunity
(Optional) A bonus applied to the player's defense or immunity stats when the boots are equipped. Default 0.
appearance
Texture The asset name for the texture containing the boots sprite. Defaults to Maps/springobjects if omitted, but should always be specified for custom boots.
SpriteIndex (Optional) The sprite's index within the Texture, where 0 is the top-left sprite. Default 0.
ColorTexture (Optional) The asset name for the texture containing the boots color sprite. Defaults to Characters/Farmer/shoeColors if omitted.
ColorSpriteIndex (Optional) The color sprite's index within the ColorTexture, where 0 is the top-left sprite. Default 0.
advanced
CustomFields (Optional) The custom fields for this entry.

For example, here's how to add new boots in 1.7:

{
    "Format": "2.8.0",
    "Changes": [
        // add data
        {
            "Action": "EditData",
            "Target": "Data/Boots",
            "Entries": {
                "{{ModId}}_FancyBoots": {
                    "Name": "{{ModId}}_FancyBoots",
                    "DisplayName": "{{i18n: fancy-boots.name}}",
                    "Description": "{{i18n: fancy-boots.description}}",
                    "Texture": "Mods/{{ModId}}/Boots",
                    "SpriteIndex": 0,
                    "ColorSpriteIndex": 1
                }
            }
        },

        // add texture
        {
            "Action": "Load",
            "Target": "Mods/{{ModId}}/Boots",
            "FromFile": "assets/boots.png"
        }
    ]
}

Data/Buffs

Added one new field:

field effect
CustomFields (Optional) The custom fields for this entry.

Data/Events/*

See event changes below.

Data/Furniture

This has been overhauled into a data model asset. The overhaul also adds support for previously-hardcoded features like custom item descriptions (via Description), custom TVs (via the new Television furniture type and TelevisionScreen* fields), and custom fields.

The data asset now consists of a string → model lookup, where...

field effect
basic info
Name The internal item name (not shown in-game).
DisplayName A tokenizable string for the item's in-game display name.
Description (Optional) A tokenizable string for the item's in-game description. Defaults to a generic description based on the other fields like CanPlaceIndoors and CanPlaceOutdoors.
Type (Optional) The furniture type, which affects various furniture functionality and default values (e.g. default bounding box size). Defaults to Other.

See table of valid types.

Price (Optional) The price for this furniture when purchased from a shop. Default 0.
ContextTags (Optional) The custom context tags to add for this item (in addition to the tags added automatically based on the other item data), specified as an array.
behavior
CanPlaceIndoors
CanPlaceOutdoors
(Optional) Whether the player can place this furniture indoors and/or outdoors. Defaults to generic behavior based on the Type field (e.g. TVs can't be placed outdoors by default).
ExcludeFromRandomSale (Optional) Whether to prevent this furniture from being shown in randomly generated shop stock or furniture catalogues. Default false.
appearance
Texture The asset name for the texture containing the furniture sprite. Defaults to TileSheets/furniture if omitted, but should always be specified for custom furniture.
SpriteIndex (Optional) The sprite's index within the Texture, where 0 is the top-left sprite. Default 0.
Rotations (Optional) The number of rotations possible (1, 2, or 4). Default 1.
SpriteSize (Optional) The sprite's size in the Texture, measured in tiles. Defaults to a generic size depending on the Type field.
BoundingBoxSize (Optional) The collision box size when the furniture is placed in-game, measured in tiles. Defaults to a generic size depending on the Type field.

The bounding box is anchored to the bottom-left corner of the SpriteSize. Width will push the right side of the box to the right, height will push the top of the box upwards.

type-specific options
BedType (Optional) When the Type field is set to Bed, the bed type which affects who can sleep in it. Default Single.

Valid values:

bed type effect
Single A single-sized bed with room for one player or NPC.
Double A double-sized bed with room for two players or NPCs.
Child A single bed for a child NPC.
TelevisionScreenOffset (Optional) When the Type field is set to Television, the X and Y pixel offset relative to the TV's bounding box to apply when drawing the screen image onto the TV. Default none.
TelevisionScreenScale (Optional) When the Type field is set to Television, the zoom multiplier to apply to the screen image so it fits onto the TV's screen.
advanced
CustomFields (Optional) The custom fields for this entry.

Data/Hats

This has been overhauled into a data model asset, with translations moved into a new Strings/Hats asset. This also includes new fields like ContextTags and CustomFields which weren't available in the old format.

The data asset now consists of a string → model lookup, where...

field effect
basic info
Name The internal item name (not shown in-game).
DisplayName
Description
A tokenizable string for the item's in-game display name and description.
HairStyle (Optional) What to do about the player's hair when they wear this hat. Default DrawObscuredHair.

The possible values are:

  • DrawFullHair: the hair is drawn like usual (e.g. for hats that don't hide the hair like Abigail's bow).
  • DrawObscuredHair: the hair is partly obscured under the hat (e.g. for most hats like the cowboy hat).
  • HideHair: the hair is fully hidden (e.g. for hats which fully cover the head like the mummy mask).
SkipHairOffset (Optional) Whether to skip offsetting the hat to sit 'on top' of the player's current hairstyle (e.g. for masks). Default false.
Texture The asset name for the texture containing the hat sprite. Defaults to Characters/Farmer/hats if omitted, but should always be specified for custom hats.
SpriteIndex (Optional) The sprite's index within the Texture, where 0 is the top-left sprite. Default 0.
ContextTags (Optional) The custom context tags to add for this item (in addition to the tags added automatically based on the other item data), specified as an array.
CustomFields (Optional) The custom fields for this entry.

For example, here's how to add a new hat in 1.7:

{
    "Format": "2.8.0",
    "Changes": [
        // add data
        {
            "Action": "EditData",
            "Target": "Data/Hats",
            "Entries": {
                "{{ModId}}_FancyHat": {
                    "Name": "{{ModId}}_FancyHat",
                    "DisplayName": "{{i18n: fancy-hat.name}}",
                    "Description": "{{i18n: fancy-hat.description}}",
                    "HairStyle": "DrawObscuredHair",
                    "Texture": "Mods/{{ModId}}/Hats",
                    "SpriteIndex": 0
                }
            }
        },

        // add texture
        {
            "Action": "Load",
            "Target": "Mods/{{ModId}}/Hats",
            "FromFile": "assets/hats.png"
        }
    ]
}

Data/Monsters

Monster data has been completely rethought in Stardew Valley 1.7. In particular...

  • For monster data in general:
    • Data/Monsters has been been overhauled into a data model asset, with translations moved into a new Strings/Monsters asset. This includes significant new features which weren't supported with the old format.
    • A new 'monster variant' concept lets multiple specific monsters share common data (e.g. Green Slime and Tiger Slime are variants of the new base Slime monster). This is particularly used for common drops.
    • A new 'monster tag' system lets monster define custom tags like slime_is_prismatic, which can be used to filter monster drops.
  • For monster drops:
    • A rethought monster drop system supports the full range of vanilla features like conditions, item queries, qualified item IDs for non-object drops, and monster-specific concepts like repeating drop chance and mutually-exclusive drops.
    • All drops are now qualified item IDs. The former 'resource IDs' (formatted as negative numbers like -4) are no longer supported; items are converted into their equivalent resource debris automatically where needed.
    • Nearly all monster drops are now defined in Data/Monsters (with just a few hardcoded drops common to all monsters left).

The data asset now consists of a string → model lookup, where...

  • The key is the unique string ID.
  • The value is a model with the fields listed below.
field effect
basic info
DisplayName A tokenizable string for the monster's display name.
IsGlider (Optional) Whether the monster is flying (e.g. so they glide over obstacles). Default false.
IsMineMonster (Optional) Whether this monster spawns in the mines, and should be buffed after the player reaches the bottom. This sometimes applies to monsters that can appear elsewhere too (e.g. wilderness golems on the farm receive mine buffs too). Default false.
ExperiencePoints (Optional) The combat experience points received for defeating the monster. Default 1.
stats
Health (Optional) The initial hit points. Default 20.
Attack (Optional) The attack power (i.e. how much damage its hits inflict on players). Default 5.
Defense (Optional) The defense which reduces damage received by this monster. Default 0.
DodgeChance (Optional) The percentage chance that the monster dodges an attack, as a value between 0 (never) and 1 (always). Default 0.
Speed (Optional) The default movement speed. Default 1.
Jitteriness (Optional) How often the monster will move in random non-player directions to try to get around objects, as a value between 0 (never) and 1 (always). Default 0.1.
DetectionDistance (Optional) The distance at which the monster detects a player and begins moving towards them, or -1 for unlimited. Default 4.
drops
Drops (Optional) The items which can drop when the monster is defeated. Default none.

All matching entries are dropped. If the player has a burglar's ring equipped, each entry will make two attempts to drop (but fields like RepeatingChance and SkipIfDropped are independent between the two attempts).

This consists of a list of models with these fields:

field effect
common fields See item spawn fields for the generic item fields supported for monster drops.

Notes:

  • If a drop has an item query which returns multiple item stacks, one of them will be selected at random.
  • The Condition field can optionally contain the %RANDOM_KEY token, which is set to a unique identifier for this monster during the current tick.
ForTags (Optional) The monster tags for which this drop applies. This can be a context tag-like query string like !variant_frost_bat, !variant_lava_bat (not frost bat or lava bat). Default none, meaning it applies to all monsters with this data.
Chance (Optional) A probability that this item will be found, as a value between 0 (never) and 1 (always). Default 1.
RepeatingChance (Optional) A compounding probability of an extra drop, as a value between 0 (never) and .95 (nearly always). Default 0.

This applies after an item has been dropped based on the other fields. This chance is repeatedly checked to produce an extra drop until it fails. Each repeat drop will ignore the Chance and Condition fields, but reapply all other item spawn fields (e.g. re-selecting RandomItemId if applicable).

RepeatingChanceKey (Optional) When checking the RepeatingChance field, use this to seed a predictable RNG. This can be used to synchronize separate drops. Default none.

This can optionally contain the %RANDOM_KEY token, which is set to a unique identifier for this monster during the current tick.

ExplodeStack (Optional) Whether to split multi-item stacks into single-item stacks. Default false.

For example, let's say a monster would drop a stack of 15 wood. With this option enabled, it would instead drop 15 stacks of one wood each.

SkipIfDropped (Optional) Skip the current entry if one of these drop IDs have already been dropped. Default none.

This is specified as an array. For example:

"SkipIfDropped": [ "ExampleDropId", "AnotherDropId" ]
variants
DefaultVariant (Optional) When the game creates a monster of this type without specifying a variant, use the given variant instead of creating it from only the base data. Default false.
Variants (Optional) The possible variations of this monster. Default none.

Each variant is simply a set of fields which override the base data when set. For example, this creates a variant which only differs from the base monster by name and health points:

"Variants": [
    {
        "DisplayName": "{{i18n: variant-name}}",
        "Health": 50
    }

This consists of a list of models with these fields:

field effect
monster fields All monster fields (except DefaultVariant and Variants) can be set on the variant. All fields are optional, and default to the value set in the monster's base data.
InheritDrops (Optional) Whether to inherit drops defined in the monster's base Drops field. Default true.

Specifically:

  • If true, the variant will combine the base Drops and variant Drops into one list.
  • If false, only drops in the variant Drops field are applied.
advanced
CustomFields (Optional) The custom fields for this entry.

For example, this Content Patcher code adds a new 'Pufferchick' monster which drops pufferfish when defeated. The monster's spritesheet is automatically loaded from Monsters/<ID>.

Note: this only adds the monster data. Currently this does nothing unless you have another mod which spawns instances of the monster in-game.

{
    "Format": "2.8.0",
    "Changes": [
        // add data
        {
            "Action": "EditData",
            "Target": "Data/Monsters",
            "Entries": {
                "{{ModId}}_Pufferchick": {
                    "DisplayName": "{{i18n: pufferchick.name}}",
                    "ExperiencePoints": 3,

                    "Health": 30,
                    "Attack": 2,
                    "Defense": 5,
                    "DodgeChance": 0.3,
                    "Speed": 2,
                    "DetectionDistance": 2,

                    "Drops": [
                        {
                            "Id": "Pufferfish",
                            "ItemId": "(O)128",
                            "Chance": 0.5,
                            "RepeatingChance": 0.1
                        }
                    ]
                }
            }
        },

        // add texture
        {
            "Action": "Load",
            "Target": "Monsters/{{ModId}}_Pufferchick",
            "FromFile": "assets/pufferchick.png"
        }
    ]
}

Data/Objects

Added one new field:

field effect
Buffs This field already existed, but has a field change:
field effect
CustomAttributes This field already existed, but has one new field:
field effect
CustomFields (Optional) The custom fields for this entry.

Changes for all mod authors

Switch blocks

'Switch blocks' are a new ${…}$ syntax which can be used in nearly all game text (not just dialogue). This extends the former 'gender-switch blocks' added in 1.6.0.

These are applied before most other commands or parsing, so you can safely use them in cases where characters like ^ have a different meaning (e.g. mail text).

The supported switch blocks are:

type syntax description
gender ${male^female}
${male^female^non-binary}
Switch between text for male, female, and non-binary players. The non-binary value is only used if a mod overrides the player's gender, since the in-game UI only allows male or female.

You can also use ¦ instead of ^, in which case any ^ characters are left as-is.

For example:

"Mon": "Hey ${lad^lass^kiddo}$!"
randomize ${variant A ||| …}$ Defines an arbitrary number of variants from which to choose each day. After randomization, any leading or trailing whitespace is trimmed. This randomization is deterministic per day (e.g. reloading the save won't change which one is shown).

For example, let's say you did this:

"Rainy_Night": "I ${love ||| like ||| adore ||| somewhat enjoy ||| enjoy}$ rain.$h"

That would create five variants which each have an equal probability of being selected.

Switch blocks can be arbitrary combined and nested. For example:

"Rainy_Night": "${Hello there ||| Hey ${lad^lass^kiddo}$ }$!"

Context tag changes

Added new context tags:

context tag item types effect
is_galaxy_weapon weapons Marks the tool as a galaxy weapon like the galaxy hammer or galaxy sword. This is set for vanilla scythes through Data/Weapons. This affects logic which checks for galaxy weapons (e.g. galaxy soul enchantments).

Dialogue changes

  • Added a new special token in dialogue strings:
    token description
    ||| This is a shortcut for the randomize switch block.

    Delimits an arbitrary number of dialogue variants from which to choose each day. After randomization, any leading or trailing whitespace is trimmed. This randomization is deterministic per day (e.g. reloading the save won't change which one is shown).

    For example, let's say you did this:

    "Rainy_Night": "
        I love rain.$h|||
        I like rain.$h|||
        I adore rain.$h|||
        I hate rain.$s#$b#Just kidding. I love it!$h|||
        I enjoy rain.$h
    "
    

    That would create five variants of the dialogue which each have an equal probability of being selected.

  • Improved some special tokens:
    token changes
    || Whitespace around the token is now ignored, so you can split text into multiple lines:
    "Wed8": "
        Isn't it expensive, coming to the desert so often like you do?#$e#You must really like to see me, huh? Hmmm... $h||
        *sigh*... I do miss the beautiful flowers of Stardew Valley...$s
    "
    
  • Some dialogues were merged or renamed using the new features. The previous dialogue keys are now ignored by the game.
    asset former key changes
    Characters/Dialogue/<NPC name> Resort_<number>
    Resort_Bar_<number>
    Resort_Chair_<number>
    Resort_Dance_<number>
    Resort_Shore_<number>
    Resort_Towel_<number>
    Resort_Umbrella_<number>
    Resort_Wander_<number>
    Merged into their base key (e.g. Resort_<random> into Resort) using the new ||| random-variant token.
    Characters/Dialogue/MarriageDialogue
    Characters/Dialogue/MarriageDialogue<NPC name>
    Characters/Dialogue/MarriageDialogue<NPC name>Roommates
    funLeave_<NPC name>
    funReturn_<NPC name>
    jobLeave_<NPC name>
    jobReturn_<NPC name>

    patio_<NPC name>
    spouseRoom_<NPC name>

    spring_<NPC name>
    summer_<NPC name>
    fall_<NPC name>
    winter_<NPC name>
    Moved into MarriageDialogue<NPC name> and removed the NPC suffix (like spouseRoom_<NPC name> → spouseRoom).
    Indoor_Day_0
    Indoor_Day_1
    Indoor_Day_2
    Indoor_Day_3
    Indoor_Day_4
    Merged into Indoor_Day.
    Indoor_Night_0
    Indoor_Night_1
    Indoor_Night_2
    Indoor_Night_3
    Indoor_Night_4
    Indoor_Night_<NPC name>
    Merged into Indoor_Night.
    NoBed_0
    NoBed_1
    NoBed_2
    NoBed_3
    Merged into NoBed.
    Outdoor_0
    Outdoor_1
    Outdoor_2
    Outdoor_3
    Outdoor_4
    Outdoor_<NPC name>
    Merged into Outdoor.
    Rainy_Day_0
    Rainy_Day_1
    Rainy_Day_2
    Rainy_Day_3
    Rainy_Day_4
    Merged into Rainy_Day.
    Rainy_Night_0
    Rainy_Night_1
    Rainy_Night_2
    Rainy_Night_3
    Rainy_Night_4
    Rainy_Night_5
    Rainy_Night_<NPC name>
    Merged into Rainy_Night.

Enchantment data

Enchantments have been partly de-hardcoded into a new Data/Enchantments data asset. Mods can now easily add new enchantments, including enchantments applied through the forge using a prismatic shard or a custom item ID.

However, this logic is still hardcoded:

  • Forging innate enchantments. The innate enchantments are in data, but the logic to choose which to apply is still hardcoded.
  • Forging diamonds into a weapon to fill all its weapon stat slots.
  • Forging three galaxy souls into galaxy weapons to transform them into infinity weapons. (The 'Galaxy Soul' enchantment is in data, but the transformation is hardcoded.)
  • Several enchantments' effects when applied (though weapon buff effects are in data).

This consists of a string → model lookup, where...

  • The key is the unique string ID for the enchantment.
  • The value is a model with the fields listed below.
field effect
DisplayName A tokenizable string for the enchantment's display name, shown in tooltips. This can contain {0} for the enchantment level, if applicable.
ForgeWith (Optional) If set, this enchantment is applied to tools by forging an item with this qualified ID into it. Default none, in which case it won't be applicable through the forge.
AppliesTo (Optional) The tools or weapons to which this enchantment can be applied. Defaults to all tools/weapons.

This is specified as an array of context tag queries. The enchantment can be applied if at least one query matches.

"AppliesTo": [
    "melee_weapon, !is_scythe", // any non-scythe melee weapon
    "hoe, upgrade_level_4"      // any hoe upgraded to iridium or higher
]
IsForge (Optional) Whether this is a weapon stat enchantment applied through the forge. Default false.
IsSecondary (Optional) Whether this is an innate enchantment applied through the forge using a dragon tooth. Default false.
IsVisible (Optional) Whether the enchantment should be shown in the tool/weapon's tooltip. Default true.
MaximumLevel (Optional) The number of times this enchantment can be applied to the same tool to upgrade the enchantment level (e.g. for weapon stat enchantments). A value of 1 means there's only one enchantment level, so it can't be upgraded by applying the enchantment again. Default 1.
EquipmentEffects (Optional) The buffs applied to the weapon when this enchantment is applied.

This consists of a list of models with the fields below. You can specify any number of entries; the first one which matches the tool will be applied.

field effect
Id A unique string ID for this entry.
MinLevel (Optional) The minimum enchantment level for which these stats apply. Default 0 (i.e. any level).
other fields See the Effects field in Data/Buffs, which is equivalent to this model.
advanced
CustomFields (Optional) The custom fields for this entry.
ClassName (Optional, specialized) The name of the C# class to construct within the StardewValley.Enchantments namespace. The class must be a subclass of StardewValley.Enchantments.Enchantment, and have a constructor with no arguments. For example, given a value of BottomlessEnchantment, the game will create StardewValley.Enchantments.BottomlessEnchantment instances.

This should usually be omitted, in which case the game will create a generic Enchantment instance which uses the data in Data/Enchantments for its ID.

Event changes

Multilingual events

All vanilla events are now multilingual, with a single copy of each event script which uses translation keys. Translations from the old per-language event files were moved into a per-language Strings/Events file.

For example:

files in 1.6.16 files in 1.7
Data/Events/Beach
Data/Events/Beach.de-DE
Data/Events/Beach.es-ES
Data/Events/Beach.fr-FR
Data/Events/Beach.hu-HU
Data/Events/Beach.it-IT
Data/Events/Beach.ja-JP
Data/Events/Beach.ko-KR
Data/Events/Beach.pt-BR
Data/Events/Beach.ru-RU
Data/Events/Beach.tr-TR
Data/Events/Beach.zh-CN
Data/Events/Beach

Content Patcher content packs should generally be unaffected, since their edits were applied to the active version of the file automatically (which will just become the base file in all languages).

In rare cases, a mod which directly targets a specific localized asset name like Data/Events/Beach.fr-FR may no longer work or break vanilla events (depending on how it edits them). That should be a very rare case, since the APIs for both Content Patcher and SMAPI were designed to discourage doing that.

Forking deprecated

All vanilla events which used forking now use goto labels instead.

Forking still works like before for backwards compatibility, but mod events should prefer goto labels since...

  • they work more consistently and intuitively with other features like skip labels;
  • it's the approach that the game will be applying and developing in future versions;
  • deprecated commands will be reported as an error if you use the EventValidator;
  • and there's no guarantee forking will always work in future versions.

The fork-related event commands are deprecated.

Precondition slash now required for numeric event IDs

In Stardew Valley 1.6.0–16, the behavior of an event key with no / depended on whether the ID was numeric. A numeric event ID like 10040609 was treated as an event with no precondition, while a string event ID like PlayerKilled was treated as a manual script. In 1.7+, the behavior is now consistent: any event ID without a slash (like 10040609) is treated as a manual script, and any with a slash (like 10040609/) is treated as an event.

In other words:

event key format behavior in 1.6.16 → behavior in 1.7
<id> event if numeric, else manual script → manual script
<id>/[preconditions] event → event

New event commands

command description
choose <question> [<answer> <go to label>]+ Show a dialogue box to choose from a list of responses, then optionally skip to a label based on the selected answer.

Arguments:

argument usage
<question> The translation key or literal text to show above the choices. This can be empty ("") to omit the question line.
<answer> The translation key or literal text for an answer to show.
<go to label> If the player chooses this answer, jump to this label in the event (see the goto command for more info). This can be "" or _ to continue to the next command instead.

For example, here's a simple choice which doesn't affect anything:

choose "Do you like apples?" "I love them." _ "I hate them." _/

Or you can change the course of the event based on the choice:

speak Abigail "Do you... like me?$l"/
choose "" "Yes!" happy "No." heartbroken/

label heartbroken/
speak Abigail "Oh. I understand.$s"/
faceDirection Abigail left/
pause 3000/
end/

label happy/
speak Abigail "We should explore the mines together next time!$h"/
...
conditionSpeak <npc> [<dialogue> [condition]]+ Make an NPC say a dialogue based on arbitrary conditions. The first dialogue with a matching dialogue is spoken; if none match, the command is skipped.

Arguments:

argument usage
<npc> The internal name of the NPC who should speak (which can be marked optional).
<dialogue> The translation key or literal text for the dialogue to speak. If omitted or empty, the command is skipped when the condition is matched.
[condition] One of:
  • a game state query;
  • or ANSWERED <response ID>+ as a shortcut for the PLAYER_HAS_DIALOGUE_ANSWER Current query;
  • or omitted/blank to always match this dialogue if no previous one matched.

For example, here Maru says a different line if the player suggested she tell the truth:

conditionSpeak Maru "I accidentally dropped one of the samples... I'm so sorry.$s" "ANSWERED 38" "@ came in and slammed the door so loud I dropped this sample.$u"
goto [<target> [condition]]+ Skip forward or backward to a specific position in the event script. Each <target> can be:
target description
end Jump to the last end event command in the script.
any other value Jump to the first label command with this name.

You can list any number of label/condition pairs, and it will go to the first label with a matching condition. If a condition is omitted, it defaults to always true. If none of the conditions match, it continues to the next command normally.

For example, this event script uses goto to repeat a question until a specific answer is selected:

.../
label question/
choose Abigail "Hey! Did you have your eye on someone?" "Abigail" correct "Penny" wrong "Alex" wrong/

label wrong/
speak Abigail "Oh?$u"/
pause 500/
goto question/

label correct/
speak Abigail \"I thought so!$l\"/
pause 500/
end

You can make goto conditional using game state queries. For example, this will go to the divorced label if you divorced Abigail, and continue to the next command if not:

goto divorced "PLAYER_NPC_RELATIONSHIP Current Abigail Divorced"/
label <label> Set a named position in the event script, which you can go to using the goto command.

Note: you can't use end as a label name, since that automatically matches the end event command.

Improved existing commands

command description
splitSpeak You should now specify each dialogue as a separate argument (though the old syntax will still work):
// in 1.6.16
splitSpeak Sam "You think so?~Yeah... kids should play and have fun while they still have the chance."

// in 1.7
splitSpeak Sam "You think so?" "Yeah... kids should play and have fun while they still have the chance."

This also now works with the new choose command too.

Deprecated commands

These event commands are deprecated. They still work just like before (except the ones at the bottom of the table), but if you use the EventValidator it'll report them as an error.

event command migration
fork
resetVariable
switchEvent
Use the choose or goto commands instead. If you used dialogue containing the %fork token, it should be removed and replaced with equivalent event commands.
question forkX Use the choose command instead, and replace the event fork with a label.

For example, this script:

// main event
question fork1 "#I believe in you!#Wow, you're really arrogant."/
fork arrogant/
speak Alex "Thanks, @. I'll remember that."/
...

// 'arrogant' event
emote Alex 12/
speak Alex "Hmmph... I think someone's a little jealous.$a"/

Becomes this script:

choose "" "I believe in you!" believe "Wow, you're really arrogant." arrogant/

label believe/
speak Alex "Thanks, @. I'll remember that."/
...

label arrogant/
emote Alex 12/
speak Alex "Hmmph... I think someone's a little jealous.$a"/
...

Forks often duplicated the end of the script. In that case, you can have both variants just goto the common ending instead.

question null Use choose with _ labels instead. (Setting a label argument to _ means it'll just continue to the next command instead.)

For example, this command:

question null "But what am I going to say to Vincent?#It's best to be honest with kids.#You did the right thing. Kids should have hope."/

Would become this command:

choose "But what am I going to say to Vincent?" "It's best to be honest with kids." _ "You did the right thing. Kids should have hope." _/
quickQuestion Use the choose command instead. The <question> and <answerX> have matching choose arguments, while the <answerX script> arguments become labels.

For example, this command:

quickQuestion #I'd like to help#Nah, I'll pass...(break)emote Willy 32\speak Willy "Aye... I thought you would.$h#$b#I'll leave this door unlocked for ya... you can come drop off the materials whenever you like."(break)emote Willy 28\speak Willy "Alright, suit yourself...$s#$b#If you have a change of heart, you can always come back and help out. I'll leave this door unlocked, anyhow."/

Becomes this script:

choose "" "I'd like to help" accept "Nah, I'll pass..." refuse/

label accept/
emote Willy 32/
speak Willy "Aye... I thought you would.$h#$b#I'll leave this door unlocked for ya... you can come drop off the materials whenever you like."/
goto resume/

label refuse/
emote Willy 28/
speak Willy "Alright, suit yourself...$s#$b#If you have a change of heart, you can always come back and help out. I'll leave this door unlocked, anyhow."/

label resume/
cutscene bandfork
elliottBookTalk
question haleyDarkRoom
question shaneCliffs
question shaneLoan
These commands are deleted and will no longer work. They're unlikely to be used by mod events, but see their relevant events for the new equivalents if needed.

Changed event keys

Events were generally unified and de-hardcoded in 1.7. In particular...

  • Several events were previously defined in the game's C# code, where they couldn't be changed by content packs. Most of these were moved into Data/Events/* with translations in Strings/Events:
    event new asset name new event ID
    forest raccoon finished event Data/Events/Forest RaccoonFinish
    forest trash bear cleanup Data/Events/Forest 777111
    island Gourmand crop inspection Data/Events/islandFarmCave GourmandInspection
    summit perfection cutscene Data/Events/Summit SummitPerfection
    summit cheat event Data/Events/Summit SummitCheat
  • Others were moved from non-event data into Data/Events/*:
    event old location new asset new event ID
    Birdie quest intro & completed Strings/Locations:IslandSecret_Event_BirdieIntro
    Strings/Locations:IslandSecret_Event_BirdieFinished
    Strings/Locations:alreadyGotNuts
    Data/Events/IslandWest -888999 (intro)
    -666777 (completed)
    field office intro & completed Strings/Locations:IslandFieldOffice_Intro_Event
    Strings/Locations:FieldOfficeFinale
    Data/Events/IslandFieldOffice FieldOfficeIntro
    FieldOfficeDone
    Leo intro Strings/Locations:IslandHut_Event_ParrotBoyIntro Data/Events/IslandHut LeoIntro
    Meowmere event Strings/1_6_Strings:ForestPylonEvent Data/Events/WizardHouseBasement ForestPylon
    Mr. Qi Skull Cavern level 100 Data/ExtraDialogue:SkullCavern_100_event
    Data/ExtraDialogue:SkullCavern_100_event_honorable
    Data/Events/SkullCave SkullCavern100
    Professor Snail exits cave Strings/Locations:IslandNorth_Event_SafariManAppear Data/Events/IslandNorth ProfSnailIntro
  • Other event keys were changed or merged as part of the other event changes:
    asset entry key change in 1.7
    Data/Events/AbandonedJojaMart missingBundleComplete Event key changed to 192393 to match the event ID.
    Data/Events/Farm 992559/t 600 1130/n clothFound/o Emily/w sunny
    992559/t 600 1130/n clothFound/O Emily/w sunny
    Merged into a single 992559/Time 600 1130/LocalMail clothFound/Weather sunny event.
    Data/Events/QiNutRoom 10040609 Event key changed to 10040609/ per the precondition change.
    Data/Events/SamHouse 94/e 93/k 95/t 1800 1950/i 136/y 1
    94/e 93/k 95/t 1800 1950/i 136/y 2
    Merged into a single 95/SawEvent 93/!SawEvent 94/Time 1800 1950/HasItem 136 event.
    Data/Events/Town 611173/Hn pamHouseUpgrade/o Penny Merged into the existing 611173/Hn pamHouseUpgrade event.

For events that didn't previously have an event ID, their new IDs will be added to the player's seen-events list automatically if needed when the save is loaded.

Other event changes

  • Moved all vanilla events' on-skip behavior into their event scripts (except the pet adoption logic).

Fish pond changes

  • Added new fish pond translation keys:
    asset key usage
    Strings/UI PondQuery_<key>_<item ID>
    PondQuery_<key>_<attitude>
    All PondQuery_* translation keys can now be suffixed with either the qualified item ID of the fish, or the fish's general attitude based on their fish_talk_* context tag.

    For example, the 'fish are OK' message for an anchovy pond will be loaded from the first key which exists in this order: PondQuery_StatusOk_(O)129, PondQuery_StatusOk_Rude, or PondQuery_StatusOk.

  • Merged some fish pond translation keys:
    asset former key changes
    Strings/UI PondQuery_Status<status><number (0–6)>
    PondQuery_StatusRequestComplete_<fish disposition><number (0–2)>
    PondQuery_StatusRequestPending_<fish disposition><number (0–2)>
    Removed the number key suffixes using switch blocks (e.g. merged PondQuery_StatusOk<number> into PondQuery_StatusOk).
  • Coral and Sea urchin now have the fish_talk_coral context tag instead of a hardcoded _Coral translation key suffixes.

Item query changes

Added one new item query:

query effect
SEASONAL_RACCOON_SEED Get a seasonal raccoon seed for the current season.

This sets the stack size to the recommended amount based on the player's luck. When used in item spawn fields, you can set MinStack and MaxStack to override the stack size.

Item spawn field changes

  • Added new item spawn fields:
    field effect
    Enchantments (Optional) For tools and weapons, the enchantment IDs to apply (matching their IDs in Data/Enchantments). This field applies the normal enchantment rules. Default none.

    This is specified as an array, and you can repeat secondary enchantments to boost their level. For example, this applies Vampiric and Attack (level 2):

    "Enchantments": [ "Vampiric", "Attack", "Attack" ]
    

    DialogueKeyValidator

    The new DialogueKeyValidator class analyses dialogue entries to detect dialogue keys which don't match one of the predefined patterns.

    This is mainly meant to implement unit tests. For example, to validate all dialogue keys in a data asset:

    string assetName = "Characters/Dialogues/Abigail";
    var dialogues = Game1.content.Load<Dictionary<string, string>>(assetName);
    
    var validator = new DialogueKeyValidator();
    foreach ((string key, string dialogue) in dialogues)
    {
        if (!validator.IsKnownFormat(assetName, key))
            Assert.Fail($"Validation failed for dialogue '{key}': key doesn't match one of the expected patterns.");
    }
    

    You can optionally extend the valid patterns by setting validator fields like MarriageDialogueKeyPatterns.

    EventValidator changes

    The EventValidator class added in 1.6.16 lets you detect issues in event scripts (mainly meant for unit tests).

    Stardew Valley 1.7 adds one token recognized by the EventArguments attribute:

    token meaning
    goToLabel An event label (see the goto and label event commands). This is equivalent to word, but is used by EventValidator to validate label references.

    Content manager changes

    1.7 adds a SourceCodeContentManager implementation of IContentManager. This is meant for internal unit tests, and isn't relevant for mod authors except as an example.

    Monster changes

    • The monster data has been overhauled.
    • The new monster.Tags field contains a set of metadata tags about the monster which can be checked in Data/Monsters. It's safe to add new tags to the list for existing monster types.
    • The former monster.objectsToDrop field (a list of string object IDs) has been replaced by monster.drops (an item inventory).
    • Removed monster.getExtraDropItems(). Drops should be added in Data/Monsters instead.

    Other breaking API changes

    (This section is meant as a quick reference if you have build errors; there's no need to read through it otherwise.)

    Removed or renamed types

    These classes renamed in 1.7:

    type migration
    BaseEnchantment Renamed to Enchantment.
    AxeEnchantment
    BaseWeaponEnchantment
    FishingRodEnchantment
    HoeEnchantment
    MilkPailEnchantment
    PanEnchantment
    PickaxeEnchantment
    ShearsEnchantment
    WateringCanEnchantment
    Obsolete. Enchantments now target tools via data instead.

    Other API changes

    These class members changed in 1.7:

    type member migration
    BaseEnchantment
    (and its subclasses)
    hideEnchantmentName Replaced by EnchantmentManager.HideEnchantmentName.
    hideSecondaryEnchantName Replaced by EnchantmentManager.HideSecondaryEnchantName.
    GetEnchantmentFromItem(…) Replaced by EnchantmentManager.GetEnchantmentFromItem.
    GetAvailableEnchantments() Removed.
    • To check whether any enchantments can be applied to a tool through the forge, use EnchantmentManager.CanForgeEnchant.
    • There's no directly equivalent method in 1.7, but you can mimic the former logic if needed.
      static List<Enchantment> GetAvailableEnchantments()
      {
          var dataAsset = DataLoader.Enchantments(Game1.content);
      
          List<Enchantment> enchantments = [];
          foreach ((string id, EnchantmentData data) in dataAsset)
          {
              if (data.ForgeWith == Object.prismaticShardQID)
                  enchantments.Add(EnchantmentManager.CreateEnchantment(dataAsset, id));
          }
      
          return enchantments;
      }
      
    GetAvailableEnchantmentsForItem(…) Removed.
    • To check whether any enchantments can be applied to a tool through the forge, use EnchantmentManager.CanForgeEnchant.
    • There's no directly equivalent method in 1.7, but you can mimic the former logic if needed.
      static List<Enchantment> GetAvailableEnchantmentsForItem(Item? tool, Item? item)
      {
          var dataAsset = DataLoader.Enchantments(Game1.content);
          var contextTags = tool?.GetContextTags();
      
          List<Enchantment> enchantments = [];
          foreach ((string id, EnchantmentData data) in dataAsset)
          {
              if (data.ForgeWith == Object.prismaticShardQID && (contextTags is null || EnchantmentManager.MatchesTags(contextTags, data.AppliesTo)))
                  enchantments.Add(EnchantmentManager.CreateEnchantment(dataAsset, id));
          }
      
          return enchantments;
      }
      
    GetName() Removed. This inconsistently returned an ID, a display name, or "Unknown Enchantment" depending on the enchantment type. Use the new Id property or the pre-existing GetDisplayName() method instead.
    GetLevel() Removed. Use Level instead.
    GetType() This was sometimes to identify enchantments (like enchantment.GetType() == expectedEnchantment.GetType()). That's no longer reliable, since 1.7 introduces data-based enchantments which may not have their own C# type. You should use the new enchantment.Id property instead.
    ResetEnchantments() Removed. This is no longer needed since it no longer has a cached list of enchantment instances.
    Furniture armchair
    bed
    bench
    bookcase
    chair
    couch
    decor
    dresser
    fireplace
    lamp
    longTable
    other
    painting
    rug
    sconce
    table
    torch
    window
    Removed. Replaced by the FurnitureType enum (e.g. Furniture.rug is now FurnitureType.Rug).
    placementRestrictions Removed. Replaced by CanPlaceIndoors and CanPlaceOutdoors.
    Monster getExtraDropItems() Removed. Drops should be added to Data/Monsters instead.

    Harmony patches which can't be moved into data can target Monster.RollForDrops instead.

    objectsToDrop Removed. Replaced by drops; see monster changes and Data/Monsters.
    Tool GetEnchantmentLevel<T>()
    GetEnchantmentOfType<T>()
    hasEnchantmentOfType<T>()
    Removed. Replaced by GetEnchantmentLevel(id), GetEnchantment(id), and HasEnchantment(id) respectively. All vanilla enchantments have a constant for the ID like EnchantmentIds.GalaxySoul.

    Name translation changes for wiki maintainers

    Some in-game item and monster names were retranslated in some languages for clarity or correctness.

    This list is mostly provided to help wiki maintainers update pages, so it doesn't include names which only changed capitalization, changed ' (straight apostrophe) to ’ (curly) in French, or aren't visible to vanilla players (like mine rocks).

    None yet.

    XNB impact

    Overview

    This section provides a summary of the XNB files which changed in Stardew Valley 1.7. This doesn't include new files (since they won't impact existing mods) or text changes in non-English files.

    XNB mods are disproportionately affected, since...

    1. they replace the entire file;
    2. they're loaded through the MonoGame content pipeline which is less tolerant of format changes;
    3. they don't benefit from the compatibility rewrites Content Patcher provides for its content packs.

    Content Patcher packs are typically unaffected (and Content Patcher will try to rewrite content packs automatically). However if a content pack replaces an entire asset instead of editing, it's more likely to be affected like an XNB mod.

    Changed assets

    Compatibility is broadly grouped into four categories:

    • "✘ broken": mods will remove new content or significant changes, or the mod's intended changes will no longer work. Effects may range from display bugs to crashes, depending how the game uses that specific content.
    • "✘ will remove changes": mods will remove minor changes in 1.7 (e.g. typo fixes).
    • "✓ mostly unaffected": mods will only be affected if they edit specific entries or fields.
    • Blank: no expected impact for the vast majority of mods.
    content asset changes in 1.7 compatibility for pre-1.7 mods
    XNB mods Content Patcher packs
    Characters/Dialogue/Abigail ✘ broken ✓ mostly unaffected
    Characters/Dialogue/Alex
    Characters/Dialogue/Clint
    ✘ broken ✓ mostly unaffected
    Characters/Dialogue/Demetrius Removed event dialogues moved into Strings/Events.
    Characters/Dialogue/Dwarf Fixed invalid dialogue keys. ✘ broken ✓ mostly unaffected
    Characters/Dialogue/Elliott ✘ broken ✓ mostly unaffected
    Characters/Dialogue/Emily Removed event dialogues moved into Strings/Events.
    Characters/Dialogue/Evelyn
    • Removed event dialogues moved into Strings/Events.
    • Fixed invalid dialogue key.
    ✘ broken ✓ mostly unaffected
    Characters/Dialogue/Haley ✘ broken ✓ mostly unaffected
    Characters/Dialogue/Harvey
    • Removed event dialogues moved into Strings/Events.
    • Fixed invalid dialogue key.
    ✘ broken ✓ mostly unaffected
    Characters/Dialogue/Jodi Fixed invalid dialogue key. ✘ broken ✓ mostly unaffected
    Characters/Dialogue/Kent Removed event dialogues moved into Strings/Events.
    Characters/Dialogue/Leah ✘ broken ✓ mostly unaffected
    Characters/Dialogue/Lewis
    • Removed event dialogues moved into Strings/Events.
    • Fixed invalid dialogue key.
    ✘ broken ✓ mostly unaffected
    Characters/Dialogue/MarriageDialogue
    Characters/Dialogue/MarriageDialogue*
    ✘ broken ✓ mostly unaffected
    Characters/Dialogue/Maru ✘ broken ✓ mostly unaffected
    Characters/Dialogue/Pam Removed event dialogues moved into Strings/Events.
    Characters/Dialogue/Penny ✘ broken ✓ mostly unaffected
    Characters/Dialogue/Pierre
    Characters/Dialogue/Robin
    Removed event dialogues moved into Strings/Events.
    Characters/Dialogue/Sam ✘ broken ✓ mostly unaffected
    Characters/Dialogue/Sebastian ✘ broken ✓ mostly unaffected
    Characters/Dialogue/Shane Removed event dialogues moved into Strings/Events.
    Data/Boots Overhauled format. ✘ broken ✘ broken
    (until Content Patcher adds runtime migrations)
    Data/Buffs Added new data field to data model. ✘ broken
    Data/Buildings
    Data/Characters
    Added new item spawn field. ✘ broken
    Data/Events/*
    Data/Events/Festivals/*
    Major changes including multilingual events, event labels, event key changes, replacing dialogue commands with event commands, etc. ✘ broken ✓ mostly unaffected
    Data/ExtraDialogues ✓ mostly unaffected ✓ mostly unaffected
    Data/FishPondData
    Data/FruitTrees
    Added new item spawn field. ✘ broken
    Data/Furniture Overhauled format. ✘ broken ✘ broken
    (until Content Patcher adds runtime migrations)
    Data/GarbageCans
    Data/GiantCrops
    Added new item spawn field. ✘ broken
    Data/Hats Overhauled format. ✘ broken ✘ broken
    (until Content Patcher adds runtime migrations)
    Data/Locations Added new item spawn field. ✘ broken
    Data/Machines Added new item spawn field. ✘ broken
    Data/Monsters Overhauled format. ✘ broken ✘ broken
    (until Content Patcher adds runtime migrations)
    Data/Movies Added new item spawn field. ✘ broken
    Data/Objects ✘ broken ✓ mostly unaffected
    Data/Pets
    Data/Shops
    Added new item spawn field. ✘ broken
    Data/Weapons ✘ broken ✓ mostly unaffected
    Data/WildTrees Added new item spawn field. ✘ broken
    Strings/1_6_Strings ✓ mostly unaffected ✓ mostly unaffected
    Strings/EnchantmentNames
    • Added translations moved from Strings/1_6_Strings.
    • Renamed two keys (Auto-Hook → <samp.AutoHook, Bug Killer → BugKiller).
    ✘ broken ✓ mostly unaffected
    Strings/Events ✘ broken
    Strings/Furniture Added translations for catalogue descriptions (moved from Strings/1_6_Strings). ✘ broken
    Strings/Locations ✓ mostly unaffected ✓ mostly unaffected
    Strings/Objects Moved catalogue descriptions into Strings/Furniture. ✓ mostly unaffected ✓ mostly unaffected
    Strings/UI Merged some fish pond translation keys. ✘ broken ✓ mostly unaffected