Modding:Migrate to Stardew Valley 1.6
This page is for mod authors. Players: see Modding:Mod compatibility instead.
This page explains how to update your mods for compatibility with the next major game version (tentatively Stardew Valley 1.6.0), and documents some of the changes and new functionality. See also Migrate to SMAPI 4.0.
This describes an unreleased alpha version of the game. Things will change before it's released!
FAQs
What's changing?
Stardew Valley 1.6 makes fundamental changes to the game code to make it more extensible for mods.
Is this the modapocalypse?
Maybe. The update includes major changes to fundamental parts of the game, and SMAPI and Content Patcher can't feasibly rewrite older mods for compatibility with these changes. This will break a large proportion of existing mods until they're updated for the changes. However, per discussion between the game developers and modding community, we've agreed that this short-term pain is more than offset by the huge long-term improvements to modding.
How to update your mod
- Update your mod code and assets for the changes listed below (particularly Breaking changes for C# mods and Breaking changes for content packs).
- If SMAPI still says your mod is incompatible, check the TRACE messages in the log file for the reason why.
If the logs say "marked 'assume broken' in SMAPI's internal compatibility list", you can increase the Version in your content pack's manifest.json file to bypass it. - Test the mod in-game and make any other changes needed.
What's new for items
Custom items
Overview
Stardew Valley 1.6 makes three major changes to how items work in the game:
- Each item type now has an ItemDataDefinition class which tells the game how to handle it. SMAPI mods can add custom item type definitions or patch the vanilla logic. Each definition has a unique prefix (like (O) for objects) which is used in qualified item IDs. The vanilla types are bigcraftables ((BC)), boots ((B)), furniture ((F)), hats ((H)), objects ((O)), pants ((P)), shirts ((S)), tools ((T)), and weapons ((W)).
- Each item now has a locally unique string ID (ItemID) and a globally unique string ID (QualifiedItemID). The ItemID is assumed to only contain alphanumeric/underscore/dot characters so they can be used in fields delimited with spaces/slashes/commas, in filenames, etc. The QualifiedItemID is auto-generated by prefixing the ItemID with the item type identifier.
For legacy reasons, the ItemID for vanilla item isn't globally unique. For example, Pufferfish (object 128) and Mushroom Box (bigcraftable 128) both have ItemID: 128. They can be distinguished by their QualifiedItemID, which is (O)128 and (BC)128 respectively.
For mod items, both IDs should be globally unique. By convention the ItemID should include your mod ID or author name, like Example.ModId_ItemName.
- Custom items can now provide their own item texture, specified in a new field in the item data assets (see below). The item's ParentSheetIndex field is the index within that texture.
In other words, the three important fields for items are:
name | type | description |
---|---|---|
ItemID | string | An item key which is only unique within its item type, like 128 (vanilla item) or Example.ModId_Watermelon (custom item). |
QualifiedItemID | string | A globally unique item key, like (O)128 (vanilla item) or (O)Example.ModId_Watermelon (custom item). |
ParentSheetIndex | int | The item's image sprite within its spritesheet (whether it's a vanilla spritesheet or custom one). |
Item references
Item references throughout the game code now use the ItemID instead of the ParentSheetIndex. Since the ItemID is identical to the index for existing vanilla items, most data assets are unaffected by this change. For example, here's from Data/NPCDispositions with one custom item:
"Universal_Like": "-2 -7 -26 -75 -80 72 395 613 634 635 636 637 638 724 459 Example.ModID_watermelon"
Unless otherwise noted, unqualified item IDs will produce objects. Some assets let you override that by specifying a QualifiedItemID value instead. For example, you can add (O)128
to the gift taste list to explicitly add for an object. Here's a partial list of data assets and their supported item ID formats:
data asset | item ID format |
---|---|
Data/CraftingRecipes Data/CookingRecipes |
|
Data/fruitTrees |
|
Data/NPCGiftTastes | Both supported, but only (O) items can be gifted. |
Define a custom item
- Overview
-
You can define custom items for most vanilla item types using only Content Patcher or SMAPI's content API. The data asset for each item type has two new fields:
field effect texture name The asset name for the texture under the game's Content folder. Use \ (or \\ in JSON) to separate name segments if needed. For example, objects use Maps\springobjects by default. sprite index The index of the sprite within the above texture, starting at 0 for the top-left sprite. Supported item types:
item type data asset sprite index index texture name index default texture name big craftables Data/BigCraftablesInformation 10 11 TileSheets/Craftables boots Data/Boots item sprite: 8
shoe color: 5item sprite: 9
shoe color: 7item sprite: Maps/springobjects
shoe color: Characters/Farmer/shoeColorscrops Data/Crops 2 9 TileSheets/crops fish (in fish tanks) Data/AquariumFish 0 6 LooseSprites/AquariumFish furniture Data/Furniture 8 9 TileSheets/furniture fruit trees Data/FruitTrees 0 4 TileSheets/fruitTrees hats Data/Hats 6 7 Characters/Farmer/hats objects Data/ObjectInformation 9 10 Maps/springobjects pants & shirts Data/ClothingInformation male: 3
female: 410 Characters/Farmer/pants
Characters/Farmer/shirtstools Data/ToolData 3 4 TileSheets/Tools weapons Data/Weapons 15 16 TileSheets/weapons For example, this content pack adds a new Pufferchick item with a custom image, custom gift tastes, and a custom crop that produces it. Note that item references in other data assets like Data/Crops and Data/NPCGiftTastes use the item ID.
{ "Format": "2.0.0", "Changes": [ // add item { "Action": "EditData", "Target": "Data/ObjectInformation", "Entries": { "Example.ModId_Pufferchick": "Pufferchick/1200/100/Seeds -74/Pufferchick/An example object.////0/Mods\\Example.ModId\\Objects" } }, // add gift tastes { "Action": "EditData", "Target": "Data/NPCGiftTastes", "TextOperations": [ { "Operation": "Append", "Target": ["Entries", "Universal_Love"], "Value": "Example.ModId_Pufferchick", "Delimiter": " " // if there are already values, add a space between them and the new one } ] }, // add crop (Pufferchick is both seed and produce, like coffee beans) { "Action": "EditData", "Target": "Data/Crops", "Entries": { "Example.ModId_Pufferchick": "1 1 1 1 1/spring summer fall/0/Example.ModId_Pufferchick/-1/0/false/false/false/Mods\\Example.ModId\\Crops" } }, // add item + crop images { "Action": "Load", "Target": "Mods/Example.ModId/Crops, Mods/Example.ModId/Objects", "FromFile": "assets/{{TargetWithoutPath}}.png" // assets/Crops.png, assets/Objects.png }, ] }
Most item data assets work just like Data/ObjectInformation. For fruit trees, see custom fruit trees.
- Tools
-
Tools are defined in the new Data/ToolData asset using this field format:
index field purpose 0 class The name of the class in the StardewValley.Tools
namespace. The class must have a constructor with no arguments. For example, given a value of Axe, the game will createStardewValley.Tools.Axe
instances.1
2name key
description keyThe string key to load for the tool's in-game display name and description, in the form <asset name>
:<key>
(e.g.,,Strings\StringsFromCSFiles:Axe.cs.1
). In JSON, use \\ for any asset path slashes.3 parent sheet index The index of the tool's sprite in its spritesheet. Tool upgrades are handled by adding an offset to this index (e.g.,, basic axe = index, copper axe = index + 1, steel axe = index + 2, etc). 4 texture (Optional) The asset name for the item's spritesheet. - Melee weapons
-
Melee weapons are defined in Data/Weapons like before, but you can now add custom behavior by editing the Data/AdditionalWeaponProperties asset. This consists of a string → model lookup, where the key is the unqualified item ID and the value is a model with these fields:
field effect SpecialAttack (Optional) The secondary attack type. This can be one of Club, Dagger, or Sword. Any other value is ignored. Projectiles (Optional) The projectiles fired when the weapon is used, which continue along their path until they hit a monster and cause damage. These always cause 10 damage and use a generic glowing-yellow-ball sprite. This consists of a list of models with these fields (one projectile will fire for each entry in the list): field effect MinAngleOffset
MaxAngleOffset(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. Note that these are magic projectiles fired when the weapon is used, these aren't slingshot-style projectiles.
AttackSound
NoAmmoAttackSound
AmmoID(Optional) Unused.
Error items
In-game items with no underlying data (e.g. because you removed the mod which adds them) would previously cause issues like invisible items, errors, and crashes. This was partly mitigated by the bundled ErrorHandler mod.
Stardew Valley 1.6 adds comprehensive handling for such items. They'll be shown with a 🛇 sprite in inventory UIs and in-game, with the name Error Item and a description which indicates the missing item ID for troubleshooting.
For C# mods
- Compare items
-
Since Item.QualifiedItemID is globally unique, it can be used to simplify comparing items. For example:
old code new code item.ParentSheetIndex == 128 item.QualifiedItemID == "(O)128" IsNormalObjectAtParentSheetIndex(item, 128) item.QualifiedItemID == "(O)128" !item.bigCraftable && item.ParentSheetIndex == 128 item.QualifiedItemID == "(O)128" item is Boots && item.ParentSheetIndex == 505 item.QualifiedItemID == "(B)505" Caveat: flavored item don't have their own ID. For example, Blueberry Wine and Wine are both (O)348. This affects flavored jellies, juices, pickles, and wines. In those cases you should still compare their separate fields like preservedParentSheetIndex (which actually contains the preserved item's ItemID, not its ParentSheetIndex).
- Construct items
- Creating items works just like before, except that you now specify the item's ItemID (not QualifiedItemID) instead of its ParentSheetIndex. For example:
new Object("128", 1); // vanilla item new Object("Example.ModId_Watermelon", 1); // custom item
You can use a new utility method to construct items from their QualifiedItemID:
Item item = Utility.CreateItemByID("(B)505"); // Rubber Boots
- Define custom item types
- You can subclass ItemDataDefinition for your own item type, and add an instance to the ItemDataDefinition.ItemTypes and IdentifierLookup lists. This provides all the logic needed by the game to handle the item type: where to get item data, how to draw them, etc. This is extremely specialized, and multiplayer compatibility is unknown. Most mods should add custom items within the existing types instead.
- New Is* methods
- 1.6 adds some StardewValley.Object methods to handle custom items in a generic way (and to let mods patch the logic):
method effect object.IsBar() Whether the item is a copper bar, iron bar, gold bar, iridium bar, or radioactive bar. object.IsFence() Whether the item is a fence. object.IsFruitTreeSapling() Whether the item is a fruit tree sapling. This checks the Data\fruitTrees keys, so it works with custom fruit trees too. object.IsHeldOverHead() Whether the player is shown holding up the item when it's selected in their toolbar. Default true (except for furniture). object.IsTapper() Whether the item is a tapper or heavy tapper. object.IsTeaSapling() Whether the item is a tea sapling.
Custom fences
You can now add or customize fences by editing the Data/FenceData asset.
This consists of a string → model lookup, where the key matches the ID field and the value is a model with these fields:
field | effect |
---|---|
ID | A key which uniquely identifies this fence. The ID should only contain alphanumeric/underscore/dot characters. For custom fences, this should be prefixed with your mod ID like Example.ModId_FenceName. |
ItemID | The unqualified item ID for the corresponding object-type item. |
Health | The health points for a fence when it's first placed, which affects how quickly it degrades. A fence loses 1/1440 points per in-game minute (roughly 0.04 points per hour or 0.5 points for a 12-hour day).
Repairing a fence sets its max health to 2 × (base_health + repair_health_adjustment), where base_health is this field's value and repair_health_adjustment is a random value between RepairHealthAdjustmentMinimum and RepairHealthAdjustmentMaximum. |
Texture | The asset name for the texture (under the game's Content folder) when the flooring is applied or the path is placed. Use \ (or \\ in JSON) to separate name segments if needed. For example, the vanilla fences use individual tilesheets like LooseSprites\Fence1 (wood fence). |
RemovalTool | A space-delimited list of tools which can be used to break the fence, matching the keys in Data\ToolData. For example, "Axe Pickaxe" will let players use the axe or pickaxe. |
PlacementSound | The audio cue ID played when the fence is placed (e.g. axe used by Wood Floor). |
RemovalSound | (Optional) The audio cue ID played when the fence is broken or picked up by the player. Defaults to the same sound as PlacementSound. |
RemovalDebrisType | (Optional) The type of cosmetic debris particles to 'splash' from the tile when the fence is broken with a tool. The defined values are 0 (copper), 2 (iron), 4 (coal), 6 (gold), 8 (coins), 10 (iridium), 12 (wood), 14 (stone), 32 (big stone), and 34 (big wood). Default 14 (stone). |
RepairHealthAdjustmentMinimum RepairHealthAdjustmentMaximum |
(Optional) A random amount added to the Health when a fence is repaired by a player. See the Health field description. Both default to 0. |
HeldObjectDrawOffset | (Optional) When an item like a torch is placed on the fence, the pixel offset to apply to its draw position. Specified as a string in the form "<x> , <y> ". Defaults to "0, -20" if omitted.
|
LeftEndHeldObjectDrawX RightEndHeldObjectDrawX |
(Optional) The X pixel offset to apply when the fence is oriented horizontally, with only one connected fence on the right (for LeftEndHeldObjectDrawX) or left (for RightEndHeldObjectDrawX). This fully replaces the X value specified by HeldObjectDrawOffset when it's applied. Default 0. |
Custom flooring & paths
You can now add or customize flooring/paths by editing the Data/FloorPathData asset.
This consists of a string → model lookup, where the key matches the ID field and the value is a model with these fields:
field | effect | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
ID | A key which uniquely identifies this floor/path. The ID should only contain alphanumeric/underscore/dot characters. For vanilla floors & paths, this matches the spritesheet index in the TerrainFeatures/Flooring spritesheet; for custom floors & paths, this should be prefixed with your mod ID like Example.ModId_FloorName. | ||||||||||
ItemID | The unqualified item ID for the corresponding object-type item. | ||||||||||
Texture | The asset name for the texture (under the game's Content folder) when the flooring is applied or the path is placed. Use \ (or \\ in JSON) to separate name segments if needed. For example, the vanilla tilesheet is TerrainFeatures\Flooring. | ||||||||||
Corner | The top-left pixel position for the sprite within the Texture spritesheet, specified as a model with X and Y fields. | ||||||||||
WinterTexture Corner |
Equivalent to Texture and Corner, but applied if the current location is in winter. These fields are required, but can be set to the same values if you don't need seasonal changes. | ||||||||||
PlacementSound | The audio cue ID played when the item is applied/placed (e.g. axchop used by Wood Floor). | ||||||||||
FootstepSound | The audio cue ID played when the player steps on the tile (e.g. woodyStep used by Wood Floor). | ||||||||||
RemovalSound | (Optional) The audio cue ID played when the item is unapplied or picked up. Defaults to the same sound as PlacementSound. | ||||||||||
RemovalDebrisType | (Optional) The type of cosmetic debris particles to 'splash' from the tile when the item is unapplied or picked up. The defined values are 0 (copper), 2 (iron), 4 (coal), 6 (gold), 8 (coins), 10 (iridium), 12 (wood), 14 (stone), 32 (big stone), and 34 (big wood). Default 12 (wood). | ||||||||||
DrawContouredShadow | (Optional) Whether the shadow under the placed/applied item follows the contour of the sprite pixels, instead of just drawing a box around the tile. Default false. | ||||||||||
ConnectType | (Optional) When drawing the flooring across multiple tiles, how the flooring sprite for each tile is selected. Defaults to Default.
The possible values are:
| ||||||||||
CornerSize | (Optional) The pixel size of the decorative border when the ConnectType field is set to CornerDecorated or Default. | ||||||||||
FarmSpeedBuff | (Optional) The speed boost applied to the player, on the farm only, when they're walking on paths of this type. Negative values are ignored. Default 0.1. |
Custom machines
You can now add/edit machine logic by editing the Data/MachinesData asset. This consists of a string → model lookup, where the key matches the ID field and the value is a model with these fields:
Required fields
field | effect |
---|---|
ItemID | The qualified or unqualified item ID for the item which acts as a machine (like (BC)127 for mushroom boxes).
If a machine has two entries, the unqualified ID takes priority. To avoid mod conflicts, custom machines should always use unqualified item IDs (since custom IDs should already be unique). |
Item processing rules
field | effect | ||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
ItemConversions | (Optional) The rules which define how to process input items. This consists of a list of models with these fields:
| ||||||||||||||||||||||
AdditionalConsumedItems | (Optional) A list of extra items required before ItemConversions or ConversionMethod will be checked. If specified, every listed item must be present in the player, hopper, or chest inventory (depending how the machine is being loaded).
This consists of a list of models with these fields:
| ||||||||||||||||||||||
Outputs | (Optional) The items produced by this machine, unless overridden by OverrideOutputs under ItemConversions. If multiple output entries match, one will be selected randomly unless you specify UseFirstValidOutput. This consists of a list of models with these fields:
| ||||||||||||||||||||||
MinutesUntilReady DaysUntilReady |
(Optional) The number of in-game minutes or days until the output is ready to collect, unless overridden by OverrideMinutesUntilReady or OverrideDaysUntilReady under ItemConversions. If both days and minutes are specified, days are used. If none are specified, the item will be ready instantly. | ||||||||||||||||||||||
UseFirstValidOutput | (Optional) If multiple Output entries match, whether to use the first match instead of choosing one randomly. Default false.
This has no effect if ItemConversions is set; use the separate UseFirstValidOutput field on each item conversion entry instead in that case. | ||||||||||||||||||||||
BulkMultiplier | (Optional) A multiplier applied to all input and output items. For output, this stacks with QuantityModifiers. Default 1. | ||||||||||||||||||||||
ReadyTimeModifiers QualityModifiers QuantityModifiers |
(Optional) Changes to apply to the produced item's processing time, quality, or stack size. If multiple entries match, they'll be applied sequentially (e.g. two matching rules to double output will quadruple it). Note that this doesn't prevent you from setting invalid values (like a negative stack size or a quality beyond iridium), which may cause in-game bugs.
For QualityModifiers, the operations are performed on the numeric quality values: 0 (normal), 1 (silver), 2 (gold), or 4 (iridium). This consists of a list of models with these fields:
| ||||||||||||||||||||||
ParentID | (Optional) The machine ID from which to inherit item conversion rules (including ItemConversion, Outputs, ConversionMethod, etc). Cosmetic effects (like sound effects, particles, changing parent sheet index, etc) aren't inherited. If the parent doesn't have any conversion logic which applies to the current item, the conversion rules defined for this machine are tried afterwards. |
Behavior tweaks
field | effect | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
PreventTimePass | (Optional) A list of cases when the machine should be paused, so the timer on any item being produced doesn't decrement. Possible values:
| ||||||||||
Trigger | (Optional) When the machine should start producing output. Possible values:
| ||||||||||
AllowLoadWhenFull | (Optional) Whether the player can drop a new item into the machine before it's done processing the last one (like the crystalarium). The previous item will be lost. Default false. | ||||||||||
ReloadOnCollect | (Optional) Whether to restart the machine with the same input when the player collects the output (like the crystalarium). Default false. |
Audio & visuals
field | effect | ||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
LoadEffects WorkingEffects |
(Optional) The cosmetic effects shown when an item is loaded into the machine (for LoadEffects), or while it's processing the item (for WorkingEffects, based on the WorkingEffectChance probability). Both default to none. These consist of a list of models with these fields:
| ||||||||||||||||||||||||||||||||||||
WorkingEffectChance | (Optional) The percentage chance to apply WorkingEffects each time the day starts or the in-game clock changes, as a value between 0 (never) and 1 (always). Default 0.33. | ||||||||||||||||||||||||||||||||||||
LitWhileWorking | (Optional) Whether the machine produces light while it's processing an item. Default false. | ||||||||||||||||||||||||||||||||||||
WobbleWhileWorking | (Optional) Whether the machine sprite should bulge in & out while it's processing an item. Default false. | ||||||||||||||||||||||||||||||||||||
ShowNextIndexWhileWorking ShowNextIndexWhenReady |
(Optional) Whether to show the next sprite in the machine's spritesheet while it's processing an item (ShowNextIndexWhileWorking) or ready (ShowNextIndexWhenReady). Default false. |
Player interaction messages
These only apply when the player interacts with a chest directly, instead of using a hopper or mod like Automate.
field | effect |
---|---|
InvalidItemMessage | (Optional) A tokenizable string for the message shown in a toaster notification if the player tries to input an item that isn't accepted by the machine. |
InvalidCountMessage | (Optional) A tokenizable string for the message shown in a toaster notification if the input inventory doesn't contain this item, unless overridden by InvalidCountMessage under ItemConversions.
This can use extra custom tokens:
|
Advanced logic
field | effect | ||||||
---|---|---|---|---|---|---|---|
ConversionMethod | (Optional) A C# method which applies custom processing logic when the player tries to drop an item into the machine.
This must be specified in the form ⚠️ Caveats:
| ||||||
InteractMethod | (Optional) A C# method invoked when the player interacts with the machine when it doesn't have output ready to harvest.
This must be specified in the form | ||||||
OutputMethod | (Optional) A C# method which produces the item to output.
This must be specified in the form ⚠️ Caveats:
| ||||||
HasInput HasOutput |
(Optional) Whether to force adding the machine_input or machine_output context tags respectively. This isn't needed for most machines, since they'll be set based on the other fields. Default false. | ||||||
ResetBuildingIncubatorFlag | (Optional) When the machine is placed in a barn or coop, whether to reset the 'has shown incubator building full message' flag on the building when an item is placed in the machine. Default false.
This is used by the incubator and ostrich incubator. The game logic assumes there's only one such machine in each building, so this generally shouldn't be used by custom machines. | ||||||
StatsToIncrementWhenLoaded StatsToIncrementWhenHarvested |
(Optional) The game stat counters to increment when an item is placed in the machine (StatsToIncrementWhenLoaded) or when the processed output is collected (StatsToIncrementWhenHarvested). Default none. This consists of a list of models with these fields:
It's fine to use this with custom machines, but you can only increment built-in stats so it won't be applicable for most custom machines. For example, the vanilla game increments PiecesOfTrashRecycled for the recycling machine and GeodesCracked for the geode crusher. |
Custom museum donations & rewards
You can now add/edit the items which the museum accepts in donation and gives back in rewards through the new Data/MuseumRewards data asset.
Format
The data asset consists of a string → model lookup, where the key matches the ID field and the value is a model with these fields:
field | effect | ||||||
---|---|---|---|---|---|---|---|
ID | A key which uniquely identifies the reward group (i.e. a set of items and the reward once they're all donated). The ID should only contain alphanumeric/underscore/dot characters. For custom entries, this should be prefixed with your mod ID like Example.ModId_GroupName. | ||||||
TargetContextTags | 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:
For example, an entry with the tag forage_item and count 2 will require donating any two forage items. Special case: an entry with the exact values | ||||||
FlagOnCompletion | (Optional if RewardItemIsSpecial is true) Whether to add the ID 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 RewardItemIsSpecial is false, the player will be able collect the reward infinite times. Default false.
After the reward is collected, you can check this value using the HasFlag condition in Content Patcher. | ||||||
RewardEventSeenFlag | (Optional) The ID to add to the player's event-seen list when the reward is collected. (You must still specify FlagOnCompletion or RewardItemIsSpecial either way.)
After the reward is collected, you can check this value using the HasSeenEvent condition in Content Patcher. | ||||||
RewardItemID | (Optional) The 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. | ||||||
RewardItemCount | (Optional) The stack size for the RewardItemID (if the item supports stacking). Default 1. | ||||||
RewardItemIsSpecial | (Optional) Whether to mark the RewardItemID as a special permanent item, which can't be destroyed/dropped and can only be collected once. Default false. | ||||||
RewardItemIsRecipe | (Optional) Whether to give the player a cooking/crafting recipe which produces the RewardItemID, instead of the item itself. Ignored if the item type can't be cooked/crafted (i.e. non-object-type items). Default false. |
Achievements
The A Complete Collection 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
Data format
You can now add custom fruit trees by editing the modified Data/fruitTrees asset. This consists of a string → string lookup, where the key is the sapling item ID and the value is a slash (/)-delimited list of these fields:
index | field | effect |
---|---|---|
0 | tree ID | A key which uniquely identifies this tree. For vanilla trees, this matches the spritesheet index. For custom trees, the ID should only contain alphanumeric/underscore/dot characters. |
1 | season | The season in which the fruit tree bears fruit. |
2 | fruit | The unqualified object ID for the fruit it produces. |
3 | sapling price | Unused. |
4 | sprite index | The tree's row index in the spritesheet (e.g. 0 for the first tree, 1 for the second tree, etc). If omitted, the game will try to parse the item ID as an index. |
5 | texture | The asset name for the texture under the game's Content folder. Use \ (or \\ in JSON) to separate name segments if needed. For example, fruit trees use TileSheets\fruitTrees by default. |
For example, this content pack adds a custom fruit tree, including custom items for the sapling and fruit:
{
"Format": "2.0.0",
"Changes": [
// add fruit + sapling items
// note: sapling must have an edibility under 0 (usually -300) to be plantable
{
"Action": "EditData",
"Target": "Data/ObjectInformation",
"Entries": {
"Example.ModId_Pufferfruit": "Pufferfruit/1200/100/Basic -6/Pufferfruit/An example fruit item.////1/Mods\\Example.ModId\\Objects",
"Example.ModId_Puffersapling": "Puffersapling/1200/-300/Basic -74/Puffersapling/An example tree sapling.////2/Mods\\Example.ModId\\Objects"
}
},
// add fruit tree
{
"Action": "EditData",
"Target": "Data/FruitTrees",
"Entries": {
"Example.ModId_Puffersapling": "Example.ModId_Puffertree/spring/Example.ModId_Pufferfruit/1000/0/Mods\\Example.ModId\\FruitTrees"
}
},
// add images
{
"Action": "Load",
"Target": "Mods/Example.ModId/FruitTrees, Mods/Example.ModId/Objects",
"FromFile": "assets/{{TargetWithoutPath}}.png" // assets/FruitTrees.png, assets/Objects.png
},
]
}
The fruit trees can then be added to the game by giving the player a sapling item in the usual ways (e.g. from a shop).
Fruit items
The fruitsOnTree field was previously the number of fruit on the tree. It's now a list of fruit items instead, so C# mods can make the same fruit tree produce different fruit.
Custom wild trees
You can now create/edit wild trees by editing the Data/WildTrees asset. This consists of a string → model lookup, where the asset key is the wild tree ID: one of 1 (oak), 2 (maple), 3 (pine), 6 (palm), 7 (mushroom), 8 (mahogany), or a custom string ID defined by a mod. The asset value is a model with these fields:
field | effect | ||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
TreeType | The tree ID; this should match the asset key. | ||||||||||||||||||
Textures | The tree textures to show in game. This can be a list containing either a single asset name, or four asset names (for spring, summer, fall, and winter in that order). | ||||||||||||||||||
SeedItemID | The qualified item ID for the seed item. | ||||||||||||||||||
SeedPlantable | (Optional) Whether the seed can be planted by the player. If this is false, it can only be spawned automatically via map properties. Default true. | ||||||||||||||||||
GrowthChance | (Optional) The probability each day that the tree will grow to the next stage without tree fertilizer, expressed as a value from 0 (will never grow) to 1 (will grow every day). Defaults to 0.2 (20% chance). | ||||||||||||||||||
FertilizedGrowthChance | (Optional) Equivalent to GrowthChance, but with tree fertilizer. Defaults to 1 (100% chance). | ||||||||||||||||||
SeedChance | (Optional) The probability each day that the tree will produce a seed that will drop when the tree is shaken. Default 0.05 (5% chance). | ||||||||||||||||||
SeedOnChopChance | (Optional) The probability that a seed will drop when the player chops down the tree. Default 0.75 (75% chance). | ||||||||||||||||||
DropWoodOnChop | (Optional) Whether to drop wood when the player chops down the tree. Default true. | ||||||||||||||||||
DropHardwoodOnLumberChop | (Optional) Whether to drop hardwood when the player chops down the tree, if they have the Lumberjack profession. Default true. | ||||||||||||||||||
IsLeafy | (Optional) Whether shaking or chopping the tree causes cosmetic leaves to drop from tree and produces a leaf rustle sound. When a leaf drops, the game will use one of the four leaf sprites in the tree's spritesheet in the slot left of the stump sprite. Default true. | ||||||||||||||||||
IsLeafyInWinter | (Optional) Whether IsLeafy also applies in winter. Default false. | ||||||||||||||||||
GrowsInWinter | (Optional) Whether the tree can grow in winter (subject to GrowthChance and FertilizedGrowthChance). Default false. | ||||||||||||||||||
IsStumpDuringWinter | (Optional) Whether the tree is reduced to a stump in winter and regrows in spring, like the vanilla mushroom tree. Default false. | ||||||||||||||||||
AllowWoodpeckers | (Optional) Whether woodpeckers can spawn on the tree. Default true. | ||||||||||||||||||
UseAlternateSeedSprite | (Optional) Whether to render a different tree sprite when it has a seed ready. If true, the tree spritesheet should be double-width with the alternate textures on the right. Default false. | ||||||||||||||||||
DebrisColor | (Optional) The color of the cosmetic wood chips when chopping the tree. The valid values are 12 (brown/woody), 100001 (light green), 100002 (light blue), 100003 (red), 100004 (yellow), 100005 (black), 100006 (gray), 100007 (charcoal / dim gray), or any other value for white. Defaults to brown/woody. | ||||||||||||||||||
AdditionalChopDrops BushChopDrops StumpChopDrops |
(Optional) The additional items to drop when the tree is chopped. One field applies depending on the tree's current state: AdditionalChopDrops for a full-grown tree, BushChopDrops for a bush (one step below full-grown), and StumpChopDrops for the stump left behind after chopping a full-grown tree. This consists of a list of models with these fields:
| ||||||||||||||||||
SpringTapItems SummerTapItems FallTapItems WinterTapItems |
The items produced by tapping the tree in each season, as a list of models with these fields. If multiple items can be produced, the first available one is selected.
|
Trees can then be added to the game by...
- spawning them on map tiles by adding Paths index 34 to the Paths layer, with a TreeType tile property with the tree ID;
- or giving the player a seed item in the usual ways (e.g. from a shop, mail letter, etc).
Hats on aquarium fish
Custom fish in aquariums can now wear hats, just like vanilla sea urchins. This can be enabled by specifying a new field in Data/AquariumFish:
index | field | purpose |
---|---|---|
7 | hat position | The pixel position of the hat on the sprite, specified as an object with X and Y values.
Note: currently this is only used to check if the fish can wear a hat, and has no effect on its position. |
New context tags
1.6 adds several new item context tags:
context tag | effect |
---|---|
campfire_item | Marks the item as a campfire. If the item also has the torch_item context tag, when it's placed in the world and turned on...
|
fish_legendary | Marks the fish as a legendary fish. For example: it can't be caught again, shows an alternate sprite in the fishing minigame and a 'caught legendary fish' message after catching it, can't be added to a fish pond, etc. |
fish_legendary_family | Marks the fish as part of the legendary fish family for the fishing minigame. For example: requires magic bait, can't catch two at once, smaller bobber bar, 5× XP gain, etc. |
geode_special | Marks the item as a geode item, and prevents it from being broken open at Clint's blacksmith shop. |
item_type_<type>
|
For an object-type item, the type value from the 'type and category' field. (Non-object items always have the exact tag item_type_ 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. |
museum_donatable not_museum_donatable |
Set whether the item can be donated to the museum, overriding the vanilla logic. |
not_placeable placeable |
Sets whether the item can be placed on the ground. |
not_plantable_context_<context ID> not_plantable_location_ <location name> plantable_context_ <context ID> plantable_greenhouse plantable_location_ <location name>
|
See custom planting restrictions. |
paddy_crop | Marks the item as a paddy crop like rice or taro. This enables paddy-related logic like needing to be planted near water. |
sign_item | Marks the item as a sign, which lets player display items on it or place it on a fish pond to show the fish count. |
torch_item | Marks the item as a torch, which lets the player turn it on/off to emit light.
See also campfire_item. |
Contexts which affect machine processing:
context tag | effect |
---|---|
crystalarium_banned | When applied to a gem or mineral item, prevents players from placing it in a crystalarium. |
fairy_dust_banned | When applied to a machine, prevents players from using fairy dust to speed it up. |
is_machine | Indicates the item has machine logic. This is added automatically based on Data/MachinesData and is informational only (it has no effect on the game logic). |
keg_juice keg_wine |
Allows processing the item in a keg to produce a juice or wine variant. |
machine_input machine_output |
Whether the item is a machine which accepts items from the player (machine_input) and/or which produces items for the player to collect (machine_output). If the machine data sets the ConversionMethod field, both tags are added since there's no way to know what the method does.
These are added automatically based on Data/MachinesData and are informational only (they have no effect on the game logic). The is_machine tag is always added if these are. |
preserves_jelly preserves_pickle |
Allows processing the item in a preserves jar to produce a jelly or pickled variant. |
seedmaker_banned | When applied to a seed item, prevents players from placing it in a seed maker. |
tapper_item | Marks the item as a tapper or heavy tapper. |
tapper_multiplier_<multiplier>
|
The multiplier applied to the tapper production speed. For example, 2 will make items take half their base time (i.e. each item will finish in base time/speed multiplier). Defaults to 1 if omitted. |
Other item changes
- Added a display name field in English too for Data/Boots, Data/CookingRecipes, Data/CraftingRecipes, and Data/Furniture.
- Added optional Condition game state query field to Data/SpecialOrders.
- The Object.performObjectDropInAction method now applies the probe argument much more consistently. This only affects method calls with probe: true.
- The IsRecipe, Quality, Stack properties are now part of the base Item class instead of Object.
What's new for locations & weather
Custom locations
You can now add/edit locations by editing the new Data/AdditionalLocationsData asset.
The asset consists of a string → model lookup, where the key matches the ID field and the value is a model with these fields:
field | effect |
---|---|
ID | A key which uniquely identifies this location, which will be used as the location's Name (not DisplayName) field. The ID should only contain alphanumeric/underscore/dot characters. For custom locations, this should be prefixed with your mod ID like Example.ModId_LocationName. |
MapPath | The asset name for the map to use for this location. |
DisplayName | (Optional but strongly recommended) A tokenizable string for the translated location name. This is used anytime the location name is shown in-game for base game logic or mods. |
Type | (Optional) The full name of the C# location class to create. 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 StardewValley.GameLocation (default value) and StardewValley.Locations.DecoratableLocation. |
Custom location contexts
Vanilla contexts
- The game previously had two hardcoded location context enums: Default (for the valley) and Island (for Ginger Island). These have been replaced with data models which define the location context settings, loaded from the Data/LocationContexts asset.
- The desert is now part of a new Desert context (instead of Default). Some of the previously hardcoded desert logic (like always sunny weather) is now just part of the context data in Data/LocationContexts.
Format
Custom contexts can be created by editing the new Data/LocationContexts asset, and setting the context name in the location's LocationContext map property.
The data asset consists of a string → model lookup, where the key matches the Name field and the value is a model with these fields:
- Required fields:
-
field effect Name The unique ID for the location context. This should only contain alphanumeric/underscore/dot characters. For custom contexts, this should be prefixed with your mod ID like Example.ModId_ContextName. - Player actions:
-
field effect DefaultValidPlantableLocations (Optional) The internal names of the locations where crops can be planted and grown by default (see also custom planting restrictions). AllowRainTotem (Optional) Whether a Rain Totem can be used to force rain in this context tomorrow. MaxPassOutCost (Optional) When the player passes out (due to exhaustion or at 2am) in this context, the maximum amount of gold lost. If omitted or set to -1, uses the same value as the Default context (1,000g by default). PassOutMail (Optional) When the player passes out (due to exhaustion or at 2am) in this context, the possible 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 SkipRandomSelection). This consists of a list of models with these fields:
field effect Mail The letter ID to add. The game will look for an existing letter ID in Data/mail in this order (where
<billed>
is Billed if they lost gold or NotBilled otherwise, and<gender>
is Female or Male):<letter id>
_<billed>
_<gender>
<letter id>
_<billed>
<letter id>
If no match is found in Data/mail, the game will send passedOut2 instead.
If the mail ID starts with passedOut, {0} in the letter text will be replaced with the gold amount lost, and it won't appear in the collections page.
MaxPassOutCost (Optional) The maximum amount of gold lost. This is applied after the context's MaxPassOutCost (i.e. the context's value is used to calculate the random amount, then this field caps the result). Defaults to unlimited. Condition (Optional) A game state query which indicates whether this entry is active. Defaults to always true. SkipRandomSelection (Optional) If true, send this mail if the Condition matches instead of choosing a random valid mail. Default false. PassOutLocations (Optional) When the player passes out (due to 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.) This consists of a list of models with these fields:
field effect Location The internal location name. Position The default tile position within the location, specified as an object with X and Y fields. If the location has any bed furniture, they'll be placed in the first bed found instead. Condition (Optional) A 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.
ReviveLocations (Optional) If the player just got knocked out in combat, the location names where they'll wake up. This consists of a list of models with these fields:
field effect Location The internal location name. Position The tile position within the location, specified as an object with X and Y fields. Condition (Optional) A game state query which indicates whether this entry is active. Defaults to always applied. If the selected location has a standard event with the exact key PlayerKilled (with no / 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.
If no locations are specified or none match, the player will wake up at Harvey's clinic.
- Season:
-
field effect SeasonOverride (Optional) The season which is always active for locations within this context (one of spring, summer, fall, or winter). For example, setting summer will make it always summer there regardless of the calendar season. If not set, the calendar season applies. - Weather:
-
field effect WeatherConditions (Optional) The weather logic to apply for locations in this context (ignored if CopyWeatherFromLocation 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:
field effect Weather The weather ID to set. Condition (Optional) A game state query which indicates whether to apply the weather. Defaults to always applied. CopyWeatherFromLocation (Optional) The Name (i.e. unique ID) of the location context from which to inherit weather. If a passive festival is active in any location within this context, the weather is sunny for the entire context regardless of these fields.
- Music:
-
field effect DefaultMusic (Optional) The cue ID for the music to play when the player is in the location, unless overridden by a Music map property. Despite the name, this has a higher priority than the seasonal music fields below. Ignored if omitted. DefaultMusicCondition (Optional) A game state query which returns whether the DefaultMusic field should be applied (if more specific music isn't playing). Defaults to always true. DefaultMusicDelayOneScreen (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. SpringMusic
SummerMusic
FallMusic
WinterMusic(Optional) A list of cue IDs to play before noon in this location unless it's raining, there's a Music map property, or the context has a DefaultMusic value. If multiple values are specified, the game will play one per day in sequence. DayAmbience
NightAmbience(Optional) The cue ID for the background ambience to play when there's no music active, depending on the time of day. Both default to none. PlayRandomAmbientSounds (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 DayAmbience and NightAmbience fields. Default true.
Custom map actions
C# mods can now handle custom Action & TouchAction map properties by calling GameLocation.RegisterTileAction & RegisterTouchAction, 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 TouchAction Example.ModId_UnlockGate
map property (e.g. by adding it directly in the map file, or using Content Patcher's EditMap, or using the content API). Then you can just handle the logic from your C# mod:
internal class ModEntry : Mod
{
/// <inheritdoc />
public override void Entry(IModHelper helper)
{
GameLocation.RegisterTouchAction("Example.ModId_UnlockGate", this.HandleUnlockGate);
}
private void HandleUnlockGate(GameLocation location, string[] args, Farmer player, Vector2 tile)
{
const string mailFlag = "Example.ModId_GateUnlocked";
const string keyId = "Example.ModId_GateKey";
// unlock gate if locked
if (!player.mailReceived.Contains(mailFlag))
{
if (!Game1.player.hasItemInInventory(keyId, 1))
{
Game1.activeClickableMenu = new DialogueBox("This gate is locked. I wonder where the key is?");
return;
}
player.removeFirstOfThisItemFromInventory(keyId);
player.mailReceived.Add(mailFlag);
}
// apply open-gate map edit
IAssetDataForMap mapHelper = this.Helper.Content.GetPatchHelper(location.map).AsMap();
mapHelper.PatchMap(
this.Helper.Content.Load<Map>("assets/unlocked-gate.tmx"),
targetArea: new Rectangle((int)tile.X - 1, (int)tile.Y - 1, 2, 2)
);
}
}
Custom map areas
You can now add/edit areas on the game menu's map UI, or even replace the entire map for a different world region, by editing the new Data/InGameMap asset. For example, this is used to show a different farm on the map depending on the current farm type.
Concepts
The game divides the map into three concepts:
- A map is one full world area rendered in one image, like the entire image shown at right.
- A map area is a smaller section of the map which is linked to one or more in-game areas. The map area might be edited/swapped depending on the context, have its own tooltip(s), or have its own player marker positions. For example, the highlighted area on the image shown at right is swapped depending on the current farm type.
- A group name is a unique key shared between all the map areas that are rendered on the same map. For example, if there was a separate map for Ginger Island, all the map areas in the valley group would be hidden.
Format
The Data/InGameMap data asset consists of a string → model lookup, where the key matches the AreaID field and the value is a model with these fields:
field | effect | ||||||||
---|---|---|---|---|---|---|---|---|---|
AreaID | A unique identifier for the area. The ID should only contain alphanumeric/underscore/dot characters. For custom areas, this should be prefixed with your mod ID like Example.ModId_AreaName. | ||||||||
Group | A unique group key shared between all areas drawn on the same map (see concepts). When the player is in an area for one group, all map areas with a different group key are hidden automatically. The base valley map added by the base game has the group key SDV. This should only contain alphanumeric/underscore/dot characters. For custom groups, this should be prefixed with your mod ID like Example.ModId_GroupName. | ||||||||
Texture | The asset name for the texture to draw when the area is applied to the map.
If set to the exact string "MOD_FARM", the game will apply the texture for the current farm type, regardless of whether it's a vanilla or mod farm type. (The vanilla DestRect for the farm area is "0 43 131 61".) Note: this field is required. To add an invisible area, you can set this to a valid texture (e.g. "LooseSprites\\map") and omit SourceRect instead. | ||||||||
SourceRect | The pixel area within the Texture to draw, formatted like "<x> <y> <width> <height> ". Omit this field to make the area invisible (e.g., to add zones or tooltips without changing the map).
| ||||||||
DestRect | The pixel area within the map which is covered by this area, formatted like "<x> <y> <width> <height> ".
| ||||||||
Zones | The in-game locations to match with the map. Each zone can provide one or more of the following:
This consists of a list models with these fields:
| ||||||||
DisplayName | (Optional) A tokenizable string for the tooltip (shown when the mouse is over the area) and scroll (shown at the bottom of the map when the player is in the location). If omitted or empty, the tooltip/scroll isn't shown. Defaults to empty. | ||||||||
Condition | (Optional) A game state query which checks whether the area should be applied (if the group is visible). Defaults to always applied. | ||||||||
DisplayAsUnknown | (Optional) Whether to replace the tooltip for the area with ??? if the Condition isn't met. Default false. | ||||||||
IncludeInGroupDetection | (Optional) Whether to use this area when the game is scanning areas to see which group the player is in. If this is false, it will be ignored even if the player is in the area. Default true. |
Example
This Content Patcher content pack adds a full world map for Ginger Island, complete with tooltips and player marker positioning. If the player unlocked the beach resort, it applies the beach resort texture on top of the base map.
{
"Format": "2.0.0",
"Changes": [
// add world map edits
{
"Action": "EditData",
"Target": "Data/IngameMap",
"Entries": {
// the base world map image with tooltips/positioning
"GingerIsland_BaseMap": {
"Group": "GingerIsland",
"AreaID": "GingerIsland_BaseMap",
"Texture": "Mods/Example.ModId/GingerIsland",
"SourceRect": "0 0 300 180",
"DestRect": "0 0 300 180",
"Zones": [
{
"ValidAreas": [ "IslandSouth" ],
"MapTileCorners": "0 0 42 45",
"MapImageCorners": "105 105 231 240",
"DisplayName": "{{i18n: map-names.island-south}}"
},
// ... list each map area here
]
},
// add beach resort if unlocked
"GingerIsland_Resort": {
"Group": "GingerIsland",
"AreaID": "GingerIsland_Resort",
"Texture": "Mods/Example.ModId/GingerIsland_Resort",
"SourceRect": "0 0 300 180",
"DestRect": "0 0 300 180",
"Condition": "PLAYER_HAS_FLAG Any Island_Resort"
}
}
},
// load textures
{
"Action": "Load",
"Target": "Mods/Example.ModId/GingerIsland",
"FromFile": "assets/ginger-island.png"
}
]
}
Custom map layers
You can now add any number of map layers by suffixing a vanilla layer name (i.e. Back, Buildings, Front, or AlwaysFront) with an offset. For example, Back-1 will be drawn before/under Back, and Back2 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
You can now add/edit minecart destinations by editing the Data\MiscGameData data asset, which consists of a data model with two relevant fields (listed below).
Note that Data\MiscGameData contains a single global entry, it isn't a list or dictionary like other assets. For example, Content Patcher would edit MineCartCondition as its own entry.
field | effect | ||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
MineCartCondition | A game state query which indicates whether minecarts in general are unlocked. You usually shouldn't change this value, unless you're changing the overall game progression (e.g. adding an alternative way to unlock minecart access). | ||||||||||||||
MineCartDestinations | The destinations which the player can travel to from any minecart. This consists of a string → model lookup, where the key is a unique destination ID (only containing alphanumeric/underscore/dot characters, with custom entries prefixed with your mod ID like Example.ModId_DestinationId), and the value is a model with these fields:
|
Custom passive festivals
You can now add or modify passive festivals by editing the Data/PassiveFestivalData asset.
(A passive festival is a 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 Data/PassiveFestivalData asset consists of a string → model lookup, where the key is the unique festival ID, and the value is a model with these fields:
field | effect |
---|---|
ID | A key which uniquely identifies this festival. For custom festivals, the ID should only contain alphanumeric/underscore/dot characters, and should ideally be prefixed with your mod ID like Example.ModId_FestivalName. |
DisplayName | A tokenizable string for the display name shown on the calendar. |
Season | The season when the festival becomes active. |
StartDay EndDay |
The days of month when the festival becomes active. |
StartTime | The time of day when the festival opens each day. |
StartMessage | A tokenizable string for the in-game toast notification shown when the festival begins each day. |
MapReplacements | The locations to swap for the duration of the festival. Despite the field name, this swaps locations (e.g. as added by CustomLocations using 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 Debug Mode mod. For example, this swaps the Beach location with BeachNightMarket during the Night Market: "MapReplacements": {
"Beach": "BeachNightMarket"
}
|
Condition | (Optional) A game state query which indicates whether the festival is enabled (subject to the other fields like StartDay and EndDay). Defaults to always enabled. |
ShowOnCalendar | (Optional) Whether the festival appears on the calendar, using the same iridium-star icon as the Night Market. Default true. |
DailySetupMethod CleanupMethod |
(Optional) A C# method which applies custom logic when the day starts (DailySetupMethod) and/or overnight after the last day of the festival (CleanupMethod).
These must be specified in the form |
NPC schedules
When a passive festival is active, NPCs will check for a schedule entry in this order:
syntax | summary |
---|---|
<festival ID> _<festival day>
|
Applies on the given date. The <festival day> is relative, so 1 matches the festival StartDay.Example: NightMarket_3 or marriage_NightMarket_3 |
<festival ID>
|
Applies if there's no date-specific entry. Example: NightMarket or marriage_NightMarket |
If the NPC is married to a player, they'll add a marriage_ prefix to the keys (like marriage_<festival ID>
_<festival day>
) and ignore any entry without the prefix.
Custom planting restrictions
You can now add context tags to a crop seed, fruit tree sapling, or wild tree seed to restrict where it can be planted. This is based on these tags:
tag | effect |
---|---|
plantable_greenhouse | Can always be planted in a greenhouse (i.e., locations with IsGreenhouse), regardless of any other context tag. |
plantable_location_<location name> not_plantable_location_ <location name>
|
Must or must not be planted in one of these locations. This must be the internal location name (as shown by Debug Mode), lowercase and with any spaces replaced with underscores. |
plantable_context_<context ID> not_plantable_context_ <context ID>
|
Must or must not be planted in one of these location contexts. The context ID must be lowercase, with any spaces replaced with underscores. |
When multiple tags are specified, they're applied in this precedence order:
precedence | rule | result |
---|---|---|
1 | plantable_greenhouse matches | plantable |
2 | plantable_location_* matches | plantable |
2 | not_plantable_location_* matches or not_plantable_context_* matches |
not plantable |
3 | plantable_context_* or plantable_location_* specified but didn't match (not_* doesn't affect this rule) |
not plantable |
4 | current location listed in the context's DefaultValidPlantableLocations field | plantable |
5 | defaults to normal planting logic |
For example:
tags | effect | plantable | reason |
---|---|---|---|
none | Farm | ☑ plantable | default behavior |
Greenhouse | ☑ plantable | ||
location listed in its context's DefaultValidPlantableLocations | ☑ plantable | ||
Bus Stop | ☐ | ||
plantable_greenhouse, not_plantable_context_default | Farm | ☐ | matches not_plantable_context_default |
Greenhouse | ☑ plantable | overridden by plantable_greenhouse | |
plantable_location_islandwest | Island West | ☑ plantable | matches plantable_location_islandwest |
Island South | ☐ | doesn't match plantable_location_islandwest | |
Farm | ☐ | ||
plantable_context_island | Island West | ☑ plantable | matches plantable_context_island |
Island South | ☑ plantable | ||
Farm | ☐ | doesn't match plantable_context_island | |
not_plantable_context_island | Island West | ☐ | matches not_plantable_context_island |
Island South | ☐ | ||
Farm | ☑ plantable | default behavior | |
plantable_location_town, plantable_location_mountain | Town | ☑ plantable | matches plantable_location_town |
Mountain | ☑ plantable | matches plantable_location_mountain | |
Farm | ☐ | doesn't match any plantable_location_* tags |
Custom weather
You can now change the weather algorithm by editing location context data, and (with a C# mod) implement custom weathers.
Fields like Game1.weather and Game1.weatherForTomorrow 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. Sun, Rain, Snow, Storm, and Wind). C# mods may also see a Festival weather, while Content Patcher packs will see Sun for it. The constants like Game1.weather_sunny have the new string values (with new constants like Game1.legacy_weather_sunny for the legacy values).
The base game will treat an invalid weather as sunny. C# mods can implement custom weather effects using normal SMAPI events like UpdateTicked, or by patching methods like Game1.ApplyWeatherForNewDay and Game1.populateDebrisWeatherArray.
New map properties
1.6 adds several new map properties.
Warps & map positions
property | explanation |
---|---|
DefaultWarpLocation <x> <y> (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 debug commands like debug warp or debug eventbyid). |
Audio
property | explanation |
---|---|
MusicContext <context> (valid in any location) |
The music context for this location. The recommended values are Default or SubLocation. This only affects the music priority in split screen, where SubLocation has a lower priority than Default. For example, if player A is at a location with the Default music context, and player B is a location with the SubLocation context, the game will choose player A's music. |
MusicIgnoreInRain T (valid in any outdoor location) |
If set to T, the Music property is ignored when it's raining in this location. |
MusicIgnoreInSpring T MusicIgnoreInSummer T MusicIgnoreInFall T MusicIgnoreInWinter T (valid in any outdoor location) |
If set to T, the Music property is ignored in the given season. |
MusicIgnoreInFallDebris T (valid in any outdoor location) |
If set to T, the Music property is ignored in fall during windy weather. |
MusicIsTownTheme T (valid in any location) |
If set to T, uses the same behavior as Pelican Town's music: it will start playing after the day music has finished, and will continue playing while the player travels through indoor areas, but will stop when entering another outdoor area that isn't marked with the same Music and MusicIsTownTheme properties. |
Crops
property | explanation |
---|---|
AllowGiantCrops T | If set with any non-blank value, giant crops can grow in this location. (To plant the crop itself, you'll need custom planting restrictions or the DefaultValidPlantableLocations context field.) |
Fishing
property | explanation | ||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
CrabPotAreaCorners [<corners> <area IDs> ]+
|
The fish areas for crab pots in this location, which can be used in fish spawn data. For example, you can define "freshwater" and "ocean" areas which have different fish.
This consists of a space-delimited list of these fields:
You can add any number of areas by appending them (with a space) at the end of the field. The area list in the last field will end when it encounters a number. For example: CrabPotAreaCorners 0 0 10 10 freshwater ocean 15 15 30 30 Example.ModId_CustomWater | ||||||||||||||||||||||
DefaultCrabPotArea <area IDs>
|
The area IDs used for tiles not covered by CrabPotAreaCorners (see that property for more info). If omitted, defaults to freshwater. | ||||||||||||||||||||||
DefaultFishingArea <location key> <area ID>
|
The area ID used for tiles not covered by FishingAreaCorners (see that properties for more info). If omitted, only fish which spawn in the special -1 area (any area) can be caught on those tiles. | ||||||||||||||||||||||
FishingAreaCorners [<corners> <location key> <area ID> ]+
|
The fish areas when fishing with fishing rod in this location, which can be used in fish spawn data. For example, you can define "lake" and "river" areas which have different fish.
This consists of a space-delimited list of these fields:
You can add any number of areas by appending them (with a space) at the end of the field. For example (note that vanilla area IDs are numbers like 1 for legacy reasons): FishingAreaCorners 0 0 10 10 Forest 1 15 15 30 30 Forest Example.ModId_Lake | ||||||||||||||||||||||
LegendaryFishAreaCorners [<corners> <anchor> <fish ID> <family ID> <min level> <min depth> <chance> <curiosity buff> <weather> <seasons> ]+
|
The map areas where legendary fish can be caught in the location. This consists of a space-delimited list of these fields:
You can add any number of areas by appending them (with a space) at the end of the field. The season list in the last field will end when it encounters a number. For example: LegendaryFishAreaCorners 0 0 15 15 player 160 899 3 0 0.2 0.05 both fall 30 30 -1 -1 bobber 682 901 0 0 0.1 0.1 both spring summer fall winter |
Building construction
property | explanation |
---|---|
CanBuildHere T (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 in what's new. |
BuildConditions <query> (valid in any outdoor location) |
If CanBuildHere is set, an optional game state query which indicates whether building is allowed currently. |
LooserBuildRestrictions T (valid in any outdoor location) |
If set, tiles don't need to be marked Buildable T or Diggable T in their properties. Tiles can be blocked with Buildable F instead. The other restrictions still apply. |
ValidBuildRect <x> <y> <width> <height> (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. |
Tile property changes
- Added new Action tile properties:
layer property explanation Buildings Action BuildingSilo If a building covers this tile, enables silo interactions on this tile subject to the building's HayCapacity field in Data/BuildingsData. Buildings Action BuildingToggleAnimalDoor If a building covers this tile, opens or closes its animal door. Buildings Action Forge Opens the Forge menu. Buildings Action ObeliskWarp <location name>
<x>
<y>
[whether to dismount]
Warps the player to the specified location name and position with the Obelisk animation/sound effects. Buildings Action OpenShop <shop id>
[from direction]
[open time]
[close time]
[owner tile area]
Open the shop with the given <shop id>
. All arguments besides the ID are optional:[from direction]
: if specified, the player must be standing in this direction relative to the shop (one of down, up, left, right, or none). Setting this to none disables the requirement. The default for most vanilla shops is down.[open time]
and[close time]
: the start & end times in 26-hour format when the shop is available. Interacting with the tile outside those times does nothing.[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 ValidNPCs field. This can be specified in two forms:<x>
<y>
for a single tile, or<x>
<y>
<width>
<height>
for a multi-tile area.
Buildings Action PlayEvent <event id>
[check preconditions]
[skip if seen]
Immediately start an event, subject to the conditions: [check preconditions]
: whether to ignore the action if the event's preconditions don't match (one of true or false). Default true.[skip if seen]
: whether to ignore the action if the player has already seen the given event. Default true.
If the event is skipped, the action is silently ignored.
For example,
Action PlayEvent 60367 false false
will replay the bus arrival event from the start of the game. - Added new TouchAction tile properties:
layer property explanation Back TouchAction PlayEvent <event id>
[check preconditions]
[skip if seen]
[fallback action]
Equivalent to Action PlayEvent. If the event is skipped, you can optionally specify another action to call instead after the other parameters, like TouchAction PlayEvent 60367 true true TouchAction PlayEvent 520702 false false
to play another event instead. - Dropped support for non-string map & tile properties. Properties set to bool, int, or float will be converted to string when the game loads them.
What's new for buildings
Custom buildings
You can now add custom buildings by editing the Data/BuildingsData asset. This consists of a string → model lookup, where the key is a unique building ID, and the value is a model with these fields:
Required fields
field | effect |
---|---|
ID | A key which uniquely identifies this building. This should match the asset key. The ID should only contain alphanumeric/underscore/dot characters, and should ideally be prefixed with your mod ID like Example.ModId_BuildingName. |
Name Description |
A tokenizable string for the display name and description (e.g. shown in the construction menu). |
Texture | The asset name for the texture under the game's Content folder. |
Construction
field | effect | ||||||||
---|---|---|---|---|---|---|---|---|---|
Builder | (Optional) The NPC from whom you can request construction. The only recognized values are Carpenter (Robin) and Wizard. Defaults to Carpenter. If omitted, it won't appear in any menu. | ||||||||
BuildCost | (Optional) The gold cost to construct the building. Defaults to 0g. | ||||||||
BuildMaterials | (Optional) The materials you must provide to start construction, as a list of models with these fields:
| ||||||||
BuildDays | (Optional) The number of days needed to complete construction (e.g. 1 for a building completed the next day). If set to 0, construction finishes instantly. Defaults to 0. | ||||||||
BuildCondition | (Optional) A game state query which indicates whether the building should be available in Robin's construction menu. Defaults to always available. | ||||||||
AdditionalPlacementTiles | (Optional) The extra tiles to treat as part of the building when placing it through Robin's menu. For example, the farmhouse uses this to make sure the stairs are clear. This consists of a list of models with these fields:
| ||||||||
IndoorItems | (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:
| ||||||||
AddMailOnBuild | (Optional) A list of letter IDs to send to all players when the building is constructed for the first time. |
Upgrades
field | effect | ||||||||
---|---|---|---|---|---|---|---|---|---|
BuildingToUpgrade | (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 Big Coop sets this to "Coop". Any numbers of buildings can be an upgrade for the same building, in which case the player can choose one upgrade path. | ||||||||
IndoorItemMoves | (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:
| ||||||||
UpgradeSignTile | (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 "<x> , <y> ". Defaults to approximately "5, 1" if the building interior type is Shed, else "0, 0".
| ||||||||
UpgradeSignHeight | (Optional) The pixel height of the upgrade sign when Robin is building an upgrade. Defaults to 0. |
Exterior behavior
field | effect |
---|---|
Size | (Optional) The building's width and height when constructed, measured in tiles. Defaults to a 1 x 1 area. |
CollisionMap | (Optional) An ASCII text block which indicates which of the building's tiles the players can walk onto, where each character can be X (blocked) or O (passable). Defaults to all tiles blocked.
For example, a stable covers a 2x4 tile area with the front two tiles passable: XXXX XOOX 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: // single line with \n line breaks
"CollisionMap": "XXXX\nXOOX"
// multi-line with optional indentation
"CollisionMap": "
XXXX
XOOX
"
|
HumanDoor | (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. |
AnimalDoor | (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 in the form "<x> <y> <width> <height> ". This is measured in tiles relative to the top-left corner tile. Defaults to disabled.
|
AnimalDoorOpenDuration AnimalDoorCloseDuration |
(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. |
AnimalDoorOpenSound AnimalDoorCloseSound |
(Optional) The sound which is played once each time the animal door is opened/closed. Disabled by default. |
Exterior appearance
field | effect | ||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
SourceRect | (Optional) The building's pixel area within the Texture, in the form "<x> <y> <width> <height> " (like "0 0 112 128"). Defaults to the entire texture.
| ||||||||||||||||||
Skins | (Optional) The appearances which can be selected from Robin's menu (like stone/plank/log cabins). If specified, it's assumed that one of the skins matches the default appearance specified by Texture (so you need at least two skins for the option to appear in-game). This consists of a list of models with these fields:
| ||||||||||||||||||
FadeWhenBehind | (Optional) Whether the building should become semi-transparent when the player is behind it. Default true. | ||||||||||||||||||
DrawOffset | (Optional) A pixel offset applied to the building sprite's placement in the world. Default 0. | ||||||||||||||||||
SeasonOffset | (Optional) A pixel offset to apply each season. This is applied to the SourceRect 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. | ||||||||||||||||||
SortTileOffset | (Optional) A Y tile offset applied when figuring out render layering. For example, a value of 2.5 will treat the building as if it was 2.5 tiles further up the screen for the purposes of layering. Default 0. | ||||||||||||||||||
DrawLayers | (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:
| ||||||||||||||||||
DrawShadow | (Optional) Whether to draw an automatic shadow along the bottom edge of the building's sprite. Default true. |
Interior
field | effect |
---|---|
IndoorMap | (Optional) The name of the map asset under Maps to load for the building interior. For example, "Shed" will load the shed's Maps/Shed map. |
IndoorMapType | (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...
Defaults to the generic StardewValley.GameLocation class. |
NonInstancedIndoorLocation | (Optional) The name of the existing global location to treat as the building's interior, like FarmHouse and Greenhouse 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 IndoorMap and IndoorMapType instead. For example, the first greenhouse will use the global Greenhouse location, and any subsequent greenhouse will use a separate instanced location. |
MaxOccupants | (Optional) The maximum number of animals who can live in this building. |
ValidOccupantTypes | (Optional) A list of building IDs whose animals to allow in this building too. For example, [ "Barn", "Coop" ] will allow barn and coop animals in this building. Default none.
|
Item processing
field | effect | ||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
HayCapacity | (Optional) The amount of hay that can be stored in this building. If built on the farm, this works just like silos and contributes to the farm's available hay. | ||||||||||||||||||||||||
ItemConversions | (Optional) The item processing rules which take input items and convert them into output items using the inventories defined by Chests. This consists of a list of models with these fields:
| ||||||||||||||||||||||||
Chests | (Optional) The input/output inventories that can be accessed from a tile on the building exterior. The allowed items are defined by the separate ItemConversions field. This is a list of models with these fields:
|
Tile interactions
field | effect | ||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
ActionTiles | (Optional) A list of tiles which the player can click to trigger an Action map tile property. This consists of a list of models with these fields:
| ||||||||||||||
DefaultAction | (Optional) The default tile action if the clicked tile isn't in ActionTiles. Default none. | ||||||||||||||
TileProperties | (Optional) The map tile properties to set. This consists of a list of models with these fields:
| ||||||||||||||
AdditionalTilePropertyRadius | (Optional) When checking whether the player clicked on a TileProperties 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. |
Advanced
field | effect |
---|---|
BuildingType | (Optional) The full name of the C# type to instantiate for the building instance. Defaults to a generic Building instance. Note that using a non-vanilla building type will cause a crash when trying to write the building to the save file. |
ModData | (Optional) A string → string lookup of arbitrary modData values to attach to the building when it's constructed. |
ConvertBuildingOffset | (Optional) Only used when migrating pre-1.6 buildings to 1.6, specifically to adjust for the barn's footprint being reduced by one tile in the back. |
UpgradeOffset ValidBuildLocations |
(Optional) Unused. |
Build anywhere
Buildings and animals are no longer hardcoded to the farm location. You can allow building construction for any location using the new CanBuildHere and related map properties. The game will adjust accordingly (e.g. Robin will let you choose where to construct the building).
What's new for NPCs
Custom NPC data
Custom NPCs were already possible, but 1.6 extends that with a new Data/AdditionalNPCData data asset to customize previously hardcoded game logic and specify some data for NPCs that aren't in Data/NPCDispositions.
This consists of a string → model lookup, where the key is the internal NPC name (i.e. the same key as Data/NPCDispositions if any), and the value is a model with these fields:
- Main info:
-
field effect ID The internal NPC name. This should match the entry key. DisplayName (Optional) A tokenizable string for the NPC's display name. Defaults to the display name in Data/NPCDispositions (if any), else the internal NPC name. Size (Optional) The pixel size of the individual sprites in their overworld sprite spritesheet. Specified as a model with X and Y fields. Defaults to (16, 32). UnlockConditions (Optional) A 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. TextureName (Optional) The last segment of the NPC's portrait and sprite asset names. For example, set to Abigail to use Portraits/Abigail and Characters/Abigail respectively. Defaults to the internal NPC name. Breather (Optional) Whether the chest on the NPC's overworld sprite puffs in and out as they breath. Default true.. - Spawn info:
-
field effect ForceSpawn (Optional) Whether to add this NPC to the world even if they don't have an entry in Data/NPCDispositions. If true, you must specify DefaultLocation to avoid errors. Defaults to false. DefaultLocation (Optional) The internal name for the home location where this NPC spawns and returns each day. Defaults to the value specified in Data/NPCDispositions (if any), else causes an error. DefaultTile (Optional) The tile position within the home location where this NPC spawns and returns each day. Specified as a model with X and Y fields. Defaults to the tile specified in Data/NPCDispositions (if any), else (0, 0). Direction (Optional) The default direction the NPC faces when they start each day. The possible values are down, left, right, and up. Defaults to the value specified in Data/NPCDispositions (if any), else up. - Social features:
-
field effect SocializeConditions (Optional) A game state query which indicates whether to enable social features (like birthdays, gift giving, friendship, and an entry in the social tab). Defaults to true (except for monsters, horses, pets, and Junimos). Visibility (Optional) Determines how the NPC is shown on the social tab when unlocked. Possible values: value effect HiddenAlways They never appear in the social tab. Hidden Until the player meets them, they don't appear on the social tab. Default Until the player meets them, their name on the social tab is replaced with "???". Friend They always appear in the social tab (including their name). Defaults to Default.
ExcludeFromIntroductionsQuest (Optional) Whether this NPC will be ignored for the introductions quest. Default false if the NPC is in Data/NPCDispositions, else true. - Hidden gift log emote:
-
field effect HiddenProfileEmoteSound (Optional) For the hidden gift log emote, the cue ID for the sound played when clicking the sprite. Defaults to drumkit6. HiddenProfileEmoteDuration (Optional) For the hidden gift log emote, how long the animation plays measured in milliseconds. Defaults to 4000 (4 seconds). HiddenProfileEmoteStartFrame (Optional) For the 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. HiddenProfileEmoteFrameCount (Optional) For the hidden gift log emote, the number of frames in the animation. The first frame corresponds to HiddenProfileEmoteStartFrame, and each subsequent frame will use the next sprite in the spritesheet. Default 1. This has no effect if HiddenProfileEmoteStartFrame isn't set.
HiddenProfileEmoteFrameDuration (Optional) For the 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 HiddenProfileEmoteStartFrame isn't set.
Custom farm animals
You can now create and edit farm animals via the new Data/AdditionalFarmAnimalData asset. This supercedes Data/FarmAnimals, which is ignored if the animal exists in Data/AdditionalFarmAnimalData (except for the perfection summit event, which only uses the original animals in Data/FarmAnimals).
This consists of a string → model lookup, where the key matches the ID field, and the value is a model with these fields:
Main info
field | effect |
---|---|
ID | The unique farm animal ID. For custom farm animals, this should be prefixed with your mod ID like Example.ModId_FarmAnimalName. |
DisplayName | A tokenizable string for the animal type's display name. |
House | The building ID for the main building type that houses this animal. The animal will also be placeable in buildings whose ValidOccupantTypes field contains this value. |
Animal shop
These fields affect how this farm animal type is shown in Marnie's animal shop. Animals are automatically listed if they have a valid PurchasePrice value.
field | effect | ||||||
---|---|---|---|---|---|---|---|
PurchasePrice | (Optional if not purchaseable) Half the cost to purchase the animal (the actual price is double this value), or a negative value to disable purchasing this animal type. Default -1. | ||||||
ShopTexture | (Optional if not purchaseable) The asset name for the icon texture to show in shops. Defaults to LooseSprites/Cursors or LooseSprites/Cursors2 based on the animal's position within the loaded data (but using the default isn't recommended if it's purchaseable). | ||||||
ShopSourceRect | (Optional if not purchaseable) The pixel area within the ShopTexture to draw, specified as an object with X, Y, Width, and Height fields. This should be 32 pixels wide and 16 high. Ignored if ShopTexture isn't set. | ||||||
RequiredBuilding | (Optional) The building that needs to be built on the farm for this animal to be available to purchase. Buildings that are upgraded from this building are valid too. Default none. | ||||||
UnlockCondition | (Optional) A game state query which indicates whether the farm animal is available in the shop menu. Default always unlocked. | ||||||
ShopDisplayName | (Optional) A tokenizable string for the display name shown in the shop menu. Defaults to the DisplayName field. | ||||||
ShopDescription | (Optional) A tokenizable string for the tooltip description shown in the shop menu. Defaults to none. | ||||||
ShopMissingBuildingDescription | (Optional) A tokenizable string which overrides ShopDescription if the RequiredBuilding isn't built. Defaults to none. | ||||||
Genders | (Optional) The possible genders for the animal type. Currently this only affects the text shown after purchasing the animal, like "Great! I'll send little <name> to [his/her] new home right away". Default Female.
The possible values are:
| ||||||
AlternatePurchaseTypes | (Optional) The possible variants for this farm animal (e.g. chickens can be Brown Chicken, Blue Chicken, or White Chicken). This consists of a list of models with these fields:
If multiple are listed, the first available variant is returned. Default none. |
Hatching
field | effect |
---|---|
EggItemIDs | (Optional) A list of the object IDs that can be placed in the incubator/ostrich incubator to hatch the animal (Todo : determine if the incubator also needs data to be added for this to work). |
IncubationTime | (Optional) The time needed for the egg to hatch. Default : todo |
IncubatorParentSheetOffset | (Optional) (Todo : sprite index of the incubator when the egg is hatching ?). Default : todo |
BirthText | (Optional) A tokenizable string for the tooltip description shown when entering the building after the egg hatched. Default : todo |
Growth
field | effect |
---|---|
DaysToMature | (Optional) The number of days until a freshly purchased/born animal becomes an adult and begins producing items. Default 1. |
CanGetPregnant | (Optional) Whether an animal can produce a child (regardless of gender). Default false. |
Produce
field | effect | ||||||
---|---|---|---|---|---|---|---|
ProduceItemIDs DeluxeProduceItemIDs |
(Optional) A pair of string condition and string of the unqualified object ID of the produced items. The list of items is first filtered via condition checking, and then one is randomly picked from the remaining, valid items. If set, the deluxe item overrides the default one if the Deluxe* fields match. Both default to none. | ||||||
DaysToProduce | (Optional) The number of days between item productions. For example, setting 1 will produce an item every other day. Default 1. | ||||||
ProduceOnMature | (Optional) Whether an item is produced on the day the animal becomes an adult. Default false. | ||||||
QualityBoostProfession | (Optional) The internal ID of a profession which increases the chance of higher-quality produce. This has the same effect as the Coopmaster and Shepherd professions, and doesn't stack with them. Defaults to the Coopmaster profession for an animal whose House value is Coop, else the Shepherd profession. | ||||||
ProduceSpeedProfession | (Optional) The internal ID of a profession which reduces the DaysToProduce by one. Defaults to none. | ||||||
ProduceSpeedBoostFriendship | (Optional) The minimum friendship points needed to reduce the DaysToProduce by one. Default to no reduction based on friendship. | ||||||
DeluxeProduceMinimumFriendship | (Optional) The minimum friendship points needed to produce the DeluxeProduceItemID. Default 200. | ||||||
DeluxeProduceCareDivisor DeluxeProduceLuckMultiplier |
(Optional) Modifiers which change the probability of producing the DeluxeProduceItemID, based on this formula:
if happiness > 200: happiness_modifier = happiness * 1.5 else if happiness > 100: happiness_modifier = 0 else happiness_modifier = happiness - 100 ((friendship + happiness_modifier) / DeluxeProduceCareDivisor) + (daily_luck * DeluxeProduceLuckMultiplier) Specifically:
For example, given a friendship of 102 and happiness of 150, the probability with the default field values will be See Animals#Produce for more info on the calculation. | ||||||
HarvestType | (Optional) How produced item are collected from the animal. The valid values are:
Default DropOvernight. | ||||||
HarvestTool | (Optional) The tool ID with which the item can be collected from the animal, if the HarvestType is set to HarvestWithTool. The values recognized by the vanilla tools are MilkPail and Shears. Default none. |
Audio & sprite
field | effect |
---|---|
Sound | (Optional) The audio cue ID for the sound produced by the animal (e.g. when pet). Default none. |
BabySound | (Optional) Overrides Sound field when the animal is a baby. Has no effect if Sound isn't specified. Default none. |
Texture | (Optional) The asset name for the texture animal's spritesheet. Defaults to Animals/<ID> (like Animals/Goat for a goat).
|
HarvestedTexture | (Optional) Overrides Texture if the animal doesn't currently have an item ready to collect (like the sheep's sheared sprite). Default none. |
BabyTexture | (Optional) Overrides Texture and HarvestedTexture when the animal is a baby. Default none. |
UseFlippedRightForLeft | (Optional) When the animal is facing left, whether to use a flipped version of their right-facing sprite. Default false. |
SpriteWidth SpriteHeight |
(Optional) The pixel height & width of the animal's sprite (before the in-game pixel zoom). Both default to 16. |
Behavior
field | effect |
---|---|
CanSwim | (Optional) Whether animals on the farm can swim in water once they've been pet. Default false. |
BabiesFollowAdults | (Optional) Whether baby animals can follow nearby adults. This only applies for animals whose House field is Coop. Default false. |
Pessimism | (Optional) An amount subtracted from the mood boost when a player pets the animal, before the Coopmaster or Shepherd profession bonus is applied. Default -1 (i.e. improves mood by one 1 point). |
Price | (Optional) The price when the player sells the animal, before the frienship boost. Default 0. |
Other
field | effect | ||||||
---|---|---|---|---|---|---|---|
StatToIncrementOnProduce | (Optional) The game stat counters to increment when the animal produces an item. Default none. This consists of a list of models with these fields:
| ||||||
MeatID | (Optional) No effect. Default none. |
Custom pets
Format
You can now create and edit pets and pet breeds via the new Data/PetsData asset. This consists of a string → model lookup, where the key matches the ID field, and the value is a model with these fields:
field | effect | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
ID | The unique pet ID. (This is for the pet type like Cat or Dog, not the breed.) For custom pets, this should be prefixed with your mod ID like Example.ModId_PetName. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
BarkSound | The cue ID for the pet's occasional 'bark' sound. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
ContentSound | The cue ID for the sound which the pet makes when you pet it. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Behaviors | 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 Walk to BeginSitDown, but it can't skip instantly from Walk to SitDownLick.
This consists of a list of models with these fields:
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Breeds | 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:
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
MoveSpeed | (Optional) How quickly the pet can move. Default 2. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
SleepOnBedChance SleepNearBedChance SleepOnRugChance |
(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. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
RepeatContentSoundAfter | (Optional) The number of milliseconds until the ContentSound is repeated once. This is used by the dog, who pants twice when pet. Defaults to -1 (disabled). |
Pet bowl
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 guid field populated with a unique ID, and each pet bowl has a petGuid field which tracks its owner (see the PetBowl::HasPet() and PetBowl::FindPet() methods).
Custom monster eradication goals
You can now add/edit Adventurer's Guild monster eradication goals by editing the new Data/MonsterSlayerQuestData data asset. This consists of a string → model lookup, where the key is a unique ID for the monster eradication goal, and the value is a model with these fields:
field | effect |
---|---|
ID | A key which uniquely identifies this goal. The ID should only contain alphanumeric/underscore/dot characters, and custom goal IDs should ideally be prefixed with your mod ID like Example.ModId_GoalName. |
DisplayName | A tokenizable string for the goal's display name, shown on the board in the Adventurer's Guild. |
Targets | A list of monster IDs that are counted towards the Count. |
Count | The total number of monsters (matching the Targets) which must be defeated to complete this goal. |
RewardItemID | (Optional) The qualified item ID for the item that can be collected from Gil when this goal is completed. There's no reward item if omitted. |
RewardItemPrice | (Optional) The price of the RewardItemID in Marlon's shop, or -1 to disable buying it from Marlon. Default -1. |
RewardMail | (Optional) The mail flag ID to set for all players when Gil's reward menu is opened and this goal is complete. The players won't see a letter in their mailbox, even if it matches a letter ID. None is set if omitted. |
RewardMailDialogue | (Optional) A tokenizable string for Gil's dialogue when the RewardMail is set. This has no effect if RewardMail isn't set. No extra dialogue is shown if omitted. |
Custom shops
Format
You can now create and edit shops via the new Data/Shops asset. This consists of a list of models with these fields:
field | effect | ||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
ID | A unique ID for the shop. For a custom shop, you should use a globally unique ID which includes your mod ID like ExampleMod.Id_ShopName.
The vanilla shop IDs are:
¹ The 'is fully editable' column shows whether the shop is fully defined in Data/Shops. If not, the shop can be extended via Data/Shops but its base shop inventory is defined in-code. | ||||||||||||||||||||||||||||||||||||||||||
ItemGroups | The items to list in the shop inventory. This consists of a list of models with these fields:
| ||||||||||||||||||||||||||||||||||||||||||
SalableItemTags | (Optional) A list of context tags for items which the player can sell to to this shop. Default none. | ||||||||||||||||||||||||||||||||||||||||||
ValidNPCs | (Optional) The NPCs who can run the shop. If the Action OpenShop property specifies the [owner tile area] , at least one of the listed NPCs must be within that area; else if the [owner tile area] was omitted, the first entry in the list is used. The selected NPC's portrait will be shown in the shop UI.
If omitted, the shop is opened regardless of any NPCs being nearby and no portrait is shown. This consists of a list of models with these fields:
| ||||||||||||||||||||||||||||||||||||||||||
PriceMultiplier | (Optional) A multiplier applied to the price when buying items from the shop, like 1.5 for a 50% markup. Defaults to 1.
Note: this is only applied to items in ItemGroups which explicitly set a price. |
Open a custom shop
You can place an Action OpenShop tile property on the map, which will open the given shop ID when the player clicks it.
In C# code, you can get the inventory for a custom shop using Utility.GetShopStock("shop id here")
, or open a shop menu using Game1.activeClickableMenu = new ShopMenu(new(), who: "shop id here")
. The ID of the opened shop is stored in the shop menu's storeContext field.
What's new for everything else
Buff overhaul
1.6 rewrites buffs to work more consistently and be more extensible:
- Buff logic is unified into Game1.player.buffs, which is the single source of truth for buff data. This replaces the previous player.added* and player.appliedBuffs fields, BuffsDisplay logic, enchantment stat bonuses, and boots/ring attribute changes on (un)equip.
- This also removes limitations on buff types (e.g. buffs can add weapon bonuses and weapons can add attribute buffs) and buffable equipment (e.g. equipped tools can have buffs too).
- Buff effects are now fully recalculated when they change, to fix a range of longstanding bugs like attribute drift and double-debuffs. Just like before, the buffs are managed locally; only the buff IDs and aggregate attribute effects are synced.
For C# mods:
- Each buff now has a unique string ID. You can apply a new buff with the same ID to replace it (so you no longer need to manually find and remove previous instances of the buff).
- You can add standard buff effects to any equipment by overriding Item.AddEquipmentEffects, or add custom behaviour/buffs by overriding Item.onEquip and Item.onUnequip.
- You can add custom food or drink buffs by overriding Item.GetFoodOrDrinkBuffs().
- The Buff constructor now supports a custom icon texture, sprite index, display name, description, and millisecond duration to fully support custom buffs.
- You can change how buff attributes are displayed (or add new attributes) by extending the BuffsDisplay.displayAttributes list.
For example, here's how to add a custom buff which adds +3 speed:
Buff buff = new Buff(
buff_id: "Example.ModId/ZoomZoom",
display_name: "Zoom Zoom", // can optionally specify description text too
icon_texture: this.Helper.Content.Load<Texture2D>("assets/zoom.png"),
icon_sheet_index: 0,
duration: 30_000, // 30 seconds
buff_effects: new BuffEffects()
{
speed = { 10 } // shortcut for buff.speed.Value = 10
}
);
Game1.player.applyBuff(buff);
You can also implement your own custom effects in code by checking if the buff is active, like Game1.player.hasBuff("Example.ModId/ZoomZoom")
.
Custom audio
You can now add custom music tracks or sound effects (called cues) to the game by editing the Data/AudioCueModificationData asset. This can be used both to add new music cues, and to replace existing cues with new audio. These are added to the game's soundbank, so they can be used anywhere normal audio can be used (e.g. the Music map property).
Format
The Data/AudioCueModificationData asset consists of a string → model lookup, where the key matches the ID, and the value is a model with these fields:
field | effect | ||||||
---|---|---|---|---|---|---|---|
ID | A unique cue ID, used when playing the sound in-game. The ID should only contain alphanumeric/underscore/dot characters. For custom locations, this should be prefixed with your mod ID like Example.ModId_AudioName. | ||||||
FilePaths | (Optional if editing a cue, required if adding a new one) A list of file paths (not asset names) from which to load the audio, relative to the game's Content folder. Each file can be .ogg or .wav. If you list multiple paths, a random one will be chosen each time it's played. | ||||||
Category | (Optional) The audio category, which determines which volume slider in the game options applies. This should be one of Default, Music, Sound, Ambient, or Footsteps (see a description of each category). Default Default. | ||||||
StreamedVorbis | (Optional) Whether the audio should be streamed from disk when it's played, instead of being loaded into memory ahead of time. This is only possible for Ogg Vorbis (.ogg) files, which otherwise will be decompressed in-memory on load. Default false.
This is a tradeoff between memory usage and performance, so you should consider which value is best for each audio cue:
| ||||||
Looped | (Optional) Whether the audio cue loops continuously until stopped. Default false. | ||||||
UseReverb | (Optional) Whether to apply a reverb effect to the audio. Default false. |
This describes a change applied to the soundbank. For example, you can specify only ID and Category to change the category for an existing music cue without overwriting other values.
Example
This content pack adds a new music cue to the game, and plays it when the player enters the bus stop:
{
"Format": "2.0.0",
"Changes": [
// add music cue
{
"Action": "EditData",
"Target": "Data/AudioCueModificationData",
"Entries": {
"Example.ModId_Music": {
"ID": "Example.ModId_Music",
"Category": "Music",
"FilePaths": [ "{{AbsoluteFilePath: assets/music.ogg}}" ],
"StreamedVorbis": true,
"Looped": true
}
}
},
// add to bus stop
{
"Action": "EditMap",
"Target": "Maps/BusStop",
"MapProperties": {
"Music": "Example.ModId_Music"
}
}
]
}
Limitations
- As hinted by the unusual asset name (Data/AudioCueModificationData instead of Data/AudioCues), this is a list of changes applied to the current audio cues for the remainder of the game session. That means:
- You can't remove an audio cue once it's added.
- You can't undo a change by removing it from the data asset. For example, if you change an audio cue's category, it won't revert to the original value when you remove it from the asset. To undo a change, you'd need to add a new entry which sets the original values.
- The game will crash if it tries to play an audio cue that doesn't exist.
Custom giant crops
You can now add/edit giant crops by editing the Data/GiantCrops data asset. This consists of a string → model lookup, where the key matches the ID and the value is a model with these fields:
field | effect |
---|---|
ID | The unqualified item ID produced by the underlying crop (i.e. the 'index of harvest' field in Data/Crops). The giant crop has a chance of growing when there's a grid of fully-grown crops which produce this item ID in a grid of TileSize tiles. |
Texture | The asset name for the texture containing the giant crop's sprite. |
Corner | (Optional) The top-left pixel position of the sprite within the Texture, specified as a model with X and Y fields. Defaults to (0, 0). |
TileSize | (Optional) The area in tiles occupied by the giant crop, specified as a model with X and Y fields. This affects both its sprite size (which should be 16 pixels per tile) and the grid of crops needed for it to grow. Note that giant crops are drawn with an extra tile's height. Defaults to (3, 3). |
Chance | (Optional) The percentage chance a given grid of crops will grow into the giant crop each night, as a value between 0 (never) and 1 (always). Default 0.01. |
HarvestedItemID | (Optional) The item ID which is harvested when you break the giant crop. Defaults to the ID. |
MinYields | (Optional) The minimum number of the HarvestedItemID to drop when the giant crop is broken. |
MaxYields | (Optional) The maximum number of the HarvestedItemID to drop when the giant crop is broken. Default 21. |
Custom wedding event
The wedding event can now be changed by editing the Data\MiscGameData data asset, which consists of a data model with two relevant fields (listed below).
Note that Data\MiscGameData contains a single global entry, it isn't a list or dictionary like other assets. For example, Content Patcher would edit WeddingEvent as its own entry.
field | effect | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
WeddingEvent | The event script which plays the wedding. The default script automatically handles marrying either an NPC or player, but mods can edit it conditionally to run a custom script (e.g. if the player is marrying their custom NPC). | ||||||||||
WeddingContextualAttendees | The other NPCs which should attend the wedding (unless they're the spouse). This consists of a string → model lookup, where the key is the internal NPC name, and the value is a model with these fields:
|
Game state queries
A game state query is a vanilla way to specify conditions for some content like shop data, inspired by Content Patcher's conditions. A query consists of a comma-delimited list of conditions in the form <type>
[arguments]
, where <type>
is case-sensitive. The type can be prefixed with !
to negate it. The query is true if it's null/blank, or if every listed condition exists and is true. For example, !SEASON Spring, WEATHER Here sunny
is true on sunny non-spring days.
Conditions
- Date & time
Condition effect DAY_OF_MONTH <day>
The day of month. DAY_OF_WEEK <day>
The day of week, formatted as an integer between 0 (Sunday) through 6 (Saturday). DAYS_PLAYED <count>
Whether at least <count>
days have been played in the current save (including the current one). This always increments in sync with the date in the base game, but when mods change the in-game date, they may or may not update this value.IS_FESTIVAL_DAY [day offset]
Whether there's a festival today, with an optional [day offset]
(e.g. 1 for tomorrow).IS_PASSIVE_FESTIVAL_OPEN <id>
Whether a passive festival with the given ID is active today, and the current time is within its opening hours. IS_PASSIVE_FESTIVAL_TODAY <id>
Whether a passive festival with the given ID is active today. SEASON <season>
The season (one of spring, summer, fall, or winter). TIME <min>
<max>
Whether the current time is between <min>
and<max>
inclusively, specified in 26-hour time. Each value can be set to 0 or less to ignore it (e.g. TIME 900 -1 for 9am or later).YEAR Whether the year is equal or more than the given value. For example, YEAR 2
is true in year 2 and all later years.
- World
Condition effect CAN_BUILD_CABIN Whether players can build more cabins (i.e. they haven't reached the maximum number of player slots yet). CAN_BUILD_FOR_CABINS <building ID>
Whether there are fewer of the given building constructed than there are cabins. FARM_CAVE <type>
The current farm cave (one of Bats, Mushrooms, or None). FARM_NAME <name>
The name of the farm. FARM_TYPE <type>
The farm type. The <type>
is one of 1 (standard), 2 (riverland), 3 (forest), 4 (hilltop), 4 (combat), 5 (four corners), 6 (beach), or the ID for a custom farm type.IS_CUSTOM_FARM_TYPE Whether the farm type is a custom one created by a mod. (This returns false for mods which edit/replace a vanilla farm type.) IS_COMMUNITY_CENTER_COMPLETE Whether the community center has been repaired. IS_HOST Whether the current player is the main/host player. IS_JOJA_MART_COMPLETE Whether the Joja warehouse has been built. LOCATION_ACCESSIBLE <name>
Whether the given location is accessible (one of CommunityCenter, JojaMart, or Railroad). Returns true for any other name, regardless of whether it's accessible. LOCATION_CONTEXT <location>
The location context name for the given location. LOCATION_IS_MINES <location>
LOCATION_IS_SKULL_CAVE<location>
Whether the given location is in the mines or Skull Cavern. LOCATION_SEASON <location>
<season>
Whether the given location is in the given season (one of spring, summer, fall, or winter). This accounts for the SeasonOverride field in the location's context data. WEATHER <location>
<weather>
The weather ID in the given location. The weather can be one of Festival, Rain, Snow, Storm, Sun, Wind, or a custom weather ID. WORLD_STATE <id>
Whether any world state flag with the given <id>
is set.
- Player info & progress
Condition effect MINE_LOWEST_LEVEL_REACHED <level>
Whether any player has reached at least level <level>
in the mines.PLAYER_COMBAT_LEVEL <player>
<level>
PLAYER_FARMING_LEVEL<player>
<level>
PLAYER_FISHING_LEVEL<player>
<level>
PLAYER_FORAGING_LEVEL<player>
<level>
PLAYER_MINING_LEVEL<player>
<level>
The skill levels for the specified player(s). PLAYER_CURRENT_MONEY <player>
<amount>
Whether the specified player(s) currently have at least <amount>
gold.PLAYER_FARMHOUSE_UPGRADE <player>
<level>
Whether the specified player(s) have upgraded their farmhouse or cabin to at least the given level (see possible levels). PLAYER_GENDER <player>
<gender>
Whether the specified player(s) are Male or Female. PLAYER_HAS_ACHIEVEMENT <player>
<achievement id>
Whether the specified player(s) have unlocked a specific achievement ID. The valid IDs are listed in Data/Achievements, plus a few Steam achievement IDs that aren't listed. PLAYER_HAS_ALL_ACHIEVEMENTS <player>
Whether the specified player(s) have unlocked every achievement listed in Data/Achievements. This doesn't count the extra Steam achievement IDs that aren't listed in that file. PLAYER_HAS_CAUGHT_FISH <player>
<id>
Whether the specified player(s) have caught at least one fish with the given ID. PLAYER_HAS_CONVERSATION_TOPIC <player>
<id>
Whether the specified player(s) have a conversation topic with the ID <id>
active.PLAYER_HAS_CRAFTING_RECIPE <player>
<recipe name>
PLAYER_HAS_COOKING_RECIPE<player>
<recipe name>
Whether the specified player(s) know the crafting/cooking recipe identified by its internal name (spaces allowed). For example, PLAYER_HAS_CRAFTING_RECIPE CURRENT Field Snack
.PLAYER_HAS_DIALOGUE_ANSWER <player>
<id>
Whether the specified player(s) have chosen the given dialogue answer in a previous dialogue. PLAYER_HAS_FLAG <player>
<id>
Whether the specified player(s) have the given mail flag set (with spaces allowed in the <id>
).PLAYER_HAS_ITEM <player>
<item>
Whether the specified player(s) have at least one of a normal item (not bigcraftable, furniture, etc) in their inventory. The <item>
can be 858 (Qi Gems), 73 (Walnuts), or the unqualified item ID.PLAYER_HAS_ITEM_NAMED <player>
<item name>
Whether the specified player(s) have at least one item in their inventory with the given <item name>
(spaces allowed).PLAYER_HAS_PROFESSION <profession id>
Whether the specified player(s) have the given profession ID. PLAYER_HAS_READ_LETTER <player>
<id>
Whether the specified player(s) have read a letter, where <id>
is the internal mail ID (spaces allowed). For example,PLAYER_HAS_READ_LETTER Any Visited_Island
.PLAYER_HAS_SECRET_NOTE <player>
<id>
Whether the specified player(s) have read a secret note, where <id>
is the secret note's integer ID.PLAYER_HAS_SEEN_EVENT <player>
<id>
Whether the specified player(s) have seen the event with given <id>
.PLAYER_LOCATION_CONTEXT <player>
<location context>
Whether the specified player(s) are in the given location context. PLAYER_LOCATION_NAME <player>
<location name>
PLAYER_LOCATION_UNIQUE_NAME<player>
<location name>
Whether the specified player(s) are in the given location, using the name or unique instanced name (you can see both names in-game using the Debug Mode mod). The <location name>
value doesn't recognize target location keywords like Here.PLAYER_MOD_DATA <player>
<key>
<value>
Whether the specified player(s) have a player.modData entry added by a mod with the given <key>
and<value>
.PLAYER_MONEY_EARNED <player>
<amount>
Whether the specified player(s) have earned at least <amount>
gold.
- Player relationships
Condition effect PLAYER_HAS_CHILDREN <player>
<count>
Whether the specified player(s) have least <count>
children.PLAYER_HAS_PET <player>
Whether the specified player(s) have a pet. PLAYER_HEARTS <player>
<npc>
<heart level>
Whether the specified player(s) have a friend with at least <heart level>
hearts of friendship. The<npc>
can be an NPC's internal name, Any (check every NPC), or AnyDateable (check every romanceable NPC).PLAYER_HAS_MET <player>
<npc>
PLAYER_IS_UNMET<player>
<npc>
Whether the specified player(s) have talked to or not talked to an NPC at least once. The <npc>
is an NPC's internal name.PLAYER_IS_DATING <player>
<npc>
PLAYER_IS_ENGAGED<player>
<target>
PLAYER_IS_MARRIED<player>
<target>
PLAYER_IS_DIVORCED<player>
<npc>
Whether the specified player(s) have this relationship status with an NPC. The player is dating after giving the NPC a bouquet, and engaged after giving a Mermaid's Pendant but before the marriage. The <npc>
can be an NPC's internal name, or Any (check every romanceable NPC).PLAYER_IS_ROOMMATE <player>
<target>
Whether the specified player(s) have a roommate. The <target>
can be an NPC's internal name, Any (with any NPC), or Player (always false).PLAYER_PREFERRED_PET <player>
<pet>
Whether the preferred pet for the specified player(s) is Cat or Dog.
- Randomization
Condition effect RANDOM <value>
A random probability check. For example, RANDOM 0.4
is true 40% of the time. This recalculates the result each time it's called.PICKED_VALUE_TICK <min>
<min>
<value>
[seed offset]
PICKED_VALUE_DAYS<min>
<max>
<value>
[seed offset]
Whether a random value between <min>
and<max>
is equal to<value>
. For example, PICKED_VALUE_TICK 1 10 2 has a 10% chance (check if 2 is equal to a random number between 1 and 10).This always choose the same value for the current tick (if PICKED_VALUE_TICK) or in-game day (if PICKED_VALUE_DAYS). To have a different synchronized value, specify
[seed offset]
with an offset number (e.g. three options in a list would use offset 0, 1, and 2).PICKED_VALUE <min>
<max>
<value>
PICKED_VALUE_CHANCE<chance>
PICKED_VALUE_SUMMER_RAIN_CHANCE<chance>
Not recommended for mods, except in shop dialogue and weather conditions.
These are specialized to to replicate older vanilla behavior, and depend onGameStateQuery.PickRandomValue(random)
being called first. The game only calls that method when opening a shop menu for shop data with dialogue or when checking weather conditions.
- For items only
- These are used with queries that check an item. For vanilla content, these are only supported for custom machine conditions. For custom queries, C# mods can specify the target_item parameter when calling GameStateQuery.CheckConditions. In any other context, they'll always return false.
Condition effect ITEM_HAS_TAG <tags>
Whether the item has all of the given space-delimited tags. For example, ITEM_HAS_TAG bone_item marine_item
will only match items with both tags.ITEM_ID <item ID>
Whether the item has the given unqualified item ID. ITEM_QUALITY <quality>
Whether the item's quality is <quality>
or higher. The possible values for<quality>
are 0 (normal), 1 (silver), 2 (gold), or 4 (iridium).ITEM_STACK <count>
Whether the item stack contains at least <count>
items. Note that this only applies to the target item, it doesn't include other stacks in the inventory.
- Immutable
Condition effect TRUE A condition which always matches. FALSE A condition which never matches.
Target location
Some conditions have a <location>
argument. This can be one of...
value | result | ||||||||
---|---|---|---|---|---|---|---|---|---|
Here | The current player's location (regardless of the target player). | ||||||||
Target | This value depends on the context:
| ||||||||
any other | The location ID (i.e. internal name) for the location to check. |
Target player
Some conditions have a <player>
argument. This can be one of...
value | result | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Any | At least one player must match the condition, regardless of whether they're online. | ||||||||||||
All | Every player must match the condition, regardless of whether they're online. | ||||||||||||
Current | The local player. | ||||||||||||
Host | The main player. | ||||||||||||
Target | This value depends on the context:
| ||||||||||||
any other | The unique multiplayer ID for the player to check. |
Using queries elsewhere
C# code can use the GameStateQuery class to work with queries, like GameStateQuery.CheckConditions(query)
.
You can also use game state queries in event preconditions using the new G condition flag, like some_event_id/G !SEASON Spring, WEATHER Here sunny
.
Extensibility
C# mods can define custom conditions by calling GameStateQuery.RegisterQueryType("condition name", (string[] fields) => ...)
. To avoid conflicts, prefixing custom condition names with your mod ID (like Example.ModId_SomeCondition) is strongly recommended.
Tokenizable string format
Stardew Valley 1.6 adds support for literal strings that contain tokens (currently only supported for custom map areas and custom shops).
Literal text
Previously you often needed to load text from a string key in data assets. With this new format, you can use the literal text directly in the asset instead (including Content Patcher tokens):
// before
"Dialogue": "Strings\\StringsFromCSFiles:ShopMenu.cs.11488",
// after: literal text supported
"Dialogue": "Welcome to Pierre's!",
// after: literal text with Content Patcher tokens
"Dialogue": "Welcome to Pierre's, {{PlayerName}}! {{i18n: translatable-text}}",
Tokens
You can inject tokens using square brackets. For example, "[LocalizedText Strings\StringsFromCSFiles:ShopMenu.cs.11488] This is raw text"
will show something like "Welcome to Pierre's! This is raw text". Here are the supported tokens:
token format | output |
---|---|
[ArticleFor <word> ]
|
The grammatical article (a or an) for the given word when playing in English, else blank. For example, [ArticleFor apple] apple will output an apple.
|
[CharacterName <name> ]
|
The translated display name for an NPC, given their internal name. |
[DataString <asset name> <key> <index> ]
|
Parses the data asset identified by <asset name> , finds the entry matching <key> , splits the slash-delimited string, and returns the value with index <index> (starting from 0).
For example, [DataString Data\Blueprints Silo 8] matches the word "Silo" from this entry in Data\Blueprints: "Silo": "390 100 330 10 334 5/3/3/-1/-1/-2/-1/null/Silo/Allows you to cut and store grass for feed./Buildings/none/48/128/-1/null/Farm/100/false"
|
[DayOfMonth] | The numeric day of month, like 5 on spring 5. |
[EscapedText <text> ]
|
Replaces spaces in the given text with a special character that lets you pass them into other space-delimited tokens. The characters are automatically turned back into spaces when displayed. |
[FarmerUniqueID] | The target player's unique internal multiplayer ID |
[FarmName] | The farm name for the current save (without the injected "Farm" text). |
[GenderedText <male text> <female text>
|
Depending on the target player's gender, show either the male text or female text. If the text contains spaces, you'll need to escape them using EscapedText. |
[LocalizedText <string key> ]
|
Translation text loaded from the given string key. If the translation has placeholder tokens like {0}, you can add the values after the string key. |
[LocationName <location ID> ]
|
The translation display name for a location given its ID (i.e. the same ID as in Data/AdditionalLocationData). |
[PositiveAdjective] | A random adjective from the Strings\Lexicon data asset's RandomPositiveAdjective_PlaceOrEvent entry. |
[Season] | The current season name, like spring. |
[SpouseFarmerText <spouse is farmer text> <spouse is NPC text>
|
Show a different text depending on whether the target player's spouse is a player or NPC. If the text contains spaces, you'll need to escape them using EscapedText. |
[SpouseGenderedText <male text> <female text> ]
|
Equivalent to GenderedText, but based on the gender of the player's NPC or player spouse instead. |
[SuggestedItem] | (For shops only.) The name of a random item currently available in the shop stock. |
When passing an input argument for tokens like ArticleFor, the input can contain its own nested tokens. For example, "[ArticleFor [SuggestedItem]] [SuggestedItem]"
would output something like an Apple.
If you're using Content Patcher, you can use its tokens anywhere in the string (including within square brackets); they'll be expanded before the game parses the string. For example, "{{Spouse}} would love [ArticleFor [SuggestedItem]] [SuggestedItem]!"
would output something like "Alexa would love an Apple!".
String event & response IDs
Event IDs and dialogue response IDs are now strings, so mods can use a unique key like Example.ModId_EventName (instead of hoping no other mod uses the same number). Prefixing the mod ID is recommended to simplify troubleshooting and avoid conflicts. For best compatibility, custom IDs should only contain alphanumeric/underscore/dot characters.
New C# utility methods
Stardew Valley 1.6 adds several new methods to the Utility class. Here are some of the most useful ones for mods:
method | effect |
---|---|
GetDataAtIndex GetIntAtIndex GetFloatAtIndex GetStringAtIndex |
Parse a value from an array with optional field indexes.
For example, code like this: string[] rawEffects = fields.Length > Object.objectInfoBuffTypesIndex && fields[Object.objectInfoBuffTypesIndex].Length > 0
? fields[Object.objectInfoBuffTypesIndex].Split(' ')
: new string[0];
int farming = rawEffects.Length > Buffs.farming && int.TryParse(rawEffects[Buffs.farming], out int _farming)
? _farming
: 0;
Can now be rewritten like this: string[] rawEffects = Utility.GetDataAtIndex(fields, Object.objectInfoBuffTypesIndex, "").Split(' ');
int farming = Utility.GetIntAtIndex(rawEffects, Buffs.farming);
|
GetItemDataForItemID | Get metadata about a given item ID like its display name, description, spritesheet index & source rectangle, etc. |
GetDescriptionForItemID GetDisplayNameForItemID GetSourceRectForItemID GetTextureForItemID GetParentSheetIndexForItemID |
Get specific details about a given item ID from GetItemDataForItemID. |
StringToDirection | Converts a string direction (one of down, left, right, or up) into a direction code recognized by various game methods (i.e. Game1.down, etc). If the string contains a number, the numeric value is returned (even if it's not a valid direction). If it's any other unrecognized value, the method returns -1. |
Other changes
- Added new debug commands:
command description bsm If the player is standing right under a building, open a menu to change the building appearance. testwedding Immediately play the wedding event. qualifiedid Print the held item's display name and qualified item ID. - Added new dialogue commands:
command description $f <response IDs>
Forget any number of space-delimited dialogue response IDs previously answered by the player. $v <event id>
[check preconditions]
[skip if seen]
Immediately start an event and end the current dialogue, subject to the conditions: [check preconditions]
: whether to ignore the command if the event's preconditions don't match (one of true or false). Default true.[skip if seen]
: whether to ignore the command if the player has already seen the given event. Default true.
If the event is skipped, the dialogue continues to the next line instead.
For example,
$v 60367 false false
will replay the bus arrival event from the start of the game. - Added new event commands:
command description temporaryAnimatedSprite ... Add a temporary animated sprite to the event, using these space-delimited fields: index field effect 0 texture The asset name for texture to draw. 1–4 rectangle The pixel area within the texture to draw, in the form <x>
<y>
<width>
<height>
.5 interval The millisecond duration for each frame in the animation. 6 frames The number of frames in the animation. 7 loops The number of times to repeat the animation. 8–9 tile The tile position at which to draw the sprite, in the form <x>
<y>
.10 flicker [TODO: document what this does] (one of true or false). 11 flip Whether to flip the sprite horizontally when it's drawn (one of true or false). 12 sort tile Y The tile Y position to use in the layer depth calculation, which affects which sprite is drawn on top if two sprites overlap. 13 alpha fade [TODO: document what this does] 14 scale A multiplier applied to the sprite size (in addition to the normal 4× pixel zoom). 15 scale change [TODO: document what this does] 16 rotation The rotation to apply to the sprite, measured in radians. 17 rotation change [TODO: document what this does] 18+ flags Any combination of these space-delimited flags: - hold_last_frame: after playing the animation once, freeze the last frame as long as the sprite is shown.
- ping_pong: [TODO: document what this does]
- motion
<x>
<y>
: [TODO: document what this does] - acceleration
<x>
<y>
: [TODO: document what this does] - acceleration_change
<x>
<y>
: [TODO: document what this does]
- Unknown dialogue commands starting with $ are no longer parsed as a portrait number if they're not numeric.
- Fixed ebi debug command not playing events correctly if called from the same location as the event.
- Added silence audio cue. This is different from none in that it suppresses both town music and ambient sounds.
- The desert no longer assumes the player arrived by bus unless their previous location was the bus stop.
Breaking changes for C# mods
This section only describes how this update may break existing mods. See the what's new sections above for more info, including new functionality mods can use.
See also Breaking changes for content packs, which affect C# mods too.
Item ID changes
- See also: custom items in what's new.
The main Item properties have changed. To migrate existing code:
- Don't use ParentSheetIndex to compare items. For example, item.ParentSheetIndex == 0 will match both weeds and any custom item whose sprite is the first one in its custom spritesheet. You should compare items using [[#Custom items|their new ItemID and QualifiedItemID properties instead. Here's how to migrate various common forms:
old code new code item.ParentSheetIndex == 848 item.QualifiedItemID == "(O)848" IsNormalObjectAtParentSheetIndex(item, 74) item.QualifiedItemID == "(O)74" !item.bigCraftable && item.ParentSheetIndex == 128 item.QualifiedItemID == "(O)128" item is Boots && item.ParentSheetIndex == 505 item.QualifiedItemID == "(B)505" - Don't assume item sprites are in the vanilla spritesheets. For example, instead of rendering Game1.objectSpriteSheet for an object, call
Utility.GetTextureForItemID(item.QualifiedItemID)
to get its texture. - Creating items works just like before, except that you now specify the item's ItemID (_not_ QualifiedItemID) instead of its ParentSheetIndex. This is the same value for vanilla items. For example:
new Object("634", 1); // vanilla item new Object("Example.ModId_Watermelon", 1); // custom item
You can also use a new utility method to construct items from their QualifiedItemID:
Item item = Utility.CreateItemByID("(B)505"); // Rubber Boots
Other ID changes
Many other things in the game now have unique string IDs too (including buffs, events, and fruit trees). To migrate existing code:
- When referencing numeric IDs, you usually just need to convert them into a string (like
Game1.player.hasBuff("1590166")
orGame1.player.eventsSeen.Contains("1590166")
). - When creating buffs, see buff overhaul for how to create buffs now.
Building and animal changes
- See also: build anywhere in what's new.
- Since all locations now allow buildings and animals, mod code which handles BuildableGameLocation and IAnimalLocation won't detect all buildable locations. You can replace them with location.IsBuildableLocation() (or just access location.buildings directly) and location.animals.Any() instead. Mods should no longer have any reference at all to BuildableGameLocation and IAnimalLocation.
- Since buildings can be built anywhere, you can no longer assume a building is on the farm. You can check the new building.buildingLocation field instead.
- You should review direct references to the farm (like
Game1.getFarm()
orGame1.getLocationFromName("Farm")
) to see if it needs to be rewritten to allow location. Utility.numSilos()
should no longer be used to calculate available hay, since it doesn't account for custom buildings with hay storage. UseGame1.getFarm().GetHayCapacity()
instead.- The Cat and Dog classes are now unused; all pets are now Pet directly.
Player changes
- See also: buff overhaul in what's new.
- Several Game1.player / Farmer fields changed as part of the buff overhaul:
old field how to migrate appliedBuffs
appliedSpecialBuffsUse Game1.player.hasBuff(id)
instead.attack
immunityUse Attack and Immunity instead. addedCombatLevel
addedFarmingLevel
addedFishingLevel
addedForagingLevel
addedLuckLevel
addedMiningLevel
attackIncreaseModifier
critChanceModifier
critPowerModifier
knockbackModifier
resilience
weaponPrecisionModifier
weaponSpeedModifierUse equivalent properties under Game1.player.buffs instead (e.g. Game1.player.buffs.CombatLevel). addedSpeed
CombatLevel
CraftingTime
FarmingLevel
FishingLevel
ForagingLevel
LuckLevel
MagneticRadius
MaxStamina
MiningLevel
StaminaThese are now readonly and can't be set directly. You can change them by adding a buff, equipment bonus, etc instead. - Buffs are now recalculated automatically, and you can reset a buff by just reapplying it. See buff overhaul for more info.
- Buff logic has been centralized into Game1.player.buffs. This replaces a number of former fields/methods like Game1.buffsDisplay.
Collision changes
The game's tile collision logic has been overhauled and merged into a simpler set of methods on GameLocation instances:
method | effect |
---|---|
CanSpawnCharacterHere | Get whether NPCs can be placed on the given tile (e.g. it's within the map bounds and tile is walkable), and there's no placed object (even if walkable like flooring) and the NoFurniture tile property isn't set. |
CanItemBePlacedHere | Get whether items can be placed on the given tile in non-floating form (e.g. it's within the map bounds and not blocked by a non-walkable item). If the item_is_passable argument is true, this ignores players/NPCs on the tile. |
isBuildable | Get whether buildings can be placed on the given tile. |
IsTilePassable | Get whether the tile can be walked on (ignoring collisions with in-game objects, NPCs, etc). |
IsTileOccupiedBy | Get whether the tile contains a player, object, NPC/monster/pet/etc, terrain feature, building, etc. You can specify ignore_passables: false to ignore objects which can be walked over (like flooring), and override collision_mask to change the collision logic (e.g. collision_mask: GameLocation.CollisionMask.All & ~GameLocation.CollisionMask.Farmers to ignore players on the tile).
|
IsTileBlockedBy | Equivalent to calling both IsTilePassable and IsTileOccupiedBy. |
IsLocationSpecificOccupantOnTile IsLocationSpecificPlacementRestriction |
Generally shouldn't be used directly. Checks for location-specific collisions (e.g. ladders in the mines or parrot platforms on Ginger Island). |
Check for obsolete code
Perform a full rebuild of your mod (in Visual Studio, click Build > Rebuild Solution), then check the Error List pane for any warnings like "'X' is obsolete". Anything from the vanilla game code which is marked obsolete won't work anymore and is only kept for save migrations. Usually the warning will include an explanation of what you should use instead.
Breaking changes for content packs
This section only describes how this update may break existing mods. See the what's new sections above for more info, including new functionality mods can use.
Standardized data fields
1.6 standardizes the number of fields in data assets, and fixes inconsistencies between English and localized files. This is a major breaking change for content packs, and for C# mods which edit data assets.
Three examples illustrate the standardization:
- Data/CookingRecipes had four fields in English, and a fifth field in other languages for the display name. The display name field is now required in English too.
- Data/BigCraftables had an optional 9th field which indicates whether it's a lamp, and a 10th field for the display name. Even if it's empty, the 9th field is now required (note the extra / before the last field):
// before "151": "Marble Brazier/500/-300/Crafting -9/Provides a moderate amount of light./true/true/0/Marble Brazier", // 9 fields // after "151": "Marble Brazier/500/-300/Crafting -9/Provides a moderate amount of light./true/true/0//Marble Brazier" // 10 fields
- Data/ObjectInformation had several optional fields at the end. These are now required even if empty:
// before "0": "Weeds/0/-1/Basic/Weeds/A bunch of obnoxious weeds." // after "0": "Weeds/0/-1/Basic/Weeds/A bunch of obnoxious weeds.///"
Existing mods which add entries without the now-required fields may cause errors and crashes. XNB mods which change data are likely universally broken.
The exception is fields which only exist for modding, like the texture + index overrides for custom items. These can typically be omitted.
Event ID changes
- See also: string event IDs in what's new.
Events now have unique string IDs.
When creating an event:
- New events should use a globally unique ID in the form Your.ModId_EventName. Existing events should be fine as-is, but it may be worth migrating them to avoid future conflicts.
- Every non-fork event must have a precondition in its key (even if it's empty). For example, change
"Your.ModId_EventName": "..."
to"Your.ModId_EventName/": "..."
. This is needed for the game to distinguish between events and fork scripts."Example.ModId_EventName/": "...", // event: loaded automatically by the game "SomeFork": "..." // event fork: ignored unless it's loaded through an event script
XNB impact
Here's a summary of the XNB files which changed in Stardew Valley 1.6.
This doesn't include...
- new files (since they won't impact existing mods);
- changes in non-English files;
- new fields when the vanilla entries didn't change (e.g. optional custom item fields).
Shorthand:
- 'broken' means removing new content or potentially important changes, or potentially causing significant display bugs. This is a broad category — the game may work fine without it or crash, depending how it uses that specific content.
- 'mostly unaffected' means mods will only be affected if they edit specific entries or fields.
- Blank means no expected impact for the vast majority of mods.
XNB mods are disproportionately affected since (a) they replace the entire file and (b) they're loaded through the MonoGame content pipeline which is less tolerant of format changes.
content file | changes | XNB | Content Patcher |
---|---|---|---|
Buildings/houses | fixed missing pixels | ✘ will remove changes | ✓ mostly unaffected |
Data/AquariumFish | changed key type, standardized fields | ✘ broken | ✘ likely broken |
Data/BigCraftablesInformation | changed key type, standardized fields | ✘ broken | ✘ likely broken |
Data/Boots | changed key type, added display name | ✘ broken | ✘ likely broken |
Data/ClothingInformation | changed key type, standardized fields | ✘ broken | ✘ likely broken |
Data/CookingRecipes | added display name | ✘ broken | ✘ likely broken |
Data/CraftingRecipes | added display name | ✘ broken | ✘ likely broken |
Data/Crops | changed key type | ✘ broken | |
Data/Events/IslandSouth | fixed typo | ✘ will remove changes | ✓ mostly unaffected |
Data/Fish | changed key type | ✘ broken | |
Data/FishPondData | changed ItemID field type | ✘ broken | |
Data/fruitTrees | changed key type | ✘ broken | |
Data/Furniture | changed key type, standardized fields, added display name | ✘ broken | ✘ likely broken |
Data/hats | changed key type, standardized fields, added display name | ✘ broken | ✘ likely broken |
Data/ObjectContextTags | added new entries & tags | ✘ broken | mostly unaffected (for content packs using best practices like appending values, or which only edit their own items) |
Data/ObjectInformation | changed key type, standardized fields | ✘ broken | ✘ likely broken |
Data/weapons | changed key type, added display name | ✘ broken | ✘ likely broken |
LooseSprites/Cursors2 | new sprite in empty area | ✘ broken | |
Maps/AbandonedJojaMart | changed map & tile properties to string | ||
Maps/AnimalShop | added Music map property | ✘ broken | |
Maps/Backwoods Maps/Backwoods_GraveSite Maps/Backwoods_Staircase Maps/Barn Maps/Barn2 |
changed map & tile properties to string | ||
Maps/Barn3 | changed map & tile properties to string, added AutoFeed map property | ✘ broken | |
Maps/BathHouse_Pool | added Music map property | ✘ broken | |
Maps/Beach | added DefaultCrabPotArea + LegendaryFishAreaCorners + Music + MusicIgnoreInRain map properties | ✘ broken | |
Maps/Beach-NightMarker | added DefaultCrabPotArea + DefaultFishingArea map properties | ✘ broken | |
Maps/BoatTunnel | changed map & tile properties to string, added DefaultCrabPotArea map property | ✘ broken | |
Maps/Cabin Maps/Cabin1 Maps/Cabin1_marriage Maps/Cabin2 Maps/Cabin2_marriage |
changed map & tile properties to string | ||
Maps/Caldera | added Music map property | ✘ broken | |
Maps/Club | added LocationContext map property | ✘ broken | |
Maps/Coop Maps/Coop2 |
changed map & tile properties to string | ||
Maps/Coop3 | changed map & tile properties to string, added AutoFeed map property | ✘ broken | |
Maps/Desert | added LocationContext map property | ✘ broken | |
Maps/ElliottHouse | added Music map property | ✘ broken | |
Maps/Farm Maps/Farm_Combat |
changed map & tile properties to string, updated farmhouse area for moveable farmhouse | ✘ corrupted visuals when farmhouse is moved | |
Maps/Farm_Fishing Maps/Farm_Foraging Maps/Farm_FourCorners |
changed map & tile properties to string, added DefaultFishingArea map property, updated farmhouse area for moveable farmhouse | ✘ broken | |
Maps/Farm_Greenhouse_Dirt Maps/Farm_Greenhouse_Dirt_FourCorners |
changed map & tile properties to string | ||
Maps/Farm_Island | changed map & tile properties to string, added DefaultFishingArea + DefaultCrabPotArea map properties, updated farmhouse area for moveable farmhouse | ✘ broken | |
Maps/Farm_Mining | changed map & tile properties to string, added DefaultFishingArea map property, updated farmhouse area for moveable farmhouse | ✘ broken | |
Maps/FarmHouse Maps/FarmHouse_Bedroom_Normal Maps/FarmHouse_Bedroom_Open Maps/FarmHouse_Cellar Maps/FarmHouse_ChildBed_0 Maps/FarmHouse_ChildBed_1 Maps/FarmHouse_CornerRoom_Add Maps/FarmHouse_CornerRoom_Remove Maps/FarmHouse_SouthernRoom_Add Maps/FarmHouse_SouthernRoom_Remove Maps/FarmHouse1 Maps/FarmHouse1_marriage Maps/FarmHouse2 Maps/FarmHouse2_marriage |
changed map & tile properties to string | ||
Maps/Forest | added DefaultFishingArea + FishingAreaCorners + LegendaryFishAreaCorners map properties | ✘ broken | |
Maps/Greenhouse | changed map & tile properties to string | ||
Maps/Hospital | added Music and MusicIgnoreInRain map properties | ✘ broken | |
Maps/Island_W | added LegendaryFishAreaCorners and FishingAreaCorners map property | ✘ broken | |
Maps/IslandFarmHouse | changed map & tile properties to string | ||
Maps/JojaMart | added Music and MusicContext map properties | ✘ broken | |
Maps/LeahHouse Maps/LeoTreeHouse |
added Music map property | ✘ broken | |
Maps/MarnieBarn Maps/Mine |
changed map & tile properties to string | ||
Maps/Mountain | changed map & tile properties to string, added LegendaryFishAreaCorners map property | ✘ broken | |
Maps/MovieTheater Maps/MovieTheaterScreen |
changed map & tile properties to string | ||
Maps/paths | added icon for custom wild tree spawn | ||
Maps/Saloon | added Music map property | ✘ broken | |
Maps/SandyHouse | added LocationContext and Music map properties | ✘ broken | |
Maps/ScienceHouse | added Music map property | ✘ broken | |
Maps/Sewer | added LegendaryFishAreaCorners map property | ✘ broken | |
Maps/Shed | added FloorIDs and WallIDs map properties | ✘ broken | |
Maps/SkullCave | added LocationContext map property | ✘ broken | |
Maps/spousePatios | changed map & tile properties to string | ||
Maps/Sunroom | changed map & tile properties to string, added Music and MusicIgnoreInRain properties | ✘ broken | |
Maps/Town | added LegendaryFishAreaCorners and multiple Music* map properties | ✘ broken | |
Maps/Mines/Volcano_SetPieces_32 | changed map & tile properties to string | ||
Maps/Woods | added Music and MusicIgnoreInRain map properties | ✘ broken |