Changes

group long list of sections into "What's new" and "Breaking changes"
Line 24: Line 24:  
# Test the mod in-game and make any other changes needed.
 
# Test the mod in-game and make any other changes needed.
   −
==Buff overhaul==
+
==What's new==
 +
===Buff overhaul===
 
1.6 rewrites buffs to work more consistently and be more extensible:
 
1.6 rewrites buffs to work more consistently and be more extensible:
   Line 57: Line 58:  
You can also implement your own custom effects in code by checking if the buff is active, like <code>Game1.player.hasBuff("Example.ModId/ZoomZoom")</code>.
 
You can also implement your own custom effects in code by checking if the buff is active, like <code>Game1.player.hasBuff("Example.ModId/ZoomZoom")</code>.
   −
==Custom items==
+
===Custom items===
===Overview===
+
====Overview====
 
Stardew Valley 1.6 makes three major changes to how items work in the game:
 
Stardew Valley 1.6 makes three major changes to how items work in the game:
   Line 86: Line 87:  
|}
 
|}
   −
===Item references===
+
====Item references====
 
Item references throughout the game code now use the <samp>ItemID</samp> instead of the <samp>ParentSheetIndex</samp>. Since the <samp>ItemID</samp> is identical to the index for existing vanilla items, most data assets are unaffected by this change. For example, here's from <samp>Data/NPCDispositions</samp> with one custom item:
 
Item references throughout the game code now use the <samp>ItemID</samp> instead of the <samp>ParentSheetIndex</samp>. Since the <samp>ItemID</samp> is identical to the index for existing vanilla items, most data assets are unaffected by this change. For example, here's from <samp>Data/NPCDispositions</samp> with one custom item:
 
<syntaxhighlight lang="json">
 
<syntaxhighlight lang="json">
Line 113: Line 114:  
|}
 
|}
   −
