Changes

→‎Tile property changes: migrated by someone else; mark as such
Line 362: Line 362:     
===Custom melee weapons===
 
===Custom melee weapons===
{{/doc status|[[Modding:Items#Weapons]]|done=false}}
+
{{/doc status|[[Modding:Items#Weapons]]|done=true}}
    
[[Modding:Items#Weapons|Melee weapons]] are still stored in <samp>Data/Weapons</samp>, but that asset has been overhauled in Stardew Valley 1.6. The slash-delimited entries are now models to simplify edits and enable new features (like the new <samp>Projectiles</samp> feature).
 
[[Modding:Items#Weapons|Melee weapons]] are still stored in <samp>Data/Weapons</samp>, but that asset has been overhauled in Stardew Valley 1.6. The slash-delimited entries are now models to simplify edits and enable new features (like the new <samp>Projectiles</samp> feature).
   −
This consists of a string → model lookup, where...
+
===Custom movie concessions===
* The key is the unqualified [[#Custom items|item ID]] for the weapon.
+
{{/doc status|[[Modding:Movie theater data]]|done=true}}
* The value is model with the fields listed below.
+
: ''See also: [[#Custom movies|custom movies]].''
   −
====Basic weapon info====
+
You could already [[Modding:Movie theater data#Concession data|add/edit concessions]] sold in the [[Movie Theater|movie theater]], but conflicts were likely since each concession had an incrementing numeric ID which matched its position in the vanilla tilesheet.
{| class="wikitable"
  −
|-
  −
! field
  −
! effect
  −
|-
  −
| <samp>Name</samp>
  −
| The internal weapon name.
  −
|-
  −
| <samp>DisplayName</samp><br /><samp>Description</samp>
  −
| A [[Modding:Tokenizable strings|tokenizable string]] for the translated display name & description.
  −
|-
  −
| <samp>Type</samp>
  −
| The weapon type. One of <samp>0</samp> (stabbing sword), <samp>1</samp> (dagger), <samp>2</samp> (club or hammer), or <samp>3</samp> (slashing sword).
  −
|}
     −
====Appearance====
+
Stardew Valley 1.6 addresses that with two changes:
 +
<ul>
 +
<li>The <samp>Id</samp> field is now a [[Modding:Common data field types#Unique string ID|unique string ID]].</li>
 +
<li>You can now use a different texture with two new required fields:
 
{| class="wikitable"
 
{| class="wikitable"
 
|-
 
|-
Line 393: Line 382:  
|-
 
|-
 
| <samp>Texture</samp>
 
| <samp>Texture</samp>
| The asset name for the spritesheet containing the weapon's sprite.
+
| The asset name for the texture containing the concession's sprite.
 
|-
 
|-
 
| <samp>SpriteIndex</samp>
 
| <samp>SpriteIndex</samp>
| The index within the <samp>Texture</samp> for the weapon sprite, where 0 is the top-left sprite.
+
| The index within the <samp>Texture</samp> for the concession sprite, where 0 is the top-left sprite.
 
|}
 
|}
 +
</li>
 +
</ul>
   −
====Stats====
+
===Custom museum donations & rewards===
{| class="wikitable"
+
{{/doc status|[[Modding:Museum]]|done=true}}
|-
  −
! field
  −
! effect
  −
|-
  −
| <samp>MinDamage</samp><br /><samp>MaxDamage</samp>
  −
| The minimum and maximum based damage caused when hitting a monster with this weapon.
  −
|-
  −
| <samp>Knockback</samp>
  −
| ''(Optional)'' How far the target is pushed when hit, as a multiplier relative to a base weapon like the [[Rusty Sword]] (e.g. <samp>1.5</samp> for 150% of Rusty Sword's weight). Default 1.
  −
|-
  −
| <samp>Speed</samp>
  −
| ''(Optional)'' How fast the player can swing the weapon. Each point of speed is worth 40ms of swing time relative to 0. This stacks with the [[speed|player's weapon speed]]. Default 0.
  −
|-
  −
| <samp>Precision</samp>
  −
| ''(Optional)'' Reduces the chance that a strike will miss. Default 0.
  −
|-
  −
| <samp>Defense</samp>
  −
| ''(Optional)'' Reduces damage received by the player. Default 0.
  −
|-
  −
| <samp>AreaOfEffect</samp>
  −
| ''(Optional)'' Slightly increases the area of effect. Default 0.
  −
|-
  −
| <samp>CritChance</samp>
  −
| ''(Optional)'' The chance of a critical hit, as a decimal value between 0 (never) and 1 (always). Default 0.02.
  −
|-
  −
| <samp>CritMultiplier</samp>
  −
| ''(Optional)'' A multiplier applied to the base damage for a critical hit. This can be a decimal value. Default 3.
  −
|}
     −
====Game logic====
+
You can now add/edit the items which the [[museum]] gives back in rewards through the new <samp>Data/MuseumRewards</samp> data asset.
{| class="wikitable"
  −
|-
  −
! field
  −
! effect
  −
|-
  −
| <samp>CanBeLostOnDeath</samp>
  −
| Whether the player can [[Adventurer's Guild#Item Recovery Service|lose this tool when they die]]. Default true.
  −
|-
  −
| <samp>MineBaseLevel</samp><br /><samp>MineMinLevel</samp>
  −
| ''(Optional)'' The base and minimum mine level, which affect [[#Mine container drops|mine container drops]]. Both default to -1, which disables automatic mine drops.
  −
|}
     −
====Advanced====
+
The ''A Complete Collection'' [[Achievements|achievement]] is automatically adjusted to require any custom donations added too. This is based on the number of donated items though, so removing custom donations later may incorrectly mark the museum complete (since you may have donated enough items to meet the total required).
{| class="wikitable"
  −
|-
  −
! field
  −
! effect
  −
|-
  −
| <samp>Projectiles</samp>
  −
| ''(Optional)'' The projectiles fired when the weapon is used, which continue along their path until they hit a monster and cause damage. A separate projectile is fired for each entry in this list.
     −
This consists of a list of models with these fields (one projectile will fire for each entry in the list):
+
===Custom fruit trees===
{| class="wikitable"
+
{{/doc status|[[Modding:Fruit trees]]|done=true}}
|-
  −
! field
  −
! effect
  −
|-
  −
| <samp>Id</samp>
  −
| The [[Modding:Common data field types#Unique string ID|unique string ID]] for the projectile within the current weapon's data.
  −
|-
  −
| <samp>Damage</samp>
  −
| ''(Optional)'' The amount of damage caused when the projectile hits a monster. Default 10.
  −
|-
  −
| <samp>Explodes</samp>
  −
| ''(Optional)'' Whether the projectile explodes when it collides with something. Default false.
  −
|-
  −
| <samp>Bounces</samp>
  −
| ''(Optional)'' The number of times the projectile can bounce off walls before being destroyed. Default 0.
  −
|-
  −
| <samp>MaxDistance</samp>
  −
| ''(Optional)'' The maximum tile distance the projectile can travel. Default 4.
  −
|-
  −
| <samp>Velocity</samp>
  −
| ''(Optional)'' The speed at which the projectile moves. Default 10.
  −
|-
  −
| <samp>RotationVelocity</samp>
  −
| ''(Optional)'' The rotation velocity. Default 32.
  −
|-
  −
| <samp>TailLength</samp>
  −
| ''(Optional)'' The length of the tail which trails behind the main projectile. Default 1.
  −
|-
  −
| <samp>FireSound</samp><br /><samp>BounceSound</samp><br /><samp>CollisionSound</samp>
  −
| ''(Optional)'' The sound played when the projectile is fired, bounces off a wall, or collides with something. All three default to none.
  −
|-
  −
| <samp>MinAngleOffset</samp><br /><samp>MaxAngleOffset</samp>
  −
| ''(Optional)'' A random offset applied to the direction of the project each time it's fired. Both fields default to 0, in which case it's always shot at the 90° angle matching the player's facing direction.
  −
|-
  −
| <samp>SpriteIndex</samp>
  −
| ''(Optional)'' The sprite index in the <samp>TileSheets/Projectiles</samp> asset to draw for this projectile. Defaults to 11 (a glowing-yellow-ball sprite).
  −
|-
  −
| <samp>Item</samp>
  −
| ''(Optional)'' The item to shoot. If set, this overrides <samp>SpriteIndex</samp>.
     −
This consists of a list of models with these fields:
+
You can now add custom [[Fruit Trees|fruit trees]] by editing the revamped <samp>Data/FruitTrees</samp> asset.
{| class="wikitable"
  −
|-
  −
! field
  −
! effect
  −
|-
  −
| ''common fields''
  −
| See [[Modding:Item queries#Item spawn fields|item spawn fields]] for the generic item fields supported for ammo items.
     −
If set to an [[Modding:Item queries|item query]] which returns multiple items, one of them will be selected at random.
+
For C# mods, the <samp>fruitsOnTree</samp> field (number of fruit on the tree) has been replaced by <samp>fruit</samp> (list of fruit items).
|}
  −
|}
     −
Note that these are magic projectiles fired when the weapon is used, they're not aimed directly like [[slingshot]] projectiles.
+
Custom trees can be added to the game in two ways:
|-
+
* Spawn them on [[Modding:Maps|map tiles]] when the location is created, using the new <samp>SpawnTree: fruit {{t|tree ID}} {{o|growth stage on location created}} {{o|growth stage on day-update regrowth}}</samp> tile property. This must be added on the <samp>Paths</samp> layer, which must also have tile index 34 from the <samp>paths</samp> tilesheet.
| <samp>CustomFields</samp>
+
* Or give the player a seed item in the usual ways (e.g. from [[#Custom shops|a shop]], [[Modding:Mail data|mail letter]], etc).
| The [[#Custom data fields|custom fields]] for this entry.
  −
|}
     −
===Custom movie concessions===
+
===Custom objects===
{{/doc status|[[Modding:Movie theater data]]|done=false}}
+
{{/doc status|[[Modding:Items#Objects]]|done=true}}
: ''See also: [[#Custom movies|custom movies]].''
     −
You could already [[Modding:Movie theater data#Concession data|add/edit concessions]] sold in the [[Movie Theater|movie theater]], but conflicts were likely since each concession had an incrementing numeric ID which matched its position in the vanilla tilesheet.
+
You can now create/edit objects (the main item type) by editing the new <samp>Data/Objects</samp> asset, which replaces the previous slash-delimited <samp>Data/objectInformation</samp>.
   −
Stardew Valley 1.6 addresses that with two changes:
+
Besides the format change, this adds...
<ul>
+
* support for custom textures;
<li>The <samp>Id</samp> field is now a [[Modding:Common data field types#Unique string ID|unique string ID]].</li>
+
* revamped geode drops with support for conditions, probabilities, and item queries;
<li>You can now use a different texture with two new required fields:
+
* expanded food/drink buffs (e.g. set a custom buff ID, add a custom buff icon, etc);
{| class="wikitable"
+
* context tags (moved from the former <samp>Data/ObjectContextTags</samp> asset);
|-
+
* [[#Custom data fields|custom fields]] to let framework mods support additional features.
! field
  −
! effect
  −
|-
  −
| <samp>Texture</samp>
  −
| The asset name for the texture containing the concession's sprite.
  −
|-
  −
| <samp>SpriteIndex</samp>
  −
| The index within the <samp>Texture</samp> for the concession sprite, where 0 is the top-left sprite.
  −
|}
  −
</li>
  −
</ul>
     −
For example, this content pack adds a new 'Pufferchick Pop' concession with a custom image:
+
===Custom pants===
{{#tag:syntaxhighlight|<nowiki>
+
{{/doc status|[[Modding:Items#Pants]]|done=true}}
{
  −
    "Format": "</nowiki>{{Content Patcher version}}<nowiki>",
  −
    "Changes": [
  −
        {
  −
            "Action": "EditData",
  −
            "Target": "Data/Concessions",
  −
            "Entries": {
  −
                "{{ModId}}_PufferchickPop": {
  −
                    "Id": "{{ModId}}_PufferchickPop",  // must specify ID again when creating a new entry
  −
                    "Name": "{{ModId}}_PufferchickPop", // best practice to match the ID, since it's sometimes used as an alternate ID
  −
                    "DisplayName": "Pufferchick Pop",
  −
                    "Description": "A cute cake pop shaped like a pufferchick.",
  −
                    "Price": 25,
  −
                    "Texture": "{{InternalAssetKey: assets/pufferchick-pop.png}}" // an image in your content pack
  −
                    "SpriteIndex": 0
  −
                }
  −
            }
  −
        }
  −
    ]
  −
}</nowiki>|lang=javascript}}
     −
===Custom museum donations & rewards===
+
You can now create/edit [[Tailoring#Pants|pants]] by editing the new <samp>Data/Pants</samp> asset, which replaces <samp>Data/clothingInformation</samp>.
{{/doc status|a new doc page|done=false}}
     −
You can now add/edit the items which the [[museum]] gives back in rewards through the new <samp>Data/MuseumRewards</samp> data asset.
+
===Custom shirts===
 +
{{/doc status|[[Modding:Items#Shirts]]|done=true}}
   −
====Format====
+
You can now create/edit [[Tailoring#Shirts|shirts]] by editing the new <samp>Data/Shirts</samp> asset, which replaces <samp>Data/clothingInformation</samp>.
The data asset consists of a string → model lookup, where...
+
 
* The key is a [[Modding:Common data field types#Unique string ID|unique string ID]] for the reward group.
+
===Custom tools===
* The value is a model with the fields listed below.
+
{{/doc status|[[Modding:Items#Tools]]|done=true}}
 +
 
 +
You can now create/edit [[tools]] by editing the new <samp>Data/Tools</samp> asset. Note that drawing the tool correctly in the world (ie, while the player is trying to use it) probably still needs custom code.
 +
 
 +
===Custom wild trees===
 +
{{/doc status|[[Modding:Wild trees]]|done=true}}
 +
 
 +
You can now create/edit [[Trees|wild trees]] by editing the <samp>Data/WildTrees</samp> asset.
 +
 
 +
Custom trees can be added to the game in two ways:
 +
* Spawn them on [[Modding:Maps|map tiles]] when the location is created, using the new <samp>SpawnTree: wild {{t|tree ID}} {{o|growth stage on location created}} {{o|growth stage on day-update regrowth}}</samp> tile property. This must be added on the <samp>Paths</samp> layer, which must also have tile index 34 from the <samp>paths</samp> tilesheet.
 +
* Or give the player a seed item in the usual ways (e.g. from [[#Custom shops|a shop]], [[Modding:Mail data|mail letter]], etc).
 +
 
 +
===Default recipes===
 +
{{/doc status|[[Modding:Recipe data]]|done=true}}
 +
 
 +
You can now have [[Modding:Recipe data|crafting and cooking recipes]] that are learned automatically by setting the condition field to <samp>default</samp>. Any missing default recipes will be learned on day start.
 +
 
 +
For example, here's the chest entry from <samp>Data/CraftingRecipes</samp>:
 +
<syntaxhighlight lang="js">
 +
"Chest": "388 50/Home/130/true/default/"
 +
</syntaxhighlight>
 +
 
 +
===Global inventories===
 +
C# mods can now set a <samp>chest.GlobalInventoryId</samp> field to make it share a global inventory with every other chest having the same ID. This replaces the equivalent hardcoded logic for [[Junimo Chest|Junimo chests]], which now just default to a <samp>"JunimoChests"</samp> global inventory ID. For example, this can be used to have multiple Junimo chest networks or make other containers share inventory.
 +
 
 +
C# mods can also use this to store items for other mod purposes, by using <samp>Game1.player.team.globalInventories</samp> or <samp>Game1.player.team.GetOrCreateGlobalInventory(id)</samp> directly.
 +
 
 +
===Hats on aquarium fish===
 +
{{/doc status|[[Modding:Fish data]]|done=true}}
 +
 
 +
Custom [[Modding:Fish data|fish in aquariums]] can now wear [[hats]], just like vanilla [[Sea Urchin|sea urchins]]. This can be enabled by specifying a new field in <samp>Data/AquariumFish</samp>:
    
{| class="wikitable"
 
{| class="wikitable"
 
|-
 
|-
 +
! index
 
! field
 
! field
! effect
+
! purpose
 
|-
 
|-
| <samp>TargetContextTags</samp>
+
| 7
| The items that must be donated to complete this reward group. The player must fulfill every entry in the list to unlock the reward. This consists of a list of models with these fields:
+
| hat position
{| class="wikitable"
+
| The pixel position of the hat on the sprite, specified as an object with <samp>X</samp> and <samp>Y</samp> values.
|-
  −
! field
  −
! effect
  −
|-
  −
| <samp>Tag</samp>
  −
| The [[Modding:Context tags|context tag]] for the items to require.
  −
|-
  −
| <samp>Count</samp>
  −
| The minimum number of items matching the context tags that must be donated.
   
|}
 
|}
   −
For example, an entry with the tag <samp>forage_item</samp> and count 2 will require donating any two forage items.
+
===Context tag changes===
 +
{{/doc status|[[Modding:Items#Context tags]]|done=true}}
   −
Special case: an entry with the exact values <code>Tag: "", Count: -1</code> passes if the museum is complete (i.e. the player has donated the max number of items).
+
====New context tags====
 +
1.6 adds several new [[Modding:Items#Context tags|item context tags]]:
 +
 
 +
{| class="wikitable"
 +
|-
 +
! context tag
 +
! effect
 +
|-
 +
| <samp>campfire_item</samp>
 +
| Marks the item as a [[campfire]]. If the item also has the <samp>torch_item</samp> context tag, when it's placed in the world and turned on...
 +
* campfire flames are drawn over it;
 +
* if the item is [[Modding:Items#Big craftables|big craftable]], light is emitted from its center instead of the top.
 
|-
 
|-
| <samp>FlagOnCompletion</samp>
+
| <samp>fish_pond_ignore</samp>
| ''(Optional if <samp>RewardItemIsSpecial</samp> is true)'' Whether to add the <samp>ID</samp> value to the player's received mail. This is used to track whether the player has collected the reward, and should almost always be true. If this is omitted and <samp>RewardItemIsSpecial</samp> is false, the player will be able collect the reward infinite times. Default false.
+
| Prevents players from adding this fish to [[Fish Pond|fish ponds]], even if it would otherwise match an entry in <samp>Data/FishPondData</samp>.
 
+
|-
After the reward is collected, you can check this value using the <samp><nowiki>HasFlag</nowiki></samp> condition in [[Modding:Content Patcher|Content Patcher]].
+
| <samp>geode_crusher_ignored</samp>
 +
| Prevents breaking this item open in a [[Geode Crusher|geode crusher]], even if the item has geode fields in [[#Custom objects|<samp>Data/Objects</samp>]].
 +
|-
 +
| <samp>item_type_{{t|type}}</samp>
 +
| For an [[Modding:Items#Objects|object-type item]], the type value from the 'type and category' field. (Non-object items always have the exact tag <samp>item_type_</samp> with nothing after the last underscore.) This is automatic and shouldn't be set manually. The tag is checked in a few places (''e.g.'' the [[museum]] to check if an item is an artifact or mineral), but most of the game won't be affected.
 
|-
 
|-
| <samp>RewardActions</samp>
+
| <samp>museum_donatable</samp><br /><samp>not_museum_donatable</samp>
| Run one or more [[Modding:Trigger actions|trigger action strings]]. For example, this adds {{price|500}} to the current player:
+
| Set whether the item can be donated to the [[museum]], overriding the vanilla logic.
<syntaxhighlight lang="js">
  −
"RewardActions": [
  −
    "AddMoney 500"
  −
]
  −
</syntaxhighlight>
   
|-
 
|-
| <samp>RewardItemId</samp>
+
| <samp>not_giftable</samp>
| ''(Optional)'' The [[#Custom items|qualified item ID]] for the item given to the player when they donate all required items for this group. There's no reward item if omitted.
+
| Prevents players from gifting this item to NPCs, who'll ignore the item entirely (e.g. as if you were holding a tool).
 +
 
 +
This only affects gift-giving, it doesn't affect non-gift logic like quest goals or special order objectives. If the NPC also has a <samp>reject_*</samp> dialogue for the item, the dialogue takes priority.
 
|-
 
|-
| <samp>RewardItemCount</samp>
+
| <samp>not_placeable</samp><br /><samp>placeable</samp>
| ''(Optional)'' The stack size for the <samp>RewardItemId</samp> (if the item supports stacking). Default 1.
+
| Sets whether the item can be placed on the ground.
 
|-
 
|-
| <samp>RewardItemIsSpecial</samp>
+
| <samp>prevent_loss_on_death</samp>
| ''(Optional)'' Whether to mark the <samp>RewardItemId</samp> as a special permanent item, which can't be destroyed/dropped and can only be collected once. Default false.
+
| Indicates the item can't be [[Adventurer's Guild#Item Recovery Service|lost when the player dies]].
 
|-
 
|-
| <samp>RewardItemIsRecipe</samp>
+
| <samp>sign_item</samp>
| ''(Optional)'' Whether to give the player a cooking/crafting recipe which produces the <samp>RewardItemId</samp>, instead of the item itself. Ignored if the item type can't be cooked/crafted (i.e. non-object-type items). Default false.
+
| Marks the item as a [[Crafting#Signs|sign]], which lets player display items on it or place it on a [[Fish Pond|fish pond]] to show the fish count.
 
|-
 
|-
| <samp>CustomFields</samp>
+
| <samp>torch_item</samp>
| The [[#Custom data fields|custom fields]] for this entry.
+
| Marks the item as a [[torch]], which lets the player turn it on/off to emit light.
 +
 
 +
See also <samp>campfire_item</samp>.
 
|}
 
|}
   −
For example, this content pack adds two rewards (one mail and one item):
+
Context tags which affect [[#Custom machines|machine processing]]:
{{#tag:syntaxhighlight|<nowiki>
+
{| class="wikitable"
{
+
|-
    "Format": "</nowiki>{{Content Patcher version}}<nowiki>",
+
! context tag
    "Changes": [
+
! effect
        {
+
|-
            "Action": "EditData",
+
| <samp>crystalarium_banned</samp>
            "Target": "Data/MuseumRewards",
+
| When applied to a gem or mineral item, prevents players from placing it in a [[crystalarium]].
            "Entries": {
+
|-
                // send a letter when a specific item is donated
+
| <samp>keg_juice</samp><br /><samp>keg_wine</samp>
                "{{ModId}}_ShinyArtifact": {
+
| Allows processing the item in a [[keg]] to produce a juice or wine variant.
                    "TargetContextTags": [
+
|-
                        {
+
| <samp>preserves_jelly</samp><br /><samp>preserves_pickle</samp>
                            "Tag": "id_{{ModId}}_ShinyArtifact", // unique context tag identifying the item by ID
+
| Allows processing the item in a [[Preserves Jar|preserves jar]] to produce a jelly or pickled variant.
                            "Count": 1
+
|-
                        },
+
| <samp>seedmaker_banned</samp>
                    ],
+
| When applied to a seed item, prevents players from placing it in a [[Seed Maker|seed maker]].
                    "FlagOnCompletion": true,
+
|-
                    "RewardActions": [ "AddMail Current {{ModId}}_ShinyArtifact" ]
+
| <samp>tapper_item</samp>
                },
+
| Marks the item as a [[tapper]] or [[Heavy Tapper|heavy tapper]].
 +
|-
 +
| <samp>tapper_multiplier_{{t|multiplier}}</samp>
 +
| The multiplier applied to the tapper production speed. For example, <samp>2</samp> will make items take half their base time (''i.e.'' each item will finish in <sup>base time</sup>/<sub>speed multiplier</sub>). Defaults to 1 if omitted.
 +
|}
   −
                // give item when 18 minerals are donated
+
And informational tags which have no effect on the game logic:
                "{{ModId}}_18MineralItems": {
+
{| class="wikitable"
                    "TargetContextTags": [
+
|-
                        {
+
! context tag
                            "Tag": "item_type_minerals",
+
! effect
                            "Count": 18
+
|-
                        },
+
| <samp>fish_legendary</samp><br /><samp>fish_legendary_family</samp>
                    ],
+
| Marks the fish as a [[Fish#Legendary Fish|legendary fish]] or [[Quests#Extended Family|legendary fish family]]. These are purely informational; the legendary fish behavior is determined by data fields like <samp>CatchLimit</samp> or <samp>IsBossFish</samp> in [[#Custom locations|<samp>Data/Locations</samp>]].
                    "RewardItemId": "(BC){{ModId}}_SuperMachine",
  −
                    "RewardItemCount": 1,
  −
                    "FlagOnCompletion": true
  −
                }
  −
            }
  −
        }
  −
    ]
  −
}</nowiki>|lang=javascript}}
  −
 
  −
See also [[Modding:Mail data|mail data]], [[#Custom items|custom items]], and [[#custom machines|custom machines]] to add the custom mail and items.
  −
 
  −
====Achievements====
  −
The ''A Complete Collection'' [[Achievements|achievement]] is automatically adjusted to require any custom donations added too. This is based on the number of donated items though, so removing custom donations later may incorrectly mark the museum complete (since you may have donated enough items to meet the total required).
  −
 
  −
===Custom fruit trees===
  −
{{/doc status|[[Modding:Fruit trees]]|done=true}}
  −
 
  −
You can now add custom [[Fruit Trees|fruit trees]] by editing the revamped <samp>Data/FruitTrees</samp> asset.
  −
 
  −
For C# mods, the <samp>fruitsOnTree</samp> field (number of fruit on the tree) has been replaced by <samp>fruit</samp> (list of fruit items).
  −
 
  −
Custom trees can be added to the game in two ways:
  −
* Spawn them on [[Modding:Maps|map tiles]] when the location is created, using the new <samp>SpawnTree: fruit {{t|tree ID}} {{o|growth stage on location created}} {{o|growth stage on day-update regrowth}}</samp> tile property. This must be added on the <samp>Paths</samp> layer, which must also have tile index 34 from the <samp>paths</samp> tilesheet.
  −
* Or give the player a seed item in the usual ways (e.g. from [[#Custom shops|a shop]], [[Modding:Mail data|mail letter]], etc).
  −
 
  −
===Custom objects===
  −
{{/doc status|[[Modding:Items#Objects]]|done=true}}
  −
 
  −
You can now create/edit objects (the main item type) by editing the new <samp>Data/Objects</samp> asset, which replaces the previous slash-delimited <samp>Data/objectInformation</samp>.
  −
 
  −
Besides the format change, this adds...
  −
* support for custom textures;
  −
* revamped geode drops with support for conditions, probabilities, and item queries;
  −
* expanded food/drink buffs (e.g. set a custom buff ID, add a custom buff icon, etc);
  −
* context tags (moved from the former <samp>Data/ObjectContextTags</samp> asset);
  −
* [[#Custom data fields|custom fields]] to let framework mods support additional features.
  −
 
  −
===Custom pants===
  −
{{/doc status|[[Modding:Items]]|done=false}}
  −
 
  −
You can now create/edit [[Tailoring#Pants|pants]] by editing the new <samp>Data/Pants</samp> asset, which replaces <samp>Data/clothingInformation</samp>. This consists of a string → model lookup, where...
  −
* The key is the unqualified [[#Custom items|item ID]].
  −
* The value is a model with the fields listed below.
  −
 
  −
====Basic pants data====
  −
{| class="wikitable"
   
|-
 
|-
! field
+
| <samp>geode</samp>
! purpose
+
| ''(Added automatically)'' Marks the item as a [[Minerals#Geodes|geode]] item, which can be broken open at [[Blacksmith|Clint's blacksmith shop]] or using a [[Geode Crusher|geode crusher]]. This is added automatically if the geode fields are present in [[#Custom objects|<samp>Data/Objects</samp>]].
 
|-
 
|-
| <samp>Name</samp>
+
| <samp>id_{{t|item id}}</samp>
| ''(Optional)'' The internal name for the item. Default <samp>Pants</samp>.
+
| ''(Added automatically)'' The [[#Custom items|qualified item ID]], like <samp>id_(o)128</samp>. This can be used to match or exclude an item by ID using context tags. Any spaces in the ID are replaced with underscores, and single quotes are removed.
 
|-
 
|-
| <samp>DisplayName</samp><br /><samp>Description</samp>
+
| <samp>is_machine</samp>
| ''(Optional)'' A [[Modding:Tokenizable strings|tokenizable string]] for the item's in-game display name and description. Defaults to the generic pants text (''Pants'' and ''A wearable pair of pants'').
+
| ''(Added automatically)'' Indicates the item has [[#Custom machines|machine logic]]. This is added automatically based on <samp>Data/Machines</samp>.
 
|-
 
|-
| <samp>Price</samp>
+
| <samp>machine_input</samp>
| ''(Optional)'' The default price when the item is sold to the player in a shop. Default 50.
+
| ''(Added automatically)'' Whether the item is a machine which accepts items from the player. This is added automatically based on the machine's fields in <samp>Data/Machines</samp>:
|}
+
* if <samp>HasInput</samp> is true;
 +
* ''or'' if any output rules have an <samp>ItemPlacedInMachine</samp> trigger.
 +
|-
 +
| <samp>machine_output</samp>
 +
| ''(Added automatically)'' Whether the item is a machine which produces items for the player to collect. This is added automatically based on the machine's fields in <samp>Data/Machines</samp>:
 +
* if <samp>HasOutput</samp> is true;
 +
* ''or'' if it has any output rules.
 +
|}
 +
 
 +
====ItemContextTagManager class====
 +
For C# mods, 1.6 adds a new <samp>ItemContextTagManager</samp> class which simplifies working with [[Modding:Items#Context tags|item context tags]] and reduces repeated code.
   −
====Appearance====
+
This provides a few utility methods:
 
{| class="wikitable"
 
{| class="wikitable"
 
|-
 
|-
! field
+
! method
! purpose
+
! effect
 
|-
 
|-
| <samp>Texture</samp>
+
| <code>GetBaseContextTags(id)</code>
| The asset name for the texture containing the pants' sprite. Defaults to <samp>Characters/Farmer/pants</samp>.
+
| Get the base context tags for an item based on its raw data in <samp>Data/Objects</samp> or <samp>Data/BigCraftables</samp>. This doesn't include dynamic tags added that are based on instance info (like quality), which you can get using <code>item.GetContextTags()</code>.
 
|-
 
|-
| <samp>SpriteIndex</samp>
+
| <code>DoesTagQueryMatch(query, tags)</code>
| The pants' sprite index within the <samp>Texture</samp>, where 0 is the top-left set.
+
| Get whether a context tag query matches the given tags. For example, <code>ItemContextTagManager.DoesTagQueryMatch("bone_item, !fossil_item", item.GetContextTags())</code> returns true if the item is a bone item but not a fossil (like the [[Bone Flute]]).
 
|-
 
|-
| <samp>DefaultColor</samp>
+
| <code>DoAllTagsMatch(requiredTags, actualTags)</code><br /><code>DoAnyTagsMatch(requiredTags, actualTags)</code>
| ''(Optional)'' The dye color to apply to the sprite when the player hasn't [[dyeing|dyed]] it yet, if any. See [[#Color fields|color format]]. Default <samp>255 235 203</samp> (which matches the color of the cloth item).
+
| Get whether every (<samp>DoAllTagsMatch</samp>) or at least one (<samp>DoAnyTagsMatch</samp) required tag matches the actual item tags. This supports negated required tags like <samp>"!fossil_item"</samp> too.
 
|-
 
|-
| <samp>CanBeDyed</samp>
+
| <code>DoesTagMatch(requiredTag, actualTags)</code>
| ''(Optional)'' Whether the player can [[dyeing|dye]] these pants. Default false.
+
| Get whether a single tag matches the actual item tags. This supports negated required tags like <samp>"!fossil_item"</samp> too.
 
|-
 
|-
| <samp>IsPrismatic</samp>
+
| <code>SanitizeContextTag(tag)</code>
| ''(Optional)'' Whether the pants continuously shift colors. This overrides <samp>DefaultColor</samp> and <samp>CanBeDyed</samp> if set. Default false.
+
| ''(Specialized)'' Replace characters that may appear in item names so they're valid in context tags. For example, <code>SanitizeContextTag("Sam's Boombox")</code> returns <samp>sams_boombox</samp>.
 
|}
 
|}
   −
====Other====
+
====Other context tag changes====
 +
* Context tags are now case-insensitive.
 +
 
 +
===Inventory class===
 +
For C# mods, 1.6 adds a new <samp>Inventory</samp> class to manage a list of items. This is used for the <samp>Farmer.items</samp> and <samp>Chest.items</samp> fields. It implements <samp>IList&lt;Item&gt;</samp>, so most existing code should still work fine.
 +
 
 +
This has three main benefits:
 +
<ul>
 +
<li>It has methods to simplify many common operations. For example:
 
{| class="wikitable"
 
{| class="wikitable"
 
|-
 
|-
! field
+
! method
! purpose
+
! effect
 
|-
 
|-
| <samp>CanChooseDuringCharacterCustomization</samp>
+
| <code>HasAny()</code>
| ''(Optional)'' Whether these pants can be selected on the character customization screen (e.g. when creating a character). Default false.
+
| Get whether the inventory contains any items (ignoring empty slots).
 
|-
 
|-
| <samp>CustomFields</samp>
+
| <code>CountItemStacks()</code>
| The [[#Custom data fields|custom fields]] for this entry.
+
| Get the number of item stacks in the inventory (ignoring empty slots).
|}
+
|-
 
+
| <code>ContainsId(id)</code>
===Custom shirts===
+
| Get whether the inventory contains any item with the given qualified or unqualified item ID.
{{/doc status|[[Modding:Items]]|done=false}}
  −
 
  −
You can now create/edit [[Tailoring#Shirts|shirts]] by editing the new <samp>Data/Shirts</samp> asset, which replaces <samp>Data/clothingInformation</samp>. This consists of a string → model lookup, where...
  −
* The key is the unqualified [[#Custom items|item ID]].
  −
* The value is a model with the fields listed below.
  −
 
  −
====Basic shirt data====
  −
{| class="wikitable"
   
|-
 
|-
! field
+
| <code>ContainsId(id, minCount)</code>
! purpose
+
| Get whether the inventory contains items with the given qualified or unqualified item ID, and their combined stack size is at least <samp>minCount</samp>.
 
|-
 
|-
| <samp>Name</samp>
+
| <code>CountId(id)</code>
| ''(Optional)'' The internal name for the item. Default <samp>Shirt</samp>.
+
| Get the combined stack size of all items with the given qualified or unqualified item ID.
 
|-
 
|-
| <samp>DisplayName</samp><br /><samp>Description</samp>
+
| <code>GetById(id)</code>
| ''(Optional)'' A [[Modding:Tokenizable strings|tokenizable string]] for the item's in-game display name and description. Defaults to the generic shirt text (''Shirt'' and ''A wearable shirt'').
+
| Get a list of items in the inventory with the given qualified or unqualified item ID.
 
|-
 
|-
| <samp>Price</samp>
+
| <code>ReduceId(id, count)</code>
| ''(Optional)'' The default price when the item is sold to the player in a shop. Default 50.
+
| Remove the given number of items matching the given qualified or unqualified item ID. This reduces the stack size for matching items until a total of <samp>count</samp> have been removed, and clears any slots which reach a stack size of zero.
|}
+
|}</li>
 +
<li>Many common operations have been unified, so previously player-only methods can now be used with chests too.</li>
 +
<li>It has an internal index by item ID, so operations like <code>items.ContainsId("(O)128")</code> are much more efficient since they no longer iterate the list.</li>
 +
</ul>
 +
 
 +
This replaces some previous methods:
   −
====Appearance====
   
{| class="wikitable"
 
{| class="wikitable"
 
|-
 
|-
! field
+
! game class
! purpose
+
! old code
 +
! migration
 
|-
 
|-
| <samp>Texture</samp>
+
|rowspan="6"| <samp>Farmer</samp>
| The asset name for the texture containing the shirt's sprite. Defaults to <samp>Characters/Farmer/shirts</samp>.
+
| <code>getItemCount(id)</code><br /><code>GetTallyOfObject(id)</code><br /><code>GetTallyOfObject(id, isBigCraftable)</code><br /><code>hasItemInInventory(id, count)</code><br /><code>hasItemInList(list, id, count)</code>
 +
| &#32;
 +
* To check an item ID, use <code>items.CountId(id)</code> or <code>Items.ContainsId(id, count)</code>.
 +
* To check Golden Walnuts or Qi Gems, use the <samp>Game1.netWorldState.Value.GoldenWalnuts</samp> and <samp>Farmer.QiGems</samp> fields.
 +
* To check category matches or <samp>-777</samp> (seasonal wild seeds), the <samp>getItemCount</samp> and <samp>getItemCountInList</samp> still exist.
 
|-
 
|-
| <samp>SpriteIndex</samp>
+
| <code>hasItemInInventoryNamed(name)</code><br /><code>hasItemWithNameThatContains(name)</code>
| The shirt's sprite index within the <samp>Texture</samp>, where 0 is the top-left set.
+
| In most cases, you should match items by ID instead (see the previous row).
|-
+
 
| <samp>DefaultColor</samp>
+
If you really need to match items by name, you can replace it like this:
| ''(Optional)'' The dye color to apply to the sprite when the player hasn't [[dyeing|dyed]] it yet, if any. See [[#Color fields|color format]]. Default none.
+
<syntaxhighlight lang="c#">
 +
// exact name
 +
bool hasMatch = Game1.player.Items.Any(item => item?.Name == name);
 +
 
 +
// name contains
 +
bool hasMatch = Game1.player.Items.Any(item => item?.Name?.Contains(name) is true);
 +
</syntaxhighlight>
 
|-
 
|-
| <samp>CanBeDyed</samp>
+
| <code>areAllItemsNull()</code>
| ''(Optional)'' Whether the player can [[dyeing|dye]] this shirt. Default false.
+
| Use <code>!items.HasAny()</code>.
 
|-
 
|-
| <samp>IsPrismatic</samp>
+
| <code>numberOfItemsInInventory()</code>
| ''(Optional)'' Whether the shirt continuously shifts colors. This overrides <samp>DefaultColor</samp> and <samp>CanBeDyed</samp> if set. Default false.
+
| Use <code>items.CountItemStacks()</code> to count all items, or <code>Items.Count(p => p is Object)</code> to match this method's actual behavior.
 
|-
 
|-
| <samp>HasSleeves</samp>
+
| <code>consumeObject(id, count)</code>
| ''(Optional)'' Whether to draw shirt sleeves. Default true.
+
| Use <code>items.ReduceId(id, count)</code>.
|}
  −
 
  −
====Other====
  −
{| class="wikitable"
   
|-
 
|-
! field
+
| <code>removeItemsFromInventory(id, count)</code>
! purpose
+
| &#32;
 +
* To remove an item by ID, use <code>items.ReduceId(id, count)</code>.
 +
* To deduct Golden Walnuts or Qi Gems, change the <samp>Game1.netWorldState.Value.GoldenWalnuts</samp> and <samp>Farmer.QiGems</samp> fields.
 
|-
 
|-
| <samp>CanChooseDuringCharacterCustomization</samp>
+
|rowspan="2"| <samp>Object</samp>
| ''(Optional)'' Whether this shirt can be selected on the character customization screen (e.g. when creating a character). Default false.
+
| <code>ConsumeInventoryItem(player, id, count)</code>
 +
| This was somewhat specialized and shouldn't be called by mod code, but the equivalent would be <code>(Object.autoLoadChest ?? player.items).ReduceId(id, count)</code>. See also notes for <samp>Farmer.removeItemsFromInventory</samp>.
 
|-
 
|-
| <samp>CustomFields</samp>
+
| <code>GetTallyOfObject(player, id)</code>
| The [[#Custom data fields|custom fields]] for this entry.
+
| This was somewhat specialized and shouldn't be called by mod code, but the equivalent would be <code>(Object.autoLoadChest ?? player.items).CountId(id)</code>. See also notes for <samp>Farmer.getTallyOfObject</samp>.
 
|}
 
|}
   −
===Custom tools===
+
It implements a new <samp>IInventory</samp> interface, which lets mods pass their own implementations to code which works on inventories.
{{/doc status|[[Modding:Items]]|done=false}}
+
 
 +
===Furniture changes===
 +
{{/doc status|[[Modding:Items#Furniture]]|done=true}}
   −
You can now create/edit [[tools]] by editing the new <samp>Data/Tools</samp> asset. This consists of a string → model lookup, where...
+
<ul>
* The key is the unqualified [[#Custom items|item ID]].
+
<li>[[Modding:Items#Furniture|<samp>Data/furniture</samp>]] no longer has language variants. Translations were moved into <samp>Strings/Furniture</samp>.</li>
* The value is a model with the fields listed below.
+
<li>
 +
There are a few changes in [[Modding:Items#Furniture|<samp>Data/furniture</samp>]]:
 +
<ul>
 +
<li>Field index 6 is now placement restrictions and field index 7 is now display name. The display name field is no longer omitted in English.</li>
 +
<li>Field index 7 (display name) now allows [[Modding:Tokenizable strings|tokenizable strings]].</li>
 +
<li>Added new fields:
   −
====Basic tool data====
   
{| class="wikitable"
 
{| class="wikitable"
 
|-
 
|-
 +
! index
 
! field
 
! field
! purpose
+
! effect
 
|-
 
|-
| <samp>ClassName</samp>
+
| 8
| The name of the C# class to construct within the <code>StardewValley.Tools</code> namespace. The class must be a subclass of <samp>StardewValley.Tool</samp>, and have a constructor with no arguments. For example, given a value of <samp>Axe</samp>, the game will create <code>StardewValley.Tools.Axe</code> instances.
+
| sprite index
 
+
| The sprite index within the spritesheet texture to draw.
The main values are:
  −
* main tools (<samp>Axe</samp>, <samp>FishingRod</samp>, <samp>Hoe</samp>, <samp>MeleeWeapon</samp>, <samp>MilkPail</samp>, <samp>Pan</samp>, <samp>Pickaxe</samp>, <samp>Shears</samp>, <samp>Wand</samp>, and <samp>WateringCan</samp>);
  −
* a special <samp>GenericTool</samp> type which applies the <samp>Data/Tools</samp> data and only has generic logic, so C# mods can patch in their own logic;
  −
* and two tools cut from the game which may not work correctly (<samp>Lantern</samp> and <samp>Raft</samp>).
   
|-
 
|-
| <samp>Name</samp>
+
| 9
| The internal name to set for the tool item.
+
| texture
 +
| ''(Optional)'' The asset name of the texture to draw. Defaults to <samp>TileSheets/furniture</samp>.
 
|-
 
|-
| <samp>DisplayName</samp><br /><samp>Description</samp>
+
| 10
| A [[Modding:Tokenizable strings|tokenizable string]] for the tool's in-game display name and description.
+
| off limits for random sale
 +
| ''(Optional)'' Whether to prevent this furniture from appearing in randomly generated shop stocks and the furniture catalogue. Default false.
 
|-
 
|-
| <samp>AttachmentSlots</samp>
+
| 11
| ''(Optional)'' The number of attachment slots to enable on the tool. Note that only <samp>FishingRod</samp> tools have the code to render and use attachment slots. Default <samp>-1</samp>, which keeps the default value set by the tool class.
+
| context tags
|-
+
| ''(Optional)'' A space-delimited list of [[Modding:Items#Context tags|context tags]] which apply to this furniture. Default none.
| <samp>SalePrice</samp>
+
|}</li>
| ''(Optional)'' The default price when the item is sold to the player in a shop. Defaults to <samp>-1</samp>, in which case you should set the price manually in shops.
+
</ul>
|-
+
</li>
| <samp>CustomFields</samp>
+
</ul>
| The [[#Custom data fields|custom fields]] for this entry.
  −
|}
     −
====Appearance====
+
===Other item changes for C# mods===
Note that drawing the tool correctly in the world (ie, while the player is trying to use it) probably still needs custom code.
+
* Placed object changes:
 
+
** Every placed object now has a <samp>Location</samp> property set to the location which contains it. This removes location parameters from many object methods.
{| class="wikitable"
+
** Setting an object's tile position through <samp>obj.TileLocation</samp> now recalculcates its collision box automatically. (Setting it through the <samp>tileLocation</samp> net field directly won't though.)
|-
+
** The <samp>obj.IsScarecrow()</samp> and <samp>GetScarecrowRadius()</samp> methods now work for non-bigcraftable objects too.
! field
+
* Clothing changes:
! purpose
+
** <samp>Clothes.clothesType</samp> is now an enum field.
|-
+
** Clothing is no longer gender-specific. This renames <samp>indexInTileSheetMale</samp> to <samp>indexInTileSheet</samp>, obsoletes <samp>indexInTileSheetFemale</samp>, and converts gender-variant clothing into regular items.
| <samp>Texture</samp>
+
** Removed unused <samp>ClothesType.ACCESSORY</samp> value.
| The asset name for the texture containing the tool's sprite.
+
** <samp>Farmer.pants</samp> and <samp>Farmer.shirt</samp> now store the item ID instead of the sprite index.
|-
+
** In <samp>Data/TailoringRecipes</samp>, added a <samp>CraftingIdFeminine</samp> field which overrides <samp>CraftingId</samp> for female characters.
| <samp>SpriteIndex</samp>
+
* Crop changes:
| The tool's sprite index within the <samp>Texture</samp>, where 0 is the top row.
+
** Added <samp>Game1.cropData</samp> to read crop info without constantly reloading the <samp>Data/Crops</samp> asset.
|-
+
** Removed most crop fields which only mirror the data (like <samp>harvestMethod</samp> or <samp>seasonsToGrowIn</samp>). Mods can get the info through <samp>crop.GetData()</samp> instead.
| <samp>MenuSpriteIndex</samp>
+
** Partly de-hardcoded fertilizer logic. Almost all fertilizer logic is now centralized into a new patchable set of <samp>HoeDirt</samp> methods (see list below). The only fertilizer logic that's still embedded elsewhere is the interaction errors in <samp>Utility.tryToPlaceItem</samp>.
| ''(Optional)'' The sprite index within the <samp>Texture</samp> for the item icon. Defaults to <samp>SpriteIndex</samp>.
+
** HoeDirt.fertilizer.Value is now set to <samp>null</samp> when there is no fertilizer. Both qualified and unqualified IDs should be expected.
|}
+
** Removed <samp>crop.InferSeedIndex()</samp>. This was used to support old crops, which are now fixed by a save migration instead.
 +
* Tool changes:
 +
** Fixed various logic not handling custom tool upgrade levels.
 +
<ul>
 +
<li>Other item logic:<ul>
 +
<li>Simplified the constructors for many item types, particularly <samp>Object</samp>.</li>
 +
<li>[[Honey]] items now have their <samp>preserve</samp> field set to a new <samp>Honey</samp> type (instead of null).</li>
 +
<li>The <samp>Object.performObjectDropInAction</samp> method now applies the <samp>probe</samp> argument much more consistently. This only affects method calls with <samp>probe: true</samp>.</li>
 +
<li>The <samp>Item.salePrice()</samp> method now has option to get the price without [[Multiplayer#Profit margins|profit margins]].</li>
 +
<li>Added new fields & methods:
   −
====Upgrades====
   
{| class="wikitable"
 
{| class="wikitable"
 
|-
 
|-
! field
+
! type
! purpose
+
! field/method
 +
! effect
 
|-
 
|-
| <samp>UpgradeLevel</samp>
+
| <samp>Chest</samp>
| ''(Optional)'' The tool upgrade level. Default <samp>-1</samp>, which keeps the default value set by the tool class.
+
| <samp>GetItemsForPlayer()</samp>
 +
| Shortcut for <samp>chest.GetItemsForPlayer(Game1.player.UniqueMultiplayerID)</samp>.
 
|-
 
|-
| <samp>ApplyUpgradeLevelToDisplayName</samp>
+
| rowspan="2"| <samp>Crop</samp>
| ''(Optional)'' Whether to adjust the <samp>DisplayName</samp> for the usual upgrade levels. For example, the display name for a level one Axe changes to 'Copper Axe'. Default false.
+
| <samp>GetHarvestMethod()</samp>
 
+
| Get the method used to harvest the crop (one of <samp>HarvestMethod.Grab</samp> or <samp>HarvestMethod.Scythe</samp>).
The display name format in English is:
  −
{| class="wikitable"
   
|-
 
|-
! upgrade level
+
| <samp>IsInSeason(location)</samp>
! display name format
+
| Whether the crop can grow in the location's current season (or true if crops ignore seasons in the location, like the [[greenhouse]]).
 
|-
 
|-
| 1
+
| rowspan="8"| <samp>HoeDirt</samp>
| Copper {{t|display name}}
+
| <samp>HasFertilizer()</samp>
 +
| Get whether the dirt has any fertilizer applied.
 
|-
 
|-
| 2
+
| <samp>CanApplyFertilizer(itemId)</samp>
| Steel {{t|display name}}
+
| Get whether a player can apply the given fertilizer to this dirt.
 
|-
 
|-
| 3
+
| <samp>CheckApplyFertilizerRules(itemId)</samp>
| Gold {{t|display name}}
+
| Get whether a player can apply the given fertilizer to this dirt, and the reason they can't if applicable.
 
|-
 
|-
| 4
+
| <samp>GetFertilizerSpeedBoost()</samp>
| Iridium {{t|display name}}
+
| Get the crop growth speed boost from fertilizers applied to this dirt.
|}
   
|-
 
|-
| <samp>ConventionalUpgradeFrom</samp>
+
| <samp>GetFertilizerWaterRetentionChance()</samp>
| ''(Optional)'' If set, prepends an upgrade for the given tool ID to the <samp>UpgradeFrom</samp> field. This applies these rules (based on the <samp>UpgradeLevel</samp> field, not the upgrade level of the specified tool ID):
+
| Get the water retention chance from fertilizers applied to this dirt, as a value between 0 (no change) and 1 (100% chance of staying watered).
 
  −
{| class="wikitable"
   
|-
 
|-
! upgrade level
+
| <samp>GetFertilizerQualityBoostLevel()</samp>
! price
+
| Get the quality boost level from fertilizers applied to this dirt, which influences the chance of producing a higher-quality crop.
! items needed
   
|-
 
|-
| 1
+
| <samp>GetFertilizerSourceRect()</samp>
| {{price|2000}}
+
| Get the pixel area within the dirt spritesheet to draw for any fertilizer applied to this dirt.
| {{name|Copper Bar|5}}
  −
|-
  −
| 2
  −
| {{price|5000}}
  −
| {{name|Iron Bar|5}}
  −
|-
  −
| 3
  −
| {{price|10000}}
  −
| {{name|Gold Bar|5}}
  −
|-
  −
| 4
  −
| {{price|25000}}
  −
| {{name|Iridium Bar|5}}
  −
|}
     −
For example, Iridium Axe specifies this value:
+
(This method existed before, but no longer requires the fertilizer ID argument.)
<syntaxhighlight lang="js">
  −
"ConventionalUpgradeFrom": "(T)GoldAxe"
  −
</syntaxhighlight>
   
|-
 
|-
| <samp>UpgradeFrom</samp>
+
| <samp>isWatered()</samp>
| ''(Optional)'' The requirements to buy this tool from Clint's [[Blacksmith#Upgrade Tools|blacksmith tool upgrade shop]]. If you specify multiple entries, the first one which matches will be applied.
+
| Get whether the dirt is currently watered.
 
  −
This consists of a list of models with these fields:
  −
{| class="wikitable"
   
|-
 
|-
! field
+
|rowspan="5"| <samp>Item</samp>
! purpose
+
| <samp>IsRecipe</samp><br /><samp>Quality</samp><br /><samp>Stack</samp></samp><br /><samp>sellToStorePrice(…)</samp>
 +
| Equivalent to the previous <samp>Object</samp> fields/methods, to simplify common code and avoid needing to special-case <samp>Object</samp> items.
 
|-
 
|-
| <samp>Price</samp>
+
| <samp>appliesProfitMargins()</samp>
| ''(Optional)'' The gold price to buy the upgrade. Defaults to 0.
+
| Get whether this item should apply [[Multiplayer#Profit margins|profit margins]] to shop prices.
 
|-
 
|-
| <samp>RequireToolId</samp>
+
| <samp>CanBeLostOnDeath()</samp>
| ''(Optional)'' If set, the [[#Custom items|qualified or unqualified item ID]] for the tool that must be in the player's inventory for the upgrade to appear. The tool will be destroyed when the upgrade is purchased.
+
| Get whether this item can be lost when the player dies, so it can be recovered from the [[Adventurer's Guild#Item Recovery Service|item recovery service]].
 
|-
 
|-
| <samp>TradeItemId</samp>
+
| <samp>HasTypeId(id)</samp><br /><samp>HasTypeObject()</samp><br /><samp>HasTypeBigCraftable()</samp>
| ''(Optional)'' If set, the [[#Custom items|qualified or unqualified item ID]] for an extra item that must be traded to upgrade the tool. (For example, many vanilla tools need metal bars.)
+
| Get whether the item has the given [[#Custom items|type definition ID]]. These are null-safe and double as a null check:
 +
<syntaxhighlight lang="c#">
 +
if (item.HasTypeId(ItemRegistry.type_object))
 +
{
 +
    // item is non-null and has type (O)
 +
}
 +
</syntaxhighlight>
 +
<samp>HasTypeObject()</samp> and <samp>HasTypeBigCraftable()</samp> are shortcuts for passing <samp>ItemRegistry.type_object</samp> and <samp>ItemRegistry.type_bigCraftable</samp> respectively.
 
|-
 
|-
| <samp>TradeItemAmount</samp>
+
| <samp>TryGetTempData</samp><br /><samp>SetTempData</samp>
| ''(Optional)'' The number of <samp>TradeItemId</samp> required. Defaults to 1.
+
| Get or set temporary item info that's not synchronized in multiplayer or written to the save file.
|-
  −
| <samp>Condition</samp>
  −
| ''(Optional)'' A [[Modding:Game state queries|game state query]] which indicates whether this upgrade is available. Defaults to always true.
  −
|}
     −
For example, these are equivalent to the Steel Axe's upgrade settings:
+
For example, the game uses this to pass spawn options to the fishing minigame:
<syntaxhighlight lang="js">
+
<syntaxhighlight lang="c#">
"UpgradeFrom": [
+
if (spawn.IsBossFish)
     {
+
     fish.SetTempData(nameof(spawn.IsBossFish), true);
        "RequireToolId": "(T)CopperAxe",
+
 
        "Price": 5000,
+
...
        "TradeItemId": "(O)335", // Iron Bar
  −
        "TradeItemAmount": 5
  −
    }
  −
]
  −
</syntaxhighlight>
     −
If you want the tool to always be available, you can just omit the conditions. For example:
+
fish.TryGetTempData(nameof(SpawnFishData.IsBossFish), out bool bossFish);
<syntaxhighlight lang="js">
  −
"UpgradeFrom": [
  −
    {
  −
        "Price": 5000
  −
    }
  −
]
   
</syntaxhighlight>
 
</syntaxhighlight>
  −
Note that Clint needs a few days to smith the new tool. If you want to sell the tool directly, [[#Custom shops|add it to a regular shop]] instead.
  −
|}
  −
  −
====Game logic====
  −
{| class="wikitable"
   
|-
 
|-
! field
+
| <samp>FishingRod</samp>
! purpose
+
| <samp>CanUseBait()</samp><br /><samp>CanUseTackle()</samp><br /><samp>GetBait()</samp><br /><samp>GetTackle()</samp><br /><samp>HasMagicBait()</samp><br /><samp>HasCuriosityLure()</samp>
 +
| Simplifies working with the fishing rod's [[bait]] and [[tackle]].
 
|-
 
|-
| <samp>CanBeLostOnDeath</samp>
+
|rowspan="2"| <samp>Furniture</samp>
| Whether the player can [[Adventurer's Guild#Item Recovery Service|lose this tool when they die]]. Default false.
+
| <samp>SetPlacement</samp><br /><samp>SetHeldObject</samp>
|}
+
| Set the furniture's position and rotation (<samp>SetPlacement</samp>) or held object (<samp>SetHeldObject</samp>). The latter will initialize the held object's tile position to match the furniture instance.
   −
====Extensibility====
+
These are used by the game to initialize furniture in one go. For example:
{| class="wikitable"
+
<syntaxhighlight lang="c#">
 +
// oak table holding decorative bowl
 +
Furniture table = ItemRegistry
 +
    .Create<Furniture>("(F)1120")
 +
    .SetPlacement(5, 4, 0)
 +
    .SetHeldObject(ItemRegistry.Create<Furniture>("(F)1364"));
 +
</syntaxhighlight>
 
|-
 
|-
! field
+
| <samp>IsTable()</samp>
! purpose
+
| Get whether this furniture is a table.
 
|-
 
|-
| <samp>ModData</samp>
+
|rowspan="2"| <samp>FruitTree</samp>
| ''(Optional)'' The mod data values to set when the tool is created, accessible in C# code via the <samp>tool.modData</samp> dictionary. For example:
+
| <samp>GetQuality()</samp>
<syntaxhighlight lang="js">
+
| Get the quality of fruit currently being produced by the fruit tree.
"ModData": {
  −
    "PowerLevel": 9000
  −
}
  −
</syntaxhighlight>
   
|-
 
|-
| <samp>SetProperties</samp>
+
| <samp>TryAddFruit()</samp>
| ''(Optional)'' Set the value of arbitrary properties on the tool class. For example, this would disable the tool animation and require no stamina:
+
| Add a fruit item to the tree based on [[#Custom fruit trees|its data]].
<syntaxhighlight lang="js">
+
|-
"SetProperties": {
+
| <samp>IndoorPot</samp>
    "InstantUse": true,
+
| <samp>Water()</samp>
    "IsEfficient": true
+
| Simplifies watering dirt in the [[Garden Pot|garden pot]].
}
+
|-
</syntaxhighlight>
+
| <samp>Object</samp>
 +
| <samp>GetBoundingBox()</samp><br /><samp>GetBoundingBoxAt(x, y)</samp>
 +
| Get the pixel collision area for the item placed in the world. These replace the former <samp>getBoundingBox(position)</samp> method.
 +
|-
 +
| <samp>Tool</samp>
 +
| <samp>isScythe()</samp>
 +
| Equivalent to the previous <samp>MeleeWeapon</samp> method, to simplify common code and avoid needing to special-case <samp>MeleeWeapon</samp> items.
 +
|-
 +
|rowspan="3"| <samp>Tree</samp>
 +
| <samp>CheckForNewTexture()</samp>
 +
| Reset the tree's texture if it would change based on [[#Custom wild trees|its data]].
 +
|-
 +
| <samp>GetMaxSizeHere</samp>
 +
| Get the maximum size the tree can grow in its current position (e.g. accounting for nearby trees blocking growth).
 +
|-
 +
| <samp>IsGrowthBlockedByNearbyTree</samp>
 +
| Get whether growth is blocked because it's too close to another fully-grown tree.
 
|}
 
|}
 +
</li>
 +
<li>Modularized <samp>Object.CheckForAction</samp> to simplify mod patches.</li>
 +
<li>Reworked <samp>Item.getOne()</samp> implementation to avoid common pitfalls. (This only affects mods with custom item classes, or which patch <samp>Item.getOne</samp> or <samp>Item._GetOneFrom</samp>.)</li>
 +
<li>Fixed fruit trees forgetting the growth stage set in their constructor when they're updated overnight.</li>
 +
</ul>
   −
===Custom wild trees===
+
===Other item changes===
{{/doc status|[[Modding:Wild trees]]|done=true}}
+
* Added per-object display names (''e.g.'' for custom flavored items). See the <samp>ObjectDisplayName</samp> [[Modding:Item queries#Item spawn fields|item spawn field]], or <samp>object.displayNameFormat</samp> in C#.
 
+
* [[Ginger Island#Gem Birds|Item pedestals]] are now normal item, so you can spawn them using a mod like CJB Item Spawner to display items.
You can now create/edit [[Trees|wild trees]] by editing the <samp>Data/WildTrees</samp> asset.
+
* Added optional <samp>Condition</samp> [[Modding:Game state queries|game state query]] field to <samp>Data/SpecialOrders</samp>.
 
+
* Item data changes:
Custom trees can be added to the game in two ways:
+
** The display name field now exists in English too for <samp>Data/Boots</samp>, <samp>Data/Bundles</samp>, <samp>Data/CookingRecipes</samp>, <samp>Data/CraftingRecipes</samp>, <samp>Data/Furniture</samp>, <samp>Data/Hats</samp>, and <samp>Data/Weapons</samp>.
* Spawn them on [[Modding:Maps|map tiles]] when the location is created, using the new <samp>SpawnTree: wild {{t|tree ID}} {{o|growth stage on location created}} {{o|growth stage on day-update regrowth}}</samp> tile property. This must be added on the <samp>Paths</samp> layer, which must also have tile index 34 from the <samp>paths</samp> tilesheet.
+
** The randomly spawned [[The Farm#Stone|stones]], [[The Farm#Wood|twigs]], and [[weeds]] have been formalized into ''litter''. They all now have object type <samp>Litter</samp>, [[Modding:Items#Categories|category]] -999 (<samp>StardewValley.Object.litterCategory</samp>), a relevant display name/description (like ''Gold Stone'' & ''Break apart to obtain gold ore'' instead of ''Stone'' & ''...''), a price of 0 (not sellable), and edibility of -300 (inedible). This also adds all mine ore nodes to <samp>Data/Objects</samp>, so the game no longer creates invalid items to show their sprite. (Doing so in 1.6 will now show an Error Item sprite instead.)
* Or give the player a seed item in the usual ways (e.g. from [[#Custom shops|a shop]], [[Modding:Mail data|mail letter]], etc).
+
** [[Honey]] items now have the <samp>honey_item</samp> context tag.
 
+
** Shirts no longer have a dynamic numeric ID range; every valid shirt is now listed in [[#Custom shirts|<samp>Data/Shirts</samp>]].
===Default recipes===
+
** You can now apply a custom buff ID when the item is eaten, via <samp>Data/Objects</samp>'s <samp>Buff</samp> field.
{{/doc status|[[Modding:Recipe data]]|done=false}}
+
** The type field in <samp>Data/Objects</samp> is no longer checked using substring matching (e.g. the game now uses <code>data.Type == "Fish"</code> instead of <code>typeAndCategory.Contains("Fish")</code>), which may impact mods which depended on that undocumented behavior.
 
+
* Crop changes:
You can now have [[Modding:Recipe data|crafting and cooking recipes]] that are learned automatically by setting the condition field to <samp>default</samp>. Any missing default recipes will be learned on day start.
+
** Paddy crops now recheck for nearby water each day, so they'll update if you add/remove a building with water or change the map layout.
 
+
** In <samp>Data/Crops</samp>, each harvest option is now self-contained. For example, you can set <samp>HarvestMinStack</samp> without <samp>ExtraHarvestChance</samp>.
For example, here's the chest entry from <samp>Data/CraftingRecipes</samp>:
+
* Fish changes:
<syntaxhighlight lang="js">
+
** <samp>Data/Fish</samp> is no longer translated, so there's only one <samp>Data/Fish.xnb</samp> field. Fish display names are now taken from <samp>Data/Objects</samp>.
"Chest": "388 50/Home/130/true/default/"
+
** Added a new field (index 13) in <samp>Data/Fish</samp>, which sets whether the fish can be selected for the first-catch tutorial.
</syntaxhighlight>
+
* Recipe changes in <samp>Data/CookingRecipes</samp> and <samp>Data/CraftingRecipes</samp>:
 +
** These assets no longer have language variants.
 +
** The display name now supports [[Modding:Tokenizable strings|tokenizable strings]].
 +
** The display name can now be left blank to get it from the first item in the output list.
 +
* Other item logic:
 +
** Missing recipes that should already be unlocked are now added to the player automatically on save load.
 +
** <samp>Data/Bundles</samp> is now loaded later, so content packs can edit it reliably.</samp>
 +
** Chests with <samp>fridge: true</samp> are now treated as mini-fridges for the cooking menu.
 +
** Gift boxes can now contain multiple items.
 +
** Fixed furniture drawn over sitting players if it has no front texture.
 +
** Fixed tool being upgraded by Clint not affected by recursive item search logic.
 +
** Fixed <samp>tool.getOne()</samp> not copying the tool name.
 +
** Fixed cooking menu constantly creating hovered item if the item/recipe names don't match.
   −
===Global inventories===
+
==What's new for locations & weather==
C# mods can now set a <samp>chest.GlobalInventoryId</samp> field to make it share a global inventory with every other chest having the same ID. This replaces the equivalent hardcoded logic for [[Junimo Chest|Junimo chests]], which now just default to a <samp>"JunimoChests"</samp> global inventory ID. For example, this can be used to have multiple Junimo chest networks or make other containers share inventory.
+
===Custom locations===
 +
{{/doc status|[[Modding:Location data]]|done=true}}
   −
C# mods can also use this to store items for other mod purposes, by using <samp>Game1.player.team.globalInventories</samp> or <samp>Game1.player.team.GetOrCreateGlobalInventory(id)</samp> directly.
+
You can now add/edit locations by editing the revamped <samp>Data/Locations</samp> asset. This makes nearly everything in the location configurable — display name, default warp arrival tile, how the location is created, artifact spots / fish / forage / weeds, music, etc.
   −
===Hats on aquarium fish===
+
See [[Modding:Location data]] for docs on the new data format.
{{/doc status|[[Modding:Fish data]]|done=false}}
     −
Custom [[Modding:Fish data|fish in aquariums]] can now wear [[hats]], just like vanilla [[Sea Urchin|sea urchins]]. This can be enabled by specifying a new field in <samp>Data/AquariumFish</samp>:
+
===Custom location contexts===
 +
{{/doc status|[[Modding:Location data]] or a new doc page|done=false}}
   −
{| class="wikitable"
+
====Vanilla contexts====
|-
+
* The game previously had two hardcoded location context enums: <samp>Default</samp> (for the valley) and <samp>Island</samp> (for [[Ginger Island]]). These have been replaced with data models which define the location context settings, loaded from the <samp>Data/LocationContexts</samp> asset.
! index
+
* [[The Desert|The desert]] is now part of a new <samp>Desert</samp> context (instead of <samp>Default</samp>). Some of the previously hardcoded desert logic (like always sunny weather) is now just part of the context data in <samp>Data/LocationContexts</samp>.
 +
 
 +
====Format====
 +
Custom contexts can be created by editing the new <samp>Data/LocationContexts</samp> asset, and setting the context name in the location's <samp>LocationContext</samp> [[Modding:Maps|map property]].
 +
 
 +
The data asset consists of a string → model lookup, where the key matches the <samp>Name</samp> field and the value is a model with these fields:
 +
 
 +
<dl style="margin-left: 2em;">
 +
<dt>Required fields:</dt>
 +
<dd>
 +
{| class="wikitable"
 +
|-
 
! field
 
! field
! purpose
+
! effect
 
|-
 
|-
| 7
+
| <samp>Name</samp>
| hat position
+
| The [[Modding:Common data field types#Unique string ID|unique string ID]] for the location context.
| The pixel position of the hat on the sprite, specified as an object with <samp>X</samp> and <samp>Y</samp> values.
   
|}
 
|}
 +
</dd>
   −
===Context tag changes===
+
<dt>Player actions:</dt>
{{/doc status|[[Modding:Items#Context tags]]|done=false}}
+
<dd>
 
  −
====New context tags====
  −
1.6 adds several new [[Modding:Items#Context tags|item context tags]]:
  −
 
   
{| class="wikitable"
 
{| class="wikitable"
 
|-
 
|-
! context tag
+
! field
 
! effect
 
! effect
 
|-
 
|-
| <samp>campfire_item</samp>
+
| <samp>AllowRainTotem</samp>
| Marks the item as a [[campfire]]. If the item also has the <samp>torch_item</samp> context tag, when it's placed in the world and turned on...
+
| ''(Optional)'' Whether a [[Rain Totem|rain totem]] can be used to force rain in this context tomorrow. If false, using a rain totem here will show a "''this item can't be used here''" message instead.
* campfire flames are drawn over it;
  −
* if the item is [[Modding:Items#Big craftables|big craftable]], light is emitted from its center instead of the top.
   
|-
 
|-
| <samp>fish_pond_ignore</samp>
+
| <samp>RainTotemAffectsContext</samp>
| Prevents players from adding this fish to [[Fish Pond|fish ponds]], even if it would otherwise match an entry in <samp>Data/FishPondData</samp>.
+
| ''(Optional)'' If set, using a rain totem here will change the weather in the given context ID. For example, rain totems in the desert change weather in the valley.
 
|-
 
|-
| <samp>geode_crusher_ignored</samp>
+
| <samp>MaxPassOutCost</samp>
| Prevents breaking this item open in a [[Geode Crusher|geode crusher]], even if the item has geode fields in [[#Custom objects|<samp>Data/Objects</samp>]].
+
| ''(Optional)'' When the player passes out (due to [[energy|exhaustion]] or at 2am) in this context, the maximum amount of [[gold]] lost. If omitted or set to <samp>-1</samp>, uses the same value as the <samp>Default</samp> context ({{price|1000}} by default).
 
|-
 
|-
| <samp>item_type_{{t|type}}</samp>
+
| <samp>PassOutMail</samp>
| For an [[Modding:Items#Objects|object-type item]], the type value from the 'type and category' field. (Non-object items always have the exact tag <samp>item_type_</samp> with nothing after the last underscore.) This is automatic and shouldn't be set manually. The tag is checked in a few places (''e.g.'' the [[museum]] to check if an item is an artifact or mineral), but most of the game won't be affected.
+
| ''(Optional)'' When the player passes out (due to [[energy|exhaustion]] or at 2am) in this context, the possible [[Modding:Mail data|letter IDs]] to add to their mailbox (if they haven't received it before). If multiple letters are valid, one will be chosen randomly (unless one specifies <samp>SkipRandomSelection</samp>).
 +
 
 +
This consists of a list of models with these fields:
 +
{| class="wikitable"
 +
|-
 +
! field
 +
! effect
 
|-
 
|-
| <samp>museum_donatable</samp><br /><samp>not_museum_donatable</samp>
+
| <samp>Id</samp>
| Set whether the item can be donated to the [[museum]], overriding the vanilla logic.
+
| The [[Modding:Common data field types#Unique string ID|unique string ID]] for this entry in the list.
 
|-
 
|-
| <samp>not_giftable</samp>
+
| <samp>Mail</samp>
| Prevents players from gifting this item to NPCs, who'll ignore the item entirely (e.g. as if you were holding a tool).
+
| The [[Modding:Mail data|letter ID]] to add.
 +
 
 +
The game will look for an existing letter ID in <samp>Data/mail</samp> in this order (where {{t|billed}} is <samp>Billed</samp> if they lost [[gold]] or <samp>NotBilled</samp> otherwise, and {{t|gender}} is <samp>Female</samp> or <samp>Male</samp>):
 +
* <samp>{{t|letter id}}_{{t|billed}}_{{t|gender}}</samp>
 +
* <samp>{{t|letter id}}_{{t|billed}}</samp>
 +
* <samp>{{t|letter id}}</samp>
 +
 
 +
If no match is found in <samp>Data/mail</samp>, the game will send <samp>passedOut2</samp> instead.
   −
This only affects gift-giving, it doesn't affect non-gift logic like quest goals or special order objectives. If the NPC also has a <samp>reject_*</samp> dialogue for the item, the dialogue takes priority.
+
If the mail ID starts with <samp>passedOut</samp>, <samp>{0}</samp> in the letter text will be replaced with the gold amount lost, and it won't appear in the [[collections]] page.
 
|-
 
|-
| <samp>not_placeable</samp><br /><samp>placeable</samp>
+
| <samp>MaxPassOutCost</samp>
| Sets whether the item can be placed on the ground.
+
| ''(Optional)'' The maximum amount of [[gold]] lost. This is applied after the context's <samp>MaxPassOutCost</samp> (i.e. the context's value is used to calculate the random amount, then this field caps the result). Defaults to unlimited.
 
|-
 
|-
| <samp>prevent_loss_on_death</samp>
+
| <samp>Condition</samp>
| Indicates the item can't be [[Adventurer's Guild#Item Recovery Service|lost when the player dies]].
+
| ''(Optional)'' A [[Modding:Game state queries|game state query]] which indicates whether this entry is active. Defaults to always true.
 
|-
 
|-
| <samp>sign_item</samp>
+
| <samp>SkipRandomSelection</samp>
| Marks the item as a [[Crafting#Signs|sign]], which lets player display items on it or place it on a [[Fish Pond|fish pond]] to show the fish count.
+
| ''(Optional)'' If true, send this mail if the <samp>Condition</samp> matches instead of choosing a random valid mail. Default false.
 +
|}
 
|-
 
|-
| <samp>torch_item</samp>
+
| <samp>PassOutLocations</samp>
| Marks the item as a [[torch]], which lets the player turn it on/off to emit light.
+
| ''(Optional)'' When the player passes out (due to [[energy|exhaustion]] or at 2am) in this context ''and'' they started the day in a different location context, the locations where they'll wake up. (If the player started the day in the same context, they'll wake up in the last bed they slept in instead.)
   −
See also <samp>campfire_item</samp>.
+
If the selected location doesn't contain a bed and doesn't have the [[#New map properties|<samp>AllowWakeUpWithoutBed</samp> map property]], the player will wake up in the farmhouse instead.
|}
     −
Context tags which affect [[#Custom machines|machine processing]]:
+
This consists of a list of models with these fields:
 
{| class="wikitable"
 
{| class="wikitable"
 
|-
 
|-
! context tag
+
! field
 
! effect
 
! effect
 
|-
 
|-
| <samp>crystalarium_banned</samp>
+
| <samp>Id</samp>
| When applied to a gem or mineral item, prevents players from placing it in a [[crystalarium]].
+
| The [[Modding:Common data field types#Unique string ID|unique string ID]] for this entry in the list.
 
|-
 
|-
| <samp>keg_juice</samp><br /><samp>keg_wine</samp>
+
| <samp>Location</samp>
| Allows processing the item in a [[keg]] to produce a juice or wine variant.
+
| The internal location name.
 
|-
 
|-
| <samp>preserves_jelly</samp><br /><samp>preserves_pickle</samp>
+
| <samp>Position</samp>
| Allows processing the item in a [[Preserves Jar|preserves jar]] to produce a jelly or pickled variant.
+
| The ''default'' tile position within the location, specified as an object with <samp>X</samp> and <samp>Y</samp> fields. If the location has any bed furniture, they'll be placed in the first bed found instead.
 
|-
 
|-
| <samp>seedmaker_banned</samp>
+
| <samp>Condition</samp>
| When applied to a seed item, prevents players from placing it in a [[Seed Maker|seed maker]].
+
| ''(Optional)'' A [[Modding:Game state queries|game state query]] which indicates whether this entry is active. Defaults to always applied.
 +
|}
 +
 
 +
If no locations are specified or none match, the player will wake up in their bed at home.
 
|-
 
|-
| <samp>tapper_item</samp>
+
| <samp>ReviveLocations</samp>
| Marks the item as a [[tapper]] or [[Heavy Tapper|heavy tapper]].
+
| ''(Optional)'' If the player just got knocked out in combat, the location names where they'll wake up.
|-
  −
| <samp>tapper_multiplier_{{t|multiplier}}</samp>
  −
| The multiplier applied to the tapper production speed. For example, <samp>2</samp> will make items take half their base time (''i.e.'' each item will finish in <sup>base time</sup>/<sub>speed multiplier</sub>). Defaults to 1 if omitted.
  −
|}
     −
And informational tags which have no effect on the game logic:
+
This consists of a list of models with these fields:
 
{| class="wikitable"
 
{| class="wikitable"
 
|-
 
|-
! context tag
+
! field
 
! effect
 
! effect
 
|-
 
|-
| <samp>fish_legendary</samp><br /><samp>fish_legendary_family</samp>
+
| <samp>Id</samp>
| Marks the fish as a [[Fish#Legendary Fish|legendary fish]] or [[Quests#Extended Family|legendary fish family]]. These are purely informational; the legendary fish behavior is determined by data fields like <samp>CatchLimit</samp> or <samp>IsBossFish</samp> in [[#Custom locations|<samp>Data/Locations</samp>]].
+
| The [[Modding:Common data field types#Unique string ID|unique string ID]] for this entry in the list.
 
|-
 
|-
| <samp>geode</samp>
+
| <samp>Location</samp>
| ''(Added automatically)'' Marks the item as a [[Minerals#Geodes|geode]] item, which can be broken open at [[Blacksmith|Clint's blacksmith shop]] or using a [[Geode Crusher|geode crusher]]. This is added automatically if the geode fields are present in [[#Custom objects|<samp>Data/Objects</samp>]].
+
| The internal location name.
 
|-
 
|-
| <samp>id_{{t|item id}}</samp>
+
| <samp>Position</samp>
| ''(Added automatically)'' The [[#Custom items|qualified item ID]], like <samp>id_(o)128</samp>. This can be used to match or exclude an item by ID using context tags. Any spaces in the ID are replaced with underscores, and single quotes are removed.
+
| The tile position within the location, specified as an object with <samp>X</samp> and <samp>Y</samp> fields.
 
|-
 
|-
| <samp>is_machine</samp>
+
| <samp>Condition</samp>
| ''(Added automatically)'' Indicates the item has [[#Custom machines|machine logic]]. This is added automatically based on <samp>Data/Machines</samp>.
+
| ''(Optional)'' A [[Modding:Game state queries|game state query]] which indicates whether this entry is active. Defaults to always applied.
|-
  −
| <samp>machine_input</samp>
  −
| ''(Added automatically)'' Whether the item is a machine which accepts items from the player. This is added automatically based on the machine's fields in <samp>Data/Machines</samp>:
  −
* if <samp>HasInput</samp> is true;
  −
* ''or'' if any output rules have an <samp>ItemPlacedInMachine</samp> trigger.
  −
|-
  −
| <samp>machine_output</samp>
  −
| ''(Added automatically)'' Whether the item is a machine which produces items for the player to collect. This is added automatically based on the machine's fields in <samp>Data/Machines</samp>:
  −
* if <samp>HasOutput</samp> is true;
  −
* ''or'' if it has any output rules.
   
|}
 
|}
   −
====ItemContextTagManager class====
+
If the selected location has a standard [[Modding:Event data|event]] with the exact key <samp>PlayerKilled</samp> (with no <samp>/</samp> or preconditions in the key), that event will play when the player wakes up and the game will apply the lost items or [[gold]] logic. The game won't track this event, so it'll repeat each time the player is revived. If there's no such event, the player will wake up without an event, and no items or gold will be lost.
For C# mods, 1.6 adds a new <samp>ItemContextTagManager</samp> class which simplifies working with [[Modding:Items#Context tags|item context tags]] and reduces repeated code.
+
 
 +
If no locations are specified or none match, the player will wake up at [[Harvey's Clinic|Harvey's clinic]].
 +
|}
 +
</dd>
   −
This provides a few utility methods:
+
<dt>Season:</dt>
 +
<dd>
 
{| class="wikitable"
 
{| class="wikitable"
 
|-
 
|-
! method
+
! field
 
! effect
 
! effect
 
|-
 
|-
| <code>GetBaseContextTags(id)</code>
+
| <samp>SeasonOverride</samp>
| Get the base context tags for an item based on its raw data in <samp>Data/Objects</samp> or <samp>Data/BigCraftables</samp>. This doesn't include dynamic tags added that are based on instance info (like quality), which you can get using <code>item.GetContextTags()</code>.
+
| ''(Optional)'' The season which is always active for locations within this context (one of <samp>spring</samp>, <samp>summer</samp>, <samp>fall</samp>, or <samp>winter</samp>). For example, setting <samp>summer</samp> will make it always [[summer]] there regardless of the calendar season. If not set, the calendar season applies.
 +
|}
 +
</dd>
 +
 
 +
<dt>Weather:</dt>
 +
<dd>
 +
{| class="wikitable"
 
|-
 
|-
| <code>DoesTagQueryMatch(query, tags)</code>
+
! field
| Get whether a context tag query matches the given tags. For example, <code>ItemContextTagManager.DoesTagQueryMatch("bone_item, !fossil_item", item.GetContextTags())</code> returns true if the item is a bone item but not a fossil (like the [[Bone Flute]]).
+
! effect
 
|-
 
|-
| <code>DoAllTagsMatch(requiredTags, actualTags)</code><br /><code>DoAnyTagsMatch(requiredTags, actualTags)</code>
+
| <samp>WeatherConditions</samp>
| Get whether every (<samp>DoAllTagsMatch</samp>) or at least one (<samp>DoAnyTagsMatch</samp) required tag matches the actual item tags. This supports negated required tags like <samp>"!fossil_item"</samp> too.
+
| ''(Optional)'' The weather logic to apply for locations in this context (ignored if <samp>CopyWeatherFromLocation</samp> is set). Defaults to always sunny. If multiple are specified, the first matching weather is applied.
 +
 
 +
This consists of a list of models with these fields:
 +
{| class="wikitable"
 +
|-
 +
! field
 +
! effect
 +
|-
 +
| <samp>Id</samp>
 +
| The [[Modding:Common data field types#Unique string ID|unique string ID]] for this entry in the list.
 +
|-
 +
| <samp>Weather</samp>
 +
| The [[#Custom weather|weather ID]] to set.
 
|-
 
|-
| <code>DoesTagMatch(requiredTag, actualTags)</code>
+
| <samp>Condition</samp>
| Get whether a single tag matches the actual item tags. This supports negated required tags like <samp>"!fossil_item"</samp> too.
+
| ''(Optional)'' A [[Modding:Game state queries|game state query]] which indicates whether to apply the weather. Defaults to always applied.
 +
|}
 
|-
 
|-
| <code>SanitizeContextTag(tag)</code>
+
| <samp>CopyWeatherFromLocation</samp>
| ''(Specialized)'' Replace characters that may appear in item names so they're valid in context tags. For example, <code>SanitizeContextTag("Sam's Boombox")</code> returns <samp>sams_boombox</samp>.
+
| ''(Optional)'' The <samp>Name</samp> (i.e. unique ID) of the location context from which to inherit weather.
 
|}
 
|}
   −
====Other context tag changes====
+
If a [[#Custom passive festivals|passive festival]] is active in any location within this context, the weather is sunny for the entire context regardless of these fields.
* Context tags are now case-insensitive.
     −
===Inventory class===
+
</dd>
For C# mods, 1.6 adds a new <samp>Inventory</samp> class to manage a list of items. This is used for the <samp>Farmer.items</samp> and <samp>Chest.items</samp> fields. It implements <samp>IList&lt;Item&gt;</samp>, so most existing code should still work fine.
     −
This has three main benefits:
+
<dt>Music:</dt>
<ul>
+
<dd>
<li>It has methods to simplify many common operations. For example:
   
{| class="wikitable"
 
{| class="wikitable"
 
|-
 
|-
! method
+
! field
 
! effect
 
! effect
 
|-
 
|-
| <code>HasAny()</code>
+
| <samp>DefaultMusic</samp>
| Get whether the inventory contains any items (ignoring empty slots).
+
| ''(Optional)'' The [[#Custom audio|cue ID]] for the music to play when the player is in the location, unless overridden by a <samp>Music</samp> map property. Despite the name, this has a higher priority than the seasonal music fields below. Ignored if omitted.
 
|-
 
|-
| <code>CountItemStacks()</code>
+
| <samp>DefaultMusicCondition</samp>
| Get the number of item stacks in the inventory (ignoring empty slots).
+
| ''(Optional)'' A [[Modding:Game state queries|game state query]] which returns whether the <samp>DefaultMusic</samp> field should be applied (if more specific music isn't playing). Defaults to always true.
 
|-
 
|-
| <code>ContainsId(id)</code>
+
| <samp>DefaultMusicDelayOneScreen</samp>
| Get whether the inventory contains any item with the given qualified or unqualified item ID.
+
| ''(Optional)'' When the player warps and the music changes, whether to silence the music and play the ambience (if any) until the next warp (similar to the default valley locations). Default false.
 
|-
 
|-
| <code>ContainsId(id, minCount)</code>
+
| <samp>Music</samp>
| Get whether the inventory contains items with the given qualified or unqualified item ID, and their combined stack size is at least <samp>minCount</samp>.
+
| ''(Optional)'' A list of [[#Custom audio|cue IDs]] to play before noon in this location unless it's raining, there's a <samp>Music</samp> map property, or the context has a <samp>DefaultMusic</samp> value. If multiple values are specified, the game will play one per day in sequence.
 +
 
 +
This consists of a list of models with these fields:
 +
{| class="wikitable"
 +
|-
 +
! field
 +
! effect
 +
|-
 +
| <samp>Id</samp>
 +
| ''(Optional)'' A [[Modding:Common data field types#Unique string ID|unique string ID]] which identifies this entry within the list. Defaults to the <samp>Track</samp> value.
 +
|-
 +
| <samp>Track</samp>
 +
| The [[Modding:Migrate to Stardew Valley 1.6#Custom audio|audio track ID]] to play.
 
|-
 
|-
| <code>CountId(id)</code>
+
| <samp>Condition</samp>
| Get the combined stack size of all items with the given qualified or unqualified item ID.
+
| ''(Optional)'' A [[Modding:Game state queries|game state query]] which indicates whether this entry applies. Default true.
 +
|}
 
|-
 
|-
| <code>GetById(id)</code>
+
| <samp>DayAmbience</samp><br /><samp>NightAmbience</samp>
| Get a list of items in the inventory with the given qualified or unqualified item ID.
+
| ''(Optional)'' The [[#Custom audio|cue ID]] for the background ambience to play when there's no music active, depending on the [[Day Cycle|time of day]]. Both default to none.
 
|-
 
|-
| <code>ReduceId(id, count)</code>
+
| <samp>PlayRandomAmbientSounds</samp>
| Remove the given number of items matching the given qualified or unqualified item ID. This reduces the stack size for matching items until a total of <samp>count</samp> have been removed, and clears any slots which reach a stack size of zero.
+
| ''(Optional)'' Whether to play random outdoor ambience sounds depending on factors like the season and time of day (e.g. birds, crickets, and mysterious groan sounds in the rain). This is unrelated to the <samp>DayAmbience</samp> and <samp>NightAmbience</samp> fields. Default true.
|}</li>
+
|}
<li>Many common operations have been unified, so previously player-only methods can now be used with chests too.</li>
+
</dd>
<li>It has an internal index by item ID, so operations like <code>items.ContainsId("(O)128")</code> are much more efficient since they no longer iterate the list.</li>
  −
</ul>
  −
 
  −
This replaces some previous methods:
      +
<dt>Advanced:</dt>
 +
<dd>
 
{| class="wikitable"
 
{| class="wikitable"
 
|-
 
|-
! game class
+
! field
! old code
+
! effect
! migration
   
|-
 
|-
|rowspan="6"| <samp>Farmer</samp>
+
| <samp>CustomFields</samp>
| <code>getItemCount(id)</code><br /><code>GetTallyOfObject(id)</code><br /><code>GetTallyOfObject(id, isBigCraftable)</code><br /><code>hasItemInInventory(id, count)</code><br /><code>hasItemInList(list, id, count)</code>
+
| The [[#Custom data fields|custom fields]] for this entry.
| &#32;
+
|}
* To check an item ID, use <code>items.CountId(id)</code> or <code>Items.ContainsId(id, count)</code>.
+
</dd>
* To check Golden Walnuts or Qi Gems, use the <samp>Game1.netWorldState.Value.GoldenWalnuts</samp> and <samp>Farmer.QiGems</samp> fields.
+
</dl>
* To check category matches or <samp>-777</samp> (seasonal wild seeds), the <samp>getItemCount</samp> and <samp>getItemCountInList</samp> still exist.
+
 
|-
+
===Custom garbage cans===
| <code>hasItemInInventoryNamed(name)</code><br /><code>hasItemWithNameThatContains(name)</code>
+
{{/doc status|a new doc page|done=false}}
| In most cases, you should match items by ID instead (see the previous row).
+
 
 +
====Format====
 +
You can now add or edit [[Garbage Can|garbage cans]] on any map by editing the new <samp>Data/GarbageCans</samp> asset (see examples below).
   −
If you really need to match items by name, you can replace it like this:
+
The asset consists of a data model with these fields:
<syntaxhighlight lang="c#">
  −
// exact name
  −
bool hasMatch = Game1.player.Items.Any(item => item?.Name == name);
     −
// name contains
+
{| class="wikitable"
bool hasMatch = Game1.player.Items.Any(item => item?.Name?.Contains(name) is true);
  −
</syntaxhighlight>
   
|-
 
|-
| <code>areAllItemsNull()</code>
+
! field
| Use <code>!items.HasAny()</code>.
+
! effect
 
|-
 
|-
| <code>numberOfItemsInInventory()</code>
+
| <samp>DefaultBaseChance</samp>
| Use <code>items.CountItemStacks()</code> to count all items, or <code>Items.Count(p => p is Object)</code> to match this method's actual behavior.
+
| The probability that an item will be found when searching garbage cans, as a value between 0 (never) and 1 (always). If the probability check fails, only items that set <samp>IgnoreBaseChance</samp> can spawn. This can be overridden by the per-garbage-can <samp>BaseChance</samp> field. Default 0.2.
 
|-
 
|-
| <code>consumeObject(id, count)</code>
+
| <samp>BeforeAll</samp><br /><samp>AfterAll</samp>
| Use <code>items.ReduceId(id, count)</code>.
+
| The items to prepend (<samp>BeforeAll</samp>) or append (<samp>AfterAll</samp>) to the <samp>GarbageCans</samp> → <samp>Items</samp> field for all garbage cans. These work exactly like the items in that field (e.g. subject to the garbage can's base chance).
 
|-
 
|-
| <code>removeItemsFromInventory(id, count)</code>
+
| <samp>GarbageCans</samp>
| &#32;
+
| The data for individual garbage cans. This consists of a string → model lookup with these fields:
* To remove an item by ID, use <code>items.ReduceId(id, count)</code>.
+
 
* To deduct Golden Walnuts or Qi Gems, change the <samp>Game1.netWorldState.Value.GoldenWalnuts</samp> and <samp>Farmer.QiGems</samp> fields.
+
{| class="wikitable"
 
|-
 
|-
|rowspan="2"| <samp>Object</samp>
+
! field
| <code>ConsumeInventoryItem(player, id, count)</code>
+
! effect
| This was somewhat specialized and shouldn't be called by mod code, but the equivalent would be <code>(Object.autoLoadChest ?? player.items).ReduceId(id, count)</code>. See also notes for <samp>Farmer.removeItemsFromInventory</samp>.
+
|-
 +
| ''entry key''
 +
| The [[Modding:Common data field types#Unique string ID|unique string ID]] for this garbage can.
 +
|-
 +
| <samp>BaseChance</samp>
 +
| ''(Optional)'' If set, overrides the root <samp>DefaultBaseChance</samp> field for this garbage can. Defaults to <samp>DefaultBaseChance</samp>.
 
|-
 
|-
| <code>GetTallyOfObject(player, id)</code>
+
| <samp>Items</samp>
| This was somewhat specialized and shouldn't be called by mod code, but the equivalent would be <code>(Object.autoLoadChest ?? player.items).CountId(id)</code>. See also notes for <samp>Farmer.getTallyOfObject</samp>.
+
| ''(Optional)'' The items to try spawning when the player searches the garbage can. The first matching item in <samp>BeforeAll</samp> + <samp>Items</samp> + <samp>AfterAll</samp> will be spawned, and any further items will be ignored. Defaults to none.
|}
  −
 
  −
It implements a new <samp>IInventory</samp> interface, which lets mods pass their own implementations to code which works on inventories.
  −
 
  −
===Furniture changes===
  −
{{/doc status|[[Modding:Items#Furniture]]|done=false}}
  −
 
  −
<ul>
  −
<li>[[Modding:Items#Furniture|<samp>Data/furniture</samp>]] no longer has language variants. Translations were moved into <samp>Strings/Furniture</samp>.</li>
  −
<li>
  −
There are a few changes in [[Modding:Items#Furniture|<samp>Data/furniture</samp>]]:
  −
<ul>
  −
<li>Field index 6 is now placement restrictions and field index 7 is now display name. The display name field is no longer omitted in English.</li>
  −
<li>Field index 7 (display name) now allows [[Modding:Tokenizable strings|tokenizable strings]].</li>
  −
<li>Added new fields:
      +
This consists of a list of models with these fields:
 
{| class="wikitable"
 
{| class="wikitable"
 
|-
 
|-
! index
   
! field
 
! field
 
! effect
 
! effect
 
|-
 
|-
| 8
+
| ''common fields''
| sprite index
+
| See [[Modding:Item queries#Item spawn fields|item spawn fields]] for the generic item fields supported by garbage cans.
| The sprite index within the spritesheet texture to draw.
+
 
 +
If set to an [[Modding:Item queries|item query]] which returns multiple items, one of them will be selected at random.
 
|-
 
|-
| 9
+
| <samp>IgnoreBaseChance</samp>
| texture
+
| ''(Optional)'' Whether this item can spawn even if the <samp>BaseChance</samp> probability check didn't pass. Default false.
| ''(Optional)'' The asset name of the texture to draw. Defaults to <samp>TileSheets/furniture</samp>.
   
|-
 
|-
| 10
+
| <samp>IsMegaSuccess</samp>
| off limits for random sale
+
| ''(Optional)'' Whether to treat this item as a 'mega success' if it's selected, which plays a special <samp>crit</samp> sound and bigger animation. Default false.
| ''(Optional)'' Whether to prevent this furniture from appearing in randomly generated shop stocks and the furniture catalogue. Default false.
   
|-
 
|-
| 11
+
| <samp>IsDoubleMegaSuccess</samp>
| context tags
+
| ''(Optional)'' Whether to treat this item as an 'double mega success' if it's selected, which plays an explosion sound and dramatic animation. Default false.
| ''(Optional)'' A space-delimited list of [[Modding:Items#Context tags|context tags]] which apply to this furniture. Default none.
  −
|}</li>
  −
</ul>
  −
</li>
  −
</ul>
  −
 
  −
===Other item changes for C# mods===
  −
* Placed object changes:
  −
** Every placed object now has a <samp>Location</samp> property set to the location which contains it. This removes location parameters from many object methods.
  −
** Setting an object's tile position through <samp>obj.TileLocation</samp> now recalculcates its collision box automatically. (Setting it through the <samp>tileLocation</samp> net field directly won't though.)
  −
** The <samp>obj.IsScarecrow()</samp> and <samp>GetScarecrowRadius()</samp> methods now work for non-bigcraftable objects too.
  −
* Clothing changes:
  −
** <samp>Clothes.clothesType</samp> is now an enum field.
  −
** Clothing is no longer gender-specific. This renames <samp>indexInTileSheetMale</samp> to <samp>indexInTileSheet</samp>, obsoletes <samp>indexInTileSheetFemale</samp>, and converts gender-variant clothing into regular items.
  −
** Removed unused <samp>ClothesType.ACCESSORY</samp> value.
  −
** <samp>Farmer.pants</samp> and <samp>Farmer.shirt</samp> now store the item ID instead of the sprite index.
  −
** In <samp>Data/TailoringRecipes</samp>, added a <samp>CraftingIdFeminine</samp> field which overrides <samp>CraftingId</samp> for female characters.
  −
* Crop changes:
  −
** Added <samp>Game1.cropData</samp> to read crop info without constantly reloading the <samp>Data/Crops</samp> asset.
  −
** Removed most crop fields which only mirror the data (like <samp>harvestMethod</samp> or <samp>seasonsToGrowIn</samp>). Mods can get the info through <samp>crop.GetData()</samp> instead.
  −
** Partly de-hardcoded fertilizer logic. Almost all fertilizer logic is now centralized into a new patchable set of <samp>HoeDirt</samp> methods (see list below). The only fertilizer logic that's still embedded elsewhere is the interaction errors in <samp>Utility.tryToPlaceItem</samp>.
  −
** HoeDirt.fertilizer.Value is now set to <samp>null</samp> when there is no fertilizer. Both qualified and unqualified IDs should be expected.
  −
** Removed <samp>crop.InferSeedIndex()</samp>. This was used to support old crops, which are now fixed by a save migration instead.
  −
* Tool changes:
  −
** Fixed various logic not handling custom tool upgrade levels.
  −
<ul>
  −
<li>Other item logic:<ul>
  −
<li>Simplified the constructors for many item types, particularly <samp>Object</samp>.</li>
  −
<li>[[Honey]] items now have their <samp>preserve</samp> field set to a new <samp>Honey</samp> type (instead of null).</li>
  −
<li>The <samp>Object.performObjectDropInAction</samp> method now applies the <samp>probe</samp> argument much more consistently. This only affects method calls with <samp>probe: true</samp>.</li>
  −
<li>The <samp>Item.salePrice()</samp> method now has option to get the price without [[Multiplayer#Profit margins|profit margins]].</li>
  −
<li>Added new fields & methods:
  −
 
  −
{| class="wikitable"
   
|-
 
|-
! type
+
| <samp>AddToInventoryDirectly</samp>
! field/method
+
| ''(Optional)'' Whether to add the item to the player's inventory directly, opening an item grab menu if they don't have room in their inventory. If false, the item will be dropped on the ground next to the garbage can instead. Default false.
! effect
   
|-
 
|-
| <samp>Chest</samp>
+
| <samp>CreateMultipleDebris</samp>
| <samp>GetItemsForPlayer()</samp>
+
| ''(Optional)'' Whether to split the spawned item into multiple stacks which each have a stack size of one. This has no effect if <samp>AddToInventoryDirectly</samp> is enabled. Default false.
| Shortcut for <samp>chest.GetItemsForPlayer(Game1.player.UniqueMultiplayerID)</samp>.
+
|}
 +
|}
 +
 
 +
If the garbage can being searched doesn't have its own entry under <samp>GarbageCans</samp>, the game will just use the <samp>BeforeAll</samp> and <samp>AfterAll</samp> fields.
 
|-
 
|-
| rowspan="2"| <samp>Crop</samp>
+
| <samp>CustomFields</samp>
| <samp>GetHarvestMethod()</samp>
+
| The [[#Custom data fields|custom fields]] for this entry.
| Get the method used to harvest the crop (one of <samp>HarvestMethod.Grab</samp> or <samp>HarvestMethod.Scythe</samp>).
+
|}
|-
  −
| <samp>IsInSeason(location)</samp>
  −
| Whether the crop can grow in the location's current season (or true if crops ignore seasons in the location, like the [[greenhouse]]).
  −
|-
  −
| rowspan="8"| <samp>HoeDirt</samp>
  −
| <samp>HasFertilizer()</samp>
  −
| Get whether the dirt has any fertilizer applied.
  −
|-
  −
| <samp>CanApplyFertilizer(itemId)</samp>
  −
| Get whether a player can apply the given fertilizer to this dirt.
  −
|-
  −
| <samp>CheckApplyFertilizerRules(itemId)</samp>
  −
| Get whether a player can apply the given fertilizer to this dirt, and the reason they can't if applicable.
  −
|-
  −
| <samp>GetFertilizerSpeedBoost()</samp>
  −
| Get the crop growth speed boost from fertilizers applied to this dirt.
  −
|-
  −
| <samp>GetFertilizerWaterRetentionChance()</samp>
  −
| Get the water retention chance from fertilizers applied to this dirt, as a value between 0 (no change) and 1 (100% chance of staying watered).
  −
|-
  −
| <samp>GetFertilizerQualityBoostLevel()</samp>
  −
| Get the quality boost level from fertilizers applied to this dirt, which influences the chance of producing a higher-quality crop.
  −
|-
  −
| <samp>GetFertilizerSourceRect()</samp>
  −
| Get the pixel area within the dirt spritesheet to draw for any fertilizer applied to this dirt.
     −
(This method existed before, but no longer requires the fertilizer ID argument.)
+
====Example new garbage can====
|-
+
You can add garbage cans using only [[Modding:Content Patcher|Content Patcher]] or [[Modding:Modder Guide/APIs/Content|SMAPI's content API]]. For example, this content pack adds a new garbage can entry with the ID <samp>Example.ModId_Carpenter</samp>:
| <samp>isWatered()</samp>
+
 
| Get whether the dirt is currently watered.
+
{{#tag:syntaxhighlight|<nowiki>
|-
  −
|rowspan="5"| <samp>Item</samp>
  −
| <samp>IsRecipe</samp><br /><samp>Quality</samp><br /><samp>Stack</samp></samp><br /><samp>sellToStorePrice(…)</samp>
  −
| Equivalent to the previous <samp>Object</samp> fields/methods, to simplify common code and avoid needing to special-case <samp>Object</samp> items.
  −
|-
  −
| <samp>appliesProfitMargins()</samp>
  −
| Get whether this item should apply [[Multiplayer#Profit margins|profit margins]] to shop prices.
  −
|-
  −
| <samp>CanBeLostOnDeath()</samp>
  −
| Get whether this item can be lost when the player dies, so it can be recovered from the [[Adventurer's Guild#Item Recovery Service|item recovery service]].
  −
|-
  −
| <samp>HasTypeId(id)</samp><br /><samp>HasTypeObject()</samp><br /><samp>HasTypeBigCraftable()</samp>
  −
| Get whether the item has the given [[#Custom items|type definition ID]]. These are null-safe and double as a null check:
  −
<syntaxhighlight lang="c#">
  −
if (item.HasTypeId(ItemRegistry.type_object))
   
{
 
{
     // item is non-null and has type (O)
+
     "Format": "</nowiki>{{Content Patcher version}}<nowiki>",
}
+
    "Changes": [
</syntaxhighlight>
+
        {
<samp>HasTypeObject()</samp> and <samp>HasTypeBigCraftable()</samp> are shortcuts for passing <samp>ItemRegistry.type_object</samp> and <samp>ItemRegistry.type_bigCraftable</samp> respectively.
+
            "Action": "EditData",
|-
+
            "Target": "Data/GarbageCans",
| <samp>TryGetTempData</samp><br /><samp>SetTempData</samp>
+
            "TargetField": [ "GarbageCans" ],
| Get or set temporary item info that's not synchronized in multiplayer or written to the save file.
+
            "Entries": {
 +
                "{{ModId}}_Carpenter": {
 +
                    "Items": [
 +
                        // 25% chance of pufferfish
 +
                        {
 +
                            "ID": "{{ModId}}_Pufferfish",
 +
                            "Condition": "RANDOM 0.25",
 +
                            "ItemId": "(O)128"
 +
                        },
   −
For example, the game uses this to pass spawn options to the fishing minigame:
+
                        // else guaranteed random House Plant item
<syntaxhighlight lang="c#">
+
                        {
if (spawn.IsBossFish)
+
                            "ID": "{{ModId}}_RandomHousePlant",
    fish.SetTempData(nameof(spawn.IsBossFish), true);
+
                            "ItemID": "RANDOM_ITEMS (F) 1376 1390"
 +
                        }
 +
                    ]
 +
                }
 +
            }
 +
        }
 +
    ]
 +
}</nowiki>|lang=javascript}}
 +
 
 +
Then you'd place an <code>Action: Garbage Example.ModId_Carpenter</code> [[Modding:Maps|map tile property]] to mark a tile as a garbage can using this data.
   −
...
+
====Example change for existing garbage can====
 +
You can edit an existing garbage cans using only [[Modding:Content Patcher|Content Patcher]] or [[Modding:Modder Guide/APIs/Content|SMAPI's content API]]. For example, this content pack adds pufferfish to the Saloon garbage can, and moves it above the dish of the day.
   −
fish.TryGetTempData(nameof(SpawnFishData.IsBossFish), out bool bossFish);
+
Note that this uses <samp>TargetField</samp> to 'move into' the item list for the saloon, and then treat those items as the entry list being edited. Specifying an ID which isn't in the list will add a new entry, just like when editing a regular list asset.
</syntaxhighlight>
  −
|-
  −
| <samp>FishingRod</samp>
  −
| <samp>CanUseBait()</samp><br /><samp>CanUseTackle()</samp><br /><samp>GetBait()</samp><br /><samp>GetTackle()</samp><br /><samp>HasMagicBait()</samp><br /><samp>HasCuriosityLure()</samp>
  −
| Simplifies working with the fishing rod's [[bait]] and [[tackle]].
  −
|-
  −
|rowspan="2"| <samp>Furniture</samp>
  −
| <samp>SetPlacement</samp><br /><samp>SetHeldObject</samp>
  −
| Set the furniture's position and rotation (<samp>SetPlacement</samp>) or held object (<samp>SetHeldObject</samp>). The latter will initialize the held object's tile position to match the furniture instance.
     −
These are used by the game to initialize furniture in one go. For example:
+
{{#tag:syntaxhighlight|<nowiki>
<syntaxhighlight lang="c#">
+
{
// oak table holding decorative bowl
+
    "Format": "</nowiki>{{Content Patcher version}}<nowiki>",
Furniture table = ItemRegistry
+
    "Changes": [
    .Create<Furniture>("(F)1120")
+
        {
    .SetPlacement(5, 4, 0)
+
            "Action": "EditData",
     .SetHeldObject(ItemRegistry.Create<Furniture>("(F)1364"));
+
            "Target": "Data/GarbageCans",
</syntaxhighlight>
+
            "TargetField": [ "GarbageCans", "Saloon", "Items" ],
|-
+
            "Entries": {
| <samp>IsTable()</samp>
+
                // 25% chance of pufferfish
| Get whether this furniture is a table.
+
               
 +
                "{{ModId}}_Pufferfish":{
 +
                    "ID": "{{ModId}}_Pufferfish",
 +
                    "Condition": "RANDOM 0.25",
 +
                    "ItemId": "(O)128"
 +
                }
 +
            },
 +
            "MoveEntries": [
 +
                { "ID": "{{ModId}}_Pufferfish", "BeforeId": "Base_DishOfTheDay" }
 +
            ]
 +
        }
 +
     ]
 +
}</nowiki>|lang=javascript}}
 +
 
 +
====Changes for C# mods====
 +
Previously garbage cans were tracked by <samp>Town.garbageChecked</samp>, an array of boolean fields. That approach doesn't work in Stardew Valley 1.6, since we're no longer limited to a specific set of garbage cans in the town map. This has been replaced by <samp>Game1.netWorldState.Value.CheckedGarbage</samp>, which is a hash set of garbage can IDs.
 +
 
 +
To migrate code:
 +
{| class="wikitable"
 
|-
 
|-
|rowspan="2"| <samp>FruitTree</samp>
+
! action
| <samp>GetQuality()</samp>
+
! code in 1.5.6
| Get the quality of fruit currently being produced by the fruit tree.
+
! code in 1.6
 
|-
 
|-
| <samp>TryAddFruit()</samp>
+
| check if a garbage can was searched
| Add a fruit item to the tree based on [[#Custom fruit trees|its data]].
+
| <syntaxhighlight lang="js">
 +
Town town = (Town)Game1.getLocationFromName("Town");
 +
if (town.garbageChecked[5])
 +
  ...
 +
</syntaxhighlight>
 +
| <syntaxhighlight lang="js">
 +
if (Game1.netWorldState.Value.CheckedGarbage.Contains("Saloon"))
 +
  ...
 +
</syntaxhighlight>
 
|-
 
|-
| <samp>IndoorPot</samp>
+
| mark a garbage can searched
| <samp>Water()</samp>
+
| <syntaxhighlight lang="js">
| Simplifies watering dirt in the [[Garden Pot|garden pot]].
+
Town town = (Town)Game1.getLocationFromName("Town");
|-
+
town.garbageChecked[5] = true;
| <samp>Object</samp>
+
</syntaxhighlight>
| <samp>GetBoundingBox()</samp><br /><samp>GetBoundingBoxAt(x, y)</samp>
+
| <syntaxhighlight lang="js">
| Get the pixel collision area for the item placed in the world. These replace the former <samp>getBoundingBox(position)</samp> method.
+
Game1.netWorldState.Value.CheckedGarbage.Add("Saloon");
 +
</syntaxhighlight>
 +
|}
 +
 
 +
To migrate former vanilla trash can IDs:
 +
{| class="wikitable"
 +
|-
 +
! position
 +
! ID in 1.5.6
 +
! ID in 1.6
 +
|-
 +
| Near [[Jodi]] and [[Kent]]'s house
 +
| <code>0</code>
 +
| <code>JodiAndKent</code>
 
|-
 
|-
| <samp>Tool</samp>
+
| Near [[Emily]] and [[Haley]]'s house
| <samp>isScythe()</samp>
+
| <code>1</code>
| Equivalent to the previous <samp>MeleeWeapon</samp> method, to simplify common code and avoid needing to special-case <samp>MeleeWeapon</samp> items.
+
| <code>EmilyAndHaley</code>
 
|-
 
|-
|rowspan="3"| <samp>Tree</samp>
+
| Near [[Lewis]]' house
| <samp>CheckForNewTexture()</samp>
+
| <code>2</code>
| Reset the tree's texture if it would change based on [[#Custom wild trees|its data]].
+
| <code>Mayor</code>
 
|-
 
|-
| <samp>GetMaxSizeHere</samp>
+
| Near [[Museum]]
| Get the maximum size the tree can grow in its current position (e.g. accounting for nearby trees blocking growth).
+
| <code>3</code>
 +
| <code>Museum</code>
 
|-
 
|-
| <samp>IsGrowthBlockedByNearbyTree</samp>
+
| Near [[Blacksmith|Clint's blacksmith]]
| Get whether growth is blocked because it's too close to another fully-grown tree.
+
| <code>4</code>
|}
+
| <code>Blacksmith</code>
</li>
+
|-
<li>Modularized <samp>Object.CheckForAction</samp> to simplify mod patches.</li>
+
| Near [[The Stardrop Saloon|the Saloon]]
<li>Reworked <samp>Item.getOne()</samp> implementation to avoid common pitfalls. (This only affects mods with custom item classes, or which patch <samp>Item.getOne</samp> or <samp>Item._GetOneFrom</samp>.)</li>
+
| <code>5</code>
<li>Fixed fruit trees forgetting the growth stage set in their constructor when they're updated overnight.</li>
+
| <code>Saloon</code>
</ul>
+
|-
 
+
| Near [[Evelyn]] and [[George]]'s house
===Other item changes===
+
| <code>6</code>
* Added per-object display names (''e.g.'' for custom flavored items). See the <samp>ObjectDisplayName</samp> [[Modding:Item queries#Item spawn fields|item spawn field]], or <samp>object.displayNameFormat</samp> in C#.
+
| <code>Evelyn</code>
* [[Ginger Island#Gem Birds|Item pedestals]] are now normal item, so you can spawn them using a mod like CJB Item Spawner to display items.
+
|-
* Added optional <samp>Condition</samp> [[Modding:Game state queries|game state query]] field to <samp>Data/SpecialOrders</samp>.
+
| Near [[JojaMart]]
* Item data changes:
+
| <code>7</code>
** The display name field now exists in English too for <samp>Data/Boots</samp>, <samp>Data/Bundles</samp>, <samp>Data/CookingRecipes</samp>, <samp>Data/CraftingRecipes</samp>, <samp>Data/Furniture</samp>, <samp>Data/Hats</samp>, and <samp>Data/Weapons</samp>.
+
| <code>JojaMart</code>
** The randomly spawned [[The Farm#Stone|stones]], [[The Farm#Wood|twigs]], and [[weeds]] have been formalized into ''litter''. They all now have object type <samp>Litter</samp>, [[Modding:Items#Categories|category]] -999 (<samp>StardewValley.Object.litterCategory</samp>), a relevant display name/description (like ''Gold Stone'' & ''Break apart to obtain gold ore'' instead of ''Stone'' & ''...''), a price of 0 (not sellable), and edibility of -300 (inedible). This also adds all mine ore nodes to <samp>Data/Objects</samp>, so the game no longer creates invalid items to show their sprite. (Doing so in 1.6 will now show an Error Item sprite instead.)
+
|}
** [[Honey]] items now have the <samp>honey_item</samp> context tag.
  −
** Shirts no longer have a dynamic numeric ID range; every valid shirt is now listed in [[#Custom shirts|<samp>Data/Shirts</samp>]].
  −
** You can now apply a custom buff ID when the item is eaten, via <samp>Data/Objects</samp>'s <samp>Buff</samp> field.
  −
** The type field in <samp>Data/Objects</samp> is no longer checked using substring matching (e.g. the game now uses <code>data.Type == "Fish"</code> instead of <code>typeAndCategory.Contains("Fish")</code>), which may impact mods which depended on that undocumented behavior.
  −
* Crop changes:
  −
** Paddy crops now recheck for nearby water each day, so they'll update if you add/remove a building with water or change the map layout.
  −
** In <samp>Data/Crops</samp>, each harvest option is now self-contained. For example, you can set <samp>HarvestMinStack</samp> without <samp>ExtraHarvestChance</samp>.
  −
* Fish changes:
  −
** <samp>Data/Fish</samp> is no longer translated, so there's only one <samp>Data/Fish.xnb</samp> field. Fish display names are now taken from <samp>Data/Objects</samp>.
  −
** Added a new field (index 13) in <samp>Data/Fish</samp>, which sets whether the fish can be selected for the first-catch tutorial.
  −
* Recipe changes in <samp>Data/CookingRecipes</samp> and <samp>Data/CraftingRecipes</samp>:
  −
** These assets no longer have language variants.
  −
** The display name now supports [[Modding:Tokenizable strings|tokenizable strings]].
  −
** The display name can now be left blank to get it from the first item in the output list.
  −
* Other item logic:
  −
** Missing recipes that should already be unlocked are now added to the player automatically on save load.
  −
** <samp>Data/Bundles</samp> is now loaded later, so content packs can edit it reliably.</samp>
  −
** Chests with <samp>fridge: true</samp> are now treated as mini-fridges for the cooking menu.
  −
** Gift boxes can now contain multiple items.
  −
** Fixed furniture drawn over sitting players if it has no front texture.
  −
** Fixed tool being upgraded by Clint not affected by recursive item search logic.
  −
** Fixed <samp>tool.getOne()</samp> not copying the tool name.
  −
** Fixed cooking menu constantly creating hovered item if the item/recipe names don't match.
     −
==What's new for locations & weather==
+
===Custom map actions===
===Custom locations===
+
{{/doc status|[[Modding:Maps#Custom_Actions]]|done=true}}
{{/doc status|[[Modding:Location data]]|done=true}}
     −
You can now add/edit locations by editing the revamped <samp>Data/Locations</samp> asset. This makes nearly everything in the location configurable — display name, default warp arrival tile, how the location is created, artifact spots / fish / forage / weeds, music, etc.
+
C# mods can now handle custom <samp>Action</samp> & <samp>TouchAction</samp> [[Modding:Maps|map properties]] by calling <samp>GameLocation.RegisterTileAction</samp> & <samp>RegisterTouchAction</samp>, and passing a callback which receives the location, map property arguments, player who activated it, and tile position.
 +
 
 +
For example, let's say you want a locked gate which needs a custom key item. You can add a regular <code>TouchAction Example.ModId_UnlockGate</code> map property (e.g. by adding it directly in the map file, or using [[Modding:Content Patcher|Content Patcher]]'s <samp>EditMap</samp>, or using the [[Modding:Modder Guide/APIs/Content|content API]]). Then you can just handle the logic from your C# mod. See the updated docs for an example.
 +
 
 +
As another example, let's say you want the gate to unlock when the player presses the action key. You can add a regular <code>Action Example.ModId_UnlockGate</code> map property (e.g. by adding it directly in the map file, or using [[Modding:Content Patcher|Content Patcher]]'s <samp>EditMap</samp>, or using the [[Modding:Modder Guide/APIs/Content|content API]]). Then you can just handle the logic from your C# mod. See the updated docs for an example.
 +
 
 +
===Custom map layers===
 +
{{/doc status|[[Modding:Maps]]|done=true}}
   −
See [[Modding:Location data]] for docs on the new data format.
+
You can now add any number of [[Modding:Maps|map layers]] by suffixing a vanilla layer name (i.e. <samp>Back</samp>, <samp>Buildings</samp>, <samp>Front</samp>, or <samp>AlwaysFront</samp>) with an offset. For example, <samp>Back-1</samp> will be drawn before/under <samp>Back</samp>, and <samp>Back2</samp> will be drawn after/over it. You can increment the number to add more layers.
   −
===Custom location contexts===
+
This only affects layer rendering. Tile properties must still be set on the original layers.
{{/doc status|[[Modding:Location data]] or a new doc page|done=false}}
     −
====Vanilla contexts====
+
===Custom minecarts===
* The game previously had two hardcoded location context enums: <samp>Default</samp> (for the valley) and <samp>Island</samp> (for [[Ginger Island]]). These have been replaced with data models which define the location context settings, loaded from the <samp>Data/LocationContexts</samp> asset.
+
{{/doc status|a new doc page|done=false}}
* [[The Desert|The desert]] is now part of a new <samp>Desert</samp> context (instead of <samp>Default</samp>). Some of the previously hardcoded desert logic (like always sunny weather) is now just part of the context data in <samp>Data/LocationContexts</samp>.
     −
====Format====
+
You can now extend [[minecart]]s by editing the <samp>Data\Minecarts</samp> data asset.
Custom contexts can be created by editing the new <samp>Data/LocationContexts</samp> asset, and setting the context name in the location's <samp>LocationContext</samp> [[Modding:Maps|map property]].
     −
The data asset consists of a string → model lookup, where the key matches the <samp>Name</samp> field and the value is a model with these fields:
+
This consists of a string → model lookup, where...
 +
* The key is a [[Modding:Common data field types#Unique string ID|unique string ID]] for the minecart network. When you interact with a minecart, the destinations listed for its network are shown.
 +
* The value is a model with the fields listed below.
   −
<dl style="margin-left: 2em;">
  −
<dt>Required fields:</dt>
  −
<dd>
   
{| class="wikitable"
 
{| class="wikitable"
 
|-
 
|-
Line 1,520: Line 1,394:  
! effect
 
! effect
 
|-
 
|-
| <samp>Name</samp>
+
| <samp>Destinations</samp>
| The [[Modding:Common data field types#Unique string ID|unique string ID]] for the location context.
+
| The destinations which the player can travel to from minecarts in this network. This consists of a list of model with these fields:
|}
  −
</dd>
  −
 
  −
<dt>Player actions:</dt>
  −
<dd>
   
{| class="wikitable"
 
{| class="wikitable"
 
|-
 
|-
Line 1,532: Line 1,401:  
! effect
 
! effect
 
|-
 
|-
| <samp>AllowRainTotem</samp>
+
| <samp>Id</samp>
| ''(Optional)'' Whether a [[Rain Totem|rain totem]] can be used to force rain in this context tomorrow. If false, using a rain totem here will show a "''this item can't be used here''" message instead.
+
| A [[Modding:Common data field types#Unique string ID|unique string ID]] for this destination within the network.
 
|-
 
|-
| <samp>RainTotemAffectsContext</samp>
+
| <samp>DisplayName</samp>
| ''(Optional)'' If set, using a rain totem here will change the weather in the given context ID. For example, rain totems in the desert change weather in the valley.
+
| A [[Modding:Tokenizable strings|tokenizable string]] for the destination name shown in the minecart menu. You can use the location's display name with the <samp>LocationName</samp> token (like <code>[LocationName Desert]</code> for the [[desert]]).
 
|-
 
|-
| <samp>MaxPassOutCost</samp>
+
| <samp>TargetLocation</samp>
| ''(Optional)'' When the player passes out (due to [[energy|exhaustion]] or at 2am) in this context, the maximum amount of [[gold]] lost. If omitted or set to <samp>-1</samp>, uses the same value as the <samp>Default</samp> context ({{price|1000}} by default).
+
| The [[#Custom locations|location ID]] for the destination.
 
|-
 
|-
| <samp>PassOutMail</samp>
+
| <samp>TargetTile</samp>
| ''(Optional)'' When the player passes out (due to [[energy|exhaustion]] or at 2am) in this context, the possible [[Modding:Mail data|letter IDs]] to add to their mailbox (if they haven't received it before). If multiple letters are valid, one will be chosen randomly (unless one specifies <samp>SkipRandomSelection</samp>).
+
| The destination tile position within the location, specified as a model with <samp>X</samp> and <samp>Y</samp> fields.
 
  −
This consists of a list of models with these fields:
  −
{| class="wikitable"
   
|-
 
|-
! field
+
| <samp>TargetDirection</samp>
! effect
+
| The direction the player should face after arrival (one of <samp>down</samp>, <samp>left</samp>, <samp>right</samp>, or <samp>up</samp>).
 
|-
 
|-
| <samp>Id</samp>
+
| <samp>Condition</samp>
| The [[Modding:Common data field types#Unique string ID|unique string ID]] for this entry in the list.
+
| ''(Optional)'' A [[Modding:Game state queries|game state query]] which indicates whether this minecart destination is available. Defaults to always available.
 
|-
 
|-
| <samp>Mail</samp>
+
| <samp>Price</samp>
| The [[Modding:Mail data|letter ID]] to add.
+
| ''(Optional)'' The gold price that must be paid each time to use this destination. Default none.
 
  −
The game will look for an existing letter ID in <samp>Data/mail</samp> in this order (where {{t|billed}} is <samp>Billed</samp> if they lost [[gold]] or <samp>NotBilled</samp> otherwise, and {{t|gender}} is <samp>Female</samp> or <samp>Male</samp>):
  −
* <samp>{{t|letter id}}_{{t|billed}}_{{t|gender}}</samp>
  −
* <samp>{{t|letter id}}_{{t|billed}}</samp>
  −
* <samp>{{t|letter id}}</samp>
  −
 
  −
If no match is found in <samp>Data/mail</samp>, the game will send <samp>passedOut2</samp> instead.
  −
 
  −
If the mail ID starts with <samp>passedOut</samp>, <samp>{0}</samp> in the letter text will be replaced with the gold amount lost, and it won't appear in the [[collections]] page.
   
|-
 
|-
| <samp>MaxPassOutCost</samp>
+
| <samp>BuyTicketMessage</samp>
| ''(Optional)'' The maximum amount of [[gold]] lost. This is applied after the context's <samp>MaxPassOutCost</samp> (i.e. the context's value is used to calculate the random amount, then this field caps the result). Defaults to unlimited.
+
| ''(Optional)'' If the destination costs money to use, a [[Modding:Tokenizable strings|tokenizable string]] for the purchase confirmation message shown. If present, <code>{0}</code> is replaced with the purchase price. Defaults to the network's <samp>BuyTicketMessage</samp> field.
 
|-
 
|-
| <samp>Condition</samp>
+
| <samp>CustomFields</samp>
| ''(Optional)'' A [[Modding:Game state queries|game state query]] which indicates whether this entry is active. Defaults to always true.
+
| ''(Optional)'' The [[#Custom data fields|custom fields]] for this entry.
 +
|}
 
|-
 
|-
| <samp>SkipRandomSelection</samp>
+
| <samp>UnlockCondition</samp>
| ''(Optional)'' If true, send this mail if the <samp>Condition</samp> matches instead of choosing a random valid mail. Default false.
+
| ''(Optional)'' A [[Modding:Game state queries|game state query]] which indicates whether this minecart network is unlocked. Default always enabled.
|}
   
|-
 
|-
| <samp>PassOutLocations</samp>
+
| <samp>LockedMessage</samp>
| ''(Optional)'' When the player passes out (due to [[energy|exhaustion]] or at 2am) in this context ''and'' they started the day in a different location context, the locations where they'll wake up. (If the player started the day in the same context, they'll wake up in the last bed they slept in instead.)
+
| ''(Optional)'' A [[Modding:Tokenizable strings|tokenizable string]] for the message shown when interacting with a minecart when the <samp>UnlockCondition</samp> false. Defaults to an "''Out of order''" translation.
 
  −
If the selected location doesn't contain a bed and doesn't have the [[#New map properties|<samp>AllowWakeUpWithoutBed</samp> map property]], the player will wake up in the farmhouse instead.
  −
 
  −
This consists of a list of models with these fields:
  −
{| class="wikitable"
   
|-
 
|-
! field
+
| <samp>ChooseDestinationMessage</samp>
! effect
+
| ''(Optional)'' A [[Modding:Tokenizable strings|tokenizable string]] for the message shown when listing destinations to choose from. Defaults to a "''Choose destination:''" translation.
 
|-
 
|-
| <samp>Id</samp>
+
| <samp>BuyTicketMessage</samp>
| The [[Modding:Common data field types#Unique string ID|unique string ID]] for this entry in the list.
+
| ''(Optional)'' When a destination costs money to use, a [[Modding:Tokenizable strings|tokenizable string]] for the purchase confirmation message shown. If present, <code>{0}</code> is replaced with the purchase price. Defaults to a "''Buy a ticket for {0}g?''" translation.
|-
  −
| <samp>Location</samp>
  −
| The internal location name.
  −
|-
  −
| <samp>Position</samp>
  −
| The ''default'' tile position within the location, specified as an object with <samp>X</samp> and <samp>Y</samp> fields. If the location has any bed furniture, they'll be placed in the first bed found instead.
  −
|-
  −
| <samp>Condition</samp>
  −
| ''(Optional)'' A [[Modding:Game state queries|game state query]] which indicates whether this entry is active. Defaults to always applied.
   
|}
 
|}
   −
If no locations are specified or none match, the player will wake up in their bed at home.
+
====Open a minecart menu====
|-
+
You can use an <samp>Action: MinecartTransport {{o|network ID}} {{o|exclude destination ID}}</samp> [[Modding:Maps|map property]] to open the minecart menu. When the player interacts with the tile, it'll open the menu for the {{o|network ID}} network (default <samp>Default</samp>). if {{o|exclude destination ID}} is specified, the matching destination will be hidden from the list (usually because you're at that minecart). For example, the [[Bus Stop|bus stop]] minecart uses <code>Action: MinecartTransport Default Bus</code>.
| <samp>ReviveLocations</samp>
+
 
| ''(Optional)'' If the player just got knocked out in combat, the location names where they'll wake up.
+
From a C# mod, you can call <code>Game1.currentLocation.ShowMineCartMenu(networkId, excludeDestinationId)</code> which works the same way (except that <samp>networkId</samp> is required).
 +
 
 +
====Example====
 +
This [[Modding:Content Patcher|Content Patcher]] content pack adds the [[Railroad]] as a minecart destination, complete with a map edit adding a decorative minecart. It is available after the [[Random Events|Earthquake]] has occurred and minecarts have been unlocked.
   −
This consists of a list of models with these fields:
+
{{#tag:syntaxhighlight|<nowiki>
{| class="wikitable"
+
{
|-
+
    "Format": "</nowiki>{{Content Patcher version}}<nowiki>",
! field
+
    "Changes": [
! effect
+
        // add minecart destination
|-
+
        {
| <samp>Id</samp>
+
            "Action": "EditData",
| The [[Modding:Common data field types#Unique string ID|unique string ID]] for this entry in the list.
+
            "Target": "Data/Minecarts",
|-
+
            "TargetField": [ "Default", "Destinations" ], // for the "Default" network, edit the "Destinations" field
| <samp>Location</samp>
+
            "Entries": {
| The internal location name.
+
                "Railroad": {
|-
+
                    "Id": "Railroad",
| <samp>Position</samp>
+
                    "DisplayName": "[LocationName Railroad]",
| The tile position within the location, specified as an object with <samp>X</samp> and <samp>Y</samp> fields.
+
                    "Condition": "LOCATION_ACCESSIBLE Railroad",
|-
+
 
| <samp>Condition</samp>
+
                    "TargetLocation": "Railroad",
| ''(Optional)'' A [[Modding:Game state queries|game state query]] which indicates whether this entry is active. Defaults to always applied.
+
                    "TargetTile": { "X": 16, "Y": 39 },
|}
+
                    "TargetDirection": "down",
 +
                }
 +
            }
 +
        },
   −
If the selected location has a standard [[Modding:Event data|event]] with the exact key <samp>PlayerKilled</samp> (with no <samp>/</samp> or preconditions in the key), that event will play when the player wakes up and the game will apply the lost items or [[gold]] logic. The game won't track this event, so it'll repeat each time the player is revived. If there's no such event, the player will wake up without an event, and no items or gold will be lost.
+
        // add decorative minecart
 +
        {
 +
            "Action": "EditMap",
 +
            "Target": "Maps/Railroad",
 +
            "FromFile": "assets/Custom_Railroad_Minecart.tmx",
 +
            "ToArea": { "X": 15, "Y": 35, "Width": 4, "Height": 5 }
 +
        }
 +
    ]
 +
}</nowiki>|lang=javascript}}
   −
If no locations are specified or none match, the player will wake up at [[Harvey's Clinic|Harvey's clinic]].
+
===Custom passive festivals===
|}
+
{{/doc status|[[Modding:Festival data]] or a new doc page|done=false}}
</dd>
     −
<dt>Season:</dt>
+
You can now add or modify passive festivals by editing the <samp>Data/PassiveFestivals</samp> asset.
<dd>
+
 
{| class="wikitable"
+
(A ''passive festival'' is a [[festivals|festival]] like the [[Night Market]]. They replace a location for a period of time, the player can enter/leave them anytime, and time continues passing while at the festival.)
|-
  −
! field
  −
! effect
  −
|-
  −
| <samp>SeasonOverride</samp>
  −
| ''(Optional)'' The season which is always active for locations within this context (one of <samp>spring</samp>, <samp>summer</samp>, <samp>fall</samp>, or <samp>winter</samp>). For example, setting <samp>summer</samp> will make it always [[summer]] there regardless of the calendar season. If not set, the calendar season applies.
  −
|}
  −
</dd>
     −
<dt>Weather:</dt>
+
====Data format====
<dd>
+
The <samp>Data/PassiveFestivals</samp> asset consists of a string → model lookup, where...
 +
* The key is a [[Modding:Common data field types#Unique string ID|unique string ID]] for the festival.
 +
* The value is a model with the fields listed below.
 
{| class="wikitable"
 
{| class="wikitable"
 
|-
 
|-
Line 1,648: Line 1,498:  
! effect
 
! effect
 
|-
 
|-
| <samp>WeatherConditions</samp>
+
| <samp>DisplayName</samp>
| ''(Optional)'' The weather logic to apply for locations in this context (ignored if <samp>CopyWeatherFromLocation</samp> is set). Defaults to always sunny. If multiple are specified, the first matching weather is applied.
+
| A [[Modding:Tokenizable strings|tokenizable string]] for the display name shown on the [[calendar]].
 
  −
This consists of a list of models with these fields:
  −
{| class="wikitable"
   
|-
 
|-
! field
+
| <samp>Season</samp>
! effect
+
| The [[season]] when the festival becomes active.
 
|-
 
|-
| <samp>Id</samp>
+
| <samp>StartDay</samp><br /><samp>EndDay</samp>
| The [[Modding:Common data field types#Unique string ID|unique string ID]] for this entry in the list.
+
| The days of month when the festival becomes active.
 
|-
 
|-
| <samp>Weather</samp>
+
| <samp>StartTime</samp>
| The [[#Custom weather|weather ID]] to set.
+
| The time of day when the festival opens each day.
 
|-
 
|-
| <samp>Condition</samp>
+
| <samp>StartMessage</samp>
| ''(Optional)'' A [[Modding:Game state queries|game state query]] which indicates whether to apply the weather. Defaults to always applied.
+
| A [[Modding:Tokenizable strings|tokenizable string]] for the in-game [[wikipedia:Pop-up notification|toast notification]] shown when the festival begins each day.
|}
   
|-
 
|-
| <samp>CopyWeatherFromLocation</samp>
+
| <samp>MapReplacements</samp>
| ''(Optional)'' The <samp>Name</samp> (i.e. unique ID) of the location context from which to inherit weather.
+
| The locations to swap for the duration of the festival. Despite the field name, this swaps '''locations''' (e.g. as added by <samp>CustomLocations</samp> using [[Modding:Content Patcher|Content Patcher]]), and not the location's map asset.
|}
     −
If a [[#Custom passive festivals|passive festival]] is active in any location within this context, the weather is sunny for the entire context regardless of these fields.
+
This is specified as a string → string lookup, where the key is the original location to replace and the value is the new location. Both use the internal location name, as shown by the {{nexus mod|679|Debug Mode}} mod. For example, this swaps the <samp>Beach</samp> location with <samp>BeachNightMarket</samp> during the [[Night Market]]:
 
+
<syntaxhighlight lang="js">
</dd>
+
"MapReplacements": {
 
+
    "Beach": "BeachNightMarket"
<dt>Music:</dt>
+
}
<dd>
+
</syntaxhighlight>
{| class="wikitable"
   
|-
 
|-
! field
+
| <samp>Condition</samp>
! effect
+
| ''(Optional)'' A [[Modding:Game state queries|game state query]] which indicates whether the festival is enabled (subject to the other fields like <samp>StartDay</samp> and <samp>EndDay</samp>). Defaults to always enabled.
 
|-
 
|-
| <samp>DefaultMusic</samp>
+
| <samp>ShowOnCalendar</samp>
| ''(Optional)'' The [[#Custom audio|cue ID]] for the music to play when the player is in the location, unless overridden by a <samp>Music</samp> map property. Despite the name, this has a higher priority than the seasonal music fields below. Ignored if omitted.
+
| ''(Optional)'' Whether the festival appears on the [[calendar]], using the same iridium-star icon as the [[Calendar#Winter|Night Market]]. Default true.
 
|-
 
|-
| <samp>DefaultMusicCondition</samp>
+
| <samp>DailySetupMethod</samp><br /><samp>CleanupMethod</samp>
| ''(Optional)'' A [[Modding:Game state queries|game state query]] which returns whether the <samp>DefaultMusic</samp> field should be applied (if more specific music isn't playing). Defaults to always true.
+
| ''(Optional)'' A C# method which applies custom logic when the day starts (<samp>DailySetupMethod</samp>) and/or overnight after the last day of the festival (<samp>CleanupMethod</samp>).
 +
 
 +
These must be specified in the form <samp>{{t|full type name}}: {{t|method name}}</samp> (like <samp>ExampleMod.Namespace.Type, ExampleMod: MethodName</samp>). The methods must be static, take zero arguments, and return void.
 
|-
 
|-
| <samp>DefaultMusicDelayOneScreen</samp>
+
| <samp>CustomFields</samp>
| ''(Optional)'' When the player warps and the music changes, whether to silence the music and play the ambience (if any) until the next warp (similar to the default valley locations). Default false.
+
| The [[#Custom data fields|custom fields]] for this entry.
|-
+
|}
| <samp>Music</samp>
+
 
| ''(Optional)'' A list of [[#Custom audio|cue IDs]] to play before noon in this location unless it's raining, there's a <samp>Music</samp> map property, or the context has a <samp>DefaultMusic</samp> value. If multiple values are specified, the game will play one per day in sequence.
+
====NPC schedules====
 +
When a passive festival is active, NPCs will check for [[Modding:Schedule data|a schedule entry]] in this order:
   −
This consists of a list of models with these fields:
   
{| class="wikitable"
 
{| class="wikitable"
 
|-
 
|-
! field
+
! syntax
! effect
+
! summary
 
|-
 
|-
| <samp>Id</samp>
+
| <samp>{{t|festival ID}}_{{t|festival day}}</samp>
| ''(Optional)'' A [[Modding:Common data field types#Unique string ID|unique string ID]] which identifies this entry within the list. Defaults to the <samp>Track</samp> value.
+
| Applies on the given date. The {{t|festival day}} is relative, so <samp>1</samp> matches the festival <samp>StartDay</samp>.<br /><small>Example: <samp>NightMarket_3</samp> or <samp>marriage_NightMarket_3</samp></small>
 
|-
 
|-
| <samp>Track</samp>
+
| <samp>{{t|festival ID}}</samp>
| The [[Modding:Migrate to Stardew Valley 1.6#Custom audio|audio track ID]] to play.
+
| Applies if there's no date-specific entry.<br /><small>Example: <samp>NightMarket</samp> or <samp>marriage_NightMarket</samp></small>
|-
  −
| <samp>Condition</samp>
  −
| ''(Optional)'' A [[Modding:Game state queries|game state query]] which indicates whether this entry applies. Default true.
   
|}
 
|}
|-
  −
| <samp>DayAmbience</samp><br /><samp>NightAmbience</samp>
  −
| ''(Optional)'' The [[#Custom audio|cue ID]] for the background ambience to play when there's no music active, depending on the [[Day Cycle|time of day]]. Both default to none.
  −
|-
  −
| <samp>PlayRandomAmbientSounds</samp>
  −
| ''(Optional)'' Whether to play random outdoor ambience sounds depending on factors like the season and time of day (e.g. birds, crickets, and mysterious groan sounds in the rain). This is unrelated to the <samp>DayAmbience</samp> and <samp>NightAmbience</samp> fields. Default true.
  −
|}
  −
</dd>
     −
<dt>Advanced:</dt>
+
If the NPC is married to a player, they'll add a <samp>marriage_</samp> prefix to the keys (like <samp>marriage_{{t|festival ID}}_{{t|festival day}}</samp>) and ignore any entry without the prefix.
<dd>
+
 
{| class="wikitable"
+
===Custom weather===
|-
+
{{/doc status|[[Modding:Weather data]]|done=false}}
! field
+
 
! effect
+
You can now change the weather algorithm by editing [[#Custom location contexts|location context data]], and (with a C# mod) implement custom weathers.
|-
  −
| <samp>CustomFields</samp>
  −
| The [[#Custom data fields|custom fields]] for this entry.
  −
|}
  −
</dd>
  −
</dl>
     −
===Custom garbage cans===
+
Fields like <samp>Game1.weather</samp> and <samp>Game1.weatherForTomorrow</samp> are now strings to support custom mod weather IDs. The change for vanilla weather has no effect on Content Patcher packs, since the new weather IDs match the ones Content Patcher was using before (i.e. <samp>Sun</samp>, <samp>Rain</samp>, <samp>Snow</samp>, <samp>Storm</samp>, and <samp>Wind</samp>). C# mods may also see a <samp>Festival</samp> weather, while Content Patcher packs will see <samp>Sun</samp> for it. The constants like <samp>Game1.weather_sunny</samp> have the new string values (with new constants like <samp>Game1.legacy_weather_sunny</samp> for the legacy values).
{{/doc status|a new doc page|done=false}}
     −
====Format====
+
The base game will treat an invalid weather as sunny. C# mods can implement custom weather effects using [[Modding:Modder Guide/APIs/Events|normal SMAPI events]] like <samp>UpdateTicked</samp>, or by [[Modding:Modder Guide/APIs/Harmony|patching]] methods like <samp>Game1.ApplyWeatherForNewDay</samp> and <samp>Game1.populateDebrisWeatherArray</samp>.
You can now add or edit [[Garbage Can|garbage cans]] on any map by editing the new <samp>Data/GarbageCans</samp> asset (see examples below).
     −
The asset consists of a data model with these fields:
+
===Custom world maps===
 +
{{/doc status|[[Modding:World map]]|done=true}}
   −
{| class="wikitable"
+
[[File:Modding map area.png|thumb|The default world map, with the farm map area highlighted.]]
|-
+
 
! field
+
You can now change the world map shown in the game menu by editing the <samp>Data/WorldMap</samp> asset. This lets you...
! effect
+
* add custom maps for certain locations;
|-
+
* apply texture overlays;
| <samp>DefaultBaseChance</samp>
+
* add/edit tooltips;
| The probability that an item will be found when searching garbage cans, as a value between 0 (never) and 1 (always). If the probability check fails, only items that set <samp>IgnoreBaseChance</samp> can spawn. This can be overridden by the per-garbage-can <samp>BaseChance</samp> field. Default 0.2.
+
* set real-time player marker positioning;
|-
+
* etc.
| <samp>BeforeAll</samp><br /><samp>AfterAll</samp>
+
 
| The items to prepend (<samp>BeforeAll</samp>) or append (<samp>AfterAll</samp>) to the <samp>GarbageCans</samp> → <samp>Items</samp> field for all garbage cans. These work exactly like the items in that field (e.g. subject to the garbage can's base chance).
+
The game's default map is fully defined in <samp>Data/WorldMap</samp>, including all the display text and conditional changes.
|-
+
 
| <samp>GarbageCans</samp>
+
===New map properties===
| The data for individual garbage cans. This consists of a string → model lookup with these fields:
+
{{/doc status|[[Modding:Maps#Known_map_properties]]|done=true}}
 +
 
 +
1.6 adds several new [[Modding:Maps|map properties]].
    +
====Building construction====
 
{| class="wikitable"
 
{| class="wikitable"
 
|-
 
|-
! field
+
! property
! effect
+
! explanation
 +
|-
 +
| <samp>CanBuildHere T</samp><br />''(valid in any outdoor location)''
 +
| Whether to allow constructing buildings in this location. The game will adjust automatically to account for it (e.g. Robin will let you choose where to build). See [[#Build anywhere|''build anywhere'' in what's new]].
 
|-
 
|-
| ''entry key''
+
| <samp>BuildConditions {{t|query}}</samp><br />''(valid in any outdoor location)''
| The [[Modding:Common data field types#Unique string ID|unique string ID]] for this garbage can.
+
| If <samp>CanBuildHere</samp> is set, an optional [[Modding:Game state queries|game state query]] which indicates whether building is allowed currently.
 
|-
 
|-
| <samp>BaseChance</samp>
+
| <samp>LooserBuildRestrictions T</samp><br />''(valid in any outdoor location)''
| ''(Optional)'' If set, overrides the root <samp>DefaultBaseChance</samp> field for this garbage can. Defaults to <samp>DefaultBaseChance</samp>.
+
| If set, tiles don't need to be marked <samp>Buildable T</samp> or <samp>Diggable T</samp> in their properties. Tiles can be blocked with <samp>Buildable F</samp> instead. The other restrictions still apply.
 
|-
 
|-
| <samp>Items</samp>
+
| <samp>ValidBuildRect {{t|x}} {{t|y}} {{t|width}} {{t|height}}</samp><br />''(valid in any outdoor location)''
| ''(Optional)'' The items to try spawning when the player searches the garbage can. The first matching item in <samp>BeforeAll</samp> + <samp>Items</samp> + <samp>AfterAll</samp> will be spawned, and any further items will be ignored. Defaults to none.
+
| The tile area within the map where buildings may be placed. If omitted, buildings may be placed in any open space in the map.
 +
|}
   −
This consists of a list of models with these fields:
+
====Crops====
 
{| class="wikitable"
 
{| class="wikitable"
 
|-
 
|-
! field
+
! property
! effect
+
! explanation
 +
|-
 +
| <samp>AllowGiantCrops T</samp>
 +
| If set with any non-blank value, [[Crops#Giant Crops|giant crops]] can grow in this location (if crops are also allowed per the [[#Custom crops|crop data]] or [[#Custom location contexts|<samp>PlantableLocations</samp> context field]]).
 
|-
 
|-
| ''common fields''
+
| <samp>DirtDecayChance {{t|chance}}</samp>
| See [[Modding:Item queries#Item spawn fields|item spawn fields]] for the generic item fields supported by garbage cans.
+
| The probability that each dirt tile will disappear overnight if it doesn't contain a crop, as a value between 0 (never) and 1 (always). Defaults to 0 (greenhouses), 0.1 (farms), and 1 (anywhere else).
 +
|}
   −
If set to an [[Modding:Item queries|item query]] which returns multiple items, one of them will be selected at random.
+
====Farmhouse interior====
 +
{| class="wikitable"
 
|-
 
|-
| <samp>IgnoreBaseChance</samp>
+
! property
| ''(Optional)'' Whether this item can spawn even if the <samp>BaseChance</samp> probability check didn't pass. Default false.
+
! explanation
 
|-
 
|-
| <samp>IsMegaSuccess</samp>
+
| <samp>FarmHouseStarterGift [{{t|id}} {{o|count}}]+</samp>
| ''(Optional)'' Whether to treat this item as a 'mega success' if it's selected, which plays a special <samp>crit</samp> sound and bigger animation. Default false.
+
| The items that should appear in the initial gift box placed in the farmhouse when the save is created. This consists of one or more pairs of item ID (which can be qualified or unqualified) and count. The count is optional on the last entry.
|-
+
 
| <samp>IsDoubleMegaSuccess</samp>
+
For example, this will add 10 pufferfish (object 128) and a blobfish mask (hat 56):
| ''(Optional)'' Whether to treat this item as an 'double mega success' if it's selected, which plays an explosion sound and dramatic animation. Default false.
+
<pre>FarmHouseStarterGift (O)128 10 (H)56 1</pre>
|-
+
 
| <samp>AddToInventoryDirectly</samp>
+
If omitted, the default items (usually a 15 parsnip seeds) are added instead.
| ''(Optional)'' Whether to add the item to the player's inventory directly, opening an item grab menu if they don't have room in their inventory. If false, the item will be dropped on the ground next to the garbage can instead. Default false.
  −
|-
  −
| <samp>CreateMultipleDebris</samp>
  −
| ''(Optional)'' Whether to split the spawned item into multiple stacks which each have a stack size of one. This has no effect if <samp>AddToInventoryDirectly</samp> is enabled. Default false.
  −
|}
   
|}
 
|}
   −
If the garbage can being searched doesn't have its own entry under <samp>GarbageCans</samp>, the game will just use the <samp>BeforeAll</samp> and <samp>AfterAll</samp> fields.
+
====Warps & map positions====
 +
{| class="wikitable"
 +
|-
 +
! property
 +
! explanation
 
|-
 
|-
| <samp>CustomFields</samp>
+
| <samp>AllowWakeUpWithoutBed {{t|allow}}</samp>
| The [[#Custom data fields|custom fields]] for this entry.
+
| Whether the player can wake up in this location without a bed, similar to the island farmhouse. This is typically used with <samp>PassOutLocations</samp> in [[#Custom location contexts|<samp>Data/LocationContexts</samp>]].
 +
|-
 +
| <samp>DefaultWarpLocation {{t|x}} {{t|y}}</samp><br />''(valid in any location)''
 +
| The default arrival tile, used when a player or NPC is added to the location without a target tile (e.g. using [[Modding:Console commands|debug commands]] like <samp>debug warp</samp> or <samp>debug eventbyid</samp>).
 +
|-
 +
| <samp>PetBowlLocation {{t|x}} {{t|y}}</samp><br />''(valid in the farm)''
 +
| The default position of the pet bowl
 +
|-
 +
| <samp>SpouseRoomPosition {{t|x}} {{t|y}}</samp><br />''(valid in farmhouse)''
 +
| The top-left position at which to place the [[Marriage#Spouse Rooms|spouse room]].
 +
|-
 +
| <samp>TravelingCartPosition {{t|x}} {{t|y}}</samp><br />''(valid in the forest)''
 +
| The top-left position at which to place the [[Traveling Cart]]. This is the top-left corner of the collision box, so the roof will extend two tiles above this tile.
 
|}
 
|}
   −
====Example new garbage can====
+
===Other map property changes===
You can add garbage cans using only [[Modding:Content Patcher|Content Patcher]] or [[Modding:Modder Guide/APIs/Content|SMAPI's content API]]. For example, this content pack adds a new garbage can entry with the ID <samp>Example.ModId_Carpenter</samp>:
+
{{/doc status|[[Modding:Maps]]|done=true}}
   −
{{#tag:syntaxhighlight|<nowiki>
+
{| class="wikitable"
{
+
|-
    "Format": "</nowiki>{{Content Patcher version}}<nowiki>",
+
! map property
    "Changes": [
+
! changes
        {
+
|-
            "Action": "EditData",
+
| <samp>Arch</samp><br /><samp>asdf</samp><br /><samp>Debris</samp><br /><samp>Fish</samp>
            "Target": "Data/GarbageCans",
+
| Removed (these were unused).
            "TargetField": [ "GarbageCans" ],
+
|-
            "Entries": {
+
| <samp>FarmHouseFlooring</samp><br /><samp>FarmHouseFurniture</samp><br /><samp>FarmHouseStarterSeedsPosition</samp><br /><samp>FarmHouseWallpaper</samp>
                "{{ModId}}_Carpenter": {
+
| These now work independently. For example, you can now use <samp>FarmHouseFlooring</samp> without needing to set <samp>FarmHouseFurniture</samp> too.
                    "Items": [
+
|-
                        // 25% chance of pufferfish
+
| <samp>Music</samp>
                        {
+
| Deprecated; use the music fields in [[#Custom locations|<samp>Data/Locations</samp>]] instead. This property is only applied if the location has no music in <samp>Data/Locations</samp>. This was removed from all vanilla maps.
                            "ID": "{{ModId}}_Pufferfish",
+
|-
                            "Condition": "RANDOM 0.25",
+
| <samp>NPCWarp</samp><br /><samp>Warp</samp>
                            "ItemId": "(O)128"
+
| Now fault-tolerant. They'll automatically ignore extra spaces, log an informative warning if parsing still fails, and continue with the next warp if possible.
                        },
+
|-
 +
| <samp>Stumps</samp>
 +
| Now works in all locations.
 +
|-
 +
| <samp>UniquePortrait</samp><br /><samp>UniqueSprite</samp>
 +
| Deprecated; use [[#Custom NPC appearance|custom NPC appearances]] instead. These properties will override NPC appearances. This was removed from all vanilla maps.
 +
|}
   −
                        // else guaranteed random House Plant item
+
===Tile property changes===
                        {
+
{{/doc status|[[Modding:Maps#Known tile properties]]|done=true}}
                            "ID": "{{ModId}}_RandomHousePlant",
  −
                            "ItemID": "RANDOM_ITEMS (F) 1376 1390"
  −
                        }
  −
                    ]
  −
                }
  −
            }
  −
        }
  −
    ]
  −
}</nowiki>|lang=javascript}}
     −
Then you'd place an <code>Action: Garbage Example.ModId_Carpenter</code> [[Modding:Maps|map tile property]] to mark a tile as a garbage can using this data.
+
<ul>
 
+
<li>You can now override a tile index property by setting it as a tile property.</li>
====Example change for existing garbage can====
+
<li>Added new [[Modding:Maps|tile properties]]:
You can edit an existing garbage cans using only [[Modding:Content Patcher|Content Patcher]] or [[Modding:Modder Guide/APIs/Content|SMAPI's content API]]. For example, this content pack adds pufferfish to the Saloon garbage can, and moves it above the dish of the day.
+
{| class="wikitable"
 
+
! layer
Note that this uses <samp>TargetField</samp> to 'move into' the item list for the saloon, and then treat those items as the entry list being edited. Specifying an ID which isn't in the list will add a new entry, just like when editing a regular list asset.
+
! property
 
+
! explanation
{{#tag:syntaxhighlight|<nowiki>
+
|-
{
+
| <samp>Paths</samp>
    "Format": "</nowiki>{{Content Patcher version}}<nowiki>",
+
| <samp>SpawnTree {{t|category}} {{t|ID}} {{t|Growth stage}} {{t|Regrowth stage}}</samp>
    "Changes": [
+
| Spawns a tree when the map is created. {{t|category}} may be either <samp>wild</samp> or <samp>fruit</samp>. <samp>wild</samp> will spawn a [[Trees|wild tree]], while <samp>fruit</samp> will spawn a [[Fruit Trees|fruit tree]].  
        {
+
|}
            "Action": "EditData",
+
</li>
            "Target": "Data/GarbageCans",
+
<li>Added new <samp>Action</samp> [[Modding:Maps|tile properties]]:
            "TargetField": [ "GarbageCans", "Saloon", "Items" ],
  −
            "Entries": {
  −
                // 25% chance of pufferfish
  −
               
  −
                "{{ModId}}_Pufferfish":{
  −
                    "ID": "{{ModId}}_Pufferfish",
  −
                    "Condition": "RANDOM 0.25",
  −
                    "ItemId": "(O)128"
  −
                }
  −
            },
  −
            "MoveEntries": [
  −
                { "ID": "{{ModId}}_Pufferfish", "BeforeId": "Base_DishOfTheDay" }
  −
            ]
  −
        }
  −
    ]
  −
}</nowiki>|lang=javascript}}
  −
 
  −
====Changes for C# mods====
  −
Previously garbage cans were tracked by <samp>Town.garbageChecked</samp>, an array of boolean fields. That approach doesn't work in Stardew Valley 1.6, since we're no longer limited to a specific set of garbage cans in the town map. This has been replaced by <samp>Game1.netWorldState.Value.CheckedGarbage</samp>, which is a hash set of garbage can IDs.
  −
 
  −
To migrate code:
   
{| class="wikitable"
 
{| class="wikitable"
 
|-
 
|-
! action
+
! layer
! code in 1.5.6
+
! property
! code in 1.6
+
! explanation
 
|-
 
|-
| check if a garbage can was searched
+
| <samp>Buildings</samp>
| <syntaxhighlight lang="js">
+
| <samp>Action BuildingSilo</samp>
Town town = (Town)Game1.getLocationFromName("Town");
+
| If a building covers this tile, enables [[silo]] interactions on this tile subject to the building's <samp>HayCapacity</samp> field in <samp>Data/Buildings</samp>.
if (town.garbageChecked[5])
  −
  ...
  −
</syntaxhighlight>
  −
| <syntaxhighlight lang="js">
  −
if (Game1.netWorldState.Value.CheckedGarbage.Contains("Saloon"))
  −
  ...
  −
</syntaxhighlight>
   
|-
 
|-
| mark a garbage can searched
+
| <samp>Buildings</samp>
| <syntaxhighlight lang="js">
+
| <samp>Action BuildingToggleAnimalDoor</samp>
Town town = (Town)Game1.getLocationFromName("Town");
+
| If a building covers this tile, opens or closes its animal door.
town.garbageChecked[5] = true;
  −
</syntaxhighlight>
  −
| <syntaxhighlight lang="js">
  −
Game1.netWorldState.Value.CheckedGarbage.Add("Saloon");
  −
</syntaxhighlight>
  −
|}
  −
 
  −
To migrate former vanilla trash can IDs:
  −
{| class="wikitable"
   
|-
 
|-
! position
+
| <samp>Buildings</samp>
! ID in 1.5.6
+
| <samp>Action Dialogue</samp>
! ID in 1.6
+
| &#32;
 +
* The message can now be a [[Modding:Tokenizable strings|tokenizable string]].
 +
* Fixed the cursor not changing to the inspection icon when hovering on an <samp>Action Dialogue</samp> tile.
 
|-
 
|-
| Near [[Jodi]] and [[Kent]]'s house
+
| <samp>Buildings</samp>
| <code>0</code>
+
| <samp>Action Forge</samp>
| <code>JodiAndKent</code>
+
| Opens the [[Forge]] menu.
 
|-
 
|-
| Near [[Emily]] and [[Haley]]'s house
+
| <samp>Buildings</samp>
| <code>1</code>
+
| <samp>Action None</samp>
| <code>EmilyAndHaley</code>
+
| Does nothing. This is used to mark the tile interactive if the click will be handled separately.
 
|-
 
|-
| Near [[Lewis]]' house
+
| <samp>Buildings</samp>
| <code>2</code>
+
| <samp>Action ObeliskWarp {{t|location name}} {{t|x}} {{t|y}} {{o|whether to dismount}}</samp>
| <code>Mayor</code>
+
| Warps the player to the specified location name and position with the [[Warp Totem|Obelisk]] animation/sound effects.
 
|-
 
|-
| Near [[Museum]]
+
| <samp>Buildings</samp>
| <code>3</code>
+
| <samp>Action OpenShop {{t|shop id}} {{o|from direction}} {{o|open time}} {{o|close time}} {{o|owner tile area}}</samp>
| <code>Museum</code>
+
| Open the [[#Custom shops|shop]] with the given {{t|shop id}}. All arguments besides the ID are optional:
 +
* {{o|from direction}}: if specified, the player must be standing in this direction relative to the shop (one of <samp>down</samp>, <samp>up</samp>, <samp>left</samp>, <samp>right</samp>, or <samp>none</samp>). Setting this to <samp>none</samp> disables the requirement. The default for most vanilla shops is <samp>down</samp>.
 +
* {{o|open time}} and {{o|close time}}: the start & end times in 26-hour format when the shop is available. Interacting with the tile outside those times does nothing.
 +
* {{o|owner tile area}}: if specified, the tile area which must contain one of the shop owners for the shop to be available. For a custom shop, these are defined by its <samp>Owners</samp> field. This can be specified in two forms: <samp>{{t|x}} {{t|y}}</samp> for a single tile, or <samp>{{t|x}} {{t|y}} {{t|width}} {{t|height}}</samp> for a multi-tile area.
 
|-
 
|-
| Near [[Blacksmith|Clint's blacksmith]]
+
| <samp>Buildings</samp>
| <code>4</code>
+
| <samp>Action PlayEvent {{t|event id}} {{o|check preconditions}} {{o|skip if seen}} {{o|fallback action}}</samp>
| <code>Blacksmith</code>
+
| Immediately start an [[Modding:Event data|event]], subject to the conditions:
 +
* {{o|check preconditions}}: whether to ignore the action if the [[Modding:Event data#Event preconditions|event's preconditions]] don't match (one of <samp>true</samp> or <samp>false</samp>). Default true.
 +
* {{o|skip if seen}}: whether to ignore the action if the player has already seen the given event. Default true.
 +
 
 +
If the event doesn't start for any reason (including the preceding conditions):
 +
* If {{o|fallback action}} is specified, it'll be run as an action. This can be any <samp>Action</samp> tile property (without the "Action " prefix), like <code>Action PlayEvent 60367 true true PlayEvent 520702 false false</code> to play a different event.
 +
* Otherwise the action is silently ignored.
 +
 
 +
For example, <code>Action PlayEvent 60367 false false</code> will replay the bus arrival event from the start of the game.
 +
|}
 +
</li>
 +
<li>Added new <samp>TouchAction</samp> [[Modding:Maps|tile properties]]:
 +
{| class="wikitable"
 +
|-
 +
! layer
 +
! property
 +
! explanation
 
|-
 
|-
| Near [[The Stardrop Saloon|the Saloon]]
+
| <samp>Back</samp>
| <code>5</code>
+
| <samp>TouchAction PlayEvent {{t|event id}} {{o|check preconditions}} {{o|skip if seen}} {{o|fallback action}}</samp>
| <code>Saloon</code>
+
| Equivalent to <samp>Action PlayEvent</samp>, but activated on touch. Note that {{o|fallback action}} is an <samp>Action</samp> tile property, ''not'' a <samp>TouchAction</samp> tile property.
 +
|}</li>
 +
<li>Changed existing tile properties:
 +
{| class="wikitable"
 
|-
 
|-
| Near [[Evelyn]] and [[George]]'s house
+
! layer
| <code>6</code>
+
! property
| <code>Evelyn</code>
+
! reason
 
|-
 
|-
| Near [[JojaMart]]
+
|rowspan="4"| <samp>Back</samp>
| <code>7</code>
+
| <samp>NoSpawn</samp>
| <code>JojaMart</code>
+
| Added <samp>NoSpawn false</samp> form, which disables any previous <samp>NoSpawn</samp> property on the tile. For example, this can be used to enable spawning on a tile which has a <samp>NoSpawn</samp> tile index property.
|}
+
|-
 
+
| <samp>TouchAction Bus</samp>
===Custom map actions===
+
| Removed. This wasn't used by the game or mods.
{{/doc status|[[Modding:Maps]]|done=false}}
+
|-
 +
| <samp>TouchAction Emote</samp>
 +
| Fixed error if the specified NPC isn't found.
 +
|-
 +
| <samp>Treasure</samp>
 +
| Added <samp>Treasure Item {{t|item ID}}</samp> form which accepts a [[#Custom items|qualified or unqualified item ID]].
 +
|-
 +
|rowspan="2"| <samp>Buildings</samp>
 +
| <samp>Action ItemChest</samp><br /><samp>Action Minecart</samp><br /><samp>Action RemoveChest</samp>
 +
| Removed. These weren't used by the game or mods.
 +
|-
 +
| <samp>Action Kitchen</samp>
 +
| Now works in any location (including those without a fridge).
 +
|}
 +
</li>
 +
</ul>
   −
C# mods can now handle custom <samp>Action</samp> & <samp>TouchAction</samp> [[Modding:Maps|map properties]] by calling <samp>GameLocation.RegisterTileAction</samp> & <samp>RegisterTouchAction</samp>, and passing a callback which receives the location, map property arguments, player who activated it, and tile position.
+
===Other location/map changes===
 +
{{/doc status|[[Modding:Maps]] and other pages as needed|done=false}}
   −
For example, let's say you want a locked gate which needs a custom key item. You can add a regular <code>TouchAction Example.ModId_UnlockGate</code> map property (e.g. by adding it directly in the map file, or using [[Modding:Content Patcher|Content Patcher]]'s <samp>EditMap</samp>, or using the [[Modding:Modder Guide/APIs/Content|content API]]). Then you can just handle the logic from your C# mod:
+
* Farm data:
<syntaxhighlight lang="c#">
+
** Added <samp>SpawnMonstersByDefault</samp> field to <samp>Data/AdditionalFarms</samp> to set the default value of the 'spawn monsters at night' [[Options#Advanced Game Options|advanced save option]].
internal class ModEntry : Mod
+
** Fixed crash on new-save screen if the farm type's tooltip has no description.
{
+
* General location data:
    /// <inheritdoc />
+
** All locations can now have animals. The <samp>IAnimalLocation</samp> is now obsolete and implemented by <samp>GameLocation</samp>.
    public override void Entry(IModHelper helper)
+
** Added new [[Modding:Fish data|fishing areas]] to simplify compatibility between fish & map mods (specifically for hilltop farm, wilderness farm, town, and desert).
    {
+
** Added a descriptive error when a required location or layer isn't found. Mods can use <samp>map.RequireLayer</samp> and <samp>Game1.RequireLocation</samp> to get a location with similar error-checking.
        GameLocation.RegisterTouchAction("Example.ModId_UnlockGate", this.HandleUnlockGate);
+
** Added <samp>WarpPathfindingCache</samp> for C# mods, which modularizes the NPC warp route logic. You can edit its <samp>IgnoreLocationNames</samp>, <samp>OverrideTargetNames</samp>, and <samp>GenderRestrictions</samp> fields if needed for custom locations.
    }
+
** Game logic which checks tile indexes is now more fault-tolerant, so it won't crash if an expected tile was edited.
 
+
** Finished migrating <samp>DecoratableLocation</samp> flooring/wallpaper areas to string IDs (started in Stardew Valley 1.5.5).
    private void HandleUnlockGate(GameLocation location, string[] args, Farmer player, Vector2 tile)
+
* General map changes:
    {
+
** Added validation for [[Modding:Maps|map properties and tile properties]]. If the format is invalid, the game will now log a detailed error and skip it.
        const string mailFlag = "Example.ModId_GateUnlocked";
+
** Removed unused [[Modding:Maps#Paths layer|path tiles]] in <samp>Maps/paths</samp> and all map files.
        const string keyId = "Example.ModId_GateKey";
+
* Location context data:
 
+
** Building interiors now inherit their parent's location context by default.
        // unlock gate if locked
+
** Added <samp>Game1.locationContextData</samp> to cache the data from <samp>Data/LocationContexts</samp>.
        if (!player.mailReceived.Contains(mailFlag))
+
** Added constants for the vanilla context IDs like <samp>LocationContexts.IslandId</samp>.
        {
+
** Added validation for required location context IDs (and <samp>LocationContexts.Require(id)</samp> for mod logic).
            if (!Game1.player.Items.ContainsId(id, count))
+
** Removed the <samp>Name</samp> field in <samp>Data/LocationContexts</samp>, which duplicated the ID.
            {
+
<ul>
                Game1.activeClickableMenu = new DialogueBox("This gate is locked. I wonder where the key is?");
+
<li>Added methods to simplify common operations:
                return;
+
{| class="wikitable"
            }
+
|-
 
+
! type
            player.removeFirstOfThisItemFromInventory(keyId);
+
! method
            player.mailReceived.Add(mailFlag);
+
! effect
        }
+
|-
 
+
|rowspan="7"| <samp>Building</samp>
        // apply open-gate map edit
+
| <samp>GetParentLocation</samp>
        // NOTE: this is a quick example which changes the location's current map. If another mod reloads the map
+
| Get the location which contains this building.
        // (e.g. a content pack editing it), the change will be lost. For persistent changes, you should use the
+
|-
        // AssetRequested event to apply the change when the map is reloaded.
+
| <samp>IsInCurrentLocation</samp>
        IAssetDataForMap mapHelper = this.Helper.GameContent.GetPatchHelper(location.map).AsMap();
+
| Get whether the building is in the same location as the current player.
        mapHelper.PatchMap(
+
|-
            this.Helper.Content.Load<Map>("assets/unlocked-gate.tmx"),
+
| <samp>HasIndoors</samp>
            targetArea: new Rectangle((int)tile.X - 1, (int)tile.Y - 1, 2, 2)
+
| Get whether the building has an interior location.
        );
  −
    }
  −
}
  −
</syntaxhighlight>
  −
 
  −
As another example, let's say you want the gate to unlock when the player presses the action key. You can add a regular <code>Action Example.ModId_UnlockGate</code> map property (e.g. by adding it directly in the map file, or using [[Modding:Content Patcher|Content Patcher]]'s <samp>EditMap</samp>, or using the [[Modding:Modder Guide/APIs/Content|content API]]). Then you can just handle the logic from your C# mod:
  −
<syntaxhighlight lang="c#">
  −
internal class ModEntry : Mod
  −
{
  −
    /// <inheritdoc />
  −
    public override void Entry(IModHelper helper)
  −
    {
  −
        GameLocation.RegisterTileAction("Example.ModId_UnlockGate", this.HandleUnlockGate);
  −
    }
  −
 
  −
    private bool HandleUnlockGate(GameLocation location, string[] args, Farmer player, Microsoft.Xna.Framework.Point point)
  −
    {
  −
        const string mailFlag = "Example.ModId_GateUnlocked";
  −
        const string keyId = "Example.ModId_GateKey";
  −
 
  −
        // unlock gate if locked
  −
        if (!player.mailReceived.Contains(mailFlag))
  −
        {
  −
            if (!Game1.player.Items.ContainsId(id, count))
  −
            {
  −
                Game1.activeClickableMenu = new DialogueBox("This gate is locked. I wonder where the key is?");
  −
                return false;
  −
            }
  −
 
  −
            player.removeFirstOfThisItemFromInventory(keyId);
  −
            player.mailReceived.Add(mailFlag);
  −
        }
  −
 
  −
        // apply open-gate map edit
  −
        // NOTE: this is a quick example which changes the location's current map. If another mod reloads the map
  −
        // (e.g. a content pack editing it), the change will be lost. For persistent changes, you should use the
  −
        // AssetRequested event to apply the change when the map is reloaded.
  −
        IAssetDataForMap mapHelper = this.Helper.GameContent.GetPatchHelper(location.map).AsMap();
  −
        mapHelper.PatchMap(
  −
            this.Helper.Content.Load<Map>("assets/unlocked-gate.tmx"),
  −
            targetArea: new Rectangle((int)point.X - 1, (int)point.Y - 1, 2, 2)
  −
        );
  −
 
  −
        return true;
  −
    }
  −
}
  −
</syntaxhighlight>
  −
 
  −
===Custom map layers===
  −
{{/doc status|[[Modding:Maps]]|done=false}}
  −
 
  −
You can now add any number of [[Modding:Maps|map layers]] by suffixing a vanilla layer name (i.e. <samp>Back</samp>, <samp>Buildings</samp>, <samp>Front</samp>, or <samp>AlwaysFront</samp>) with an offset. For example, <samp>Back-1</samp> will be drawn before/under <samp>Back</samp>, and <samp>Back2</samp> will be drawn after/over it. You can increment the number to add more layers.
  −
 
  −
This only affects layer rendering. Tile properties must still be set on the original layers.
  −
 
  −
===Custom minecarts===
  −
{{/doc status|a new doc page|done=false}}
  −
 
  −
You can now extend [[minecart]]s by editing the <samp>Data\Minecarts</samp> data asset.
  −
 
  −
This consists of a string → model lookup, where...
  −
* The key is a [[Modding:Common data field types#Unique string ID|unique string ID]] for the minecart network. When you interact with a minecart, the destinations listed for its network are shown.
  −
* The value is a model with the fields listed below.
  −
 
  −
{| class="wikitable"
   
|-
 
|-
! field
+
| <samp>GetIndoors</samp>
! effect
+
| Get the location within this building, if applicable.
 
|-
 
|-
| <samp>Destinations</samp>
+
| <samp>HasIndoorsName</samp>
| The destinations which the player can travel to from minecarts in this network. This consists of a list of model with these fields:
+
| Get whether the building has an interior location and its unique name matches the given value (like <code>building.HasIndoorsName("FarmHouse")</code>).
{| class="wikitable"
   
|-
 
|-
! field
+
| <samp>GetIndoorsName</samp>
! effect
+
| Get the unique name of the location within this building, if applicable.
 
|-
 
|-
| <samp>Id</samp>
+
| ...
| A [[Modding:Common data field types#Unique string ID|unique string ID]] for this destination within the network.
+
| ''see also [[#Other building changes|other building changes]] for non-location methods.''
 
|-
 
|-
| <samp>DisplayName</samp>
+
|rowspan="7"|<samp>Cabin</samp><br /><samp>FarmHouse</samp>
| A [[Modding:Tokenizable strings|tokenizable string]] for the destination name shown in the minecart menu. You can use the location's display name with the <samp>LocationName</samp> token (like <code>[LocationName Desert]</code> for the [[desert]]).
+
| <samp>GetCellar</samp>
 +
| Get the [[cellar]] location linked to this cabin, if any.
 
|-
 
|-
| <samp>TargetLocation</samp>
+
| <samp>CanAssignFarmhand</samp><br /><samp>AssignFarmhand</samp>
| The [[#Custom locations|location ID]] for the destination.
+
| ''(Cabin only)'' Check whether the cabin is available to assign to a farmhand, or perform the assignment.
 
|-
 
|-
| <samp>TargetTile</samp>
+
| <samp>HasOwner</samp>
| The destination tile position within the location, specified as a model with <samp>X</samp> and <samp>Y</samp> fields.
+
| Get whether the home has an assigned player, regardless of whether they've finished creating their character.
 
|-
 
|-
| <samp>TargetDirection</samp>
+
| <samp>OwnerId</samp>
| The direction the player should face after arrival (one of <samp>down</samp>, <samp>left</samp>, <samp>right</samp>, or <samp>up</samp>).
+
| Get the unique ID of the player who owns this home, if any.
 
|-
 
|-
| <samp>Condition</samp>
+
| <samp>IsOwnedByCurrentPlayer</samp>
| ''(Optional)'' A [[Modding:Game state queries|game state query]] which indicates whether this minecart destination is available. Defaults to always available.
+
| Get whether the cabin belongs to the current player.
 
|-
 
|-
| <samp>Price</samp>
+
| <samp>IsOwnerActivated</samp>
| ''(Optional)'' The gold price that must be paid each time to use this destination. Default none.
+
| Get whether the home has an assigned player and they've finished creating their character.
 
|-
 
|-
| <samp>BuyTicketMessage</samp>
+
| <samp>HasNpcSpouse</samp>
| ''(Optional)'' If the destination costs money to use, a [[Modding:Tokenizable strings|tokenizable string]] for the purchase confirmation message shown. If present, <code>{0}</code> is replaced with the purchase price. Defaults to the network's <samp>BuyTicketMessage</samp> field.
+
| Get whether the player who owns this home is married to any NPC (when used like <samp>HasNpcSpouse()</samp>) or a specific NPC (like <samp>HasNpcSpouse(name)</samp>). This also replaces <samp>shouldShowSpouseRoom()</samp>.
 
|-
 
|-
| <samp>CustomFields</samp>
+
|rowspan="2"| <samp>Farm</samp>
| ''(Optional)'' The [[#Custom data fields|custom fields]] for this entry.
+
| <samp>GetStarterFarmhouseLocation</samp>
|}
+
| Get the default tile position for the farmhouse. (See also <samp>farm.GetMainFarmHouseEntry()</samp>.)
 
|-
 
|-
| <samp>UnlockCondition</samp>
+
| <samp>GetStarterPetBowlLocation</samp>
| ''(Optional)'' A [[Modding:Game state queries|game state query]] which indicates whether this minecart network is unlocked. Default always enabled.
+
| Get the default tile position for the pet bowl.
 
|-
 
|-
| <samp>LockedMessage</samp>
+
|rowspan="19"| <samp>GameLocation</samp>
| ''(Optional)'' A [[Modding:Tokenizable strings|tokenizable string]] for the message shown when interacting with a minecart when the <samp>UnlockCondition</samp> false. Defaults to an "''Out of order''" translation.
+
| <samp>AddDefaultBuildings</samp>
 +
| Can be overridden to add custom buildings when the location is created and/or loaded. These can either be re-added whenever they're missing (like the vanilla farmhouse), or only built once on save creation (like the vanilla pre-built cabins).
 +
 
 +
This replaces the former <samp>farm.AddModularShippingBin()</samp> method.
 
|-
 
|-
| <samp>ChooseDestinationMessage</samp>
+
| <samp>GetFridge</samp><br /><samp>GetFridgePosition</samp>
| ''(Optional)'' A [[Modding:Tokenizable strings|tokenizable string]] for the message shown when listing destinations to choose from. Defaults to a "''Choose destination:''" translation.
+
| Get the fridge's chest or tile position, if the location has one.
 
|-
 
|-
| <samp>BuyTicketMessage</samp>
+
| <samp>GetSeason</samp><br /><samp>GetSeasonIndex</samp><br /><samp>GetSeasonKey</samp>
| ''(Optional)'' When a destination costs money to use, a [[Modding:Tokenizable strings|tokenizable string]] for the purchase confirmation message shown. If present, <code>{0}</code> is replaced with the purchase price. Defaults to a "''Buy a ticket for {0}g?''" translation.
+
| Get the local season that applies within the location as an enum, number (like <samp>0</samp> for spring), or string (like <samp>spring</samp>) respectively. For example, it's always summer on [[Ginger Island]].
|}
+
|-
 +
| <samp>GetWeather</samp><br /><samp>IsDebrisWeatherHere</samp><br /><samp>IsLightningHere</samp><br /><samp>IsRainingHere</samp><br /><samp>IsSnowingHere</samp>
 +
| Get the current weather in this location's context, regardless of whether the player is indoors and sheltered from it.
 +
|-
 +
| <samp>InDesertContext</samp><br /><samp>InIslandContext</samp><br /><samp>InValleyContext</samp>
 +
| Get whether this location is within the <samp>Island</samp> or <samp>Default</samp> location context respectively.
 +
|-
 +
| <samp>IsActiveLocation</samp>
 +
| Get whether this location is actively synced to the current player (see [[Modding:Modder Guide/Game Fundamentals#Farmhand shadow world|farmhand shadow world]]).
 +
|-
 +
| <samp>IsTemporary</samp>
 +
| Get whether this is a temporary location for a festival or minigame. This is cached based on the location name (e.g. locations starting with <samp>Temp</samp> or some other specific names).
 +
|-
 +
| <samp>GetLocationContextId</samp>
 +
| Get the ID of the location context in <samp>Data/LocationContexts</samp> which contains this building.
 +
|-
 +
| <samp>GetContainingBuilding</samp>
 +
| Get the building instance which contains this location (like the cabin for a cabin interior), if applicable.
 +
|-
 +
| <samp>GetParentLocation</samp>
 +
| Get the parent location which contains this one (like the farm for a cabin interior), or <samp>null</samp> if it has no parent.
 +
|-
 +
| <samp>GetRootLocation</samp>
 +
| Get the parent location which contains this one (like the farm for a cabin interior), or the location itself if it has no parent.
 +
|-
 +
| <samp>GetInstancedBuildingInteriors</samp>
 +
| Get all building interiors within this location which are instanced to the building (i.e. not in <samp>Game1.locations</samp> separately).
 +
|-
 +
| <samp>GetMapPropertySplitBySpaces</samp><br /><samp>GetTilePropertySplitBySpaces</samp>
 +
| Get the value of a map/tile property and split it into individual words. If the map/tile property isn't defined, returns an empty array.
   −
====Open a minecart menu====
+
For example:
You can use an <samp>Action: MinecartTransport {{o|network ID}} {{o|exclude destination ID}}</samp> [[Modding:Maps|map property]] to open the minecart menu. When the player interacts with the tile, it'll open the menu for the {{o|network ID}} network (default <samp>Default</samp>). if {{o|exclude destination ID}} is specified, the matching destination will be hidden from the list (usually because you're at that minecart). For example, the [[Bus Stop|bus stop]] minecart uses <code>Action: MinecartTransport Default Bus</code>.
+
<syntaxhighlight lang="c#">
 +
string[] fields = Game1.currentLocation.GetMapPropertySplitBySpaces("ScreenshotRegion");
 +
</syntaxhighlight>
 +
|-
 +
| <samp>HasMapPropertyWithValue</samp>
 +
| Get whether a map property is defined and has a non-empty value.
   −
From a C# mod, you can call <code>Game1.currentLocation.ShowMineCartMenu(networkId, excludeDestinationId)</code> which works the same way (except that <samp>networkId</samp> is required).
+
For example:
 
+
<syntaxhighlight lang="c#">
====Example====
+
bool canUseCasks = Game1.currentLocation.HasMapPropertyWithValue("CanCaskHere");
This [[Modding:Content Patcher|Content Patcher]] content pack adds the [[Railroad]] as a minecart destination, complete with a map edit adding a decorative minecart. It is available after the [[Random Events|Earthquake]] has occurred and minecarts have been unlocked.
+
</syntaxhighlight>
 +
|-
 +
| <samp>StoreHayInAnySilo</samp>
 +
| Add hay to any silo with free space (preferring silos in the current location, then the farm, then anywhere).
 +
|-
 +
| <samp>TryGetMapProperty</samp>
 +
| Get a map property value as a string, if it's defined.
   −
{{#tag:syntaxhighlight|<nowiki>
+
For example:
 +
<syntaxhighlight lang="c#">
 +
if (this.TryGetMapProperty("Warps", out string warps))
 
{
 
{
     "Format": "</nowiki>{{Content Patcher version}}<nowiki>",
+
     // ...
    "Changes": [
+
}
        // add minecart destination
+
</syntaxhighlight>
        {
+
|-
            "Action": "EditData",
+
| <samp>TryGetMapPropertyAs</samp>
            "Target": "Data/Minecarts",
+
| Get a map property and parse it into into a <samp>bool</samp>, <samp>double</samp>, <samp>Point</samp>, <samp>Rectangle</samp>, or <samp>Vector2</samp> value.
            "TargetField": [ "Default", "Destinations" ], // for the "Default" network, edit the "Destinations" field
  −
            "Entries": {
  −
                "Railroad": {
  −
                    "Id": "Railroad",
  −
                    "DisplayName": "[LocationName Railroad]",
  −
                    "Condition": "LOCATION_ACCESSIBLE Railroad",
     −
                    "TargetLocation": "Railroad",
+
For example:
                    "TargetTile": { "X": 16, "Y": 39 },
+
<syntaxhighlight lang="c#">
                    "TargetDirection": "down",
+
if (!this.TryGetMapPropertyAs("MailboxLocation", out Point position))
                }
+
{
            }
+
    position = new Point(68, 16); // default value
        },
+
}
 
+
</syntaxhighlight>
        // add decorative minecart
+
|-
        {
+
| <samp>removeObjectsAndSpawned</samp>
            "Action": "EditMap",
+
| Remove all objects, bushes, resource clumps, and terrain features within a tile area.
            "Target": "Maps/Railroad",
  −
            "FromFile": "assets/Custom_Railroad_Minecart.tmx",
  −
            "ToArea": { "X": 15, "Y": 35, "Width": 4, "Height": 5 }
  −
        }
  −
    ]
  −
}</nowiki>|lang=javascript}}
  −
 
  −
===Custom passive festivals===
  −
{{/doc status|[[Modding:Festival data]] or a new doc page|done=false}}
  −
 
  −
You can now add or modify passive festivals by editing the <samp>Data/PassiveFestivals</samp> asset.
  −
 
  −
(A ''passive festival'' is a [[festivals|festival]] like the [[Night Market]]. They replace a location for a period of time, the player can enter/leave them anytime, and time continues passing while at the festival.)
  −
 
  −
====Data format====
  −
The <samp>Data/PassiveFestivals</samp> asset consists of a string → model lookup, where...
  −
* The key is a [[Modding:Common data field types#Unique string ID|unique string ID]] for the festival.
  −
* The value is a model with the fields listed below.
  −
{| class="wikitable"
   
|-
 
|-
! field
+
| <samp>OnBuildingConstructed</samp><br /><samp>OnBuildingMoved</samp><br /><samp>OnBuildingDemolished</samp>
! effect
+
| These methods are called for all players when any player constructs, moves, or demolishes a building.
 
|-
 
|-
| <samp>DisplayName</samp>
+
|rowspan="3"| <samp>LibraryMuseum</samp>
| A [[Modding:Tokenizable strings|tokenizable string]] for the display name shown on the [[calendar]].
+
| <samp>HasDonatedArtifacts()</samp>
 +
| Get whether any items have been donated to the [[museum]].
 
|-
 
|-
| <samp>Season</samp>
+
| <samp>HasDonatedArtifactAt(tile)</samp>
| The [[season]] when the festival becomes active.
+
| Get whether any donated item is currently placed at the given tile position within the [[museum]].
 
|-
 
|-
| <samp>StartDay</samp><br /><samp>EndDay</samp>
+
| <samp>HasDonatedArtifact(itemId)</samp>
| The days of month when the festival becomes active.
+
| Get whether an artifact with the given qualified or unqualified item ID has been donated to the [[museum]].
 
|-
 
|-
| <samp>StartTime</samp>
+
|rowspan="2"| <samp>MineShaft</samp>
| The time of day when the festival opens each day.
+
| <samp>GetLevelName</samp>
|-
+
| Get the location name for a generated [[The Mines|mine]] or [[Skull Cavern]] level.
| <samp>StartMessage</samp>
  −
| A [[Modding:Tokenizable strings|tokenizable string]] for the in-game [[wikipedia:Pop-up notification|toast notification]] shown when the festival begins each day.
  −
|-
  −
| <samp>MapReplacements</samp>
  −
| The locations to swap for the duration of the festival. Despite the field name, this swaps '''locations''' (e.g. as added by <samp>CustomLocations</samp> using [[Modding:Content Patcher|Content Patcher]]), and not the location's map asset.
     −
This is specified as a string → string lookup, where the key is the original location to replace and the value is the new location. Both use the internal location name, as shown by the {{nexus mod|679|Debug Mode}} mod. For example, this swaps the <samp>Beach</samp> location with <samp>BeachNightMarket</samp> during the [[Night Market]]:
+
For example:
<syntaxhighlight lang="js">
+
<syntaxhighlight lang="c#">
"MapReplacements": {
+
string locationName = MineShaft.GetLevelName(10); // returns "UndergroundMine10"
    "Beach": "BeachNightMarket"
+
Game1.warpFarmer(locationName, 0, 0, false);
}
   
</syntaxhighlight>
 
</syntaxhighlight>
 
|-
 
|-
| <samp>Condition</samp>
+
| <samp>IsGeneratedLevel</samp>
| ''(Optional)'' A [[Modding:Game state queries|game state query]] which indicates whether the festival is enabled (subject to the other fields like <samp>StartDay</samp> and <samp>EndDay</samp>). Defaults to always enabled.
+
| Get whether a location or location name is a generated [[The Mines|mine]] or [[Skull Cavern]] level.
|-
  −
| <samp>ShowOnCalendar</samp>
  −
| ''(Optional)'' Whether the festival appears on the [[calendar]], using the same iridium-star icon as the [[Calendar#Winter|Night Market]]. Default true.
  −
|-
  −
| <samp>DailySetupMethod</samp><br /><samp>CleanupMethod</samp>
  −
| ''(Optional)'' A C# method which applies custom logic when the day starts (<samp>DailySetupMethod</samp>) and/or overnight after the last day of the festival (<samp>CleanupMethod</samp>).
     −
These must be specified in the form <samp>{{t|full type name}}: {{t|method name}}</samp> (like <samp>ExampleMod.Namespace.Type, ExampleMod: MethodName</samp>). The methods must be static, take zero arguments, and return void.
+
For example:
 +
<syntaxhighlight lang="c#">
 +
string locationName = "UndergroundMine10";
 +
bool isMine = MineShaft.IsGeneratedLevel(locationName, out int level); // returns true, 10
 +
</syntaxhighlight>
 
|-
 
|-
| <samp>CustomFields</samp>
+
| <samp>VolcanoDungeon</samp>
| The [[#Custom data fields|custom fields]] for this entry.
+
| <samp>GetLevelName</samp><br /><samp>IsGeneratedLevel</samp>
 +
| Equivalent to the matching <samp>MineShaft</samp> methods, but for the [[Volcano Dungeon]].
 
|}
 
|}
 +
</li>
 +
</ul>
 +
* Added map/tile property <samp>TryAdd</samp>/<samp>TryGetValue</samp> extensions in <samp>StardewValley.Extensions</samp> for string property values. For example, this lets you do <samp>map.Properties.TryGetValue(key, out string value)</samp>.
 +
* <samp>MineShaft.tryToAddMonster</samp> now returns whether a monster was added.
 +
* <samp>Game1.GetNumberBuildingsConstructed</samp> and <samp>location.getNumberBuildingsConstructed</samp> now have overloads to count all building types and/or specify whether to count under-construction buildings.
 +
* Fixed <samp>location.refurbishMapPortion</samp> copying <samp>Back</samp> source properties to the <samp>Building</samp> target layer.
 +
* Fixed door warps in custom indoor locations not consistently detected by the game.
   −
====NPC schedules====
+
==What's new for buildings==
When a passive festival is active, NPCs will check for [[Modding:Schedule data|a schedule entry]] in this order:
+
===Custom buildings===
 +
{{/doc status|[[Modding:Blueprint data]]|done=false}}
 +
 
 +
You can now add custom buildings by editing the <samp>Data/Buildings</samp> asset. This consists of a string → model lookup, where...
 +
* The key is a [[Modding:Common data field types#Unique string ID|unique string ID]] for the building type.
 +
* The value is a model with the fields listed below.
    +
====Required fields====
 
{| class="wikitable"
 
{| class="wikitable"
 
|-
 
|-
! syntax
+
! field
! summary
+
! effect
 
|-
 
|-
| <samp>{{t|festival ID}}_{{t|festival day}}</samp>
+
| <samp>Name</samp><br /><samp>Description</samp>
| Applies on the given date. The {{t|festival day}} is relative, so <samp>1</samp> matches the festival <samp>StartDay</samp>.<br /><small>Example: <samp>NightMarket_3</samp> or <samp>marriage_NightMarket_3</samp></small>
+
| A [[Modding:Tokenizable strings|tokenizable string]] for the display name and description (e.g. shown in the construction menu).
 
|-
 
|-
| <samp>{{t|festival ID}}</samp>
+
| <samp>Texture</samp>
| Applies if there's no date-specific entry.<br /><small>Example: <samp>NightMarket</samp> or <samp>marriage_NightMarket</samp></small>
+
| The asset name for the texture under the game's Content folder.
 
|}
 
|}
   −
If the NPC is married to a player, they'll add a <samp>marriage_</samp> prefix to the keys (like <samp>marriage_{{t|festival ID}}_{{t|festival day}}</samp>) and ignore any entry without the prefix.
+
====Construction====
 
+
{| class="wikitable"
===Custom weather===
+
|-
{{/doc status|[[Modding:Weather data]]|done=false}}
+
! field
 
+
! effect
You can now change the weather algorithm by editing [[#Custom location contexts|location context data]], and (with a C# mod) implement custom weathers.
+
|-
 
+
| <samp>Builder</samp>
Fields like <samp>Game1.weather</samp> and <samp>Game1.weatherForTomorrow</samp> are now strings to support custom mod weather IDs. The change for vanilla weather has no effect on Content Patcher packs, since the new weather IDs match the ones Content Patcher was using before (i.e. <samp>Sun</samp>, <samp>Rain</samp>, <samp>Snow</samp>, <samp>Storm</samp>, and <samp>Wind</samp>). C# mods may also see a <samp>Festival</samp> weather, while Content Patcher packs will see <samp>Sun</samp> for it. The constants like <samp>Game1.weather_sunny</samp> have the new string values (with new constants like <samp>Game1.legacy_weather_sunny</samp> for the legacy values).
+
| ''(Optional)'' The NPC from whom you can request construction. The vanilla values are [[Carpenter's Shop|<samp>Robin</samp>]] and [[Wizard's Tower#Buildings|<samp>Wizard</samp>]], but you can specify a different name if a C# mod opens a construction menu for them. Defaults to <samp>Robin</samp>. If omitted, it won't appear in any menu.
 
+
|-
The base game will treat an invalid weather as sunny. C# mods can implement custom weather effects using [[Modding:Modder Guide/APIs/Events|normal SMAPI events]] like <samp>UpdateTicked</samp>, or by [[Modding:Modder Guide/APIs/Harmony|patching]] methods like <samp>Game1.ApplyWeatherForNewDay</samp> and <samp>Game1.populateDebrisWeatherArray</samp>.
+
| <samp>BuildCost</samp>
 
+
| ''(Optional)'' The gold cost to construct the building. Defaults to {{price|0}}.
===Custom world maps===
+
|-
{{/doc status|[[Modding:World map]]|done=true}}
+
| <samp>BuildMaterials</samp>
 
+
| ''(Optional)'' The materials you must provide to start construction, as a list of models with these fields:
[[File:Modding map area.png|thumb|The default world map, with the farm map area highlighted.]]
  −
 
  −
You can now change the world map shown in the game menu by editing the <samp>Data/WorldMap</samp> asset. This lets you...
  −
* add custom maps for certain locations;
  −
* apply texture overlays;
  −
* add/edit tooltips;
  −
* set real-time player marker positioning;
  −
* etc.
  −
 
  −
The game's default map is fully defined in <samp>Data/WorldMap</samp>, including all the display text and conditional changes.
  −
 
  −
===New map properties===
  −
{{/doc status|[[Modding:Maps]]|done=false}}
  −
 
  −
1.6 adds several new [[Modding:Maps|map properties]].
  −
 
  −
====Building construction====
   
{| class="wikitable"
 
{| class="wikitable"
 
|-
 
|-
! property
+
! field
! explanation
+
! effect
 
|-
 
|-
| <samp>CanBuildHere T</samp><br />''(valid in any outdoor location)''
+
| <samp>Id</samp>
| Whether to allow constructing buildings in this location. The game will adjust automatically to account for it (e.g. Robin will let you choose where to build). See [[#Build anywhere|''build anywhere'' in what's new]].
+
| ''(Optional)'' The [[Modding:Common data field types#Unique string ID|unique string ID]] for this entry within the current list. Defaults to the <samp>ItemId</samp> if not specified.
 
|-
 
|-
| <samp>BuildConditions {{t|query}}</samp><br />''(valid in any outdoor location)''
+
| <samp>ItemId</samp>
| If <samp>CanBuildHere</samp> is set, an optional [[Modding:Game state queries|game state query]] which indicates whether building is allowed currently.
+
| The required item ID (qualified or unqualified).
 
|-
 
|-
| <samp>LooserBuildRestrictions T</samp><br />''(valid in any outdoor location)''
+
| <samp>Amount</samp>
| If set, tiles don't need to be marked <samp>Buildable T</samp> or <samp>Diggable T</samp> in their properties. Tiles can be blocked with <samp>Buildable F</samp> instead. The other restrictions still apply.
+
| The number of the item required.
|-
  −
| <samp>ValidBuildRect {{t|x}} {{t|y}} {{t|width}} {{t|height}}</samp><br />''(valid in any outdoor location)''
  −
| The tile area within the map where buildings may be placed. If omitted, buildings may be placed in any open space in the map.
   
|}
 
|}
  −
====Crops====
  −
{| class="wikitable"
   
|-
 
|-
! property
+
| <samp>BuildDays</samp>
! explanation
+
| ''(Optional)'' The number of days needed to complete construction (e.g. <samp>1</samp> for a building completed the next day). If set to 0, construction finishes instantly. Defaults to 0.
 
|-
 
|-
| <samp>AllowGiantCrops T</samp>
+
| <samp>BuildCondition</samp>
| If set with any non-blank value, [[Crops#Giant Crops|giant crops]] can grow in this location (if crops are also allowed per the [[#Custom crops|crop data]] or [[#Custom location contexts|<samp>PlantableLocations</samp> context field]]).
+
| ''(Optional)'' A [[Modding:Game state queries|game state query]] which indicates whether the building should be available in the construction menu. Defaults to always available.
 
|-
 
|-
| <samp>DirtDecayChance {{t|chance}}</samp>
+
| <samp>BuildMenuDrawOffset</samp>
| The probability that each dirt tile will disappear overnight if it doesn't contain a crop, as a value between 0 (never) and 1 (always). Defaults to 0 (greenhouses), 0.1 (farms), and 1 (anywhere else).
+
| ''(Optional)'' A pixel offset to apply to the building sprite when drawn in the construction menu. Default none.
|}
+
|-
 
+
| <samp>AdditionalPlacementTiles</samp>
====Farmhouse interior====
+
| ''(Optional)'' The extra tiles to treat as part of the building when placing it through the construction menu. For example, the farmhouse uses this to make sure the stairs are clear. This consists of a list of models with these fields:
 
{| class="wikitable"
 
{| class="wikitable"
 
|-
 
|-
! property
+
! field
! explanation
+
! effect
 +
|-
 +
| <samp>TileArea</samp>
 +
| The tile area relative to the top-left corner of the building, specified as an object with <samp>X</samp>, <samp>Y</samp>, <samp>Width</samp>, and <samp>Height</samp> fields.
 
|-
 
|-
| <samp>FarmHouseStarterGift [{{t|id}} {{o|count}}]+</samp>
+
| <samp>OnlyNeedsToBePassable</samp>
| The items that should appear in the initial gift box placed in the farmhouse when the save is created. This consists of one or more pairs of item ID (which can be qualified or unqualified) and count. The count is optional on the last entry.
+
| ''(Optional)'' Whether this area allows tiles that would normally not be buildable, so long as they are passable. For example, this is used to ensure that an entrance is accessible. Default false.
 
  −
For example, this will add 10 pufferfish (object 128) and a blobfish mask (hat 56):
  −
<pre>FarmHouseStarterGift (O)128 10 (H)56 1</pre>
  −
 
  −
If omitted, the default items (usually a 15 parsnip seeds) are added instead.
   
|}
 
|}
 
+
|-
====Warps & map positions====
+
| <samp>IndoorItems</samp>
 +
| ''(Optional)'' The items to place in the building interior when it's constructed or upgraded. This consists of a list of models with these fields:
 
{| class="wikitable"
 
{| class="wikitable"
 
|-
 
|-
! property
+
! field
! explanation
+
! effect
 
|-
 
|-
| <samp>AllowWakeUpWithoutBed {{t|allow}}</samp>
+
| <samp>Id</samp>
| Whether the player can wake up in this location without a bed, similar to the island farmhouse. This is typically used with <samp>PassOutLocations</samp> in [[#Custom location contexts|<samp>Data/LocationContexts</samp>]].
+
| The [[Modding:Common data field types#Unique string ID|unique string ID]] for this entry within the current list.
 
|-
 
|-
| <samp>DefaultWarpLocation {{t|x}} {{t|y}}</samp><br />''(valid in any location)''
+
| <samp>ItemId</samp>
| The default arrival tile, used when a player or NPC is added to the location without a target tile (e.g. using [[Modding:Console commands|debug commands]] like <samp>debug warp</samp> or <samp>debug eventbyid</samp>).
+
| The [[#Custom items|qualified item ID]] for the item to place.
 
|-
 
|-
| <samp>PetBowlLocation {{t|x}} {{t|y}}</samp><br />''(valid in the farm)''
+
| <samp>Tile</samp>
| The default position of the pet bowl
+
| The tile position at which to place the item, specified as an object with <samp>X</samp> and <samp>Y</samp> fields.
 +
|-
 +
| <samp>Indestructible</samp>
 +
| ''(Optional)'' Whether to prevent the player from destroying, picking up, or moving the item. Default false.
 +
|}
 
|-
 
|-
| <samp>SpouseRoomPosition {{t|x}} {{t|y}}</samp><br />''(valid in farmhouse)''
+
| <samp>MagicalConstruction</samp>
| The top-left position at which to place the [[Marriage#Spouse Rooms|spouse room]].
+
| ''(Optional)'' Whether the building is magical. This changes the carpenter menu to a mystic theme while this building's blueprint is selected, and completes the construction instantly when placed.
 
|-
 
|-
| <samp>TravelingCartPosition {{t|x}} {{t|y}}</samp><br />''(valid in the forest)''
+
| <samp>AddMailOnBuild</samp>
| The top-left position at which to place the [[Traveling Cart]]. This is the top-left corner of the collision box, so the roof will extend two tiles above this tile.
+
| ''(Optional)'' A list of [[Modding:Mail data|letter IDs]] to send to all players when the building is constructed for the first time.
 
|}
 
|}
   −
===Other map property changes===
+
====Upgrades====
{{/doc status|[[Modding:Maps]]|done=false}}
  −
 
   
{| class="wikitable"
 
{| class="wikitable"
 
|-
 
|-
! map property
+
! field
! changes
+
! effect
 +
|-
 +
| <samp>BuildingToUpgrade</samp>
 +
| ''(Optional)'' The ID of the building for which this is an upgrade, or omit to allow constructing it as a new building. For example, the [[Coop|Big Coop]] sets this to <samp>"Coop"</samp>. Any numbers of buildings can be an upgrade for the same building, in which case the player can choose one upgrade path.
 
|-
 
|-
| <samp>Arch</samp><br /><samp>asdf</samp><br /><samp>Debris</samp><br /><samp>Fish</samp>
+
| <samp>IndoorItemMoves</samp>
| Removed (these were unused).
+
| ''(Optional)'' When applied as an upgrade to an existing building, the placed items in its interior to move when transitioning to the new map. This is a list of models with these fields:
 +
{| class="wikitable"
 
|-
 
|-
| <samp>FarmHouseFlooring</samp><br /><samp>FarmHouseFurniture</samp><br /><samp>FarmHouseStarterSeedsPosition</samp><br /><samp>FarmHouseWallpaper</samp>
+
! field
| These now work independently. For example, you can now use <samp>FarmHouseFlooring</samp> without needing to set <samp>FarmHouseFurniture</samp> too.
+
! effect
 
|-
 
|-
| <samp>Music</samp>
+
| <samp>Id</samp>
| Deprecated; use the music fields in [[#Custom locations|<samp>Data/Locations</samp>]] instead. This property is only applied if the location has no music in <samp>Data/Locations</samp>. This was removed from all vanilla maps.
+
| The [[Modding:Common data field types#Unique string ID|unique string ID]] for this entry within the current list.
 
|-
 
|-
| <samp>NPCWarp</samp><br /><samp>Warp</samp>
+
| <samp>Source</samp>
| Now fault-tolerant. They'll automatically ignore extra spaces, log an informative warning if parsing still fails, and continue with the next warp if possible.
+
| The tile position on which any item will be moved.
 
|-
 
|-
| <samp>Stumps</samp>
+
| <samp>Destination</samp>
| Now works in all locations.
+
| The tile position to which to move the item.
 
|-
 
|-
| <samp>UniquePortrait</samp><br /><samp>UniqueSprite</samp>
+
| <samp>Size</samp>
| Deprecated; use [[#Custom NPC appearance|custom NPC appearances]] instead. These properties will override NPC appearances. This was removed from all vanilla maps.
+
| ''(Optional)'' The tile size of the area to move, specified as a model with <samp>X</samp> and <samp>Y</samp> fields. Defaults to a 1×1 area. If this is multiple tiles, the <samp>Source</samp> and <samp>Destination</samp> specify the top-left coordinate of the area.
 
|}
 
|}
  −
===Tile property changes===
  −
{{/doc status|[[Modding:Maps]]|done=false}}
  −
  −
<ul>
  −
<li>You can now override a tile index property by setting it as a tile property.</li>
  −
<li>Added new [[Modding:Maps|tile properties]]:
  −
{| class="wikitable"
  −
! layer
  −
! property
  −
! explanation
   
|-
 
|-
| <samp>Paths</samp>
+
| <samp>UpgradeSignTile</samp>
| <samp>SpawnTree {{t|category}} {{t|ID}} {{t|Growth stage}} {{t|Regrowth stage}}</samp>
+
| ''(Optional)'' The tile position relative to the top-left corner of the building where the upgrade sign will be placed when Robin is building an upgrade, in the form <samp>"{{t|x}}, {{t|y}}"</samp>. Defaults to approximately <samp>"5, 1"</samp> if the building interior type is <samp>Shed</samp>, else <samp>"0, 0"</samp>.
| Spawns a tree when the map is created. {{t|category}} may be either <samp>wild</samp> or <samp>fruit</samp>. <samp>wild</samp> will spawn a [[Trees|wild tree]], while <samp>fruit</samp> will spawn a [[Fruit Trees|fruit tree]].  
+
|-
 +
| <samp>UpgradeSignHeight</samp>
 +
| ''(Optional)'' The pixel height of the upgrade sign when Robin is building an upgrade. Defaults to 0.
 
|}
 
|}
</li>
+
 
<li>Added new <samp>Action</samp> [[Modding:Maps|tile properties]]:
+
====Exterior behavior====
 
{| class="wikitable"
 
{| class="wikitable"
 
|-
 
|-
! layer
+
! field
! property
+
! effect
! explanation
   
|-
 
|-
| <samp>Buildings</samp>
+
| <samp>Size</samp>
| <samp>Action BuildingSilo</samp>
+
| ''(Optional)'' The building's width and height when constructed, measured in tiles. Defaults to a 1 x 1 area.
| If a building covers this tile, enables [[silo]] interactions on this tile subject to the building's <samp>HayCapacity</samp> field in <samp>Data/Buildings</samp>.
   
|-
 
|-
| <samp>Buildings</samp>
+
| <samp>CollisionMap</samp>
| <samp>Action BuildingToggleAnimalDoor</samp>
+
| ''(Optional)'' An ASCII text block which indicates which of the building's tiles the players can walk onto, where each character can be <samp>X</samp> (blocked) or <samp>O</samp> (passable). Defaults to all tiles blocked.
| If a building covers this tile, opens or closes its animal door.
+
 
|-
+
For example, a [[stable]] covers a 2x4 tile area with the front two tiles passable:
| <samp>Buildings</samp>
+
<pre>XXXX
| <samp>Action Dialogue</samp>
+
XOOX</pre>
| &#32;
+
 
* The message can now be a [[Modding:Tokenizable strings|tokenizable string]].
+
When the collision map is parsed, leading/trailing whitespace is trimmed (both for the entire map and for each line). In JSON, you can specify it in two forms:
* Fixed the cursor not changing to the inspection icon when hovering on an <samp>Action Dialogue</samp> tile.
+
<syntaxhighlight lang="js">
 +
// single line with \n line breaks
 +
"CollisionMap": "XXXX\nXOOX"
 +
 
 +
// multi-line with optional indentation
 +
"CollisionMap": "
 +
    XXXX
 +
    XOOX
 +
"
 +
</syntaxhighlight>
 
|-
 
|-
| <samp>Buildings</samp>
+
| <samp>HumanDoor</samp>
| <samp>Action Forge</samp>
+
| ''(Optional)'' The position of the door that can be clicked to warp into the building interior. This is measured in tiles relative to the top-left corner tile. Defaults to disabled.
| Opens the [[Forge]] menu.
   
|-
 
|-
| <samp>Buildings</samp>
+
| <samp>AnimalDoor</samp>
| <samp>Action None</samp>
+
| ''(Optional)'' The position and size of the door that animals use to enter/exit the building, if the building interior is an animal location, specified as an object with <samp>X</samp>, <samp>Y</samp>, <samp>Width</samp>, and <samp>Height</samp> fields. This is measured in tiles relative to the top-left corner tile. Defaults to disabled.
| Does nothing. This is used to mark the tile interactive if the click will be handled separately.
   
|-
 
|-
| <samp>Buildings</samp>
+
| <samp>AnimalDoorOpenDuration</samp><br /><samp>AnimalDoorCloseDuration</samp>
| <samp>Action ObeliskWarp {{t|location name}} {{t|x}} {{t|y}} {{o|whether to dismount}}</samp>
+
| ''(Optional)'' The duration of the open/close animation for the animal door, measured in milliseconds. If omitted, the door switches to the open/closed state instantly.
| Warps the player to the specified location name and position with the [[Warp Totem|Obelisk]] animation/sound effects.
   
|-
 
|-
| <samp>Buildings</samp>
+
| <samp>AnimalDoorOpenSound</samp><br /><samp>AnimalDoorCloseSound</samp>
| <samp>Action OpenShop {{t|shop id}} {{o|from direction}} {{o|open time}} {{o|close time}} {{o|owner tile area}}</samp>
+
| ''(Optional)'' The sound which is played once each time the animal door is opened/closed. Disabled by default.
| Open the [[#Custom shops|shop]] with the given {{t|shop id}}. All arguments besides the ID are optional:
+
|}
* {{o|from direction}}: if specified, the player must be standing in this direction relative to the shop (one of <samp>down</samp>, <samp>up</samp>, <samp>left</samp>, <samp>right</samp>, or <samp>none</samp>). Setting this to <samp>none</samp> disables the requirement. The default for most vanilla shops is <samp>down</samp>.
+
 
* {{o|open time}} and {{o|close time}}: the start & end times in 26-hour format when the shop is available. Interacting with the tile outside those times does nothing.
+
====Exterior appearance====
* {{o|owner tile area}}: if specified, the tile area which must contain one of the shop owners for the shop to be available. For a custom shop, these are defined by its <samp>Owners</samp> field. This can be specified in two forms: <samp>{{t|x}} {{t|y}}</samp> for a single tile, or <samp>{{t|x}} {{t|y}} {{t|width}} {{t|height}}</samp> for a multi-tile area.
+
{| class="wikitable"
 
|-
 
|-
| <samp>Buildings</samp>
+
! field
| <samp>Action PlayEvent {{t|event id}} {{o|check preconditions}} {{o|skip if seen}} {{o|fallback action}}</samp>
+
! effect
| Immediately start an [[Modding:Event data|event]], subject to the conditions:
  −
* {{o|check preconditions}}: whether to ignore the action if the [[Modding:Event data#Event preconditions|event's preconditions]] don't match (one of <samp>true</samp> or <samp>false</samp>). Default true.
  −
* {{o|skip if seen}}: whether to ignore the action if the player has already seen the given event. Default true.
  −
 
  −
If the event doesn't start for any reason (including the preceding conditions):
  −
* If {{o|fallback action}} is specified, it'll be run as an action. This can be any <samp>Action</samp> tile property (without the "Action " prefix), like <code>Action PlayEvent 60367 true true PlayEvent 520702 false false</code> to play a different event.
  −
* Otherwise the action is silently ignored.
  −
 
  −
For example, <code>Action PlayEvent 60367 false false</code> will replay the bus arrival event from the start of the game.
  −
|}
  −
</li>
  −
<li>Added new <samp>TouchAction</samp> [[Modding:Maps|tile properties]]:
  −
{| class="wikitable"
   
|-
 
|-
! layer
+
| <samp>SourceRect</samp>
! property
+
| ''(Optional)'' The building's pixel area within the <samp>Texture</samp>, specified as an object with <samp>X</samp>, <samp>Y</samp>, <samp>Width</samp>, and <samp>Height</samp> fields. Defaults to the entire texture.
! explanation
   
|-
 
|-
| <samp>Back</samp>
+
| <samp>Skins</samp>
| <samp>TouchAction PlayEvent {{t|event id}} {{o|check preconditions}} {{o|skip if seen}} {{o|fallback action}}</samp>
+
| ''(Optional)'' The appearances which can be selected from Robin's menu (like stone/plank/log [[cabin]]s), in addition to the default appearance based on <samp>Texture</samp>. This consists of a list of models with these fields:
| Equivalent to <samp>Action PlayEvent</samp>, but activated on touch. Note that {{o|fallback action}} is an <samp>Action</samp> tile property, ''not'' a <samp>TouchAction</samp> tile property.
  −
|}</li>
  −
<li>Changed existing tile properties:
   
{| class="wikitable"
 
{| class="wikitable"
 
|-
 
|-
! layer
+
! field
! property
+
! effect
! reason
   
|-
 
|-
|rowspan="4"| <samp>Back</samp>
+
| <samp>Id</samp>
| <samp>NoSpawn</samp>
+
| The [[Modding:Common data field types#Unique string ID|unique string ID]] for the skin.
| Added <samp>NoSpawn false</samp> form, which disables any previous <samp>NoSpawn</samp> property on the tile. For example, this can be used to enable spawning on a tile which has a <samp>NoSpawn</samp> tile index property.
   
|-
 
|-
| <samp>TouchAction Bus</samp>
+
| <samp>Name</samp><br /><samp>Description</samp>
| Removed. This wasn't used by the game or mods.
+
| [[Modding:Tokenizable strings|Tokenizable strings]] for the skin's display name and description.
 
|-
 
|-
| <samp>TouchAction Emote</samp>
+
| <samp>Texture</samp>
| Fixed error if the specified NPC isn't found.
+
| The asset name for the texture under the game's Content folder.
 
|-
 
|-
| <samp>Treasure</samp>
+
| <samp>Condition</samp>
| Added <samp>Treasure Item {{t|item ID}}</samp> form which accepts a [[#Custom items|qualified or unqualified item ID]].
+
| ''(Optional)'' A [[Modding:Game state queries|game state query]] which indicates whether this skin should be available to apply. This doesn't change buildings which already have it applied. Defaults to always true.
 +
|-
 +
| <samp>BuildDays</samp><br /><samp>BuildCost</samp><br /><samp>BuildMaterials</samp>
 +
| ''(Optional)'' If set, overrides the equivalent field in the building data.
 
|-
 
|-
|rowspan="2"| <samp>Buildings</samp>
+
| <samp>ShowAsSeparateConstructionEntry</samp>
| <samp>Action ItemChest</samp><br /><samp>Action Minecart</samp><br /><samp>Action RemoveChest</samp>
+
| ''(Optional)'' Whether this skin should be shown as a separate building option in the construction menu (like cabins). Default false.
| Removed. These weren't used by the game or mods.
   
|-
 
|-
| <samp>Action Kitchen</samp>
+
| <samp>Metadata</samp>
| Now works in any location (including those without a fridge).
+
| ''(Optional)'' Equivalent to the <samp>Metadata</samp> field on the building. Properties defined in this field are added to the building's metadata when this skin is active, overwriting the previous property with the same name if applicable. Default none.
 
|}
 
|}
</li>
  −
</ul>
  −
  −
===Other location/map changes===
  −
{{/doc status|[[Modding:Maps]] and other pages as needed|done=false}}
  −
  −
* Farm data:
  −
** Added <samp>SpawnMonstersByDefault</samp> field to <samp>Data/AdditionalFarms</samp> to set the default value of the 'spawn monsters at night' [[Options#Advanced Game Options|advanced save option]].
  −
** Fixed crash on new-save screen if the farm type's tooltip has no description.
  −
* General location data:
  −
** All locations can now have animals. The <samp>IAnimalLocation</samp> is now obsolete and implemented by <samp>GameLocation</samp>.
  −
** Added new [[Modding:Fish data|fishing areas]] to simplify compatibility between fish & map mods (specifically for hilltop farm, wilderness farm, town, and desert).
  −
** Added a descriptive error when a required location or layer isn't found. Mods can use <samp>map.RequireLayer</samp> and <samp>Game1.RequireLocation</samp> to get a location with similar error-checking.
  −
** Added <samp>WarpPathfindingCache</samp> for C# mods, which modularizes the NPC warp route logic. You can edit its <samp>IgnoreLocationNames</samp>, <samp>OverrideTargetNames</samp>, and <samp>GenderRestrictions</samp> fields if needed for custom locations.
  −
** Game logic which checks tile indexes is now more fault-tolerant, so it won't crash if an expected tile was edited.
  −
** Finished migrating <samp>DecoratableLocation</samp> flooring/wallpaper areas to string IDs (started in Stardew Valley 1.5.5).
  −
* General map changes:
  −
** Added validation for [[Modding:Maps|map properties and tile properties]]. If the format is invalid, the game will now log a detailed error and skip it.
  −
** Removed unused [[Modding:Maps#Paths layer|path tiles]] in <samp>Maps/paths</samp> and all map files.
  −
* Location context data:
  −
** Building interiors now inherit their parent's location context by default.
  −
** Added <samp>Game1.locationContextData</samp> to cache the data from <samp>Data/LocationContexts</samp>.
  −
** Added constants for the vanilla context IDs like <samp>LocationContexts.IslandId</samp>.
  −
** Added validation for required location context IDs (and <samp>LocationContexts.Require(id)</samp> for mod logic).
  −
** Removed the <samp>Name</samp> field in <samp>Data/LocationContexts</samp>, which duplicated the ID.
  −
<ul>
  −
<li>Added methods to simplify common operations:
  −
{| class="wikitable"
   
|-
 
|-
! type
+
| <samp>FadeWhenBehind</samp>
! method
+
| ''(Optional)'' Whether the building should become semi-transparent when the player is behind it. Default true.
! effect
   
|-
 
|-
|rowspan="7"| <samp>Building</samp>
+
| <samp>DrawOffset</samp>
| <samp>GetParentLocation</samp>
+
| ''(Optional)'' A pixel offset applied to the building sprite's placement in the world. Default 0.
| Get the location which contains this building.
   
|-
 
|-
| <samp>IsInCurrentLocation</samp>
+
| <samp>SeasonOffset</samp>
| Get whether the building is in the same location as the current player.
+
| ''(Optional)'' A pixel offset to apply each season. This is applied to the <samp>SourceRect</samp> position by multiplying the offset by 0 (spring), 1 (summer), 2 (fall), or 3 (winter). Default 0, so all seasons use the same source rect.
 
|-
 
|-
| <samp>HasIndoors</samp>
+
| <samp>SortTileOffset</samp>
| Get whether the building has an interior location.
+
| ''(Optional)'' A Y tile offset applied when figuring out render layering. For example, a value of <samp>2.5</samp> will treat the building as if it was 2.5 tiles further up the screen for the purposes of layering. Default 0.
 
|-
 
|-
| <samp>GetIndoors</samp>
+
| <samp>DrawLayers</samp>
| Get the location within this building, if applicable.
+
| ''(Optional)'' A list of textures to draw over or behind the building, with support for conditions and animations. This consists of a list of models with these fields:
 +
{| class="wikitable"
 
|-
 
|-
| <samp>HasIndoorsName</samp>
+
! field
| Get whether the building has an interior location and its unique name matches the given value (like <code>building.HasIndoorsName("FarmHouse")</code>).
+
! effect
 
|-
 
|-
| <samp>GetIndoorsName</samp>
+
| <samp>Id</samp>
| Get the unique name of the location within this building, if applicable.
+
| The [[Modding:Common data field types#Unique string ID|unique string ID]] for this entry within the current list.
 
|-
 
|-
| ...
+
| <samp>SourceRect</samp>
| ''see also [[#Other building changes|other building changes]] for non-location methods.''
+
| The pixel area within the <samp>texture</samp> to draw, formatted like <samp>"{{t|x}} {{t|y}} {{t|width}} {{t|height}}"</samp>. If the overlay is animated via <samp>FrameCount</samp>, this is the area of the first frame.
 
|-
 
|-
|rowspan="7"|<samp>Cabin</samp><br /><samp>FarmHouse</samp>
+
| <samp>DrawPosition</samp>
| <samp>GetCellar</samp>
+
| The tile position at which to draw the top-left corner of the texture, relative to the building's top-left corner tile.
| Get the [[cellar]] location linked to this cabin, if any.
   
|-
 
|-
| <samp>CanAssignFarmhand</samp><br /><samp>AssignFarmhand</samp>
+
| <samp>Texture</samp>
| ''(Cabin only)'' Check whether the cabin is available to assign to a farmhand, or perform the assignment.
+
| ''(Optional)'' The asset name of the texture to draw. Defaults to the building's default <samp>Texture</samp> field.
 
|-
 
|-
| <samp>HasOwner</samp>
+
| <samp>DrawInBackground</samp>
| Get whether the home has an assigned player, regardless of whether they've finished creating their character.
+
| ''(Optional)'' Whether to draw the texture behind the building sprite (i.e. underlay) instead of over it.
 
|-
 
|-
| <samp>OwnerId</samp>
+
| <samp>SortTileOffset</samp>
| Get the unique ID of the player who owns this home, if any.
+
| ''(Optional)'' A Y tile offset applied when figuring out render layering. For example, a value of <samp>2.5</samp> will treat the texture as if it was 2.5 tiles further up the screen for the purposes of layering. Default 0.
 
|-
 
|-
| <samp>IsOwnedByCurrentPlayer</samp>
+
| <samp>OnlyDrawIfChestHasContents</samp>
| Get whether the cabin belongs to the current player.
+
| ''(Optional)'' The ID of a chest defined in the <samp>Chests</samp> field which must contain items. If it's empty, this overlay won't be rendered. Default none.
 
|-
 
|-
| <samp>IsOwnerActivated</samp>
+
| <samp>FrameCount</samp><br /><samp>FramesPerRow</samp><br /><samp>FrameDuration</samp>
| Get whether the home has an assigned player and they've finished creating their character.
+
| ''(Optional)'' If <samp>FrameCount</samp> is more than one, the building overlay will be animated automatically. For each frame, the <samp>SourceRect</samp> will be offset by its <samp>Width</samp> to the right up to <samp>FramesPerRow - 1</samp> times, and then down by its <samp>Height</samp>. Each frame will be rendered on-screen for <samp>FrameDuration</samp> milliseconds before switching to the next frame.
 +
 
 +
For example, if you set <samp>FrameCount</samp> to 6 and <samp>FramesPerRow</samp> to 3, the building will expect the frames to be laid out like this in the spritesheet (where frame 1 matches <samp>SourceRect</samp>):
 +
<pre>
 +
┌───┬───┬───┐
 +
│ 1 │ 2 │ 3 │
 +
├───┼───┼───┤
 +
│ 4 │ 5 │ 6 │
 +
└───┴───┴───┘
 +
</pre>
 
|-
 
|-
| <samp>HasNpcSpouse</samp>
+
| <samp>AnimalDoorOffset</samp>
| Get whether the player who owns this home is married to any NPC (when used like <samp>HasNpcSpouse()</samp>) or a specific NPC (like <samp>HasNpcSpouse(name)</samp>). This also replaces <samp>shouldShowSpouseRoom()</samp>.
+
| ''(Optional)'' A pixel offset applied to the draw layer when the animal door is open. While the door is opening, the percentage open is applied to the offset (e.g. 50% open = 50% offset).
 +
|}
 
|-
 
|-
|rowspan="2"| <samp>Farm</samp>
+
| <samp>DrawShadow</samp>
| <samp>GetStarterFarmhouseLocation</samp>
+
| ''(Optional)'' Whether to draw an automatic shadow along the bottom edge of the building's sprite. Default true.
| Get the default tile position for the farmhouse. (See also <samp>farm.GetMainFarmHouseEntry()</samp>.)
+
|}
 +
 
 +
====Interior====
 +
{| class="wikitable"
 
|-
 
|-
| <samp>GetStarterPetBowlLocation</samp>
+
! field
| Get the default tile position for the pet bowl.
+
! effect
 
|-
 
|-
|rowspan="19"| <samp>GameLocation</samp>
+
| <samp>IndoorMap</samp>
| <samp>AddDefaultBuildings</samp>
+
| ''(Optional)'' The name of the map asset under <samp>Maps</samp> to load for the building interior. For example, <samp>"Shed"</samp> will load the [[shed]]'s <samp>Maps/Shed</samp> map.
| Can be overridden to add custom buildings when the location is created and/or loaded. These can either be re-added whenever they're missing (like the vanilla farmhouse), or only built once on save creation (like the vanilla pre-built cabins).
  −
 
  −
This replaces the former <samp>farm.AddModularShippingBin()</samp> method.
   
|-
 
|-
| <samp>GetFridge</samp><br /><samp>GetFridgePosition</samp>
+
| <samp>IndoorMapType</samp>
| Get the fridge's chest or tile position, if the location has one.
+
| ''(Optional)'' The full name of the C# location class which will manage the building's interior location. This must be one of the vanilla types to avoid a crash when saving. There are too many to list here, but the most useful types are likely...
|-
+
* <samp>StardewValley.AnimalHouse</samp>;
| <samp>GetSeason</samp><br /><samp>GetSeasonIndex</samp><br /><samp>GetSeasonKey</samp>
+
* <samp>StardewValley.Locations.Cabin</samp>;
| Get the local season that applies within the location as an enum, number (like <samp>0</samp> for spring), or string (like <samp>spring</samp>) respectively. For example, it's always summer on [[Ginger Island]].
+
* <samp>StardewValley.Locations.Cellar</samp>;
 +
* <samp>StardewValley.Locations.DecoratableLocation</samp>;
 +
* <samp>StardewValley.Locations.FarmCave</samp>;
 +
* <samp>StardewValley.Locations.FarmHouse</samp>;
 +
* <samp>StardewValley.Shed</samp>;
 +
* and <samp>StardewValley.SlimeHutch</samp>.
 +
Defaults to the generic <samp>StardewValley.GameLocation</samp> class.
 
|-
 
|-
| <samp>GetWeather</samp><br /><samp>IsDebrisWeatherHere</samp><br /><samp>IsLightningHere</samp><br /><samp>IsRainingHere</samp><br /><samp>IsSnowingHere</samp>
+
| <samp>NonInstancedIndoorLocation</samp>
| Get the current weather in this location's context, regardless of whether the player is indoors and sheltered from it.
+
| ''(Optional)'' The name of the existing global location to treat as the building's interior, like <samp>FarmHouse</samp> and <samp>Greenhouse</samp> for their buildings.
 +
 
 +
Each location can only be used by one building. If the location is already in use (e.g. because the player has two of this building), each subsequent building will use the <samp>IndoorMap</samp> and <samp>IndoorMapType</samp> instead. For example, the first greenhouse will use the global <samp>Greenhouse</samp> location, and any subsequent greenhouse will use a separate instanced location.
 
|-
 
|-
| <samp>InDesertContext</samp><br /><samp>InIslandContext</samp><br /><samp>InValleyContext</samp>
+
| <samp>MaxOccupants</samp>
| Get whether this location is within the <samp>Island</samp> or <samp>Default</samp> location context respectively.
+
| ''(Optional)'' The maximum number of animals who can live in this building.
 
|-
 
|-
| <samp>IsActiveLocation</samp>
+
| <samp>AllowAnimalPregnancy</samp>
| Get whether this location is actively synced to the current player (see [[Modding:Modder Guide/Game Fundamentals#Farmhand shadow world|farmhand shadow world]]).
+
| ''(Optional)'' Whether animals can get pregnant and produce offspring in this building. Default false.
 
|-
 
|-
| <samp>IsTemporary</samp>
+
| <samp>ValidOccupantTypes</samp>
| Get whether this is a temporary location for a festival or minigame. This is cached based on the location name (e.g. locations starting with <samp>Temp</samp> or some other specific names).
+
| ''(Optional)'' A list of building IDs whose animals to allow in this building too. For example, <code>[ "Barn", "Coop" ]</code> will allow [[barn]] and [[coop]] animals in this building. Default none.
 +
|}
 +
 
 +
====Item processing====
 +
{| class="wikitable"
 
|-
 
|-
| <samp>GetLocationContextId</samp>
+
! field
| Get the ID of the location context in <samp>Data/LocationContexts</samp> which contains this building.
+
! effect
 
|-
 
|-
| <samp>GetContainingBuilding</samp>
+
| <samp>HayCapacity</samp>
| Get the building instance which contains this location (like the cabin for a cabin interior), if applicable.
+
| ''(Optional)'' The amount of hay that can be stored in this building. If built on the [[The Farm|farm]], this works just like [[silo]]s and contributes to the farm's available hay.
 
|-
 
|-
| <samp>GetParentLocation</samp>
+
| <samp>ItemConversions</samp>
| Get the parent location which contains this one (like the farm for a cabin interior), or <samp>null</samp> if it has no parent.
+
| ''(Optional)'' The item processing rules which take input items and convert them into output items using the inventories defined by <samp>Chests</samp>. This consists of a list of models with these fields:
 +
{| class="wikitable"
 +
|-
 +
! field
 +
! effect
 +
|-
 +
| <samp>Id</samp>
 +
| The [[Modding:Common data field types#Unique string ID|unique string ID]] for this rule within the current list.
 
|-
 
|-
| <samp>GetRootLocation</samp>
+
| <samp>RequiredTags</samp>
| Get the parent location which contains this one (like the farm for a cabin interior), or the location itself if it has no parent.
+
| A list of [[Modding:Items#Context tags|context tags]] to match against an input item. An item must have ''all'' of these tags to be accepted.
 
|-
 
|-
| <samp>GetInstancedBuildingInteriors</samp>
+
| <samp>SourceChest</samp>
| Get all building interiors within this location which are instanced to the building (i.e. not in <samp>Game1.locations</samp> separately).
+
| The ID of the inventory defined in <samp>Chests</samp> from which to take input items.
 
|-
 
|-
| <samp>GetMapPropertySplitBySpaces</samp><br /><samp>GetTilePropertySplitBySpaces</samp>
+
| <samp>DestinationChest</samp>
| Get the value of a map/tile property and split it into individual words. If the map/tile property isn't defined, returns an empty array.
+
| The ID of the inventory defined in <samp>Chests</samp> in which to store output items.
 
  −
For example:
  −
<syntaxhighlight lang="c#">
  −
string[] fields = Game1.currentLocation.GetMapPropertySplitBySpaces("ScreenshotRegion");
  −
</syntaxhighlight>
   
|-
 
|-
| <samp>HasMapPropertyWithValue</samp>
+
| <samp>ProducedItems</samp>
| Get whether a map property is defined and has a non-empty value.
+
| The output items produced when an input item is converted. This consists of a list of models with these fields:
 
+
{| class="wikitable"
For example:
  −
<syntaxhighlight lang="c#">
  −
bool canUseCasks = Game1.currentLocation.HasMapPropertyWithValue("CanCaskHere");
  −
</syntaxhighlight>
   
|-
 
|-
| <samp>StoreHayInAnySilo</samp>
+
! field
| Add hay to any silo with free space (preferring silos in the current location, then the farm, then anywhere).
+
! effect
 
|-
 
|-
| <samp>TryGetMapProperty</samp>
+
| ''common fields''
| Get a map property value as a string, if it's defined.
+
| See [[Modding:Item queries#Item spawn fields|item spawn fields]] for the generic item fields supported by machine output.
   −
For example:
+
If set to an [[Modding:Item queries|item query]] which returns multiple items, one of them will be selected at random.
<syntaxhighlight lang="c#">
  −
if (this.TryGetMapProperty("Warps", out string warps))
  −
{
  −
    // ...
  −
}
  −
</syntaxhighlight>
   
|-
 
|-
| <samp>TryGetMapPropertyAs</samp>
+
| <samp>Chance</samp>
| Get a map property and parse it into into a <samp>bool</samp>, <samp>double</samp>, <samp>Point</samp>, <samp>Rectangle</samp>, or <samp>Vector2</samp> value.
+
| ''(Optional)'' The probability that the item will be produced, as a value between 0 (never drops) and 1 (always drops). Default 1 (100% chance).
 
+
|}
For example:
  −
<syntaxhighlight lang="c#">
  −
if (!this.TryGetMapPropertyAs("MailboxLocation", out Point position))
  −
{
  −
    position = new Point(68, 16); // default value
  −
}
  −
</syntaxhighlight>
   
|-
 
|-
| <samp>removeObjectsAndSpawned</samp>
+
| <samp>RequiredCount</samp>
| Remove all objects, bushes, resource clumps, and terrain features within a tile area.
+
| ''(Optional)'' The number of the input item to consume. Default 1.
 
|-
 
|-
| <samp>OnBuildingConstructed</samp><br /><samp>OnBuildingMoved</samp><br /><samp>OnBuildingDemolished</samp>
+
| <samp>MaxDailyConversions</samp>
| These methods are called for all players when any player constructs, moves, or demolishes a building.
+
| ''(Optional)'' The maximum number of the input item which can be processed each day. Each conversion rule has its own separate maximum (e.g. if you have two rules each with a max of 1, then you can convert one of each daily). Set to -1 to allow unlimited conversions. Default 1.
 +
|}
 
|-
 
|-
|rowspan="3"| <samp>LibraryMuseum</samp>
+
| <samp>Chests</samp>
| <samp>HasDonatedArtifacts()</samp>
+
| ''(Optional)'' The input/output inventories that can be accessed from a tile on the building exterior. The allowed items are defined by the separate <samp>ItemConversions</samp> field. This is a list of models with these fields:
| Get whether any items have been donated to the [[museum]].
+
{| class="wikitable"
 
|-
 
|-
| <samp>HasDonatedArtifactAt(tile)</samp>
+
! field
| Get whether any donated item is currently placed at the given tile position within the [[museum]].
+
! effect
 
|-
 
|-
| <samp>HasDonatedArtifact(itemId)</samp>
+
| <samp>Id</samp>
| Get whether an artifact with the given qualified or unqualified item ID has been donated to the [[museum]].
+
| The [[Modding:Common data field types#Unique string ID|unique string ID]] for this chest within the current list.
 +
 
 +
This is referenced from the <samp>ItemConversions</samp> field.
 
|-
 
|-
|rowspan="2"| <samp>MineShaft</samp>
+
| <samp>Type</samp>
| <samp>GetLevelName</samp>
+
| The inventory type. This must be one of:
| Get the location name for a generated [[The Mines|mine]] or [[Skull Cavern]] level.
+
* <samp>Chest</samp>: show a normal chest UI on click.
 
+
* <samp>Collect</samp>: provides items for the player to collect. Clicking the tile will do nothing (if empty), grab the item directly (if it only contains one item), else show a grab-only inventory UI.
For example:
+
* <samp>Load</samp>: lets the player add items for the building to process.
<syntaxhighlight lang="c#">
+
|-
string locationName = MineShaft.GetLevelName(10); // returns "UndergroundMine10"
+
| <samp>Sound</samp>
Game1.warpFarmer(locationName, 0, 0, false);
+
| ''(Optional)'' The sound to play once when the player clicks the chest.
</syntaxhighlight>
+
|-
 +
| <samp>InvalidItemMessage</samp><br /><samp>InvalidCountMessage</samp><br /><samp>ChestFullMessage</samp>
 +
| ''(Optional)'' A [[Modding:Tokenizable strings|tokenizable string]] to show when the player tries to add an item to the chest when...
 +
* it isn't a supported item;
 +
* it's supported but they don't have enough in their inventory;
 +
* the chest has no more room to accept it.
 +
If omitted, the player interaction is ignored with no message shown.
 +
|-
 +
| <samp>InvalidItemMessageCondition</samp>
 +
| ''(Optional)'' A [[Modding:Game state queries|game state query]] which indicates whether <samp>InvalidItemMessage</samp> should be shown. This can use item-related queries like <samp>ITEM_TYPE</samp>. Defaults to always true.
 +
|-
 +
| <samp>DisplayTile</samp>
 +
| ''(Optional)'' The chest's position on the building exterior, measured in tiles from the top-left corner of the building, specified in the form <samp>"{{t|x}}, {{t|y}}"</samp>. This affects the position of the 'item ready to collect' bubble. If omitted, the bubble is disabled.
 
|-
 
|-
| <samp>IsGeneratedLevel</samp>
+
| <samp>DisplayHeight</samp>
| Get whether a location or location name is a generated [[The Mines|mine]] or [[Skull Cavern]] level.
+
| ''(Optional)'' If <samp>DisplayTile</samp> is set, the chest's tile height like <samp>1.5</samp>.
 +
|}
 +
|}
   −
For example:
+
====Tile interactions====
<syntaxhighlight lang="c#">
+
{| class="wikitable"
string locationName = "UndergroundMine10";
  −
bool isMine = MineShaft.IsGeneratedLevel(locationName, out int level); // returns true, 10
  −
</syntaxhighlight>
   
|-
 
|-
| <samp>VolcanoDungeon</samp>
+
! field
| <samp>GetLevelName</samp><br /><samp>IsGeneratedLevel</samp>
+
! effect
| Equivalent to the matching <samp>MineShaft</samp> methods, but for the [[Volcano Dungeon]].
+
|-
|}
+
| <samp>ActionTiles</samp>
</li>
+
| ''(Optional)'' A list of tiles which the player can click to trigger an <samp>Action</samp> [[Modding:Maps|map tile property]]. This consists of a list of models with these fields:
</ul>
  −
* Added map/tile property <samp>TryAdd</samp>/<samp>TryGetValue</samp> extensions in <samp>StardewValley.Extensions</samp> for string property values. For example, this lets you do <samp>map.Properties.TryGetValue(key, out string value)</samp>.
  −
* <samp>MineShaft.tryToAddMonster</samp> now returns whether a monster was added.
  −
* <samp>Game1.GetNumberBuildingsConstructed</samp> and <samp>location.getNumberBuildingsConstructed</samp> now have overloads to count all building types and/or specify whether to count under-construction buildings.
  −
* Fixed <samp>location.refurbishMapPortion</samp> copying <samp>Back</samp> source properties to the <samp>Building</samp> target layer.
  −
* Fixed door warps in custom indoor locations not consistently detected by the game.
  −
 
  −
==What's new for buildings==
  −
===Custom buildings===
  −
{{/doc status|[[Modding:Blueprint data]]|done=false}}
  −
 
  −
You can now add custom buildings by editing the <samp>Data/Buildings</samp> asset. This consists of a string → model lookup, where...
  −
* The key is a [[Modding:Common data field types#Unique string ID|unique string ID]] for the building type.
  −
* The value is a model with the fields listed below.
  −
 
  −
====Required fields====
   
{| class="wikitable"
 
{| class="wikitable"
 
|-
 
|-
Line 2,663: Line 2,411:  
! effect
 
! effect
 
|-
 
|-
| <samp>Name</samp><br /><samp>Description</samp>
+
| <samp>Id</samp>
| A [[Modding:Tokenizable strings|tokenizable string]] for the display name and description (e.g. shown in the construction menu).
+
| The [[Modding:Common data field types#Unique string ID|unique string ID]] for this entry within the current list.
 +
|-
 +
| <samp>Tile</samp>
 +
| The tile position, relative to the building's top-left corner tile.
 
|-
 
|-
| <samp>Texture</samp>
+
| <samp>Action</samp>
| The asset name for the texture under the game's Content folder.
+
| The [[Modding:Tokenizable strings|tokenizable string]] for the action to perform, excluding the <samp>Action</samp> prefix. For example, <samp>"Dialogue Hi there @!"</samp> to show a messagebox like "''Hi there <player name>!''". The tokenizable string is expected before the action is raised. See the [[Modding:Maps#Tile properties 2|list of tile properties]] for useful <samp>Action</samp> values.
 
|}
 
|}
 
+
|-
====Construction====
+
| <samp>DefaultAction</samp>
 +
| ''(Optional)'' The default tile action if the clicked tile isn't in <samp>ActionTiles</samp>. Default none.
 +
|-
 +
| <samp>TileProperties</samp>
 +
| ''(Optional)'' The [[Modding:Maps|map tile properties]] to set. This consists of a list of models with these fields:
 
{| class="wikitable"
 
{| class="wikitable"
 
|-
 
|-
Line 2,676: Line 2,431:  
! effect
 
! effect
 
|-
 
|-
| <samp>Builder</samp>
+
| <samp>Id</samp>
| ''(Optional)'' The NPC from whom you can request construction. The vanilla values are [[Carpenter's Shop|<samp>Robin</samp>]] and [[Wizard's Tower#Buildings|<samp>Wizard</samp>]], but you can specify a different name if a C# mod opens a construction menu for them. Defaults to <samp>Robin</samp>. If omitted, it won't appear in any menu.
+
| The [[Modding:Common data field types#Unique string ID|unique string ID]] for this entry within the current list.
 
|-
 
|-
| <samp>BuildCost</samp>
+
| <samp>Name</samp>
| ''(Optional)'' The gold cost to construct the building. Defaults to {{price|0}}.
+
| The tile property name to set.
 
|-
 
|-
| <samp>BuildMaterials</samp>
+
| <samp>Value</samp>
| ''(Optional)'' The materials you must provide to start construction, as a list of models with these fields:
+
| ''(Optional)'' The tile property value to set, or omit to set a null value.
{| class="wikitable"
   
|-
 
|-
! field
+
| <samp>Layer</samp>
! effect
+
| The name of the map layer whose tiles to change.
 
|-
 
|-
| <samp>Id</samp>
+
| <samp>TileArea</samp>
| ''(Optional)'' The [[Modding:Common data field types#Unique string ID|unique string ID]] for this entry within the current list. Defaults to the <samp>ItemId</samp> if not specified.
+
| The tiles to which to add the property, relative to the top-left corner of the building's collision box. This is specified as an object with <samp>X</samp>, <samp>Y</samp>, <samp>Width</samp>, and <samp>Height</samp> fields.
 +
|}
 
|-
 
|-
| <samp>ItemId</samp>
+
| <samp>AdditionalTilePropertyRadius</samp>
| The required item ID (qualified or unqualified).
+
| ''(Optional)'' When checking whether the player clicked on a <samp>TileProperties</samp> tile, an added distance around the building at which tile locations may be placed. Default 0, so only tile properties within the normal building bounds will work.
|-
  −
| <samp>Amount</samp>
  −
| The number of the item required.
   
|}
 
|}
|-
+
 
| <samp>BuildDays</samp>
+
====Advanced====
| ''(Optional)'' The number of days needed to complete construction (e.g. <samp>1</samp> for a building completed the next day). If set to 0, construction finishes instantly. Defaults to 0.
  −
|-
  −
| <samp>BuildCondition</samp>
  −
| ''(Optional)'' A [[Modding:Game state queries|game state query]] which indicates whether the building should be available in the construction menu. Defaults to always available.
  −
|-
  −
| <samp>BuildMenuDrawOffset</samp>
  −
| ''(Optional)'' A pixel offset to apply to the building sprite when drawn in the construction menu. Default none.
  −
|-
  −
| <samp>AdditionalPlacementTiles</samp>
  −
| ''(Optional)'' The extra tiles to treat as part of the building when placing it through the construction menu. For example, the farmhouse uses this to make sure the stairs are clear. This consists of a list of models with these fields:
   
{| class="wikitable"
 
{| class="wikitable"
 
|-
 
|-
Line 2,715: Line 2,457:  
! effect
 
! effect
 
|-
 
|-
| <samp>TileArea</samp>
+
| <samp>Metadata</samp>
| The tile area relative to the top-left corner of the building, specified as an object with <samp>X</samp>, <samp>Y</samp>, <samp>Width</samp>, and <samp>Height</samp> fields.
+
| ''(Optional)'' A list of custom properties applied to the building, which can optionally be overridden per-skin in the <samp>Skins</samp> field. Default none.
 +
 
 +
The base game recognizes these properties:
 +
{| class="wikitable"
 +
|-
 +
! property
 +
! description
 
|-
 
|-
| <samp>OnlyNeedsToBePassable</samp>
+
| <samp>ChimneyPosition: {{t|x}} {{t|y}}</samp>
| ''(Optional)'' Whether this area allows tiles that would normally not be buildable, so long as they are passable. For example, this is used to ensure that an entrance is accessible. Default false.
+
| ''(Optional)'' The pixel position at which to place a chimney on the building exterior, relative to the top-left corner of the sprite. This will apply the same logic as the farmhouse chimney (e.g. producing smoke if there's a lit fireplace inside the building).
 +
|-
 +
| <samp>ChimneyPosition{{o|upgrade level}}: {{t|x}} {{t|y}}</samp>
 +
| ''(Optional, for farmhouses/cabins only)'' Override <samp>ChimneyPosition</samp> for the given upgrade level, starting from 0 for the initial farmhouse/cabin. If there's no override for the current upgrade level, the highest override for a lower upgrade level is used (if any). For example, <samp>ChimneyPosition3</samp> would be used for the third house upgrade (and the fourth if there's no <samp>ChimneyPosition4</samp>).
 
|}
 
|}
 +
 +
This can also contain arbitrary custom properties, which C# mods can read using <samp>building.GetMetadata(key)</samp>.
 
|-
 
|-
| <samp>IndoorItems</samp>
+
| <samp>BuildingType</samp>
| ''(Optional)'' The items to place in the building interior when it's constructed or upgraded. This consists of a list of models with these fields:
+
| ''(Optional)'' The full name of the C# type to instantiate for the building instance. Defaults to a generic <samp>Building</samp> instance.
{| class="wikitable"
+
 
 +
'''⚠ Caution:''' this is meant to support vanilla building types like <samp>StardewValley.Shed</samp>. Setting this to a non-vanilla type will cause a crash when it's written to the save file, and may cause crashes in multiplayer. If you need custom behavior, consider handling it in C# based on the building type instead of creating a custom subclass; otherwise you'll need a framework mod like {{nexus mod|1348|SpaceCore}} to handle serialization and multiplayer sync.
 
|-
 
|-
! field
+
| <samp>ModData</samp>
! effect
+
| ''(Optional)'' A string → string lookup of arbitrary <samp>modData</samp> values to attach to the building when it's constructed.
 
|-
 
|-
| <samp>Id</samp>
+
| <samp>CustomFields</samp>
| The [[Modding:Common data field types#Unique string ID|unique string ID]] for this entry within the current list.
+
| The [[#Custom data fields|custom fields]] for this entry.
|-
  −
| <samp>ItemId</samp>
  −
| The [[#Custom items|qualified item ID]] for the item to place.
  −
|-
  −
| <samp>Tile</samp>
  −
| The tile position at which to place the item, specified as an object with <samp>X</samp> and <samp>Y</samp> fields.
  −
|-
  −
| <samp>Indestructible</samp>
  −
| ''(Optional)'' Whether to prevent the player from destroying, picking up, or moving the item. Default false.
  −
|}
  −
|-
  −
| <samp>MagicalConstruction</samp>
  −
| ''(Optional)'' Whether the building is magical. This changes the carpenter menu to a mystic theme while this building's blueprint is selected, and completes the construction instantly when placed.
  −
|-
  −
| <samp>AddMailOnBuild</samp>
  −
| ''(Optional)'' A list of [[Modding:Mail data|letter IDs]] to send to all players when the building is constructed for the first time.
   
|}
 
|}
   −
====Upgrades====
+
===Build anywhere===
{| class="wikitable"
+
{{/doc status|[[Modding:Blueprint data]] and [[Modding:Maps]]|done=false}}
|-
+
 
! field
+
* You can now allow building construction for any location using the [[#Map/tile property changes|new <samp>CanBuildHere</samp> and related map properties]]. The game will adjust accordingly (e.g. Robin will let you choose where to construct the building).
! effect
+
* Buildings and animals are no longer hardcoded to the [[The Farm|farm]] location (except [[cabin]]s and the [[farmhouse]] which still are).
|-
+
* Scything hay will now add hay to silos in any location, and animals will be auto-fed from hay in any location.
| <samp>BuildingToUpgrade</samp>
+
 
| ''(Optional)'' The ID of the building for which this is an upgrade, or omit to allow constructing it as a new building. For example, the [[Coop|Big Coop]] sets this to <samp>"Coop"</samp>. Any numbers of buildings can be an upgrade for the same building, in which case the player can choose one upgrade path.
+
===Other building changes===
|-
+
{{/doc status|[[Modding:Blueprint data]]|done=false}}
| <samp>IndoorItemMoves</samp>
+
 
| ''(Optional)'' When applied as an upgrade to an existing building, the placed items in its interior to move when transitioning to the new map. This is a list of models with these fields:
+
: ''See also: [[#Other location/map changes|other location changes]] for location-related building changes.''
 +
 
 +
; General building changes
 +
* Building display names & descriptions are now in <samp>Strings/Buildings</samp> for reuse.
 +
* Removed <samp>Data/Blueprints</samp>. This has been replaced by <samp>Data/Buildings</samp> (building data) and <samp>Strings/Buildings</samp> (display names & descriptions).
 +
<ul>
 +
<li>Added methods to simplify common operations:
 
{| class="wikitable"
 
{| class="wikitable"
 
|-
 
|-
! field
+
! type
 +
! method
 
! effect
 
! effect
 
|-
 
|-
| <samp>Id</samp>
+
|rowspan="7"| <samp>Building</samp>
| The [[Modding:Common data field types#Unique string ID|unique string ID]] for this entry within the current list.
+
| <samp>CreateInstanceFromId</samp>
 +
| Create a building instance from its type ID in <samp>Data/Buildings</samp>. For example:
 +
<syntaxhighlight lang="c#">
 +
Building shippingBin = Building.CreateInstanceFromId("Shipping Bin", Vector2.Zero); // creates an instance of StardewValley.Buildings.ShippingBin
 +
</syntaxhighlight>
 
|-
 
|-
| <samp>Source</samp>
+
| <samp>GetData</samp><br /><samp>TryGetData</samp>
| The tile position on which any item will be moved.
+
| Get the data for the building's type from <samp>Data/Building</samp>.
 
|-
 
|-
| <samp>Destination</samp>
+
| <samp>GetMetadata</samp>
| The tile position to which to move the item.
+
| Get a value from [[#Custom buildings|the <samp>Metadata</samp> field in <samp>Data/Buildings</samp>]] for this building.
 
|-
 
|-
| <samp>Size</samp>
+
| <samp>GetPaintDataKey</samp>
| ''(Optional)'' The tile size of the area to move, specified as a model with <samp>X</samp> and <samp>Y</samp> fields. Defaults to a 1×1 area. If this is multiple tiles, the <samp>Source</samp> and <samp>Destination</samp> specify the top-left coordinate of the area.
+
| Get the key in <samp>Data/PaintData</samp> for this building, if it has any.
|}
   
|-
 
|-
| <samp>UpgradeSignTile</samp>
+
| <samp>ReloadBuildingData</samp>
| ''(Optional)'' The tile position relative to the top-left corner of the building where the upgrade sign will be placed when Robin is building an upgrade, in the form <samp>"{{t|x}}, {{t|y}}"</samp>. Defaults to approximately <samp>"5, 1"</samp> if the building interior type is <samp>Shed</samp>, else <samp>"0, 0"</samp>.
+
| Apply the latest data in <samp>Data/Buildings</samp> to this building.
 +
|-
 +
| <samp>FinishConstruction</samp>
 +
| If the building is being constructed or upgrade, instantly finish doing so.
 +
|-
 +
| <samp>UpdateTransparency</samp>
 +
| Update the building transparency on tick for the local player's position.
 +
 
 +
This method mainly exists to let mods override/patch the transparency logic.
 +
|-
 +
| <samp>Farm</samp>
 +
| <samp>GetMainFarmHouse</samp>
 +
| Get the main [[farmhouse]] building.
 
|-
 
|-
| <samp>UpgradeSignHeight</samp>
+
| <samp>GameLocation</samp>
| ''(Optional)'' The pixel height of the upgrade sign when Robin is building an upgrade. Defaults to 0.
+
| <samp>OnParentBuildingUpgraded</samp>
 +
| Called when the building containing this location is upgraded, if applicable.
 
|}
 
|}
 +
</li>
 +
</ul>
 +
* Added building <samp>id</samp> field, which uniquely identifies each building in the world.
 +
 +
; [[Junimo Hut|Junimo hut]] changes
 +
* The <samp>JunimoHut.cropHarvestRange</samp> field is now per-building and editable.
   −
====Exterior behavior====
+
; [[Fish Pond|Fish pond]] changes
 +
<ul>
 +
<li>In <samp>Data/FishPondData</samp>, added a <samp>Precedence</samp> field which sets the order in which entries are checked for a match (with lower values checked first). This ensures that the fallback entries are checked after specific fish. For consistency, vanilla entries use these values:
 
{| class="wikitable"
 
{| class="wikitable"
 
|-
 
|-
! field
+
! precedence
! effect
+
! used for
 +
|-
 +
| 0<br /><small>(default value)</small>
 +
| specific fish
 
|-
 
|-
| <samp>Size</samp>
+
| 100
| ''(Optional)'' The building's width and height when constructed, measured in tiles. Defaults to a 1 x 1 area.
+
| custom groups (e.g. desert fish)
 
|-
 
|-
| <samp>CollisionMap</samp>
+
| 500
| ''(Optional)'' An ASCII text block which indicates which of the building's tiles the players can walk onto, where each character can be <samp>X</samp> (blocked) or <samp>O</samp> (passable). Defaults to all tiles blocked.
+
| broad fish type (e.g. ocean fish)
 
+
|-
For example, a [[stable]] covers a 2x4 tile area with the front two tiles passable:
+
| 1000
<pre>XXXX
+
| fallback (e.g. fish category)
XOOX</pre>
+
|}
 +
</li>
 +
<li>In <samp>Data/FishPondData</samp>, the reward <samp>ItemId</samp> can now be an [[Modding:Item queries|item query]].</li>
 +
<li>[[Legendary Fish|Legendary fish]] can now be added to [[Fish Pond|fish ponds]] if they have an entry in <samp>Data/FishPondData</samp>.</li>
 +
</ul>
 +
 
 +
==What's new for NPCs==
 +
===Custom NPCs===
 +
{{/doc status|[[Modding:NPC data]]|done=false}}
 +
 
 +
[[Modding:NPC data|Custom NPC data]] has been overhauled in 1.6. The new <samp>Data/Characters</samp> asset (which replaces <samp>Data/NPCDispositions</samp> + <samp>Data/spousePatios</samp> + <samp>Data/spouseRooms</samp>) uses a data model format that's easier to edit and understand, and has a lot of fields to customize previously-hardcoded data.
   −
When the collision map is parsed, leading/trailing whitespace is trimmed (both for the entire map and for each line). In JSON, you can specify it in two forms:
+
====Format====
<syntaxhighlight lang="js">
+
This consists of a string → model lookup, where...
// single line with \n line breaks
+
* The key is a [[Modding:Common data field types#Unique string ID|unique string ID]] for the NPC like <samp>Example.ModId_NpcName</samp>, which will be used as the internal <samp>Name</samp> (not <samp>DisplayName</samp>).
"CollisionMap": "XXXX\nXOOX"
+
* The value is a model with the following fields.
   −
// multi-line with optional indentation
+
<dl style="margin-left: 2em;">
"CollisionMap": "
+
<dt>Basic info:</dt>
    XXXX
+
<dd>
    XOOX
+
{| class="wikitable"
"
  −
</syntaxhighlight>
   
|-
 
|-
| <samp>HumanDoor</samp>
+
! field
| ''(Optional)'' The position of the door that can be clicked to warp into the building interior. This is measured in tiles relative to the top-left corner tile. Defaults to disabled.
+
! effect
 
|-
 
|-
| <samp>AnimalDoor</samp>
+
| <samp>DisplayName</samp>
| ''(Optional)'' The position and size of the door that animals use to enter/exit the building, if the building interior is an animal location, specified as an object with <samp>X</samp>, <samp>Y</samp>, <samp>Width</samp>, and <samp>Height</samp> fields. This is measured in tiles relative to the top-left corner tile. Defaults to disabled.
+
| A [[Modding:Tokenizable strings|tokenizable string]] for the NPC's display name.
 
|-
 
|-
| <samp>AnimalDoorOpenDuration</samp><br /><samp>AnimalDoorCloseDuration</samp>
+
| <samp>Language</samp>
| ''(Optional)'' The duration of the open/close animation for the animal door, measured in milliseconds. If omitted, the door switches to the open/closed state instantly.
+
| ''(Optional)'' The language spoken by the NPC. One of <samp>Default</samp> (the default language understood by the player) or <samp>Dwarvish</samp> (which the player can only understand after finding the [[Dwarvish Translation Guide|Dwarvish translation guide]]). Default <samp>Default</samp>.
 +
|-
 +
| <samp>Gender</samp>
 +
| ''(Optional)'' The NPC's gender identity. One of <samp>Female</samp>, <samp>Male</samp>, or <samp>Undefined</samp>. Default <samp>Undefined</samp>.
 
|-
 
|-
| <samp>AnimalDoorOpenSound</samp><br /><samp>AnimalDoorCloseSound</samp>
+
| <samp>Age</samp>
| ''(Optional)'' The sound which is played once each time the animal door is opened/closed. Disabled by default.
+
| ''(Optional)'' The general age of the NPC. One of <samp>Child</samp>, <samp>Teen</samp>, or <samp>Adult</samp>. Default <samp>Adult</samp>.
|}
     −
====Exterior appearance====
+
This affects generated dialogue lines (e.g. a child might say "stupid" and an adult might say "depressing"), generic dialogue (e.g. a child might respond to dumpster diving with "''Eww... What are you doing?''" and a teen would say "''Um... Why are you digging in the trash?''"), and the gift they choose as [[Feast of the Winter Star]] gift-giver. Children are also excluded from item delivery quests.
{| class="wikitable"
+
|-
 +
| <samp>Manner</samp>
 +
| ''(Optional)'' A measure of the character's general politeness, which affects some generic dialogue lines. One of <samp>Neutral</samp>, <samp>Polite</samp>, or <samp>Rude</samp>. Default <samp>Neutral</samp>.
 +
|-
 +
| <samp>SocialAnxiety</samp>
 +
| ''(Optional)'' A measure of the character's comfort with social situations, which affects some generic dialogue lines. One of <samp>Neutral</samp>, <samp>Outgoing</samp>, or <samp>Shy</samp>. Default <samp>Neutral</samp>.
 +
|-
 +
| <samp>Optimism</samp>
 +
| ''(Optional)'' A measure of the character's overall optimism. One of <samp>Neutral</samp>, <samp>Negative</samp>, or <samp>Positive</samp>. Default <samp>Neutral</samp>.
 +
|-
 +
| <samp>BirthSeason</samp>
 +
| ''(Optional if non-social)'' The season name (case-sensitive) for the NPC's birthday. One of <samp>spring</samp>, <samp>summer</samp>, <samp>fall</samp>, or <samp>winter</samp>. Default none.
 
|-
 
|-
! field
+
| <samp>BirthDay</samp>
! effect
+
| ''(Optional if non-social)'' The day number for the NPC's birthday. Default 0.
 
|-
 
|-
| <samp>SourceRect</samp>
+
| <samp>HomeRegion</samp>
| ''(Optional)'' The building's pixel area within the <samp>Texture</samp>, specified as an object with <samp>X</samp>, <samp>Y</samp>, <samp>Width</samp>, and <samp>Height</samp> fields. Defaults to the entire texture.
+
| ''(Optional)'' The region of the world in which the NPC lives (one of <samp>Desert</samp>, <samp>Town</samp>, or <samp>Other</samp>). For example, only <samp>Town</samp> NPCs are counted for the introductions [[Quests#List of Story Quests|quest]], can be selected as a secret santa for the [[Feast of the Winter Star]], or get a friendship boost from the [[Luau]]. Default <samp>Other</samp>.
 
|-
 
|-
| <samp>Skins</samp>
+
| <samp>IsDarkSkinned</samp>
| ''(Optional)'' The appearances which can be selected from Robin's menu (like stone/plank/log [[cabin]]s), in addition to the default appearance based on <samp>Texture</samp>. This consists of a list of models with these fields:
+
| ''(Optional)'' Whether the NPC has dark skin, which affects the chance of children with the player having dark skin too. Default false.
 +
|}
 +
</dd>
 +
 
 +
<dt>Social features:</dt>
 +
<dd>
 
{| class="wikitable"
 
{| class="wikitable"
 
|-
 
|-
Line 2,842: Line 2,640:  
! effect
 
! effect
 
|-
 
|-
| <samp>Id</samp>
+
| <samp>CanSocialize</samp>
| The [[Modding:Common data field types#Unique string ID|unique string ID]] for the skin.
+
| ''(Optional)'' A [[Modding:Game state queries|game state query]] which indicates whether to enable social features (like birthdays, gift giving, [[friendship]], and an entry in the social tab). Default true.
 
|-
 
|-
| <samp>Name</samp><br /><samp>Description</samp>
+
| <samp>CanBeRomanced</samp>
| [[Modding:Tokenizable strings|Tokenizable strings]] for the skin's display name and description.
+
| ''(Optional)'' Whether the NPC can be dated and romanced. This enables romance features for this NPC (like a 'single' label in the social menu, bouquet gifting, and marriage). Default false.
 
|-
 
|-
| <samp>Texture</samp>
+
| <samp>CanReceiveGifts</samp>
| The asset name for the texture under the game's Content folder.
+
| ''(Optional)'' Whether players can give gifts to this NPC. Default true.
 +
 
 +
The NPC must also be social per <samp>CanSocialize</samp> and have an entry in <samp>Data/NPCGiftTastes</samp> to be giftable, regardless of this value.
 
|-
 
|-
| <samp>Condition</samp>
+
| <samp>CanCommentOnPurchasedShopItems</samp>
| ''(Optional)'' A [[Modding:Game state queries|game state query]] which indicates whether this skin should be available to apply. This doesn't change buildings which already have it applied. Defaults to always true.
+
| ''(Optional)'' Whether this NPC can comment on items that a player sold to a shop which then resold it to them. If null (or omitted), this will default to true if their <samp>HomeRegion</samp> is set to <samp>Town</samp>.
 +
 
 +
The NPC must also be social per <samp>CanSocialize</samp> to allow it, regardless of this value.
 
|-
 
|-
| <samp>BuildDays</samp><br /><samp>BuildCost</samp><br /><samp>BuildMaterials</samp>
+
| <samp>CanGreetNearbyCharacters</samp>
| ''(Optional)'' If set, overrides the equivalent field in the building data.
+
| ''(Optional)'' Whether this NPC can show a speech bubble greeting nearby players or NPCs, and or be greeted by other NPCs. Default true.
 
|-
 
|-
| <samp>ShowAsSeparateConstructionEntry</samp>
+
| <samp>CanVisitIsland</samp>
| ''(Optional)'' Whether this skin should be shown as a separate building option in the construction menu (like cabins). Default false.
+
| ''(Optional)'' A [[Modding:Game state queries|game state query]] which indicates whether the NPC can visit the [[Ginger Island]] resort once it's unlocked. Default true.
 +
 
 +
The NPC must also be social per <samp>CanSocialize</samp> to visit the island, regardless of this value.
 
|-
 
|-
| <samp>Metadata</samp>
+
| <samp>LoveInterest</samp>
| ''(Optional)'' Equivalent to the <samp>Metadata</samp> field on the building. Properties defined in this field are added to the building's metadata when this skin is active, overwriting the previous property with the same name if applicable. Default none.
+
| ''(Optional)'' Unused.
|}
   
|-
 
|-
| <samp>FadeWhenBehind</samp>
+
| <samp>Calendar</samp>
| ''(Optional)'' Whether the building should become semi-transparent when the player is behind it. Default true.
+
| ''(Optional)'' Determines when the NPC's birthday is shown in the [[calendar]]. Possible values:
 +
{| class="wikitable"
 
|-
 
|-
| <samp>DrawOffset</samp>
+
! value
| ''(Optional)'' A pixel offset applied to the building sprite's placement in the world. Default 0.
+
! effect
 
|-
 
|-
| <samp>SeasonOffset</samp>
+
| <samp>HiddenAlways</samp>
| ''(Optional)'' A pixel offset to apply each season. This is applied to the <samp>SourceRect</samp> position by multiplying the offset by 0 (spring), 1 (summer), 2 (fall), or 3 (winter). Default 0, so all seasons use the same source rect.
+
| They never appear in the calendar.
 
|-
 
|-
| <samp>SortTileOffset</samp>
+
| <samp>HiddenUntilMet</samp>
| ''(Optional)'' A Y tile offset applied when figuring out render layering. For example, a value of <samp>2.5</samp> will treat the building as if it was 2.5 tiles further up the screen for the purposes of layering. Default 0.
+
| Until the player meets them, they don't appear in the calendar.
 +
|-
 +
| <samp>AlwaysShown</samp>
 +
| They always appear in the calendar.
 +
|}
 +
 
 +
Defaults to <samp>AlwaysShown</samp>.
 
|-
 
|-
| <samp>DrawLayers</samp>
+
| <samp>SocialTab</samp>
| ''(Optional)'' A list of textures to draw over or behind the building, with support for conditions and animations. This consists of a list of models with these fields:
+
| ''(Optional)'' Determines how the NPC is shown on the [[friendship|social tab]] when unlocked. Possible values:
 
{| class="wikitable"
 
{| class="wikitable"
 
|-
 
|-
! field
+
! value
 
! effect
 
! effect
 
|-
 
|-
| <samp>Id</samp>
+
| <samp>HiddenAlways</samp>
| The [[Modding:Common data field types#Unique string ID|unique string ID]] for this entry within the current list.
+
| They never appear in the social tab.
 
|-
 
|-
| <samp>SourceRect</samp>
+
| <samp>HiddenUntilMet</samp>
| The pixel area within the <samp>texture</samp> to draw, formatted like <samp>"{{t|x}} {{t|y}} {{t|width}} {{t|height}}"</samp>. If the overlay is animated via <samp>FrameCount</samp>, this is the area of the first frame.
+
| Until the player meets them, they don't appear on the social tab.
 
|-
 
|-
| <samp>DrawPosition</samp>
+
| <samp>UnknownUntilMet</samp>
| The tile position at which to draw the top-left corner of the texture, relative to the building's top-left corner tile.
+
| Until the player meets them, their name on the social tab is replaced with "???".
 
|-
 
|-
| <samp>Texture</samp>
+
| <samp>AlwaysShown</samp>
| ''(Optional)'' The asset name of the texture to draw. Defaults to the building's default <samp>Texture</samp> field.
+
| They always appear in the social tab (including their name).
 +
|}
 +
 
 +
Defaults to <samp>UnknownUntilMet</samp>.
 
|-
 
|-
| <samp>DrawInBackground</samp>
+
| <samp>SpouseAdopts</samp>
| ''(Optional)'' Whether to draw the texture behind the building sprite (i.e. underlay) instead of over it.
+
| ''(Optional)'' A [[Modding:Game state queries|game state query]] which indicates whether the player will need to adopt children with this spouse, instead of either the player or NPC giving birth. If null, defaults to true for same-gender and false for opposite-gender spouses.
 +
 
 +
The <samp>Target</samp> player is the one they're married to.
 
|-
 
|-
| <samp>SortTileOffset</samp>
+
| <samp>SpouseWantsChildren</samp>
| ''(Optional)'' A Y tile offset applied when figuring out render layering. For example, a value of <samp>2.5</samp> will treat the texture as if it was 2.5 tiles further up the screen for the purposes of layering. Default 0.
+
| ''(Optional)'' A [[Modding:Game state queries|game state query]] which indicates whether the spouse will ask to have children. Defaults to true.
 +
 
 +
The <samp>Target</samp> player is the one they're married to.
 
|-
 
|-
| <samp>OnlyDrawIfChestHasContents</samp>
+
| <samp>SpouseGiftJealousy</samp>
| ''(Optional)'' The ID of a chest defined in the <samp>Chests</samp> field which must contain items. If it's empty, this overlay won't be rendered. Default none.
+
| ''(Optional)'' A [[Modding:Game state queries|game state query]] which indicates whether the [[Marriage#Jealousy|spouse will get jealous of gifts to other NPCs]]. Defaults to true.
 +
 
 +
The <samp>Target</samp> player is the one they're married to, and the <samp>Target</samp> item is the one that was gifted.
 +
|-
 +
| <samp>SpouseGiftJealousyFriendshipChange</samp>
 +
| ''(Optional)'' The [[Friendship|friendship point]] effect when the <samp>SpouseGiftJealously</samp> is triggered. Default -30.
 
|-
 
|-
| <samp>FrameCount</samp><br /><samp>FramesPerRow</samp><br /><samp>FrameDuration</samp>
+
| <samp>SpouseRoom</samp>
| ''(Optional)'' If <samp>FrameCount</samp> is more than one, the building overlay will be animated automatically. For each frame, the <samp>SourceRect</samp> will be offset by its <samp>Width</samp> to the right up to <samp>FramesPerRow - 1</samp> times, and then down by its <samp>Height</samp>. Each frame will be rendered on-screen for <samp>FrameDuration</samp> milliseconds before switching to the next frame.
+
| ''(Optional)'' The [[Marriage#Spouse Rooms|NPC's spouse room]] in the farmhouse when the player marries them, if applicable. If this is omitted for a marriageable NPC, they'll use Abigail's spouse room by default.
   −
For example, if you set <samp>FrameCount</samp> to 6 and <samp>FramesPerRow</samp> to 3, the building will expect the frames to be laid out like this in the spritesheet (where frame 1 matches <samp>SourceRect</samp>):
+
This consists of a model with these fields:
<pre>
+
{| class="wikitable"
┌───┬───┬───┐
+
|-
│ 1 │ 2 │ 3 │
+
! field
├───┼───┼───┤
+
! effect
│ 4 │ 5 │ 6 │
+
|-
└───┴───┴───┘
+
| <samp>MapAsset</samp>
</pre>
+
| ''(Optional)'' The asset name for the spouse room map. The <samp>Map/</samp> prefix is added automatically and shouldn't be included. Defaults to <samp>spouseRooms</samp>.
 
|-
 
|-
| <samp>AnimalDoorOffset</samp>
+
| <samp>MapSourceRect</samp>
| ''(Optional)'' A pixel offset applied to the draw layer when the animal door is open. While the door is opening, the percentage open is applied to the offset (e.g. 50% open = 50% offset).
+
| ''(Optional)'' The tile area within the <samp>MapAsset</samp> containing the spouse's room. This should usually be a 6x9 tile area, though the game will try to adjust to a different size. Specified as a model with <samp>X</samp>, <samp>Y</samp>, <samp>Width</samp>, and <samp>Height</samp> fields. Defaults to <samp>(0, 0, 6, 9)</samp>.
 
|}
 
|}
 
|-
 
|-
| <samp>DrawShadow</samp>
+
| <samp>SpousePatio</samp>
| ''(Optional)'' Whether to draw an automatic shadow along the bottom edge of the building's sprite. Default true.
+
| ''(Optional)'' The [[Marriage#Spouse Outside Area|NPC's patio area]] on the farm when the player marries them, if any. Default none.
|}
     −
====Interior====
+
This consists of a model with these fields:
 
{| class="wikitable"
 
{| class="wikitable"
 
|-
 
|-
Line 2,930: Line 2,751:  
! effect
 
! effect
 
|-
 
|-
| <samp>IndoorMap</samp>
+
| <samp>MapAsset</samp>
| ''(Optional)'' The name of the map asset under <samp>Maps</samp> to load for the building interior. For example, <samp>"Shed"</samp> will load the [[shed]]'s <samp>Maps/Shed</samp> map.
+
| ''(Optional)'' The asset name for the patio area. The <samp>Map/</samp> prefix is added automatically and shouldn't be included. Defaults to <samp>spousePatios</samp>.
 
|-
 
|-
| <samp>IndoorMapType</samp>
+
| <samp>MapSourceRect</samp>
| ''(Optional)'' The full name of the C# location class which will manage the building's interior location. This must be one of the vanilla types to avoid a crash when saving. There are too many to list here, but the most useful types are likely...
+
| ''(Optional)'' The tile area within the <samp>MapAsset</samp> containing the spouse's patio area. This must be a 4x4 tile area. Specified as a model with <samp>X</samp>, <samp>Y</samp>, <samp>Width</samp>, and <samp>Height</samp> fields. Defaults to <samp>(0, 0, 4, 4)</samp>.
* <samp>StardewValley.AnimalHouse</samp>;
  −
* <samp>StardewValley.Locations.Cabin</samp>;
  −
* <samp>StardewValley.Locations.Cellar</samp>;
  −
* <samp>StardewValley.Locations.DecoratableLocation</samp>;
  −
* <samp>StardewValley.Locations.FarmCave</samp>;
  −
* <samp>StardewValley.Locations.FarmHouse</samp>;
  −
* <samp>StardewValley.Shed</samp>;
  −
* and <samp>StardewValley.SlimeHutch</samp>.
  −
Defaults to the generic <samp>StardewValley.GameLocation</samp> class.
   
|-
 
|-
| <samp>NonInstancedIndoorLocation</samp>
+
| <samp>SpriteAnimationFrames</samp>
| ''(Optional)'' The name of the existing global location to treat as the building's interior, like <samp>FarmHouse</samp> and <samp>Greenhouse</samp> for their buildings.
+
| ''(Optional)'' The spouse's animation frames when they're in the patio. Each frame is an array containing [0] the sprite index in their spritesheet, and [1] the optional duration in milliseconds (default 100). If omitted or empty, the NPC won't be animated.
   −
Each location can only be used by one building. If the location is already in use (e.g. because the player has two of this building), each subsequent building will use the <samp>IndoorMap</samp> and <samp>IndoorMapType</samp> instead. For example, the first greenhouse will use the global <samp>Greenhouse</samp> location, and any subsequent greenhouse will use a separate instanced location.
+
For example, here is Abigail playing the flute:
 +
<syntaxhighlight lang="js">
 +
"SpriteAnimationFrames": [
 +
    [16, 500], // show index 16 for 500ms
 +
    [17, 500],
 +
    [18, 500],
 +
    [19]      // if duration is omitted, defaults to 100ms
 +
]
 +
</syntaxhighlight>
 +
|-
 +
| <samp>SpriteAnimationPixelOffset</samp>
 +
| ''(Optional)'' The pixel offset to apply to the NPC's sprite when they're animated in the patio, specified as a model with <samp>X</samp> and <samp>Y</samp> fields. This is ignored if the NPC isn't animated via <samp>SpriteAnimationFrames</samp>. Default none.
 +
|}
 
|-
 
|-
| <samp>MaxOccupants</samp>
+
| <samp>SpouseFloors</samp><br /><samp>SpouseWallpapers</samp>
| ''(Optional)'' The maximum number of animals who can live in this building.
+
| ''(Optional)'' The floors and wallpapers which the NPC may randomly apply to the farmhouse when married to the player. If omitted or empty, the NPC will randomly choose a base floor (0–39) or wallpaper (0–111).
 
|-
 
|-
| <samp>AllowAnimalPregnancy</samp>
+
| <samp>IntroductionsQuest</samp>
| ''(Optional)'' Whether animals can get pregnant and produce offspring in this building. Default false.
+
| ''(Optional)'' Whether to include this NPC in [[Quests#List of Story Quests|the ''introductions'' quest]]. If <samp>null</samp> (or omitted), this will default to true if the <samp>HomeRegion</samp> field is set to <samp>Town</samp>.
 
|-
 
|-
| <samp>ValidOccupantTypes</samp>
+
| <samp>ItemDeliveryQuests</samp>
| ''(Optional)'' A list of building IDs whose animals to allow in this building too. For example, <code>[ "Barn", "Coop" ]</code> will allow [[barn]] and [[coop]] animals in this building. Default none.
+
| ''(Optional)'' A [[Modding:Game state queries|game state query]] which indicates whether this NPC can give item delivery quests. If <samp>null</samp> (or omitted), this will default to true if the <samp>HomeRegion</samp> field is set to <samp>Town</samp>.
|}
     −
====Item processing====
+
The NPC must also be social per <samp>CanSocialize</samp> to allow it, regardless of this value.
{| class="wikitable"
   
|-
 
|-
! field
+
| <samp>PerfectionScore</samp>
! effect
+
| ''(Optional)'' Whether to include this NPC when checking whether the player has max friendships with every NPC for the perfection score. Default true.
 +
 
 +
The NPC must also be social per <samp>CanSocialize</samp> to be counted, regardless of this value.
 
|-
 
|-
| <samp>HayCapacity</samp>
+
| <samp>EndSlideShow</samp>
| ''(Optional)'' The amount of hay that can be stored in this building. If built on the [[The Farm|farm]], this works just like [[silo]]s and contributes to the farm's available hay.
+
| ''(Optional)'' How the NPC appears in the end-game perfection slide show. Possible values:
|-
  −
| <samp>ItemConversions</samp>
  −
| ''(Optional)'' The item processing rules which take input items and convert them into output items using the inventories defined by <samp>Chests</samp>. This consists of a list of models with these fields:
   
{| class="wikitable"
 
{| class="wikitable"
 
|-
 
|-
! field
+
! value
 
! effect
 
! effect
 
|-
 
|-
| <samp>Id</samp>
+
| <samp>Hidden</samp>
| The [[Modding:Common data field types#Unique string ID|unique string ID]] for this rule within the current list.
+
| The NPC doesn't appear in the slide show.
 
|-
 
|-
| <samp>RequiredTags</samp>
+
| <samp>MainGroup</samp>
| A list of [[Modding:Items#Context tags|context tags]] to match against an input item. An item must have ''all'' of these tags to be accepted.
+
| The NPC is added to the main group of NPCs which walk across the screen.
 
|-
 
|-
| <samp>SourceChest</samp>
+
| <samp>TrailingGroup</samp>
| The ID of the inventory defined in <samp>Chests</samp> from which to take input items.
+
| The NPC is added to the trailing group of NPCs which follow the main group.
 +
|}
 +
 
 +
Defaults to <samp>MainGroup</samp>.
 
|-
 
|-
| <samp>DestinationChest</samp>
+
| <samp>FriendsAndFamily</samp>
| The ID of the inventory defined in <samp>Chests</samp> in which to store output items.
+
| ''(Optional)'' The NPC's closest friends and family, as a dictionary where the key is the other NPC's internal name and the value is an optional tokenizable string for the name to use in dialogue text (like 'mom'). Default none.
|-
+
 
| <samp>ProducedItems</samp>
+
This affects generic dialogue for revealing likes and dislikes to family members, and may affect <samp>inlaw_&lt;NPC&gt;</samp> dialogues. This isn't necessarily comprehensive.
| The output items produced when an input item is converted. This consists of a list of models with these fields:
+
|}
 +
</dd>
 +
 
 +
<dt>Dumpster diving:</dt>
 +
<dd>
 
{| class="wikitable"
 
{| class="wikitable"
 
|-
 
|-
Line 2,995: Line 2,823:  
! effect
 
! effect
 
|-
 
|-
| ''common fields''
+
| <samp>DumpsterDiveEmote</samp>
| See [[Modding:Item queries#Item spawn fields|item spawn fields]] for the generic item fields supported by machine output.
+
| ''(Optional)'' The emote ID to show above the NPC's head when they see a player rummaging through trash. See [[Modding:event data#Emotes|emote IDs]]. If omitted or <samp>null</samp>, the default depends on the NPC's age: a child will show sad (28), a teen will show a question mark (8), and an adult will show angry (12).
 +
|-
 +
| <samp>DumpsterDiveFriendshipEffect</samp>
 +
| ''(Optional)'' The friendship point change if this NPC sees a player rummaging through trash. Default -25.
 +
|}</dd>
   −
If set to an [[Modding:Item queries|item query]] which returns multiple items, one of them will be selected at random.
+
<dt>Festivals:</dt>
 +
<dd>
 +
{| class="wikitable"
 
|-
 
|-
| <samp>Chance</samp>
+
! field
| ''(Optional)'' The probability that the item will be produced, as a value between 0 (never drops) and 1 (always drops). Default 1 (100% chance).
+
! effect
|}
   
|-
 
|-
| <samp>RequiredCount</samp>
+
| <samp>FlowerDanceCanDance</samp>
| ''(Optional)'' The number of the input item to consume. Default 1.
+
| ''(Optional)'' Whether players can ask the NPC to dance at the Flower Dance festival. The possible values are <samp>true</samp> (can always ask), <samp>false</samp> (can never ask), or <samp>null</samp> (can ask if they're romanceable). Default <samp>null</samp>.
 +
 
 +
If the NPC can dance, you should also add the [[Modding:NPC data#Overworld_sprites|dance sprite frames]] and <samp>FlowerDance_Decline</samp> [[Modding:Dialogue|dialogue text]]. You can optionally set the <samp>FlowerDance_Accept</samp> dialogue too (though NPCs have a default accept dialogue if not).
 
|-
 
|-
| <samp>MaxDailyConversions</samp>
+
| <samp>WinterStarParticipant</samp>
| ''(Optional)'' The maximum number of the input item which can be processed each day. Each conversion rule has its own separate maximum (e.g. if you have two rules each with a max of 1, then you can convert one of each daily). Set to -1 to allow unlimited conversions. Default 1.
+
| ''(Optional)'' A [[Modding:Game state queries|game state query]] which indicates whether this NPC can give and receive gifts at the [[Feast of the Winter Star]]. If <samp>null</samp> (or omitted), this will default to true if the <samp>HomeRegion</samp> field is set to <samp>Town</samp>.
|}
   
|-
 
|-
| <samp>Chests</samp>
+
| <samp>WinterStarGifts</samp>
| ''(Optional)'' The input/output inventories that can be accessed from a tile on the building exterior. The allowed items are defined by the separate <samp>ItemConversions</samp> field. This is a list of models with these fields:
+
| At the [[Feast of the Winter Star]], the possible gifts this NPC can give to players. A matching entry is selected at random.
 +
 
 +
This consists of a list of models with these fields:
 
{| class="wikitable"
 
{| class="wikitable"
 
|-
 
|-
Line 3,018: Line 2,854:  
! effect
 
! effect
 
|-
 
|-
| <samp>Id</samp>
+
| ''common fields''
| The [[Modding:Common data field types#Unique string ID|unique string ID]] for this chest within the current list.
+
| See [[Modding:Item queries#Item spawn fields|item spawn fields]] for the generic item fields.
 +
 
 +
If set to an [[Modding:Item queries|item query]] which returns multiple items, one of them will be selected at random.
 +
|}
 +
|}
   −
This is referenced from the <samp>ItemConversions</samp> field.
+
<dt>Spawn rules:</dt>
 +
<dd>
 +
{| class="wikitable"
 
|-
 
|-
| <samp>Type</samp>
+
! field
| The inventory type. This must be one of:
+
! effect
* <samp>Chest</samp>: show a normal chest UI on click.
  −
* <samp>Collect</samp>: provides items for the player to collect. Clicking the tile will do nothing (if empty), grab the item directly (if it only contains one item), else show a grab-only inventory UI.
  −
* <samp>Load</samp>: lets the player add items for the building to process.
   
|-
 
|-
| <samp>Sound</samp>
+
| <samp>UnlockConditions</samp>
| ''(Optional)'' The sound to play once when the player clicks the chest.
+
| ''(Optional)'' A [[Modding:Game state queries|game state query]] which indicates whether the NPC should be added to the world, checked when loading a save and when ending each day. This only affects whether the NPC is added when missing; returning false won't remove an NPC that's already been added. Defaults to true.
 
|-
 
|-
| <samp>InvalidItemMessage</samp><br /><samp>InvalidCountMessage</samp><br /><samp>ChestFullMessage</samp>
+
| <samp>SpawnIfMissing</samp>
| ''(Optional)'' A [[Modding:Tokenizable strings|tokenizable string]] to show when the player tries to add an item to the chest when...
+
| ''(Optional)'' Whether to add this NPC to the world if they're missing (if the <samp>UnlockConditions</samp> match and <samp>HomeLocation</samp> is valid). Default true.
* it isn't a supported item;
  −
* it's supported but they don't have enough in their inventory;
  −
* the chest has no more room to accept it.
  −
If omitted, the player interaction is ignored with no message shown.
   
|-
 
|-
| <samp>InvalidItemMessageCondition</samp>
+
| <samp>Home</samp>
| ''(Optional)'' A [[Modding:Game state queries|game state query]] which indicates whether <samp>InvalidItemMessage</samp> should be shown. This can use item-related queries like <samp>ITEM_TYPE</samp>. Defaults to always true.
+
| ''(Optional)'' The default place where this NPC spawns and returns each day. If there are multiple entries, the first matching one is used.
|-
  −
| <samp>DisplayTile</samp>
  −
| ''(Optional)'' The chest's position on the building exterior, measured in tiles from the top-left corner of the building, specified in the form <samp>"{{t|x}}, {{t|y}}"</samp>. This affects the position of the 'item ready to collect' bubble. If omitted, the bubble is disabled.
  −
|-
  −
| <samp>DisplayHeight</samp>
  −
| ''(Optional)'' If <samp>DisplayTile</samp> is set, the chest's tile height like <samp>1.5</samp>.
  −
|}
  −
|}
     −
====Tile interactions====
+
This consists of a list of models with these fields:
 
{| class="wikitable"
 
{| class="wikitable"
 
|-
 
|-
Line 3,056: Line 2,883:  
! effect
 
! effect
 
|-
 
|-
| <samp>ActionTiles</samp>
+
| <samp>ID</samp>
| ''(Optional)'' A list of tiles which the player can click to trigger an <samp>Action</samp> [[Modding:Maps|map tile property]]. This consists of a list of models with these fields:
+
| The [[Modding:Common data field types#Unique string ID|unique string ID]] for this entry within the current list.
{| class="wikitable"
   
|-
 
|-
! field
+
| <samp>Location</samp>
! effect
+
| ''(Optional)'' The internal name for the home location where this NPC spawns and returns each day. Default none.
|-
  −
| <samp>Id</samp>
  −
| The [[Modding:Common data field types#Unique string ID|unique string ID]] for this entry within the current list.
   
|-
 
|-
 
| <samp>Tile</samp>
 
| <samp>Tile</samp>
| The tile position, relative to the building's top-left corner tile.
+
| ''(Optional)'' The tile position within the home location where this NPC spawns and returns each day. Specified as a model with <samp>X</samp> and <samp>Y</samp> fields. Defaults to <samp>(0, 0)</samp>.
 
|-
 
|-
| <samp>Action</samp>
+
| <samp>Direction</samp>
| The [[Modding:Tokenizable strings|tokenizable string]] for the action to perform, excluding the <samp>Action</samp> prefix. For example, <samp>"Dialogue Hi there @!"</samp> to show a messagebox like "''Hi there <player name>!''". The tokenizable string is expected before the action is raised. See the [[Modding:Maps#Tile properties 2|list of tile properties]] for useful <samp>Action</samp> values.
+
| ''(Optional)'' The default direction the NPC faces when they start each day. The possible values are <samp>down</samp>, <samp>left</samp>, <samp>right</samp>, and <samp>up</samp>. Defaults to <samp>up</samp>.
 +
|-
 +
| <samp>Condition</samp>
 +
| ''(Optional)'' A [[Modding:Game state queries|game state query]] which indicates whether this entry can be selected. Default true.
 +
|}
 
|}
 
|}
 +
</dd>
 +
 +
<dt>Appearance & sprite:</dt>
 +
<dd>
 +
{| class="wikitable"
 
|-
 
|-
| <samp>DefaultAction</samp>
+
! field
| ''(Optional)'' The default tile action if the clicked tile isn't in <samp>ActionTiles</samp>. Default none.
+
! effect
 +
|-
 +
| <samp>TextureName</samp>
 +
| ''(Optional)'' The '''last segment''' of the NPC's portrait and sprite asset names. For example, set to <samp>Abigail</samp> to use <samp>Portraits/Abigail</samp> and <samp>Characters/Abigail</samp> respectively. Defaults to the internal NPC name.
 
|-
 
|-
| <samp>TileProperties</samp>
+
| <samp>Appearance</samp>
| ''(Optional)'' The [[Modding:Maps|map tile properties]] to set. This consists of a list of models with these fields:
+
| ''(Optional)'' The portrait/sprite textures to use.
 +
 
 +
This can list any number of appearance options. They'll be sorted by <samp>Precedence</samp> value (with lower values taking priority), then filtered to those whose fields match. If multiple matching appearances have precedence, one entry is randomly chosen based on their relative weight. This randomization is stable per day, so the NPC always makes the same choice until the next day. If a portrait/sprite can't be loaded (or no appearances match), the NPC will use the default asset based on <samp>TextureName</samp>.
 +
 
 +
The NPC rechecks this field each time they change location.
 +
 
 +
This consists of a list of models with these fields:  
 
{| class="wikitable"
 
{| class="wikitable"
 
|-
 
|-
Line 3,086: Line 2,927:  
| The [[Modding:Common data field types#Unique string ID|unique string ID]] for this entry within the current list.
 
| The [[Modding:Common data field types#Unique string ID|unique string ID]] for this entry within the current list.
 
|-
 
|-
| <samp>Name</samp>
+
| <samp>Season</samp>
| The tile property name to set.
+
| ''(Optional)'' The season in which this appearance should be used (one of <samp>spring</samp>, <samp>summer</samp>, <samp>fall</samp>, or <samp>winter</samp>), or omit for any season. Defaults to any season.
 
|-
 
|-
| <samp>Value</samp>
+
| <samp>Indoors</samp><br /><samp>Outdoors</samp>
| ''(Optional)'' The tile property value to set, or omit to set a null value.
+
| ''(Optional)'' Whether this appearance should be used when indoors and/or outdoors. Both default to true.
 
|-
 
|-
| <samp>Layer</samp>
+
| <samp>Condition</samp>
| The name of the map layer whose tiles to change.
+
| ''(Optional)'' A [[Modding:Game state queries|game state query]] which indicates whether this entry can be selected. Default true.
 
|-
 
|-
| <samp>TileArea</samp>
+
| <samp>Portrait</samp><br /><samp>Sprite</samp>
| The tiles to which to add the property, relative to the top-left corner of the building's collision box. This is specified as an object with <samp>X</samp>, <samp>Y</samp>, <samp>Width</samp>, and <samp>Height</samp> fields.
+
| ''(Optional)'' The asset name for the portraits and/or sprites texture to load. If omitted or it can't be loaded, it will default to the default asset per the <samp>Texture</samp> field.
|}
   
|-
 
|-
| <samp>AdditionalTilePropertyRadius</samp>
+
| <samp>IsIslandAttire</samp>
| ''(Optional)'' When checking whether the player clicked on a <samp>TileProperties</samp> tile, an added distance around the building at which tile locations may be placed. Default 0, so only tile properties within the normal building bounds will work.
+
| ''(Optional)'' Whether this is island beach attire worn at the resort. Default false.
|}
     −
====Advanced====
+
This is mutually exclusive: NPCs will never wear it in other contexts if it's true, and will never wear it as island attire if it's false.
{| class="wikitable"
   
|-
 
|-
! field
+
| <samp>Precedence</samp>
! effect
+
| ''(Optional)'' The order in which this entry should be checked, where lower values are checked first. This can be a negative value. Default 0.
 
|-
 
|-
| <samp>Metadata</samp>
+
| <samp>Weight</samp>
| ''(Optional)'' A list of custom properties applied to the building, which can optionally be overridden per-skin in the <samp>Skins</samp> field. Default none.
+
| ''(Optional)'' If multiple entries with the same <samp>Precedence</samp> match, the relative weight to use when randomly choosing one. Default 1.
 +
 
 +
For example, let's say two appearance entries match: one has a weight of 2, and the other has a weight of 1. Their probability of being chosen is 2/3 and 1/3 respectively.
 +
|}
   −
The base game recognizes these properties:
+
'''Note:''' the default textures based on <samp>TextureName</samp> must still exist, even if you use this field to override them.
{| class="wikitable"
   
|-
 
|-
! property
+
| <samp>MugShotSourceRect</samp>
! description
+
| ''(Optional)'' The 16x24-pixel area in the character's sprite texture to show as their mug shot icon in the calendar, social menu, and other contexts. Defaults to part of their first sprite.
 
|-
 
|-
| <samp>ChimneyPosition: {{t|x}} {{t|y}}</samp>
+
| <samp>Size</samp>
| ''(Optional)'' The pixel position at which to place a chimney on the building exterior, relative to the top-left corner of the sprite. This will apply the same logic as the farmhouse chimney (e.g. producing smoke if there's a lit fireplace inside the building).
+
| ''(Optional)'' The pixel size of the individual sprites in their overworld sprite spritesheet. Specified as a model with <samp>X</samp> and <samp>Y</samp> fields. Defaults to <samp>(16, 32)</samp>.
|-
  −
| <samp>ChimneyPosition{{o|upgrade level}}: {{t|x}} {{t|y}}</samp>
  −
| ''(Optional, for farmhouses/cabins only)'' Override <samp>ChimneyPosition</samp> for the given upgrade level, starting from 0 for the initial farmhouse/cabin. If there's no override for the current upgrade level, the highest override for a lower upgrade level is used (if any). For example, <samp>ChimneyPosition3</samp> would be used for the third house upgrade (and the fourth if there's no <samp>ChimneyPosition4</samp>).
  −
|}
     −
This can also contain arbitrary custom properties, which C# mods can read using <samp>building.GetMetadata(key)</samp>.
+
'''Note:''' sizes bigger than 16×32 will cause issues like broken spawning, pathfinding, misalignment in the [[perfection]] end-game slide show, etc.
 
|-
 
|-
| <samp>BuildingType</samp>
+
| <samp>Breather</samp>
| ''(Optional)'' The full name of the C# type to instantiate for the building instance. Defaults to a generic <samp>Building</samp> instance.
+
| ''(Optional)'' Whether the chest on the NPC's overworld sprite puffs in and out as they breathe. Default true</samp>.
 
  −
'''⚠ Caution:''' this is meant to support vanilla building types like <samp>StardewValley.Shed</samp>. Setting this to a non-vanilla type will cause a crash when it's written to the save file, and may cause crashes in multiplayer. If you need custom behavior, consider handling it in C# based on the building type instead of creating a custom subclass; otherwise you'll need a framework mod like {{nexus mod|1348|SpaceCore}} to handle serialization and multiplayer sync.
   
|-
 
|-
| <samp>ModData</samp>
+
| <samp>BreathChestRect</samp>
| ''(Optional)'' A string → string lookup of arbitrary <samp>modData</samp> values to attach to the building when it's constructed.
+
| ''(Optional)'' A [[Modding:Common data field types#Rectangle|rectangle]] pixel area within the spritesheet which expands and contracts to simulate breathing, relative to the top-left corner of the source rectangle for their current sprite. Omit to calculate it automatically. This should be omitted for most NPCs, unless they have a non-standard size.
 
|-
 
|-
| <samp>CustomFields</samp>
+
| <samp>BreathChestPosition</samp>
| The [[#Custom data fields|custom fields]] for this entry.
+
| ''(Optional)'' A [[Modding:Common data field types#Point|point]] pixel offset to apply to the NPC's <samp>BreathChestPosition</samp> when drawn over the NPC. Omit to calculate it automatically. This should be omitted for most NPCs, unless they have a non-standard size.
|}
+
|-
 +
| <samp>Shadow</samp>
 +
| ''(Optional)'' The options for the shadow to draw under the NPC, or omit to apply the default shadow behavior.
   −
===Build anywhere===
+
This consists of a model with these fields:
{{/doc status|[[Modding:Blueprint data]] and [[Modding:Maps]]|done=false}}
     −
* You can now allow building construction for any location using the [[#Map/tile property changes|new <samp>CanBuildHere</samp> and related map properties]]. The game will adjust accordingly (e.g. Robin will let you choose where to construct the building).
  −
* Buildings and animals are no longer hardcoded to the [[The Farm|farm]] location (except [[cabin]]s and the [[farmhouse]] which still are).
  −
* Scything hay will now add hay to silos in any location, and animals will be auto-fed from hay in any location.
  −
  −
===Other building changes===
  −
{{/doc status|[[Modding:Blueprint data]]|done=false}}
  −
  −
: ''See also: [[#Other location/map changes|other location changes]] for location-related building changes.''
  −
  −
; General building changes
  −
* Building display names & descriptions are now in <samp>Strings/Buildings</samp> for reuse.
  −
* Removed <samp>Data/Blueprints</samp>. This has been replaced by <samp>Data/Buildings</samp> (building data) and <samp>Strings/Buildings</samp> (display names & descriptions).
  −
<ul>
  −
<li>Added methods to simplify common operations:
   
{| class="wikitable"
 
{| class="wikitable"
 
|-
 
|-
! type
+
! field
! method
   
! effect
 
! effect
 
|-
 
|-
|rowspan="7"| <samp>Building</samp>
+
| <samp>Visible</samp>
| <samp>CreateInstanceFromId</samp>
+
| ''(Optional)'' Whether the shadow should be drawn. Default true.
| Create a building instance from its type ID in <samp>Data/Buildings</samp>. For example:
  −
<syntaxhighlight lang="c#">
  −
Building shippingBin = Building.CreateInstanceFromId("Shipping Bin", Vector2.Zero); // creates an instance of StardewValley.Buildings.ShippingBin
  −
</syntaxhighlight>
   
|-
 
|-
| <samp>GetData</samp><br /><samp>TryGetData</samp>
+
| <samp>Offset</samp>
| Get the data for the building's type from <samp>Data/Building</samp>.
+
| ''(Optional)'' A [[Modding:Common data field types#Point|point]] pixel offset applied to the shadow position. Default zero.
 
|-
 
|-
| <samp>GetMetadata</samp>
+
| <samp>Scale</samp>
| Get a value from [[#Custom buildings|the <samp>Metadata</samp> field in <samp>Data/Buildings</samp>]] for this building.
+
| ''(Optional)'' The scale at which to draw the shadow. Default 1.
 +
 
 +
This is a multiplier applied to the default shadow scale, which can change based on factors like whether the NPC is jumping. For example, <samp>0.5</samp> means half the size it'd be drawn if you didn't specify a scale.
 +
|}
 
|-
 
|-
| <samp>GetPaintDataKey</samp>
+
| <samp>EmoteOffset</samp>
| Get the key in <samp>Data/PaintData</samp> for this building, if it has any.
+
| ''(Optional)'' A [[Modding:Common data field types#Point|point]] pixel offset applied to emote drawn over the NPC. Default zero.
 
|-
 
|-
| <samp>ReloadBuildingData</samp>
+
| <samp>ShakePortraits</samp>
| Apply the latest data in <samp>Data/Buildings</samp> to this building.
+
| ''(Optional)'' The portrait indexes which should shake when displayed. Default none.
 
|-
 
|-
| <samp>FinishConstruction</samp>
+
| <samp>KissSpriteIndex</samp>
| If the building is being constructed or upgrade, instantly finish doing so.
+
| ''(Optional)'' If the NPC can be married, the sprite index within their <samp>Texture</samp> to use when kissing a player. Default 28.
 
|-
 
|-
| <samp>UpdateTransparency</samp>
+
| <samp>KissSpriteFacingDirection</samp>
| Update the building transparency on tick for the local player's position.
+
| ''(Optional)'' Whether the character is facing right (true) or left (false) in their <samp>KissSpriteIndex</samp>. The sprite will be flipped as needed to face the player. Default true.
 
  −
This method mainly exists to let mods override/patch the transparency logic.
  −
|-
  −
| <samp>Farm</samp>
  −
| <samp>GetMainFarmHouse</samp>
  −
| Get the main [[farmhouse]] building.
  −
|-
  −
| <samp>GameLocation</samp>
  −
| <samp>OnParentBuildingUpgraded</samp>
  −
| Called when the building containing this location is upgraded, if applicable.
   
|}
 
|}
</li>
+
</dd>
</ul>
  −
* Added building <samp>id</samp> field, which uniquely identifies each building in the world.
     −
; [[Junimo Hut|Junimo hut]] changes
+
<dt>[[Secrets#Gift Log|Hidden gift log emote]]:</dt>
* The <samp>JunimoHut.cropHarvestRange</samp> field is now per-building and editable.
+
<dd>
 
  −
; [[Fish Pond|Fish pond]] changes
  −
<ul>
  −
<li>In <samp>Data/FishPondData</samp>, added a <samp>Precedence</samp> field which sets the order in which entries are checked for a match (with lower values checked first). This ensures that the fallback entries are checked after specific fish. For consistency, vanilla entries use these values:
   
{| class="wikitable"
 
{| class="wikitable"
 
|-
 
|-
! precedence
+
! field
! used for
+
! effect
 
|-
 
|-
| 0<br /><small>(default value)</small>
+
| <samp>HiddenProfileEmoteSound</samp>
| specific fish
+
| ''(Optional)'' For the [[Secrets#Gift Log|hidden gift log emote]], the [[#Custom audio|cue ID]] for the sound played when clicking the sprite. Defaults to <samp>drumkit6</samp>.
 
|-
 
|-
| 100
+
| <samp>HiddenProfileEmoteDuration</samp>
| custom groups (e.g. desert fish)
+
| ''(Optional)'' For the [[Secrets#Gift Log|hidden gift log emote]], how long the animation plays measured in milliseconds. Defaults to 4000 (4 seconds).
 
|-
 
|-
| 500
+
| <samp>HiddenProfileEmoteStartFrame</samp>
| broad fish type (e.g. ocean fish)
+
| ''(Optional)'' For the [[Secrets#Gift Log|hidden gift log emote]], the index within the NPC's overworld sprite spritesheet at which the animation starts. If omitted for a vanilla NPC, the game plays a default animation specific to that NPC; if omitted for a custom NPC, the game just shows them walking while facing down.
 
|-
 
|-
| 1000
+
| <samp>HiddenProfileEmoteFrameCount</samp>
| fallback (e.g. fish category)
+
| ''(Optional)'' For the [[Secrets#Gift Log|hidden gift log emote]], the number of frames in the animation. The first frame corresponds to <samp>HiddenProfileEmoteStartFrame</samp>, and each subsequent frame will use the next sprite in the spritesheet. Default 1.
|}
  −
</li>
  −
<li>In <samp>Data/FishPondData</samp>, the reward <samp>ItemId</samp> can now be an [[Modding:Item queries|item query]].</li>
  −
<li>[[Legendary Fish|Legendary fish]] can now be added to [[Fish Pond|fish ponds]] if they have an entry in <samp>Data/FishPondData</samp>.</li>
  −
</ul>
     −
==What's new for NPCs==
+
This has no effect if <samp>HiddenProfileEmoteStartFrame</samp> isn't set.
===Custom NPCs===
+
|-
{{/doc status|[[Modding:NPC data]]|done=false}}
+
| <samp>HiddenProfileEmoteFrameDuration</samp>
 +
| ''(Optional)'' For the [[Secrets#Gift Log|hidden gift log emote]], how long each animation frame is shown on-screen before switching to the next one, measured in milliseconds. Default 200.
   −
[[Modding:NPC data|Custom NPC data]] has been overhauled in 1.6. The new <samp>Data/Characters</samp> asset (which replaces <samp>Data/NPCDispositions</samp> + <samp>Data/spousePatios</samp> + <samp>Data/spouseRooms</samp>) uses a data model format that's easier to edit and understand, and has a lot of fields to customize previously-hardcoded data.
+
This has no effect if <samp>HiddenProfileEmoteStartFrame</samp> isn't set.
 +
|}
 +
</dd>
   −
====Format====
+
<dt>Advanced:</dt>
This consists of a string → model lookup, where...
  −
* The key is a [[Modding:Common data field types#Unique string ID|unique string ID]] for the NPC like <samp>Example.ModId_NpcName</samp>, which will be used as the internal <samp>Name</samp> (not <samp>DisplayName</samp>).
  −
* The value is a model with the following fields.
  −
 
  −
<dl style="margin-left: 2em;">
  −
<dt>Basic info:</dt>
   
<dd>
 
<dd>
 
{| class="wikitable"
 
{| class="wikitable"
Line 3,248: Line 3,043:  
! effect
 
! effect
 
|-
 
|-
| <samp>DisplayName</samp>
+
| <samp>CustomFields</samp>
| A [[Modding:Tokenizable strings|tokenizable string]] for the NPC's display name.
+
| The [[#Custom data fields|custom fields]] for this entry.
 
|-
 
|-
| <samp>Language</samp>
+
| <samp>FormerCharacterNames</samp>
| ''(Optional)'' The language spoken by the NPC. One of <samp>Default</samp> (the default language understood by the player) or <samp>Dwarvish</samp> (which the player can only understand after finding the [[Dwarvish Translation Guide|Dwarvish translation guide]]). Default <samp>Default</samp>.
+
| ''(Optional)'' The former NPC names which may appear in save data. If matched, the game will rename the NPC and update related data (e.g. friendship).
|-
+
 
| <samp>Gender</samp>
+
A former name is only applied if:
| ''(Optional)'' The NPC's gender identity. One of <samp>Female</samp>, <samp>Male</samp>, or <samp>Undefined</samp>. Default <samp>Undefined</samp>.
+
# it doesn't match a current ID in <samp>Data/Characters</samp>;
|-
+
# the save has an NPC with the former name;
| <samp>Age</samp>
+
# the save doesn't already have an NPC with the new name.
| ''(Optional)'' The general age of the NPC. One of <samp>Child</samp>, <samp>Teen</samp>, or <samp>Adult</samp>. Default <samp>Adult</samp>.
+
 
 +
For example:
 +
<syntaxhighlight lang="js">
 +
"FormerCharacterNames": [ "SomeOldName" ]
 +
</syntaxhighlight>
   −
This affects generated dialogue lines (e.g. a child might say "stupid" and an adult might say "depressing"), generic dialogue (e.g. a child might respond to dumpster diving with "''Eww... What are you doing?''" and a teen would say "''Um... Why are you digging in the trash?''"), and the gift they choose as [[Feast of the Winter Star]] gift-giver. Children are also excluded from item delivery quests.
+
Former names can have any format, but they must be '''globally''' unique. They can't match the ID or <samp>FormerCharacterNames</samp> of any other NPC in <samp>Data/Characters</samp> (whether vanilla or custom).
 
|-
 
|-
| <samp>Manner</samp>
+
| <samp>FestivalVanillaActorIndex</samp>
| ''(Optional)'' A measure of the character's general politeness, which affects some generic dialogue lines. One of <samp>Neutral</samp>, <samp>Polite</samp>, or <samp>Rude</samp>. Default <samp>Neutral</samp>.
+
| ''(Optional, Specialized)'' The NPC's index in the <samp>Maps/characterSheet</samp> tilesheet, if applicable. This is used for placing vanilla NPCs in festivals from the map; custom NPCs should use the <samp>&lt;layer&gt;_additionalCharacters</samp> field in the festival data instead.
|-
  −
| <samp>SocialAnxiety</samp>
  −
| ''(Optional)'' A measure of the character's comfort with social situations, which affects some generic dialogue lines. One of <samp>Neutral</samp>, <samp>Outgoing</samp>, or <samp>Shy</samp>. Default <samp>Neutral</samp>.
  −
|-
  −
| <samp>Optimism</samp>
  −
| ''(Optional)'' A measure of the character's overall optimism. One of <samp>Neutral</samp>, <samp>Negative</samp>, or <samp>Positive</samp>. Default <samp>Neutral</samp>.
  −
|-
  −
| <samp>BirthSeason</samp>
  −
| ''(Optional if non-social)'' The season name (case-sensitive) for the NPC's birthday. One of <samp>spring</samp>, <samp>summer</samp>, <samp>fall</samp>, or <samp>winter</samp>. Default none.
  −
|-
  −
| <samp>BirthDay</samp>
  −
| ''(Optional if non-social)'' The day number for the NPC's birthday. Default 0.
  −
|-
  −
| <samp>HomeRegion</samp>
  −
| ''(Optional)'' The region of the world in which the NPC lives (one of <samp>Desert</samp>, <samp>Town</samp>, or <samp>Other</samp>). For example, only <samp>Town</samp> NPCs are counted for the introductions [[Quests#List of Story Quests|quest]], can be selected as a secret santa for the [[Feast of the Winter Star]], or get a friendship boost from the [[Luau]]. Default <samp>Other</samp>.
  −
|-
  −
| <samp>IsDarkSkinned</samp>
  −
| ''(Optional)'' Whether the NPC has dark skin, which affects the chance of children with the player having dark skin too. Default false.
   
|}
 
|}
 
</dd>
 
</dd>
 +
</dl>
   −
<dt>Social features:</dt>
+
====Examples====
<dd>
+
For example, this content pack adds a new ''Amabel'' NPC with full social features:
{| class="wikitable"
+
 
|-
+
{{#tag:syntaxhighlight|<nowiki>
! field
+
{
! effect
+
    "Format": "</nowiki>{{Content Patcher version}}<nowiki>",
|-
+
    "Changes": [
| <samp>CanSocialize</samp>
+
        {
| ''(Optional)'' A [[Modding:Game state queries|game state query]] which indicates whether to enable social features (like birthdays, gift giving, [[friendship]], and an entry in the social tab). Default true.
+
            "Action": "EditData",
|-
+
            "Target": "Data/Characters",
| <samp>CanBeRomanced</samp>
+
            "Entries": {
| ''(Optional)'' Whether the NPC can be dated and romanced. This enables romance features for this NPC (like a 'single' label in the social menu, bouquet gifting, and marriage). Default false.
+
                "{{ModId}}_Amabel": {
|-
+
                    "DisplayName": "Amabel", // this would normally use {{i18n:}} to support translations
| <samp>CanReceiveGifts</samp>
+
                    "BirthSeason": "Fall",
| ''(Optional)'' Whether players can give gifts to this NPC. Default true.
+
                    "BirthDay": 14,
 +
                    "HomeRegion": "Town",
 +
                    "Gender": "Female",
 +
                    "Age": "Teen",
 +
                    "Manner": "Rude",
 +
                    "SocialAnxiety": "Outgoing",
 +
                    "Optimism": "Neutral",
   −
The NPC must also be social per <samp>CanSocialize</samp> and have an entry in <samp>Data/NPCGiftTastes</samp> to be giftable, regardless of this value.
+
                    "CanBeRomanced": true,
|-
+
                    "LoveInterest": "Abigail",
| <samp>CanCommentOnPurchasedShopItems</samp>
  −
| ''(Optional)'' Whether this NPC can comment on items that a player sold to a shop which then resold it to them. If null (or omitted), this will default to true if their <samp>HomeRegion</samp> is set to <samp>Town</samp>.
     −
The NPC must also be social per <samp>CanSocialize</samp> to allow it, regardless of this value.
+
                    "Home": [
|-
+
                        {
| <samp>CanGreetNearbyCharacters</samp>
+
                            "Id": "Default",
| ''(Optional)'' Whether this NPC can show a speech bubble greeting nearby players or NPCs, and or be greeted by other NPCs. Default true.
+
                            "Location": "SeedShop",
|-
+
                            "Tile": { "X": 1, "Y": 9 },
| <samp>CanVisitIsland</samp>
+
                            "Direction": "Left"
| ''(Optional)'' A [[Modding:Game state queries|game state query]] which indicates whether the NPC can visit the [[Ginger Island]] resort once it's unlocked. Default true.
+
                        }
 +
                    ]
 +
                }
 +
            }
 +
        }
 +
    ]
 +
}</nowiki>|lang=javascript}}
   −
The NPC must also be social per <samp>CanSocialize</samp> to visit the island, regardless of this value.
+
You can also add non-social NPCs which don't have birthdays or friendship points, accept gifts, give quests, etc:
|-
+
{{#tag:syntaxhighlight|<nowiki>
| <samp>LoveInterest</samp>
+
{
| ''(Optional)'' Unused.
+
    "Format": "</nowiki>{{Content Patcher version}}<nowiki>",
|-
+
    "Changes": [
| <samp>Calendar</samp>
+
        {
| ''(Optional)'' Determines when the NPC's birthday is shown in the [[calendar]]. Possible values:
+
            "Action": "EditData",
{| class="wikitable"
+
            "Target": "Data/Characters",
|-
+
            "Entries": {
! value
+
                "{{ModId}}_Belwick": {
! effect
+
                    "DisplayName": "Belwick", // this would normally use {{i18n:}} to support translations
|-
  −
| <samp>HiddenAlways</samp>
  −
| They never appear in the calendar.
  −
|-
  −
| <samp>HiddenUntilMet</samp>
  −
| Until the player meets them, they don't appear in the calendar.
  −
|-
  −
| <samp>AlwaysShown</samp>
  −
| They always appear in the calendar.
  −
|}
     −
Defaults to <samp>AlwaysShown</samp>.
+
                    "SocialTab": "HiddenAlways",
|-
+
                    "CanSocialize": "FALSE",
| <samp>SocialTab</samp>
+
                    "IntroductionsQuest": false,
| ''(Optional)'' Determines how the NPC is shown on the [[friendship|social tab]] when unlocked. Possible values:
+
                    "PerfectionScore": false,
{| class="wikitable"
+
                    "EndSlideShow": true
|-
+
                }
! value
+
            }
! effect
+
        }
|-
+
    ]
| <samp>HiddenAlways</samp>
+
}</nowiki>|lang=javascript}}
| They never appear in the social tab.
  −
|-
  −
| <samp>HiddenUntilMet</samp>
  −
| Until the player meets them, they don't appear on the social tab.
  −
|-
  −
| <samp>UnknownUntilMet</samp>
  −
| Until the player meets them, their name on the social tab is replaced with "???".
  −
|-
  −
| <samp>AlwaysShown</samp>
  −
| They always appear in the social tab (including their name).
  −
|}
     −
Defaults to <samp>UnknownUntilMet</samp>.
+
===Custom NPC appearance===
|-
+
{{/doc status|[[Modding:NPC data]]|done=false}}
| <samp>SpouseAdopts</samp>
  −
| ''(Optional)'' A [[Modding:Game state queries|game state query]] which indicates whether the player will need to adopt children with this spouse, instead of either the player or NPC giving birth. If null, defaults to true for same-gender and false for opposite-gender spouses.
     −
The <samp>Target</samp> player is the one they're married to.
+
Each NPC can now have any number of custom portraits/sprites in <samp>Data/Characters</samp> with arbitrary conditions. This lets mods add features like indoor/outdoor outfits without the performance impact of reloading textures. If multiple outfits apply, the game will choose between them with a day-stable randomization.
|-
  −
| <samp>SpouseWantsChildren</samp>
  −
| ''(Optional)'' A [[Modding:Game state queries|game state query]] which indicates whether the spouse will ask to have children. Defaults to true.
     −
The <samp>Target</samp> player is the one they're married to.
+
For example, you can load indoor/outdoor outfits for a custom NPC to swap between automatically:
|-
+
<syntaxhighlight lang="js">
| <samp>SpouseGiftJealousy</samp>
+
// add base indoor/outdoor sprites
| ''(Optional)'' A [[Modding:Game state queries|game state query]] which indicates whether the [[Marriage#Jealousy|spouse will get jealous of gifts to other NPCs]]. Defaults to true.
+
{
 
+
    "Action": "Load",
The <samp>Target</samp> player is the one they're married to, and the <samp>Target</samp> item is the one that was gifted.
+
    "Target": "Characters/Johnny_Indoor, Characters/Johnny_Outdoor, Portraits/Johnny_Indoor, Portraits/Johnny_Outdoor",
|-
+
    "FromFile": "assets/{{Target}}.png"
| <samp>SpouseGiftJealousyFriendshipChange</samp>
+
},
| ''(Optional)'' The [[Friendship|friendship point]] effect when the <samp>SpouseGiftJealously</samp> is triggered. Default -30.
  −
|-
  −
| <samp>SpouseRoom</samp>
  −
| ''(Optional)'' The [[Marriage#Spouse Rooms|NPC's spouse room]] in the farmhouse when the player marries them, if applicable. If this is omitted for a marriageable NPC, they'll use Abigail's spouse room by default.
     −
This consists of a model with these fields:
+
// apply any overlays needed
{| class="wikitable"
+
{
|-
+
    "Action": "EditImage",
! field
+
    "Target": "Characters/Johnny_Indoor, Portraits/Johnny_Indoor",
! effect
+
    "FromFile": "assets/overlays/{{Target}}_married.png",
|-
+
    "When": {
| <samp>MapAsset</samp>
+
        "Spouse": "Johnny"
| ''(Optional)'' The asset name for the spouse room map. The <samp>Map/</samp> prefix is added automatically and shouldn't be included. Defaults to <samp>spouseRooms</samp>.
+
    }
|-
+
},
| <samp>MapSourceRect</samp>
  −
| ''(Optional)'' The tile area within the <samp>MapAsset</samp> containing the spouse's room. This should usually be a 6x9 tile area, though the game will try to adjust to a different size. Specified as a model with <samp>X</samp>, <samp>Y</samp>, <samp>Width</samp>, and <samp>Height</samp> fields. Defaults to <samp>(0, 0, 6, 9)</samp>.
  −
|}
  −
|-
  −
| <samp>SpousePatio</samp>
  −
| ''(Optional)'' The [[Marriage#Spouse Outside Area|NPC's patio area]] on the farm when the player marries them, if any. Default none.
     −
This consists of a model with these fields:
+
// add NPC
{| class="wikitable"
+
{
|-
+
    "Action": "EditData",
! field
+
    "Target": "Data/Characters",
! effect
+
    "Entries": {
|-
+
        "SomeMod.Id_Johnny": {
| <samp>MapAsset</samp>
+
            ...,
| ''(Optional)'' The asset name for the patio area. The <samp>Map/</samp> prefix is added automatically and shouldn't be included. Defaults to <samp>spousePatios</samp>.
+
            "Appearance": [
|-
+
                {
| <samp>MapSourceRect</samp>
+
                    "Id": "Outdoors",
| ''(Optional)'' The tile area within the <samp>MapAsset</samp> containing the spouse's patio area. This must be a 4x4 tile area. Specified as a model with <samp>X</samp>, <samp>Y</samp>, <samp>Width</samp>, and <samp>Height</samp> fields. Defaults to <samp>(0, 0, 4, 4)</samp>.
+
                    "Indoors": false,
|-
+
                    "Portrait": "Portraits/Johnny_Outdoor",
| <samp>SpriteAnimationFrames</samp>
+
                    "Sprite": "Characters/Johnny_Outdoor"
| ''(Optional)'' The spouse's animation frames when they're in the patio. Each frame is an array containing [0] the sprite index in their spritesheet, and [1] the optional duration in milliseconds (default 100). If omitted or empty, the NPC won't be animated.
+
                },
 +
                {
 +
                    "Id": "Default",
 +
                    "Portrait": "Portraits/Johnny_Indoor",
 +
                    "Sprite": "Characters/Johnny_Indoor"
 +
                }
 +
            ]
 +
        }
 +
    }
 +
}
 +
</syntaxhighlight>
   −
For example, here is Abigail playing the flute:
+
See the <samp>Appearance</samp> field in [[#Custom NPCs|custom NPC data]] for more info.
<syntaxhighlight lang="js">
+
 
"SpriteAnimationFrames": [
+
===Custom farm animals===
    [16, 500], // show index 16 for 500ms
+
{{/doc status|[[Modding:Animal data]]|done=true}}
    [17, 500],
  −
    [18, 500],
  −
    [19]      // if duration is omitted, defaults to 100ms
  −
]
  −
</syntaxhighlight>
  −
|-
  −
| <samp>SpriteAnimationPixelOffset</samp>
  −
| ''(Optional)'' The pixel offset to apply to the NPC's sprite when they're animated in the patio, specified as a model with <samp>X</samp> and <samp>Y</samp> fields. This is ignored if the NPC isn't animated via <samp>SpriteAnimationFrames</samp>. Default none.
  −
|}
  −
|-
  −
| <samp>SpouseFloors</samp><br /><samp>SpouseWallpapers</samp>
  −
| ''(Optional)'' The floors and wallpapers which the NPC may randomly apply to the farmhouse when married to the player. If omitted or empty, the NPC will randomly choose a base floor (0–39) or wallpaper (0–111).
  −
|-
  −
| <samp>IntroductionsQuest</samp>
  −
| ''(Optional)'' Whether to include this NPC in [[Quests#List of Story Quests|the ''introductions'' quest]]. If <samp>null</samp> (or omitted), this will default to true if the <samp>HomeRegion</samp> field is set to <samp>Town</samp>.
  −
|-
  −
| <samp>ItemDeliveryQuests</samp>
  −
| ''(Optional)'' A [[Modding:Game state queries|game state query]] which indicates whether this NPC can give item delivery quests. If <samp>null</samp> (or omitted), this will default to true if the <samp>HomeRegion</samp> field is set to <samp>Town</samp>.
  −
 
  −
The NPC must also be social per <samp>CanSocialize</samp> to allow it, regardless of this value.
  −
|-
  −
| <samp>PerfectionScore</samp>
  −
| ''(Optional)'' Whether to include this NPC when checking whether the player has max friendships with every NPC for the perfection score. Default true.
  −
 
  −
The NPC must also be social per <samp>CanSocialize</samp> to be counted, regardless of this value.
  −
|-
  −
| <samp>EndSlideShow</samp>
  −
| ''(Optional)'' How the NPC appears in the end-game perfection slide show. Possible values:
  −
{| class="wikitable"
  −
|-
  −
! value
  −
! effect
  −
|-
  −
| <samp>Hidden</samp>
  −
| The NPC doesn't appear in the slide show.
  −
|-
  −
| <samp>MainGroup</samp>
  −
| The NPC is added to the main group of NPCs which walk across the screen.
  −
|-
  −
| <samp>TrailingGroup</samp>
  −
| The NPC is added to the trailing group of NPCs which follow the main group.
  −
|}
  −
 
  −
Defaults to <samp>MainGroup</samp>.
  −
|-
  −
| <samp>FriendsAndFamily</samp>
  −
| ''(Optional)'' The NPC's closest friends and family, as a dictionary where the key is the other NPC's internal name and the value is an optional tokenizable string for the name to use in dialogue text (like 'mom'). Default none.
  −
 
  −
This affects generic dialogue for revealing likes and dislikes to family members, and may affect <samp>inlaw_&lt;NPC&gt;</samp> dialogues. This isn't necessarily comprehensive.
  −
|}
  −
</dd>
  −
 
  −
<dt>Dumpster diving:</dt>
  −
<dd>
  −
{| class="wikitable"
  −
|-
  −
! field
  −
! effect
  −
|-
  −
| <samp>DumpsterDiveEmote</samp>
  −
| ''(Optional)'' The emote ID to show above the NPC's head when they see a player rummaging through trash. See [[Modding:event data#Emotes|emote IDs]]. If omitted or <samp>null</samp>, the default depends on the NPC's age: a child will show sad (28), a teen will show a question mark (8), and an adult will show angry (12).
  −
|-
  −
| <samp>DumpsterDiveFriendshipEffect</samp>
  −
| ''(Optional)'' The friendship point change if this NPC sees a player rummaging through trash. Default -25.
  −
|}</dd>
  −
 
  −
<dt>Festivals:</dt>
  −
<dd>
  −
{| class="wikitable"
  −
|-
  −
! field
  −
! effect
  −
|-
  −
| <samp>FlowerDanceCanDance</samp>
  −
| ''(Optional)'' Whether players can ask the NPC to dance at the Flower Dance festival. The possible values are <samp>true</samp> (can always ask), <samp>false</samp> (can never ask), or <samp>null</samp> (can ask if they're romanceable). Default <samp>null</samp>.
  −
 
  −
If the NPC can dance, you should also add the [[Modding:NPC data#Overworld_sprites|dance sprite frames]] and <samp>FlowerDance_Decline</samp> [[Modding:Dialogue|dialogue text]]. You can optionally set the <samp>FlowerDance_Accept</samp> dialogue too (though NPCs have a default accept dialogue if not).
  −
|-
  −
| <samp>WinterStarParticipant</samp>
  −
| ''(Optional)''  A [[Modding:Game state queries|game state query]] which indicates whether this NPC can give and receive gifts at the [[Feast of the Winter Star]]. If <samp>null</samp> (or omitted), this will default to true if the <samp>HomeRegion</samp> field is set to <samp>Town</samp>.
  −
|-
  −
| <samp>WinterStarGifts</samp>
  −
| At the [[Feast of the Winter Star]], the possible gifts this NPC can give to players. A matching entry is selected at random.
  −
 
  −
This consists of a list of models with these fields:
  −
{| class="wikitable"
  −
|-
  −
! field
  −
! effect
  −
|-
  −
| ''common fields''
  −
| See [[Modding:Item queries#Item spawn fields|item spawn fields]] for the generic item fields.
  −
 
  −
If set to an [[Modding:Item queries|item query]] which returns multiple items, one of them will be selected at random.
  −
|}
  −
|}
  −
 
  −
<dt>Spawn rules:</dt>
  −
<dd>
  −
{| class="wikitable"
  −
|-
  −
! field
  −
! effect
  −
|-
  −
| <samp>UnlockConditions</samp>
  −
| ''(Optional)'' A [[Modding:Game state queries|game state query]] which indicates whether the NPC should be added to the world, checked when loading a save and when ending each day. This only affects whether the NPC is added when missing; returning false won't remove an NPC that's already been added. Defaults to true.
  −
|-
  −
| <samp>SpawnIfMissing</samp>
  −
| ''(Optional)'' Whether to add this NPC to the world if they're missing (if the <samp>UnlockConditions</samp> match and <samp>HomeLocation</samp> is valid). Default true.
  −
|-
  −
| <samp>Home</samp>
  −
| ''(Optional)'' The default place where this NPC spawns and returns each day. If there are multiple entries, the first matching one is used.
  −
 
  −
This consists of a list of models with these fields:
  −
{| class="wikitable"
  −
|-
  −
! field
  −
! effect
  −
|-
  −
| <samp>ID</samp>
  −
| The [[Modding:Common data field types#Unique string ID|unique string ID]] for this entry within the current list.
  −
|-
  −
| <samp>Location</samp>
  −
| ''(Optional)'' The internal name for the home location where this NPC spawns and returns each day. Default none.
  −
|-
  −
| <samp>Tile</samp>
  −
| ''(Optional)'' The tile position within the home location where this NPC spawns and returns each day. Specified as a model with <samp>X</samp> and <samp>Y</samp> fields. Defaults to <samp>(0, 0)</samp>.
  −
|-
  −
| <samp>Direction</samp>
  −
| ''(Optional)'' The default direction the NPC faces when they start each day. The possible values are <samp>down</samp>, <samp>left</samp>, <samp>right</samp>, and <samp>up</samp>. Defaults to <samp>up</samp>.
  −
|-
  −
| <samp>Condition</samp>
  −
| ''(Optional)'' A [[Modding:Game state queries|game state query]] which indicates whether this entry can be selected. Default true.
  −
|}
  −
|}
  −
</dd>
  −
 
  −
<dt>Appearance & sprite:</dt>
  −
<dd>
  −
{| class="wikitable"
  −
|-
  −
! field
  −
! effect
  −
|-
  −
| <samp>TextureName</samp>
  −
| ''(Optional)'' The '''last segment''' of the NPC's portrait and sprite asset names. For example, set to <samp>Abigail</samp> to use <samp>Portraits/Abigail</samp> and <samp>Characters/Abigail</samp> respectively. Defaults to the internal NPC name.
  −
|-
  −
| <samp>Appearance</samp>
  −
| ''(Optional)'' The portrait/sprite textures to use.
  −
 
  −
This can list any number of appearance options. They'll be sorted by <samp>Precedence</samp> value (with lower values taking priority), then filtered to those whose fields match. If multiple matching appearances have precedence, one entry is randomly chosen based on their relative weight. This randomization is stable per day, so the NPC always makes the same choice until the next day. If a portrait/sprite can't be loaded (or no appearances match), the NPC will use the default asset based on <samp>TextureName</samp>.
  −
 
  −
The NPC rechecks this field each time they change location.
  −
 
  −
This consists of a list of models with these fields:
  −
{| class="wikitable"
  −
|-
  −
! field
  −
! effect
  −
|-
  −
| <samp>Id</samp>
  −
| The [[Modding:Common data field types#Unique string ID|unique string ID]] for this entry within the current list.
  −
|-
  −
| <samp>Season</samp>
  −
| ''(Optional)'' The season in which this appearance should be used (one of <samp>spring</samp>, <samp>summer</samp>, <samp>fall</samp>, or <samp>winter</samp>), or omit for any season. Defaults to any season.
  −
|-
  −
| <samp>Indoors</samp><br /><samp>Outdoors</samp>
  −
| ''(Optional)'' Whether this appearance should be used when indoors and/or outdoors. Both default to true.
  −
|-
  −
| <samp>Condition</samp>
  −
| ''(Optional)'' A [[Modding:Game state queries|game state query]] which indicates whether this entry can be selected. Default true.
  −
|-
  −
| <samp>Portrait</samp><br /><samp>Sprite</samp>
  −
| ''(Optional)'' The asset name for the portraits and/or sprites texture to load. If omitted or it can't be loaded, it will default to the default asset per the <samp>Texture</samp> field.
  −
|-
  −
| <samp>IsIslandAttire</samp>
  −
| ''(Optional)'' Whether this is island beach attire worn at the resort. Default false.
  −
 
  −
This is mutually exclusive: NPCs will never wear it in other contexts if it's true, and will never wear it as island attire if it's false.
  −
|-
  −
| <samp>Precedence</samp>
  −
| ''(Optional)'' The order in which this entry should be checked, where lower values are checked first. This can be a negative value. Default 0.
  −
|-
  −
| <samp>Weight</samp>
  −
| ''(Optional)'' If multiple entries with the same <samp>Precedence</samp> match, the relative weight to use when randomly choosing one. Default 1.
  −
 
  −
For example, let's say two appearance entries match: one has a weight of 2, and the other has a weight of 1. Their probability of being chosen is 2/3 and 1/3 respectively.
  −
|}
  −
 
  −
'''Note:''' the default textures based on <samp>TextureName</samp> must still exist, even if you use this field to override them.
  −
|-
  −
| <samp>MugShotSourceRect</samp>
  −
| ''(Optional)'' The 16x24-pixel area in the character's sprite texture to show as their mug shot icon in the calendar, social menu, and other contexts. Defaults to part of their first sprite.
  −
|-
  −
| <samp>Size</samp>
  −
| ''(Optional)'' The pixel size of the individual sprites in their overworld sprite spritesheet. Specified as a model with <samp>X</samp> and <samp>Y</samp> fields. Defaults to <samp>(16, 32)</samp>.
  −
 
  −
'''Note:''' sizes bigger than 16×32 will cause issues like broken spawning, pathfinding, misalignment in the [[perfection]] end-game slide show, etc.
  −
|-
  −
| <samp>Breather</samp>
  −
| ''(Optional)'' Whether the chest on the NPC's overworld sprite puffs in and out as they breathe. Default true</samp>.
  −
|-
  −
| <samp>BreathChestRect</samp>
  −
| ''(Optional)'' A [[Modding:Common data field types#Rectangle|rectangle]] pixel area within the spritesheet which expands and contracts to simulate breathing, relative to the top-left corner of the source rectangle for their current sprite. Omit to calculate it automatically. This should be omitted for most NPCs, unless they have a non-standard size.
  −
|-
  −
| <samp>BreathChestPosition</samp>
  −
| ''(Optional)'' A [[Modding:Common data field types#Point|point]] pixel offset to apply to the NPC's <samp>BreathChestPosition</samp> when drawn over the NPC. Omit to calculate it automatically. This should be omitted for most NPCs, unless they have a non-standard size.
  −
|-
  −
| <samp>Shadow</samp>
  −
| ''(Optional)'' The options for the shadow to draw under the NPC, or omit to apply the default shadow behavior.
  −
 
  −
This consists of a model with these fields:
  −
 
  −
{| class="wikitable"
  −
|-
  −
! field
  −
! effect
  −
|-
  −
| <samp>Visible</samp>
  −
| ''(Optional)'' Whether the shadow should be drawn. Default true.
  −
|-
  −
| <samp>Offset</samp>
  −
| ''(Optional)'' A [[Modding:Common data field types#Point|point]] pixel offset applied to the shadow position. Default zero.
  −
|-
  −
| <samp>Scale</samp>
  −
| ''(Optional)'' The scale at which to draw the shadow. Default 1.
  −
 
  −
This is a multiplier applied to the default shadow scale, which can change based on factors like whether the NPC is jumping. For example, <samp>0.5</samp> means half the size it'd be drawn if you didn't specify a scale.
  −
|}
  −
|-
  −
| <samp>EmoteOffset</samp>
  −
| ''(Optional)'' A [[Modding:Common data field types#Point|point]] pixel offset applied to emote drawn over the NPC. Default zero.
  −
|-
  −
| <samp>ShakePortraits</samp>
  −
| ''(Optional)'' The portrait indexes which should shake when displayed. Default none.
  −
|-
  −
| <samp>KissSpriteIndex</samp>
  −
| ''(Optional)'' If the NPC can be married, the sprite index within their <samp>Texture</samp> to use when kissing a player. Default 28.
  −
|-
  −
| <samp>KissSpriteFacingDirection</samp>
  −
| ''(Optional)'' Whether the character is facing right (true) or left (false) in their <samp>KissSpriteIndex</samp>. The sprite will be flipped as needed to face the player. Default true.
  −
|}
  −
</dd>
  −
 
  −
<dt>[[Secrets#Gift Log|Hidden gift log emote]]:</dt>
  −
<dd>
  −
{| class="wikitable"
  −
|-
  −
! field
  −
! effect
  −
|-
  −
| <samp>HiddenProfileEmoteSound</samp>
  −
| ''(Optional)'' For the [[Secrets#Gift Log|hidden gift log emote]], the [[#Custom audio|cue ID]] for the sound played when clicking the sprite. Defaults to <samp>drumkit6</samp>.
  −
|-
  −
| <samp>HiddenProfileEmoteDuration</samp>
  −
| ''(Optional)'' For the [[Secrets#Gift Log|hidden gift log emote]], how long the animation plays measured in milliseconds. Defaults to 4000 (4 seconds).
  −
|-
  −
| <samp>HiddenProfileEmoteStartFrame</samp>
  −
| ''(Optional)'' For the [[Secrets#Gift Log|hidden gift log emote]], the index within the NPC's overworld sprite spritesheet at which the animation starts. If omitted for a vanilla NPC, the game plays a default animation specific to that NPC; if omitted for a custom NPC, the game just shows them walking while facing down.
  −
|-
  −
| <samp>HiddenProfileEmoteFrameCount</samp>
  −
| ''(Optional)'' For the [[Secrets#Gift Log|hidden gift log emote]], the number of frames in the animation. The first frame corresponds to <samp>HiddenProfileEmoteStartFrame</samp>, and each subsequent frame will use the next sprite in the spritesheet. Default 1.
  −
 
  −
This has no effect if <samp>HiddenProfileEmoteStartFrame</samp> isn't set.
  −
|-
  −
| <samp>HiddenProfileEmoteFrameDuration</samp>
  −
| ''(Optional)'' For the [[Secrets#Gift Log|hidden gift log emote]], how long each animation frame is shown on-screen before switching to the next one, measured in milliseconds. Default 200.
  −
 
  −
This has no effect if <samp>HiddenProfileEmoteStartFrame</samp> isn't set.
  −
|}
  −
</dd>
  −
 
  −
<dt>Advanced:</dt>
  −
<dd>
  −
{| class="wikitable"
  −
|-
  −
! field
  −
! effect
  −
|-
  −
| <samp>CustomFields</samp>
  −
| The [[#Custom data fields|custom fields]] for this entry.
  −
|-
  −
| <samp>FormerCharacterNames</samp>
  −
| ''(Optional)'' The former NPC names which may appear in save data. If matched, the game will rename the NPC and update related data (e.g. friendship).
  −
 
  −
A former name is only applied if:
  −
# it doesn't match a current ID in <samp>Data/Characters</samp>;
  −
# the save has an NPC with the former name;
  −
# the save doesn't already have an NPC with the new name.
  −
 
  −
For example:
  −
<syntaxhighlight lang="js">
  −
"FormerCharacterNames": [ "SomeOldName" ]
  −
</syntaxhighlight>
  −
 
  −
Former names can have any format, but they must be '''globally''' unique. They can't match the ID or <samp>FormerCharacterNames</samp> of any other NPC in <samp>Data/Characters</samp> (whether vanilla or custom).
  −
|-
  −
| <samp>FestivalVanillaActorIndex</samp>
  −
| ''(Optional, Specialized)'' The NPC's index in the <samp>Maps/characterSheet</samp> tilesheet, if applicable. This is used for placing vanilla NPCs in festivals from the map; custom NPCs should use the <samp>&lt;layer&gt;_additionalCharacters</samp> field in the festival data instead.
  −
|}
  −
</dd>
  −
</dl>
  −
 
  −
====Examples====
  −
For example, this content pack adds a new ''Amabel'' NPC with full social features:
  −
 
  −
{{#tag:syntaxhighlight|<nowiki>
  −
{
  −
    "Format": "</nowiki>{{Content Patcher version}}<nowiki>",
  −
    "Changes": [
  −
        {
  −
            "Action": "EditData",
  −
            "Target": "Data/Characters",
  −
            "Entries": {
  −
                "{{ModId}}_Amabel": {
  −
                    "DisplayName": "Amabel", // this would normally use {{i18n:}} to support translations
  −
                    "BirthSeason": "Fall",
  −
                    "BirthDay": 14,
  −
                    "HomeRegion": "Town",
  −
                    "Gender": "Female",
  −
                    "Age": "Teen",
  −
                    "Manner": "Rude",
  −
                    "SocialAnxiety": "Outgoing",
  −
                    "Optimism": "Neutral",
  −
 
  −
                    "CanBeRomanced": true,
  −
                    "LoveInterest": "Abigail",
  −
 
  −
                    "Home": [
  −
                        {
  −
                            "Id": "Default",
  −
                            "Location": "SeedShop",
  −
                            "Tile": { "X": 1, "Y": 9 },
  −
                            "Direction": "Left"
  −
                        }
  −
                    ]
  −
                }
  −
            }
  −
        }
  −
    ]
  −
}</nowiki>|lang=javascript}}
  −
 
  −
You can also add non-social NPCs which don't have birthdays or friendship points, accept gifts, give quests, etc:
  −
{{#tag:syntaxhighlight|<nowiki>
  −
{
  −
    "Format": "</nowiki>{{Content Patcher version}}<nowiki>",
  −
    "Changes": [
  −
        {
  −
            "Action": "EditData",
  −
            "Target": "Data/Characters",
  −
            "Entries": {
  −
                "{{ModId}}_Belwick": {
  −
                    "DisplayName": "Belwick", // this would normally use {{i18n:}} to support translations
  −
 
  −
                    "SocialTab": "HiddenAlways",
  −
                    "CanSocialize": "FALSE",
  −
                    "IntroductionsQuest": false,
  −
                    "PerfectionScore": false,
  −
                    "EndSlideShow": true
  −
                }
  −
            }
  −
        }
  −
    ]
  −
}</nowiki>|lang=javascript}}
  −
 
  −
===Custom NPC appearance===
  −
{{/doc status|[[Modding:NPC data]]|done=false}}
  −
 
  −
Each NPC can now have any number of custom portraits/sprites in <samp>Data/Characters</samp> with arbitrary conditions. This lets mods add features like indoor/outdoor outfits without the performance impact of reloading textures. If multiple outfits apply, the game will choose between them with a day-stable randomization.
  −
 
  −
For example, you can load indoor/outdoor outfits for a custom NPC to swap between automatically:
  −
<syntaxhighlight lang="js">
  −
// add base indoor/outdoor sprites
  −
{
  −
    "Action": "Load",
  −
    "Target": "Characters/Johnny_Indoor, Characters/Johnny_Outdoor, Portraits/Johnny_Indoor, Portraits/Johnny_Outdoor",
  −
    "FromFile": "assets/{{Target}}.png"
  −
},
  −
 
  −
// apply any overlays needed
  −
{
  −
    "Action": "EditImage",
  −
    "Target": "Characters/Johnny_Indoor, Portraits/Johnny_Indoor",
  −
    "FromFile": "assets/overlays/{{Target}}_married.png",
  −
    "When": {
  −
        "Spouse": "Johnny"
  −
    }
  −
},
  −
 
  −
// add NPC
  −
{
  −
    "Action": "EditData",
  −
    "Target": "Data/Characters",
  −
    "Entries": {
  −
        "SomeMod.Id_Johnny": {
  −
            ...,
  −
            "Appearance": [
  −
                {
  −
                    "Id": "Outdoors",
  −
                    "Indoors": false,
  −
                    "Portrait": "Portraits/Johnny_Outdoor",
  −
                    "Sprite": "Characters/Johnny_Outdoor"
  −
                },
  −
                {
  −
                    "Id": "Default",
  −
                    "Portrait": "Portraits/Johnny_Indoor",
  −
                    "Sprite": "Characters/Johnny_Indoor"
  −
                }
  −
            ]
  −
        }
  −
    }
  −
}
  −
</syntaxhighlight>
  −
 
  −
See the <samp>Appearance</samp> field in [[#Custom NPCs|custom NPC data]] for more info.
  −
 
  −
===Custom farm animals===
  −
{{/doc status|[[Modding:Animal data]]|done=true}}
  −
 
  −
You can now create and edit [[Animals|farm animals]] by editing the revamped <samp>Data/FarmAnimals</samp> asset. This changes to a data model, adds built-in support for custom animals, and allows far more customizability per animal (like its size, growth, produce, appearance and sounds, etc).
  −
 
  −
===Custom pets===
  −
{{/doc status|a new doc page|done=false}}
  −
 
  −
====Format====
  −
You can now create and customize [[Animals#Cat or Dog|pet]]s & pet breeds by editing the new <samp>Data/Pets</samp> asset.
  −
 
  −
This consists of a string → model lookup, where...
  −
* The key is a [[Modding:Common data field types#Unique string ID|unique string ID]] for the pet (not the pet breed). The vanilla IDs are <samp>Cat</samp> and <samp>Dog</samp>.
  −
* The value is a model with the fields listed below.
  −
 
  −
=====Basic info=====
  −
{| class="wikitable"
  −
|-
  −
! field
  −
! effect
  −
|-
  −
| <samp>DisplayName</samp>
  −
| A [[Modding:Tokenizable strings|tokenizable string]] for the pet type's display name (e.g. "cat" or "dog"). For example, the vanilla adoption events show this when Marnie asks if you want to adopt the cat/dog.
  −
|}
  −
 
  −
=====Audio & sprites=====
  −
{| class="wikitable"
  −
|-
  −
! field
  −
! effect
  −
|-
  −
| <samp>BarkSound</samp>
  −
| The [[#Custom audio|cue ID]] for the pet's occasional 'bark' sound.
  −
|-
  −
| <samp>ContentSound</samp>
  −
| The [[#Custom audio|cue ID]] for the sound which the pet makes when you pet it.
  −
|-
  −
| <samp>RepeatContentSoundAfter</samp>
  −
| ''(Optional)'' The number of milliseconds until the <samp>ContentSound</samp> is repeated once. This is used by the dog, who pants twice when pet. Defaults to -1 (disabled).
  −
|-
  −
| <samp>EmoteOffset</samp>
  −
| ''(Optional)'' A pixel offset for the emote drawn above the pet sprite, specified as an object with <samp>X</samp> and <samp>Y</samp> fields. For example, this affects the heart emote shown after petting it. Default none.
  −
|}
  −
 
  −
=====Events=====
  −
{| class="wikitable"
  −
|-
  −
! field
  −
! effect
  −
|-
  −
| <samp>EventOffset</samp>
  −
| ''(Optional)'' The pixel offset for the pet when shown in events like Marnie's adoption event, specified as an object with <samp>X</samp> and <samp>Y</samp> fields. Default none.
  −
|-
  −
| <samp>AdoptionEventLocation</samp><br /><samp>AdoptionEventId</samp>
  −
| ''(Optional)'' If both fields are set, the location and [[Modding:Event data|event ID]] which lets the player adopt this pet. This forces the event to play after 20 days if its preconditions haven't been met yet. Default <samp>Farm</samp> and none respectively.
  −
|-
  −
| <samp>SummitPerfectionEvent</samp>
  −
| ''(Optional)'' How to render the pet during the summit [[perfection]] slideshow. If this isn't set, the pet won't be shown in the slideshow.
  −
 
  −
This consists of a model with these fields:
  −
 
  −
{| class="wikitable"
  −
|-
  −
! field
  −
! effect
  −
|-
  −
| <samp>SourceRect</samp>
  −
| The source rectangle within the pet's texture to draw.
  −
|-
  −
| <samp>AnimationLength</samp>
  −
| The number of frames to show starting from the <samp>SourceRect</samp>.
  −
|-
  −
| <samp>Motion</samp>
  −
| The motion to apply to the pet sprite.
  −
|-
  −
| <samp>Flipped</samp>
  −
| ''(Optional)'' Whether to flip the pet sprite left-to-right. Default false.
  −
|-
  −
| <samp>PingPong</samp>
  −
| ''(Optional)'' Whether to apply the 'ping pong' effect to the pet sprite animation. Default false.
  −
|}
  −
|}
  −
 
  −
=====Gifts=====
  −
{| class="wikitable"
  −
|-
  −
! field
  −
! effect
  −
|-
  −
| <samp>GiftChance</samp>
  −
| ''(Optional)'' The random probability each day that the pet will give the player a gift from the <samp>Gifts</samp> list when they interact with the pet. Specified as a value between 0 (never) and 1 (always). Default .2 (20% chance).
  −
|-
  −
| <samp>Gifts</samp>
  −
| ''(Optional)'' The list of gifts that this pet can give if the <samp>GiftChance</samp> is successful. Default none.
  −
 
  −
This consists of a list of models with these fields:
  −
 
  −
{| class="wikitable"
  −
|-
  −
! field
  −
! effect
  −
|-
  −
| <samp>Id</samp>
  −
| The [[Modding:Common data field types#Unique string ID|unique string ID]] for this entry within the list.
  −
|-
  −
| <samp>QualifiedItemID</samp>
  −
| The [[Modding:Common data field types#Item ID|qualified item ID]] for the gift item to create.
  −
|-
  −
| <samp>Stack</samp>
  −
| ''(Optional)'' The stack size of the gift item to produce. Default 1.
  −
|-
  −
| <samp>MinimumFriendshipThreshold</samp>
  −
| ''(Optional)'' The friendship level that this pet must be at before it can give this gift. Defaults to 1000 (max friendship).
  −
|-
  −
| <samp>Weight</samp>
  −
| ''(Optional)'' The option's weight when randomly choosing a gift, relative to other gifts in the list (e.g. <samp>2</samp> is twice as likely as <samp>1</samp>). Default 1.
  −
|}
  −
|}
  −
 
  −
=====Behavior=====
  −
{| class="wikitable"
  −
|-
  −
! field
  −
! effect
  −
|-
  −
| <samp>Id</samp>
  −
| The [[Modding:Common data field types#Unique string ID|unique string ID]] for this entry within the list.
  −
|-
  −
| <samp>MoveSpeed</samp>
  −
| ''(Optional)'' How quickly the pet can move. Default 2.
  −
|-
  −
| <samp>SleepOnBedChance</samp><br /><samp>SleepNearBedChance</samp><br /><samp>SleepOnRugChance</samp>
  −
| ''(Optional)'' The percentage chances for the locations where the pet will sleep each night, as a decimal value between 0 (never) and 1 (always). Each value is checked in the order listed at left until a match is found. If none of them match, the pet will choose a random empty spot in the farmhouse; if none was found, it'll sleep next to its pet bowl outside.
  −
|-
  −
| <samp>Behaviors</samp>
  −
| The pet's possible actions and behaviors, defined as the states in a state machine. Essentially the pet will be in one state at any given time, which also determines which state they can transition to next. For example, a cat can transition from <samp>Walk</samp> to <samp>BeginSitDown</samp>, but it can't skip instantly from <samp>Walk</samp> to <samp>SitDownLick</samp>.
  −
 
  −
This consists of a list of models with these fields:
  −
 
  −
<dl>
  −
<dt>Required fields:</dt>
  −
<dd>
  −
{| class="wikitable"
  −
|-
  −
! field
  −
! effect
  −
|-
  −
| <samp>Id</samp>
  −
| A unique ID for the state. This only needs to be unique within the pet type (e.g. <samp>Cat</samp> and <samp>Dog</samp> can have different behaviors with the same ID).
  −
|}
  −
</dd>
  −
 
  −
<dt>Direction:</dt>
  −
<dd>
  −
{| class="wikitable"
  −
|-
  −
! field
  −
! effect
  −
|-
  −
| <samp>Direction</samp>
  −
| ''(Optional)'' The specific direction to face at the start of this state (one of <samp>left</samp>, <samp>right</samp>, <samp>up</samp>, or <samp>down</samp>), unless overridden by <samp>RandomizeDirection</samp>.
  −
|-
  −
| <samp>RandomizeDirection</samp>
  −
| ''(Optional)'' Whether to point the pet in a random direction at the start of this state (overriding the <samp>Direction</samp> if specified). Default false.
  −
|-
  −
| <samp>IsSideBehavior</samp>
  −
| ''(Optional)'' Whether to constrain the pet's facing direction to left and right while the state is active. Default false.
  −
|}
  −
</dd>
  −
 
  −
<dt>Movement:</dt>
  −
<dd>
  −
{| class="wikitable"
  −
|-
  −
! field
  −
! effect
  −
|-
  −
| <samp>WalkInDirection</samp>
  −
| ''(Optional)'' Whether to walk in the pet's facing direction. Default false.
  −
|-
  −
| <samp>MoveSpeed</samp>
  −
| ''(Optional)'' Overrides the pet's <samp>MoveSpeed</samp> field while this state is active. Default -1 (which uses the pet's <samp>MoveSpeed</samp> value).
  −
|}
  −
</dd>
  −
 
  −
<dt>Audio:</dt>
  −
<dd>
  −
{| class="wikitable"
  −
|-
  −
! field
  −
! effect
  −
|-
  −
| <samp>SoundOnStart</samp>
  −
| ''(Optional)'' The [[#Custom audio|audio cue ID]] for the sound to play when the state starts. If set to <samp>BARK</samp>, the pet's <samp>BarkSound</samp> (or breed's <samp>BarkOverride</samp>) field is used. Defaults to none.
  −
|-
  −
| <samp>SoundRange</samp><br /><samp>SoundRangeFromBorder</samp>
  −
| ''(Optional)'' When set, the <samp>SoundOnStart</samp> is only audible if the pet is within this many tiles away from the player (<samp>SoundRange</samp>) or past the border of the screen (<samp>SoundRangeFromBorder</samp>). Default -1 (no distance check).
  −
|-
  −
| <samp>SoundIsVoice</samp>
  −
| ''(Optional)'' Whether to mute the <samp>SoundOnStart</samp> when the 'mute animal sounds' option is set. Default false.
  −
|}
  −
</dd>
  −
 
  −
<dt>Behavior transitions:</dt>
  −
<dd>
  −
{| class="wikitable"
  −
|-
  −
! field
  −
! effect
  −
|-
  −
| <samp>AnimationEndBehaviorChanges</samp><br /><samp>TimeoutBehaviorChanges</samp><br /><samp>PlayerNearbyBehaviorChanges</samp><br /><samp>RandomBehaviorChanges</samp><br /><samp>JumpLandBehaviorChanges</samp>
  −
| ''(Optional)'' A list of possible behavior transitions to start when the criteria are achieved. If multiple transitions are listed, a random one will be selected. If omitted, it won't affect behavior transitions.
  −
 
  −
These are triggered when this behavior's animation finishes (<samp>AnimationEndBehaviorChanges</samp>), when the set duration ends (<samp>TimeoutBehaviorChanges</samp>), when the player is within 2 tiles of the pet (<samp>PlayerNearbyBehaviorChanges</samp>), randomly at the start of each frame based on the <samp>RandomBehaviorChangeChance</samp> field (<samp>RandomBehaviorChanges</samp>), and when the pet finishes a jump (<samp>JumpLandBehaviorChanges</samp>).
  −
 
  −
These consist of a list of models with these fields:
  −
{| class="wikitable"
  −
|-
  −
! field
  −
! effect
  −
|-
  −
| <samp>Behavior</samp><br /><samp>LeftBehavior</samp><br /><samp>RightBehavior</samp><br /><samp>UpBehavior</samp><br /><samp>DownBehavior</samp>
  −
| The ID of the behavior to start. The pet will check for a behavior field matching its current facing direction first, then try the <samp>Behavior</samp>. If none are specified, the current behavior will continue unchanged.
  −
|-
  −
| <samp>OutsideOnly</samp>
  −
| ''(Optional)'' Whether the transition can only happen if the pet is outside. Default false.
  −
|-
  −
| <samp>Weight</samp>
  −
| ''(Optional)'' The option's weight when randomly choosing a behavior, relative to other behaviors in the list (e.g. <samp>2</samp> is twice as likely as <samp>1</samp>). Default 1.
  −
|}
  −
|-
  −
| <samp>Duration</samp><br /><samp>MinimumDuration</samp><br /><samp>MaximumDuration</samp>
  −
| ''(Optional)'' The millisecond duration until the pet transitions to a behavior in the <samp>TimeoutBehaviorChanges</samp> field, if set. You must specify either a specific duration, or an inclusive minimum-to-maximum range in which the game will choose a random duration. If omitted, the behavior won't have a duration limit.
  −
|-
  −
| <samp>RandomBehaviorChangeChance</samp>
  −
| ''(Optional)'' The random probability at the start of each frame that the pet will transition to a behavior in the <samp>RandomBehaviorChanges</samp> field, if set. Specified as a value between 0 (never) and 1 (always). Default 0.
  −
|}
  −
</dd>
  −
 
  −
<dt>Animation and per-frame sounds:</dt>
  −
<dd>
  −
{| class="wikitable"
  −
|-
  −
! field
  −
! effect
  −
|-
  −
| <samp>Animation</samp>
  −
| ''(Optional)'' The animation frames to play while this state is active. This consists of a list of models with these fields:
  −
{| class="wikitable"
  −
|-
  −
! field
  −
! effect
  −
|-
  −
| <samp>Frame</samp>
  −
| The frame index in the animation. This should be an incremental number starting at 0.
  −
|-
  −
| <samp>Duration</samp>
  −
| The millisecond duration for which the frame should be kept on-screen before continuing to the next frame.
  −
|-
  −
| <samp>HitGround</samp>
  −
| ''(Optional)'' Whether to play the footstep sound for the tile under the pet when the frame starts. Default false.
  −
|-
  −
| <samp>Jump</samp>
  −
| ''(Optional)'' Whether the pet should perform a small hop when the frame starts, including a 'dwop' sound. Default false.
  −
|-
  −
| <samp>Sound</samp>
  −
| ''(Optional)'' The [[#Custom audio|audio cue ID]] for the sound to play when the animation starts or loops. If set to <samp>BARK</samp>, the pet's <samp>BarkSound</samp> (or breed's <samp>BarkOverride</samp>) field is used. Defaults to none.
  −
|-
  −
| <samp>SoundRange</samp><br /><samp>SoundRangeFromBorder</samp><br /><samp>SoundIsVoice</samp>
  −
| See description for the equivalent behavior fields, but applies to the frame's <samp>Sound</samp> field instead.
  −
|}
  −
|-
  −
| <samp>Shake</samp>
  −
| ''(Optional)'' The millisecond duration for which to shake the pet when the state starts. Default 0.
  −
|-
  −
| <samp>LoopMode</samp>
  −
| ''(Optional)'' What to do when the last animation frame is reached while the behavior is still active. The possible values are <samp>Hold</samp> (keep the last frame visible until the animation ends), <samp>Loop</samp> (restart from the first frame), or <samp>None</samp> (equivalent to <samp>Loop</samp>). Default <samp>None</samp>.
  −
|-
  −
| <samp>AnimationMinimumLoops</samp><br /><samp>AnimationMaximumLoops</samp>
  −
| ''(Optional)'' The minimum and maximum number of times to play the animation. Both must be specified to have any effect. The game will choose an inclusive random value between them. Both default to -1 (don't repeat animation).
  −
|}
  −
</dd>
  −
</dl>
  −
|}
     −
=====Breeds=====
+
You can now create and edit [[Animals|farm animals]] by editing the revamped <samp>Data/FarmAnimals</samp> asset. This changes to a data model, adds built-in support for custom animals, and allows far more customizability per animal (like its size, growth, produce, appearance and sounds, etc).
{| class="wikitable"
  −
|-
  −
! field
  −
! effect
  −
|-
  −
| <samp>Breeds</samp>
  −
| The cosmetic breeds which can be selected in the character customization menu when creating a save. This consists of a list of models with these fields:
  −
{| class="wikitable"
  −
|-
  −
! field
  −
! effect
  −
|-
  −
| <samp>ID</samp>
  −
| The unique ID for the breed within the pet type.
  −
|-
  −
| <samp>Texture</samp>
  −
| The asset name for the breed spritesheet for the pet's in-game sprite. This should be 128 pixels wide, and 256 (cat) or 288 (dog) pixels high.
  −
|-
  −
| <samp>IconTexture</samp>
  −
| The asset name for the breed icon texture, shown on the character customization screen and in-game menu. This should be a 16x16 pixel icon.
  −
|-
  −
| <samp>IconSourceRect</samp>
  −
| The icon's pixel area within the <samp>IconTexture</samp>, specified as an object with <samp>X</samp>, <samp>Y</samp>, <samp>Width</samp>, and <samp>Height</samp> fields.
  −
|-
  −
| <samp>BarkOverride</samp>
  −
| ''(Optional)'' Override the pet's <samp>BarkSound</samp> field for this breed, if set.
  −
|-
  −
| <samp>VoicePitch</samp>
  −
| ''(Optional)'' The [[wikipedia:Pitch (music)|pitch]] applied to the pet's bark sound, measured as a decimal value relative to 1. Defaults to 1.
  −
|}
  −
|}
     −
=====Advanced=====
+
===Custom pets===
{| class="wikitable"
+
{{/doc status|[[Modding:Pets]]|done=true}}
|-
  −
! field
  −
! effect
  −
|-
  −
| <samp>CustomFields</samp>
  −
| The [[#Custom data fields|custom fields]] for this entry.
  −
|}
     −
====Other changes====
+
* You can now create and customize [[Animals#Cat or Dog|pet]]s & pet breeds by editing the new <samp>Data/Pets</samp> asset.*
 
* The pet bowl is now a building which can be constructed or moved. Each pet is assigned to an available pet bowl. For C# mods, each pet now has a <samp>guid</samp> field populated with a unique ID, and each pet bowl has a <samp>petGuid</samp> field which tracks its owner (see the <samp>PetBowl::HasPet()</samp> and <samp>PetBowl::FindPet()</samp> methods).
 
* The pet bowl is now a building which can be constructed or moved. Each pet is assigned to an available pet bowl. For C# mods, each pet now has a <samp>guid</samp> field populated with a unique ID, and each pet bowl has a <samp>petGuid</samp> field which tracks its owner (see the <samp>PetBowl::HasPet()</samp> and <samp>PetBowl::FindPet()</samp> methods).
 
* In the [[Modding:Event data#Basic format|event character setup]], you can now use <samp>pet</samp> to add a pet of the player's selected type. Its actor name will be <samp>PetActor</samp> in other event commands. This supersedes <samp>cat</samp> (with name <samp>Cat</samp>) and <samp>dog</samp> (with name <samp>Dog</samp>), though those still work too.
 
* In the [[Modding:Event data#Basic format|event character setup]], you can now use <samp>pet</samp> to add a pet of the player's selected type. Its actor name will be <samp>PetActor</samp> in other event commands. This supersedes <samp>cat</samp> (with name <samp>Cat</samp>) and <samp>dog</samp> (with name <samp>Dog</samp>), though those still work too.
Line 6,261: Line 5,289:     
====Debug commands====
 
====Debug commands====
{{/doc status|[[Modding:Console commands]]|done=false}}
+
{{/doc status|[[Modding:Console commands]]|done=true}}
    
<ul>
 
<ul>
138

edits