← README
This document helps mod authors update their content packs for newer versions of Content Patcher.
See the main README for other info.
- Does this page affect me as a player?
-
No, this is only for content pack authors. Existing content packs should work fine.
- Are Content Patcher updates backwards-compatible?
-
Yes, even content packs written for Content Patcher 1.0.0 should still work. Content Patcher uses your
Format
field to convert the content pack to the latest version if needed (without changing the actual files). - Do I need to update my content packs?
-
Usually your content packs will work indefinitely without manual updates. Game changes may sometimes break content packs (though Content Patcher will try to rewrite those too).
However, using an old
Format
version has some major disadvantages. Your content pack...- Won't have access to newer features.
- May have legacy behavior that doesn't match the current docs.
- May increase startup time or cause in-game lag. Rewriting code for compatibility is sometimes complicated and inefficient, so it's much faster if the code is already updated instead.
- May have more bugs. For example, a content pack for
Format
version 1.0 has dozens of automated migrations applied, which increases the chance that something will be migrated incorrectly.
Migrating to the latest format when you update the content pack is strongly encouraged.
- How do I update my content pack?
-
Just set the
Format
field to the latest version shown in the author guide, then review the sections below for any changes you need to make. If a version isn't listed on this page, there's nothing else to change for that version. - Why does my content pack show "reported warnings when applying runtime migration 2.0.0" in the SMAPI console?
-
Your content pack has a
Format
version from before Stardew Valley 1.6, so Content Patcher tried to migrate your content pack to the new asset format and failed.You can fix it by:
- Setting
"Format": "2.0.0"
in yourcontent.json
. - Updating your content pack to the latest Content Patcher and Stardew Valley format (see below).
- Setting
Tip
Feel free to ask on Discord if you need help!
These changes only apply when you set the Format
version in your content.json
to the listed
version or higher. See release notes for a full list of changes.
Released 22 May 2024.
-
"Action": "Load"
patches now apply to localized asset names only if they have localized forms in the base game folder.For example, this patch will now always load
Characters/Toddler
, and not a localized variant likeCharacters/Toddler.fr-FR
:{ "Action": "Load", "Target": "Characters/Toddler", "FromFile": "assets/toddler.png" }
This should have no effect on most content packs, besides fixing various issues with some edits for non-English players.
Released 19 March 2024.
-
See migrate to Stardew Valley 1.6 for content changes in the game update.
-
Load
patches have a newPriority
field. It's optional, but you can improve mod compatibility by using it when relevant. -
CustomLocations
is now deprecated. You should add custom locations to the newData/Locations
asset in Stardew Valley 1.6 instead.For example, if you have a custom location like this:
"CustomLocations": [ { "Name": "Custom_ExampleMod_AbigailCloset", "FromMapFile": "assets/abigail-closet.tmx" } ]
You can now add it to the game directly like this:
"Changes": [ // add map { "Action": "Load", "Target": "Maps/{{ModId}}_AbigailCloset", "FromFile": "assets/abigail-closet.tmx" }, // add location { "Action": "EditData", "Target": "Data/Locations", "Entries": { "{{ModId}}_AbigailCloset": { "CreateOnLoad": { "MapPath": "Maps/{{ModId}}_AbigailCloset" }, "FormerLocationNames": [ "Custom_ExampleMod_AbigailCloset" ] } } } ]
The game uses a standard unique string ID format for the location name. In the example above, we use the new name format (
{{ModId}}_AbigailCloset
) and add the old name (Custom_ExampleMod_AbigailCloset
) to theFormerLocationNames
field so the location will be migrated automatically for current players.Content Patcher will replace
{{ModId}}
automatically with your mod's manifestUniqueId
.Known limitations:
- You can't migrate TMXL Map Toolkit locations directly to Data/Locations. If you need to support migrations from TMXL,
you can continue using
CustomLocations
which still supports specifying TMXL locations. You can then editData/Locations
to edit the data added for your location.
- You can't migrate TMXL Map Toolkit locations directly to Data/Locations. If you need to support migrations from TMXL,
you can continue using
Released 27 February 2022.
- The
Enabled
field is no longer supported. You can useWhen
conditions instead.
Released 31 October 2021.
- The
Spouse
token no longer includes roommates. If you want to check for both roommate and spouse, you can use{{Merge: {{Roommate}}, {{Spouse}}}}
to match the previous behavior. - Some tokens return values in a different order to match the game order. This should have no
effect on most content packs, unless they use
valueAt
with any of these tokens:HasActiveQuest
,HasCaughtFish
,HasDialogueAnswer
,HasFlag
,HasProfession
, andHasSeenEvent
.
Released 07 March 2021.
- The
Enabled
field no longer allows tokens. You should useWhen
for conditional logic instead.
Released 06 February 2021.
- The
Weather
token now returns weather for the current location context (i.e. island or valley) by default. You can use{{Weather: Valley}}
to match the previous behavior.
Released 12 September 2020.
-
Using the
FromFile
field with anEditData
patch is no longer supported. This worked differently thanFromFile
on any other patch type and often caused confusion, so it's been deprecated since 1.16.This has no effect on using
FromFile
with a non-EditData
patch, or onEditData
patches which don't useFromFile
.If you have a patch like this:
// in content.json { "Action": "EditData", "Target": "Characters/Dialogue/Abigail", "FromFile": "assets/abigail.json" } // assets/abigail.json { "Entries": { "4": "Oh, hi.", "Sun_17": "Hmm, interesting..." } }
You can migrate it to this:
// in content.json { "Action": "Include", "FromFile": "assets/abigail.json" } // assets/abigail.json { "Changes": [ { "Action": "EditData", "Target": "Characters/Dialogue/Abigail", "Entries": { "4": "Oh, hi.", "Sun_17": "Hmm, interesting..." } } ] }
Released 16 August 2020.
-
Patch updates on location change: using
LocationName
orIsOutdoors
as a condition/token no longer automatically updates the patch when the player changes location. You can add this patch field to enable that:"Update": "OnLocationChange"
(This is part of the migration to realtime content updates, since all tokens will soon update live.)
Released 04 July 2020.
-
Token search syntax: you could previously search some tokens by passing the value as an input argument like
{{Season: Spring}}
. That should now be written like{{Season |contains=Spring}}
, which works with all tokens.The change affects all tokens except
HasFile
,HasValue
,Hearts
,Lowercase
/Uppercase
,Query
,Random
,Range
,Round
Relationship
,SkillLevel
, and mod-provided tokens (which all use input arguments for a different purpose).That also affects conditions:
"When": { "Season: Spring": "true" // should be "Season |contains=Spring": "true" }
Note that conditions like this aren't affected:
// still okay! "When": { "Season": "Spring" }
-
Random pinned keys: the
Random
token allows an optional pinned key. The previous format was{{Random: choices | pinned-key}}
; that should be changed to{{Random: choices |key=pinned-key}}
.
Released 08 May 2019.
- The
ConfigSchema
field changed:AllowValues
is no longer required. If you omit it, the config field will allow any value.- If you omit
Default
, the default is now blank instead of the firstAllowValues
value.
Released 08 December 2018.
- The
Weather
token now returnsWind
on windy days instead ofSun
.
- README for other info
- Ask for help