===Define a custom item===
+
====Define a custom item====
====Overview====
+
:; Overview
You can define custom items for most vanilla item types using only [[Modding:Content Patcher|Content Patcher]] or [[Modding:Modder Guide/APIs/Content|SMAPI's content API]]. The data asset for each item type has two new fields:
+
:: You can define custom items for most vanilla item types using only [[Modding:Content Patcher|Content Patcher]] or [[Modding:Modder Guide/APIs/Content|SMAPI's content API]]. The data asset for each item type has two new fields:
 
+
:: {| class="wikitable"
{| class="wikitable"
   
|-
 
|-
 
! field
 
! field
Line 129: Line 129:  
|}
 
|}
   −
Supported item types:
+
:: Supported item types:
   −
{| class="wikitable"
+
:: {| class="wikitable"
 
|-
 
|-
 
! item type
 
! item type
Line 201: Line 201:  
|}
 
|}
   −
For example, this content pack adds a new Pufferchick item with a custom image, custom gift tastes, and a custom crop that produces it. Note that item references in other data assets like <samp>Data/Crops</samp> and <samp>Data/NPCGiftTastes</samp> use the item ID.
+
:: For example, this content pack adds a new Pufferchick item with a custom image, custom gift tastes, and a custom crop that produces it. Note that item references in other data assets like <samp>Data/Crops</samp> and <samp>Data/NPCGiftTastes</samp> use the item ID.
   −
{{#tag:syntaxhighlight|<nowiki>
+
:: {{#tag:syntaxhighlight|<nowiki>
 
{
 
{
 
     "Format": "</nowiki>{{Content Patcher version}}<nowiki>",
 
     "Format": "</nowiki>{{Content Patcher version}}<nowiki>",
Line 248: Line 248:  
}</nowiki>|lang=javascript}}
 
}</nowiki>|lang=javascript}}
   −
Most item data assets work just like <samp>Data/ObjectInformation</samp>. For fruit trees, see [[#Custom fruit trees|custom fruit trees]].
+
:: Most item data assets work just like <samp>Data/ObjectInformation</samp>. For fruit trees, see [[#Custom fruit trees|custom fruit trees]].
   −
====Tools====
+
:; Tools
Tools are defined in the new <samp>Data/ToolData</samp> asset using this field format:
+
:: Tools are defined in the new <samp>Data/ToolData</samp> asset using this field format:
   −
{| class="wikitable"
+
:: {| class="wikitable"
 
|-
 
|-
 
! index
 
! index
Line 276: Line 276:  
|}
 
|}
   −
===Error items===
+
====Error items====
 
In-game items with no underlying data (e.g. because you removed the mod which adds them) would previously cause issues like invisible items, errors, and crashes. This was partly mitigated by the bundled ErrorHandler mod.
 
In-game items with no underlying data (e.g. because you removed the mod which adds them) would previously cause issues like invisible items, errors, and crashes. This was partly mitigated by the bundled ErrorHandler mod.
    
Stardew Valley 1.6 adds comprehensive handling for such items. They'll be shown with a <samp>🛇</samp> sprite in inventory UIs and in-game, with the name Error Item and a description which indicates the missing item ID for troubleshooting.
 
Stardew Valley 1.6 adds comprehensive handling for such items. They'll be shown with a <samp>🛇</samp> sprite in inventory UIs and in-game, with the name Error Item and a description which indicates the missing item ID for troubleshooting.
   −
===For C# mods===
+
====For C# mods====
<dl>
+
<dl style="margin-left: 2em;">
    
<dt>Compare items</dt>
 
<dt>Compare items</dt>
Line 352: Line 352:  
</dl>
 
</dl>
   −
==Custom buildings==
+
===Custom buildings===
 
You can now add custom buildings by editing the <samp>Data/BuildingsData</samp> asset. This consists of a string &rarr; model lookup, where the key is a unique building ID, and the value is a model with these fields:
 
You can now add custom buildings by editing the <samp>Data/BuildingsData</samp> asset. This consists of a string &rarr; model lookup, where the key is a unique building ID, and the value is a model with these fields:
   Line 622: Line 622:  
|}
 
|}
   −
==Custom map areas==
+
===Custom map areas===
 
[[File:Modding map area.png|thumb|The valley map, with one map area highlighted.]]
 
[[File:Modding map area.png|thumb|The valley map, with one map area highlighted.]]
    
You can now add/edit areas on the game menu's map UI, or even replace the entire map for a different world region, by editing the new <samp>Data/InGameMap</samp> asset. For example, this is used to show a different farm on the map depending on the current [[Farm Maps|farm type]].
 
You can now add/edit areas on the game menu's map UI, or even replace the entire map for a different world region, by editing the new <samp>Data/InGameMap</samp> asset. For example, this is used to show a different farm on the map depending on the current [[Farm Maps|farm type]].
   −
===Concepts===
+
====Concepts====
 
The game divides the map into three concepts:
 
The game divides the map into three concepts:
   Line 634: Line 634:  
* A '''group name''' is a unique key shared between all the map areas that are rendered on the same map. For example, if there was a separate map for [[Ginger Island]], all the map areas in the valley group would be hidden.
 
* A '''group name''' is a unique key shared between all the map areas that are rendered on the same map. For example, if there was a separate map for [[Ginger Island]], all the map areas in the valley group would be hidden.
   −
===Format===
+
====Format====
 
The <samp>Data/InGameMap</samp> data asset consists of a string &rarr; model lookup, where the key is a unique identifier for the map area, and the value is a model with these fields:
 
The <samp>Data/InGameMap</samp> data asset consists of a string &rarr; model lookup, where the key is a unique identifier for the map area, and the value is a model with these fields:
   Line 703: Line 703:  
|}
 
|}
   −
===Example===
+
====Example====
 
This [[Modding:Content Patcher|Content Patcher]] content pack adds a full world map for [[Ginger Island]], complete with tooltips and player marker positioning. If the player unlocked the [[Ginger Island#Beach Resort|beach resort]], it applies the beach resort texture on top of the base map.
 
This [[Modding:Content Patcher|Content Patcher]] content pack adds a full world map for [[Ginger Island]], complete with tooltips and player marker positioning. If the player unlocked the [[Ginger Island#Beach Resort|beach resort]], it applies the beach resort texture on top of the base map.
   Line 754: Line 754:  
}</nowiki>|lang=javascript}}
 
}</nowiki>|lang=javascript}}
   −
==Custom shops==
+
===Custom shops===
===Format===
+
====Format====
 
You can now create and edit shops via the new <samp>Data/Shops</samp> asset. This consists of a list of models with these fields:
 
You can now create and edit shops via the new <samp>Data/Shops</samp> asset. This consists of a list of models with these fields:
   Line 825: Line 825:  
|}
 
|}
   −
===Open a custom shop===
+
====Open a custom shop====
 
You can place an [[#Map/tile property changes|<samp>Action OpenShop</samp> tile property]] on the map, which will open the given shop ID when the player clicks it.
 
You can place an [[#Map/tile property changes|<samp>Action OpenShop</samp> tile property]] on the map, which will open the given shop ID when the player clicks it.
    
In C# code, you can get the inventory for a custom shop using <code>Utility.GetShopStock("shop id here")</code>, or open a shop menu using <code>Game1.activeClickableMenu = new ShopMenu(new(), who: "shop id here")</code>.
 
In C# code, you can get the inventory for a custom shop using <code>Utility.GetShopStock("shop id here")</code>, or open a shop menu using <code>Game1.activeClickableMenu = new ShopMenu(new(), who: "shop id here")</code>.
   −
==Custom fruit trees==
+
===Custom fruit trees===
 
You can now add custom [[Fruit Trees|fruit trees]] by editing the modified <samp>Data/fruitTrees</samp> asset. This consists of a <samp>string</samp>&rarr;<samp>string</samp> lookup, where the key is the sapling item ID and the value is a slash (<samp>/</samp>)-delimited list of these fields:
 
You can now add custom [[Fruit Trees|fruit trees]] by editing the modified <samp>Data/fruitTrees</samp> asset. This consists of a <samp>string</samp>&rarr;<samp>string</samp> lookup, where the key is the sapling item ID and the value is a slash (<samp>/</samp>)-delimited list of these fields:
   Line 901: Line 901:  
The fruit trees can then be added to the game by giving the player a sapling item in the usual ways (e.g. from [[#Custom shops|a shop]]).
 
The fruit trees can then be added to the game by giving the player a sapling item in the usual ways (e.g. from [[#Custom shops|a shop]]).
   −
==Custom wild trees==
+
===Custom wild trees===
 
You can now create/edit [[Trees|wild trees]] by editing the <samp>Data/WildTrees</samp> asset. This consists of a string => model lookup, where the asset key is the wild tree ID: one of <samp>1</samp> (oak), <samp>2</samp> (maple), <samp>3</samp> (pine), <samp>6</samp> (palm), <samp>7</samp> (mushroom), <samp>8</samp> (mahogany), or a custom string ID defined by a mod. The asset value is a model with these fields:
 
You can now create/edit [[Trees|wild trees]] by editing the <samp>Data/WildTrees</samp> asset. This consists of a string => model lookup, where the asset key is the wild tree ID: one of <samp>1</samp> (oak), <samp>2</samp> (maple), <samp>3</samp> (pine), <samp>6</samp> (palm), <samp>7</samp> (mushroom), <samp>8</samp> (mahogany), or a custom string ID defined by a mod. The asset value is a model with these fields:
   Line 1,019: Line 1,019:  
* or giving the player a seed item in the usual ways (e.g. from [[#Custom shops|a shop]], [[Modding:Mail data|mail letter]], etc).
 
* or giving the player a seed item in the usual ways (e.g. from [[#Custom shops|a shop]], [[Modding:Mail data|mail letter]], etc).
   −
==Standardized data fields==
+
===Standardized data fields===
 
1.6 standardizes the number of fields in data assets, and fixes inconsistencies between English and localized files. '''This is a major breaking change for content packs, and for C# mods which edit data assets.'''
 
1.6 standardizes the number of fields in data assets, and fixes inconsistencies between English and localized files. '''This is a major breaking change for content packs, and for C# mods which edit data assets.'''
   Line 1,048: Line 1,048:  
The exception is fields which only exist for modding, like the texture + index overrides for [[#Custom items|custom items]]. These can typically be omitted.
 
The exception is fields which only exist for modding, like the texture + index overrides for [[#Custom items|custom items]]. These can typically be omitted.
   −
==String event IDs==
+
===String event IDs===
 
[[Modding:Event data|Events]] now use string IDs, so mods can use a unique key like <samp>Example.ModId_EventName</samp> (instead of hoping no other mod uses the same number). Prefixing the mod ID to event keys is recommended to simplify troubleshooting and avoid conflicts. For best compatibility, custom IDs should only contain alphanumeric/underscore/dot characters.
 
[[Modding:Event data|Events]] now use string IDs, so mods can use a unique key like <samp>Example.ModId_EventName</samp> (instead of hoping no other mod uses the same number). Prefixing the mod ID to event keys is recommended to simplify troubleshooting and avoid conflicts. For best compatibility, custom IDs should only contain alphanumeric/underscore/dot characters.
   Line 1,057: Line 1,057:  
</syntaxhighlight>
 
</syntaxhighlight>
   −
==New C# utility methods==
+
===New C# utility methods===
 
1.6 adds a new set of utilities (<samp>GetDataAtIndex</samp>, <samp>GetIntAtIndex</samp>, and <samp>GetFloatAtIndex</samp>) to replace common logic for parsing the game's data assets while accounting for optional field indexes.
 
1.6 adds a new set of utilities (<samp>GetDataAtIndex</samp>, <samp>GetIntAtIndex</samp>, and <samp>GetFloatAtIndex</samp>) to replace common logic for parsing the game's data assets while accounting for optional field indexes.
   Line 1,083: Line 1,083:  
</syntaxhighlight>
 
</syntaxhighlight>
   −
==Game state queries==
+
===Game state queries===
 
A ''game state query'' is a vanilla way to specify conditions for some content like [[#Custom shops|shop data]], inspired by [[Modding:Content Patcher|Content Patcher]]'s conditions. A query consists of a comma-delimited list of conditions in the form {{t|type}} {{o|arguments}}, where {{t|type}} is case-sensitive. The type can be prefixed with <code>!</code> to negate it. The query is true if it's null/blank, or if every listed condition exists and is true. For example, <code>!SEASON Spring, WEATHER Here sunny</code> is true on sunny non-[[spring]] days.
 
A ''game state query'' is a vanilla way to specify conditions for some content like [[#Custom shops|shop data]], inspired by [[Modding:Content Patcher|Content Patcher]]'s conditions. A query consists of a comma-delimited list of conditions in the form {{t|type}} {{o|arguments}}, where {{t|type}} is case-sensitive. The type can be prefixed with <code>!</code> to negate it. The query is true if it's null/blank, or if every listed condition exists and is true. For example, <code>!SEASON Spring, WEATHER Here sunny</code> is true on sunny non-[[spring]] days.
   −
===Conditions===
+
====Conditions====
 
; World
 
; World
 
:{| class="wikitable"
 
:{| class="wikitable"
Line 1,255: Line 1,255:  
|}
 
|}
   −
===Player ID===
+
====Player ID====
 
Some conditions have a {{t|player}} argument. This can be one of...
 
Some conditions have a {{t|player}} argument. This can be one of...
 
{| class="wikitable"
 
{| class="wikitable"
Line 1,281: Line 1,281:  
|}
 
|}
   −
===Using queries elsewhere===
+
====Using queries elsewhere====
 
C# code can use the <samp>GameStateQuery</samp> class to work with queries, like <code>GameStateQuery.CheckConditions(query)</code>.
 
C# code can use the <samp>GameStateQuery</samp> class to work with queries, like <code>GameStateQuery.CheckConditions(query)</code>.
    
You can also use game state queries in [[Modding:Event data|event preconditions]] using the new <samp>G</samp> condition flag, like <code>some_event_id/G !SEASON Spring, WEATHER Here sunny</code>.
 
You can also use game state queries in [[Modding:Event data|event preconditions]] using the new <samp>G</samp> condition flag, like <code>some_event_id/G !SEASON Spring, WEATHER Here sunny</code>.
   −
===Extensibility===
+
====Extensibility====
 
C# mods can define custom conditions by calling <code>GameStateQuery.RegisterQueryType("condition name", (string[] fields) => ...)</code>. To avoid conflicts, prefixing custom condition names with your mod ID (like <samp>Example.ModId_SomeCondition</samp>) is strongly recommended.
 
C# mods can define custom conditions by calling <code>GameStateQuery.RegisterQueryType("condition name", (string[] fields) => ...)</code>. To avoid conflicts, prefixing custom condition names with your mod ID (like <samp>Example.ModId_SomeCondition</samp>) is strongly recommended.
   −
==Tokenizable string format==
+
===Tokenizable string format===
 
Stardew Valley 1.6 adds support for literal strings that contain tokens (currently only supported for [[#Custom map areas|custom map areas]] and [[#Custom shops|custom shops]]).
 
Stardew Valley 1.6 adds support for literal strings that contain tokens (currently only supported for [[#Custom map areas|custom map areas]] and [[#Custom shops|custom shops]]).
   −
===Literal text===
+
====Literal text====
 
Previously you often needed to load text from a [[Modding:Modder Guide/Game Fundamentals#String keys|string key]] in data assets. With this new format, you can use the literal text directly in the asset instead (including Content Patcher tokens):
 
Previously you often needed to load text from a [[Modding:Modder Guide/Game Fundamentals#String keys|string key]] in data assets. With this new format, you can use the literal text directly in the asset instead (including Content Patcher tokens):
   Line 1,306: Line 1,306:  
</syntaxhighlight>
 
</syntaxhighlight>
   −
===Tokens===
+
====Tokens====
 
You can inject tokens using square brackets. For example, <code>"[LocalizedText Strings\StringsFromCSFiles:ShopMenu.cs.11488] This is raw text"</code> will show something like "''Welcome to Pierre's! This is raw text''". Here are the supported tokens:
 
You can inject tokens using square brackets. For example, <code>"[LocalizedText Strings\StringsFromCSFiles:ShopMenu.cs.11488] This is raw text"</code> will show something like "''Welcome to Pierre's! This is raw text''". Here are the supported tokens:
   Line 1,334: Line 1,334:  
If you're using [[Modding:Content Patcher|Content Patcher]], you can use its tokens anywhere in the string (including within square brackets); they'll be expanded before the game parses the string. For example, <code><nowiki>"{{Spouse}} would love [ArticleFor [SuggestedItem]] [SuggestedItem]!"</nowiki></code> would output something like "''Alexa would love an Apple!''".
 
If you're using [[Modding:Content Patcher|Content Patcher]], you can use its tokens anywhere in the string (including within square brackets); they'll be expanded before the game parses the string. For example, <code><nowiki>"{{Spouse}} would love [ArticleFor [SuggestedItem]] [SuggestedItem]!"</nowiki></code> would output something like "''Alexa would love an Apple!''".
   −
==[[Modding:Maps|Map/tile property]] changes==
+
===[[Modding:Maps|Map/tile property]] changes===
 
<ul>
 
<ul>
 
<li>Added new <samp>Action</samp> tile properties:
 
<li>Added new <samp>Action</samp> tile properties:
Line 1,362: Line 1,362:  
</ul>
 
</ul>
   −
==Other changes==
+
===Other changes===
 
* Added a display name field in English too for <samp>Data/Boots</samp>, <samp>Data/CookingRecipes</samp>, <samp>Data/CraftingRecipes</samp>, and <samp>Data/Furniture</samp>.
 
* Added a display name field in English too for <samp>Data/Boots</samp>, <samp>Data/CookingRecipes</samp>, <samp>Data/CraftingRecipes</samp>, and <samp>Data/Furniture</samp>.
 
* Added optional <samp>Conditions</samp> [[#Game state queries|game state query]] field to <samp>Data/SpecialOrders</samp>.
 
* Added optional <samp>Conditions</samp> [[#Game state queries|game state query]] field to <samp>Data/SpecialOrders</samp>.
   −
==XNB impact==
+
==Breaking changes==
 +
'''This section only describes how this update may break existing mods. See [[#What's new|What's new]] for more info, including new functionality mods can use.'''
 +
 
 +
===XNB impact===
 
Here's a summary of the XNB files which changed in Stardew Valley 1.6.
 
Here's a summary of the XNB files which changed in Stardew Valley 1.6.
  
translators
8,447

edits