Jump to content

Modding:Objects: Difference between revisions

From Stardew Valley Wiki
imported>Pathoschild
imported>Pathoschild
split common info to Modding:Items
Line 1: Line 1:
← [[Modding:Index|Index]]
← [[Modding:Items|Items]]


This page explains how the game stores and parses item data. This is an advanced guide for mod developers.
This page explains how the game stores and parses item data. This is an advanced guide for mod developers.
==Introduction==
===Overview===
As of Stardew Valley 1.6, there are a few important features of Items in the game.
# Each item as a string ID (<samp>ItemId</samp>) and a globally-unique string ID (<samp>QualifiedItemId</samp>). The <samp>QualifiedItemId</samp> is auto-generated by prefixing the <samp>ItemId</samp> with the item type identifier.<p>For legacy reasons, the <samp>ItemId</samp> for vanilla items may not be globally unique. For example, Pufferfish (object 128) and Mushroom Box (bigcraftable 128) both have <samp>ItemId: 128</samp>. They can be distinguished by their <samp>QualifiedItemId</samp>, which are <samp>(O)128</samp> and <samp>(BC)128</samp> respectively.
# Each item type has an ''item data definition'' in the game code which tells the game how to handle it. [[#For C# mods|C# mods can add or edit definitions]]. Each definition has a unique prefix which is used in the qualified item IDs. The vanilla types are bigcraftables (<samp>(BC)</samp>), boots (<samp>(B)</samp>), farmhouse flooring (<samp>(FL)</samp>), furniture (<samp>(F)</samp>), hats (<samp>(H)</samp>), objects (<samp>(O)</samp>), pants (<samp>(P)</samp>), shirts (<samp>(S)</samp>), tools (<samp>(T)</samp>), wallpaper (<samp>(WP)</samp>), and weapons (<samp>(W)</samp>).</li>
# Custom items can now provide their own item texture, specified in a new field in the item data assets (see below). The item's <samp>ParentSheetIndex</samp> field is the index within that texture.
In other words, the four important fields for items are:
{| class="wikitable"
|-
! name
! type
! description
|-
| <samp>ItemId</samp>
| <samp>string</samp>
| A [[Modding:Common data field types#Unique string ID|unique string ID]] for this item which should be globally unique (but may not be for existing vanilla items for backwards compatibility). For example, <samp>128</samp> (vanilla item) or <samp>Example.ModId_Watermelon</samp> (custom item).
|-
| <samp>QualifiedItemId</samp>
| <samp>string</samp>
| A globally unique item key, like <samp>(O)128</samp> for a vanilla item or <samp>(O)Example.ModId_Watermelon</samp> for a custom one. This is auto-generated from the <samp>TypeDefinitionId</samp> and <samp>ItemId</samp> fields.
|-
| <samp>ParentSheetIndex</samp>
| <samp>int</samp>
| The item's sprite index within its spritesheet.
|-
| <samp>TypeDefinitionId</samp>
| <samp>string</samp>
| The ID for the data definition which defines the item, like <samp>(O)</samp> for an object. You can use <samp>ItemRegistry.type_*</samp> constants with this field:
<syntaxhighlight lang="c#">
if (item.TypeDefinitionId == ItemRegistry.type_object)
  ...
</syntaxhighlight>
|}
===Item references===
Item references throughout the game code now use the <samp>ItemId</samp> instead of the <samp>ParentSheetIndex</samp>. Since the <samp>ItemId</samp> is identical to the index for existing vanilla items, most data assets are unaffected by this change. For example, here's from <samp>Data/NPCGiftTastes</samp> with one custom item:
<syntaxhighlight lang="json">
"Universal_Like": "-2 -7 -26 -75 -80 72 395 613 634 635 636 637 638 724 459 Example.ModID_watermelon"
</syntaxhighlight>
Unless otherwise noted, unqualified item IDs will produce [[Modding:Items|objects]]. Some assets let you override that by specifying a <samp>QualifiedItemId</samp> value instead. For example, you can add <code>(O)128</code> 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:
{| class="wikitable"
|-
! data asset
! item ID format
|-
| [[Modding:Recipe data|<samp>Data/CraftingRecipes</samp><br /><samp>Data/CookingRecipes</samp>]]
| &#32;
* Ingredients: both supported.
* Output: set field 2 to the unqualified item ID, and field 3 to one of <samp>true</samp> (bigcraftable) or <samp>false</samp> (object).
|-
| [[Modding:Fruit_trees|<samp>Data/FruitTrees</samp>]]
| &#32;
* Fruit: both supported.
* Sapling: unqualified only.
|-
| [[Modding:Gift taste data|<samp>Data/NPCGiftTastes</samp>]]
| Both supported, but only <samp>(O)</samp> items can be gifted.
|}
===Item types===
These are the item types for which custom items can added/edited:
{| class="wikitable"
|-
! item type
! type identifier
! data asset
|-
| [[Modding:Items#Big_craftables|Big craftables]]
| <samp>(BC)</samp>
| <samp>Data/BigCraftables</samp><br /><small>Each item can set a custom texture name in the <samp>Texture</samp> field, and sprite index in the <samp>SpriteIndex</samp> field. The default texture is <samp>TileSheets/Craftables</samp>.</small>
|-
| [[Modding:Items#Boots|Boots]]
| <samp>(B)</samp>
| <samp>Data/Boots</samp><br /><small>Each item can set a custom texture name in fields 9 (item) and 7 (shoe color), and sprite index in fields 8 (item) and 5 (shoe color). The default textures are <samp>Maps/springobjects</samp> (item) and <samp>Characters/Farmer/shoeColors</samp> (shoe color).</small>
|-
| [[Modding:Crop data|Crops]]
| <small>''not technically an item type''</small>
| <samp>Data/Crops</samp><br /><small>Each crop can set a custom texture name and sprite index. The default texture is <samp>TileSheets/crops</samp>.</small>
|-
| [[Modding:Fish data|Fish (in fish tanks)]]
| <small>''not technically an item type''</small>
| <samp>Data/AquariumFish</samp><br /><small>Each fish can set a custom aquarium texture name in field 6, and sprite index in field 0. The default texture is <samp>LooseSprites/AquariumFish</samp>.</small>
|-
| [[Modding:Items#Furniture|Furniture]]
| <samp>(F)</samp>
| <samp>Data/Furniture</samp><br /><small>Each item can set a custom texture name in field 9, and sprite index in field 8. The default texture is <samp>TileSheets/furniture</samp>.</small>
|-
| [[Modding:Fruit_trees|Fruit Trees]]
| <small>''not technically an item type''</small>
| <samp>Data/FruitTrees</samp><br /><small>Each fruit tree can set a custom texture name and sprite index. The default texture is <samp>TileSheets/fruitTrees</samp>.</small>
|-
| [[Modding:Items#Hats|Hats]]
| <samp>(H)</samp>
| <samp>Data/Hats</samp><br /><small>Each item can set a custom texture name in field 7, and sprite index in field 6. The default texture is <samp>Characters/Farmer/hats</samp>.</small>
|-
| [[Modding:Items#Objects|Objects]]
| <samp>(O)</samp>
| <samp>Data/Objects</samp><br /><small>Each item can set a custom texture name in the <samp>Texture</samp> field, and sprite index in the <samp>SpriteIndex</samp> field. The default texture is <samp>Maps/springobjects</samp>.</small>
|-
| [[Modding:Items#Pants|Pants]]
| <samp>(P)</samp>
| <samp>Data/pantsData</samp><br /><small>Each item can set a custom texture name in the <samp>Texture</samp> field, and sprite index in the <samp>SpriteIndex</samp> field. The default texture is <samp>Characters/Farmer/pants</samp>.</small>
|-
| [[Modding:Items#Shirts|Shirts]]
| <samp>(S)</samp>
| <samp>Data/shirtData</samp><br /><small>Each item can set a custom texture name in the <samp>Texture</samp> field, and sprite index in the <samp>SpriteIndex</samp> field. The default texture is <samp>Characters/Farmer/shirts</samp>.</small>
<small>Shirt textures must be exactly 256 pixels wide, divided into two halves: the left half for the shirt sprites, and the right half for any dye masks. The remaining space can be left blank if needed.</small>
<pre>
      sprites      dye masks
  /-----------\  /-----------\
┌────────────────────────────────┐
│ ┌───┐┌───┐┌───┐┌───┐┌───┐┌───┐ │
│ │ 0 ││ 1 ││ 2 ││ a ││ b ││ c │ │
│ └───┘└───┘└───┘└───┘└───┘└───┘ │
│ ┌───┐┌───┐┌───┐┌───┐┌───┐┌───┐ │
│ │ 3 ││ 4 ││ 5 ││ d ││ e ││ f │ │
│ └───┘└───┘└───┘└───┘└───┘└───┘ │
└────────────────────────────────┘
</pre>
|-
| [[#Custom tools|Tools]]
| <samp>(T)</samp>
| <samp>Data/Tools</samp><br /><small>Each item can set a custom texture name in the <samp>Texture</samp> field, and sprite index in the <samp>SpriteIndex</samp> field. The vanilla tools use the <samp>TileSheets/Tools</samp> texture.</small>
|-
| Wallpaper & flooring
| <samp>(WP)</samp> and <samp>(FL)</samp>
| <samp>Data/AdditionalWallpaperFlooring</samp><br /><small>See [[Modding:Migrate to Stardew Valley 1.5.5#In the furniture catalogue|format docs]].</small>
|-
| [[Modding:Items#Weapons|Weapons]]
| <samp>(W)</samp>
| <samp>Data/Weapons</samp><br />
|}
When resolving an unqualified item ID like <samp>128</samp>, the game will get the first item type for which it exists in this order: object, big craftable, furniture, weapon, boots, hat, pants, shirt, tool, wallpaper, and floorpaper.
For each item type, the game has two files in its <samp>Content</samp> folder (which can be [[Modding:Editing XNB files#unpacking|unpacked for editing]]):
* a ''data asset'' for the text data for its items (names, descriptions, prices, etc);
* and a ''spritesheet'' for the in-game item icons.
Each item has a <samp>ParentSheetIndex</samp> field which is its position in the item type's spritesheet, starting at 0 in the top-left and incrementing by one as you move across and then down. For example, hat #0 is the first sprite in <samp>Characters/Farmer/hats</samp>. The <samp>ParentSheetIndex</samp> is also used to identify the item itself; since spritesheet indexes aren't unique (''e.g.,'' there's both a hat #10 and object #10), code needs to check the type too like <code>item is Weapon weapon && weapon.ParentSheetIndex == 4</code>.
===Get a list of items===
With [[Modding:Player Guide/Getting Started|SMAPI installed]], you can [[Modding:Console commands#Console commands|run the <samp>list_items</samp> console command]] in-game to view/search items and their IDs.
===Define a custom item===
You can define custom items for most vanilla item types using only [[Modding:Content Patcher|Content Patcher]] or [[Modding:Modder Guide/APIs/Content|SMAPI's content API]].
For example, this content pack adds a new Pufferchick item with a custom image, custom gift tastes, and a custom crop that produces it. Note that item references in other data assets like <samp>Data/Crops</samp> and <samp>Data/NPCGiftTastes</samp> use the item ID.
{{#tag:syntaxhighlight|<nowiki>
{
    "Format": "</nowiki>{{Content Patcher version}}<nowiki>",
    "Changes": [
        // add item
        {
            "Action": "EditData",
            "Target": "Data/Objects",
            "Entries": {
                "{{ModId}}_Pufferchick": {
                    "Name": "{{ModId}}_Pufferchick", // best practice to match the ID, since it's sometimes used as an alternate ID (e.g. in Data/CraftingRecipes)
                    "Displayname": "Pufferchick",
                    "Description": "An example object.",
                    "Type": "Seeds",
                    "Category": -74,
                    "Price": 1200,
                    "Texture": "Mods/{{ModId}}/Objects",
                    "SpriteIndex": 0
                }
            }
        },
        // add gift tastes
        {
            "Action": "EditData",
            "Target": "Data/NPCGiftTastes",
            "TextOperations": [
                {
                    "Operation": "Append",
                    "Target": ["Entries", "Universal_Love"],
                    "Value": "{{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": {
                "{{ModId}}_Pufferchick": {
                    "Seasons": [ "spring", "summer", "fall" ],
                    "DaysInPhase": [ 1, 1, 1, 1, 1 ],
                    "HarvestItemId": "{{ModId}}_Pufferchick",
                    "Texture": "Mods/{{ModId}}/Crops",
                    "SpriteIndex": 0
                }
            }
        },
        // add item + crop images
        {
            "Action": "Load",
            "Target": "Mods/{{ModId}}/Crops, Mods/{{ModId}}/Objects",
            "FromFile": "assets/{{TargetWithoutPath}}.png" // assets/Crops.png, assets/Objects.png
        }
    ]
}</nowiki>|lang=javascript}}
Most item data assets work just like <samp>Data/Objects</samp>. See also specific info for [[Modding:Fruit_trees|custom fruit trees]], [[Modding:Items#Tools|custom tools]], and [[Modding:Items#Weapons|melee weapons]].
===Error items===
Prior to 1.6, 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 Error Handler mod.
Stardew Valley 1.6 added comprehensive handling for such items. They'll be shown with a <samp>🛇</samp> sprite in inventory UIs and in-game, the name Error Item, and a description which indicates the missing item ID for troubleshooting.
===For C# mods===
<dl style="margin-left: 2em;">
<dt>Compare items</dt>
<dd>
Since <samp>Item.QualifiedItemId</samp> is globally unique, it can be used to simplify comparing items. For example:
{| class="wikitable"
|-
! old code
! new code
|-
|-
| <samp>item.ParentSheetIndex == 128</samp>
| <samp>item.QualifiedItemId == "(O)128"</samp>
|-
| <samp>IsNormalObjectAtParentSheetIndex(item, 128)</samp>
| <samp>item.QualifiedItemId == "(O)128"</samp>
|-
| <samp>!item.bigCraftable && item.ParentSheetIndex == 128</samp>
| <samp>item.QualifiedItemId == "(O)128"</samp>
|-
| <samp>item is Boots && item.ParentSheetIndex == 505</samp>
| <samp>item.QualifiedItemId == "(B)505"</samp>
|}
You can also use <samp>ItemRegistry.QualifyItemId</samp> to convert any item ID into a qualified one (if it's valid), and <samp>ItemRegistry.HasItemId</samp> to check if an item has a qualified or unqualified item ID.
Note that flavored item don't have their own ID. For example, Blueberry Wine and Wine are both <samp>(O)348</samp>. This affects flavored jellies, juices, pickles, and wines. In those cases you should still compare their separate fields like <samp>preservedParentSheetIndex</samp> (which actually contains the preserved item's <samp>ItemId</samp>, not its <samp>ParentSheetIndex</samp>).
</dd>
<dt>Construct items</dt>
<dd>When constructing items, specify the item's <samp>ItemId</samp> (''not'' <samp>QualifiedItemId</samp>). For example:
<syntaxhighlight lang="c#">
new Object("128", 1);                      // vanilla item
new Object("Example.ModId_Watermelon", 1); // custom item
</syntaxhighlight>
You can use a utility method to construct items from their <samp>QualifiedItemId</samp>:
<syntaxhighlight lang="c#">
Item item = ItemRegistry.Create("(B)505"); // Rubber Boots
</syntaxhighlight>
</dd>
<dt>Define custom item types</dt>
<dd>You can implement <samp>IItemDataDefinition</samp> for your own item type, and call <samp>ItemRegistry.AddTypeDefinition</samp> to register it. 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.</dd>
<dt>New <samp>Is*</samp> methods</dt>
<dd>1.6 added some <samp>StardewValley.Object</samp> methods to handle custom items in a generic way (and to let mods patch the logic):
{| class="wikitable"
|-
! method
! effect
|-
| <samp>object.IsBar()</samp>
| Whether the item is a [[Copper Bar|copper bar]], [[Iron Bar|iron bar]], [[Gold Bar|gold bar]], [[Iridium Bar|iridium bar]], or [[Radioactive Bar|radioactive bar]].
|-
| <samp>object.IsBreakableStone()</samp>
| Whether the item is a stone debris item which can be broken by a pickaxe.
|-
| <samp>object.IsFence()</samp>
| Whether the item is a [[Crafting#Fences|fence]].
|-
| <samp>object.IsFruitTreeSapling()</samp>
| Whether the item is a [[Fruit Trees|fruit tree]] sapling. This checks the <samp>Data\fruitTrees</samp> keys, so it works with custom fruit trees too.
|-
| <samp>object.IsHeldOverHead()</samp>
| Whether the player is shown holding up the item when it's selected in their toolbar. Default true (except for furniture).
|-
| <samp>object.IsIncubator()</samp>
| Whether the item can incubate [[Animals|farm animal]] eggs when placed in a building.
|-
| <samp>object.IsTapper()</samp>
| Whether the item is a [[Tapper|tapper]] or [[Heavy Tapper|heavy tapper]].
|-
| <samp>object.IsTeaSapling()</samp>
| Whether the item is a [[Tea Sapling|tea sapling]].
|-
| <samp>object.IsTwig()</samp>
| Whethere the item is a twig debris item.
|-
| <samp>object.IsWeeds()</samp>
| Whether the item is a weed debris item.
|}
</dd>
<dt>Work with item metadata</dt>
<dd>
1.6 added an <samp>ItemRegistry</samp> API for working with the new item system. Some of the provided methods are:
{| class="wikitable"
|-
! method
! effect
|-
| <samp>ItemRegistry.Create</samp>
| Create an item from its item ID (qualified or unqualified). If the ID doesn't match a real item, the optional <samp>allowNull</samp> parameter indicates whether to return null or an Error Item. For example:
<syntaxhighlight lang="c#">
Item item = ItemRegistry.Create("(B)505"); // Rubber Boots
</syntaxhighlight>
You can also get a specific value type instead of <samp>Item</samp> if needed. This will throw a descriptive exception if the type isn't compatible (e.g. you try to convert furniture to boots).
<syntaxhighlight lang="c#">
Boots item = ItemRegistry.Create<Boots>("(B)505"); // Rubber Boots
</syntaxhighlight>
|-
| <samp>ItemRegistry.Exists</samp>
| Get whether a qualified or unqualified item ID matches an existing item. For example:
<syntaxhighlight lang="c#">
bool pufferfishExist = ItemRegistry.Exists("(O)128");
</syntaxhighlight>
|-
| <samp>ItemRegistry.IsQualifiedId</samp>
| Get whether the given item ID is qualified with the type prefix (like <samp>(O)128</samp> instead of <samp>128</samp>).
|-
| <samp>ItemRegistry.QualifyItemId</samp>
| Get the unique qualified item ID given an unqualified or qualified one. For example:
<syntaxhighlight lang="c#">
string qualifiedId = ItemRegistry.QualifyItemId("128"); // returns (O)128
</syntaxhighlight>
|-
| <samp>ItemRegistry.GetMetadata</samp>
| This lets you get high-level info about an item:
<syntaxhighlight lang="c#">
// get info about Rubber Boots
ItemMetadata info = ItemRegistry.GetMetadata("(B)505");
// get item ID info
$"The item has unqualified ID {info.LocalId}, qualified ID {info.QualifiedId}, and is defined by the {info.TypeIdentifier} item data definition.";
// does the item exist in the data files?
bool exists = info.Exists();
</syntaxhighlight>
And get common parsed item data:
<syntaxhighlight lang="c#">
// get parsed info
ParsedItemData data = info.GetParsedData();
$"The internal name is {data.InternalName}, translated name {data.DisplayName}, description {data.Description}, etc.";
// draw an item sprite
Texture2D texture = data.GetTexture();
Rectangle sourceRect = data.GetSourceRect();
spriteBatch.Draw(texture, Vector2.Zero, sourceRect, Color.White);
</syntaxhighlight>
And create an item:
<syntaxhighlight lang="c#">
Item item = metadata.CreateItem();
</syntaxhighlight>
And get the type definition (note that this is very specialized, and you should usually use <samp>ItemRegistry</samp> instead to benefit from its caching and optimizations):
<syntaxhighlight lang="c#">
IItemDataDefinition typeDefinition = info.GetTypeDefinition();
</syntaxhighlight>
|-
| <samp>ItemRegistry.ResolveMetadata</samp>
| Equivalent to <samp>ItemRegistry.GetMetadata</samp>, except that it'll return null if the item doesn't exist.
|-
| <samp>ItemRegistry.GetData</samp>
| Get the parsed data about an item, or <samp>null</samp> if the item doesn't exist. This is a shortcut for <code>ItemRegistry.ResolveMetadata(id)?.GetParsedData()</code>; see the previous method for info on the parsed data.
|-
| <samp>ItemRegistry.GetDataOrErrorItem</samp>
| Equivalent to <samp>ItemRegistry.GetData</samp>, except that it'll return info for an Error Item if the item doesn't exist (e.g. for drawing in inventory).
|-
| <samp>ItemRegistry.GetErrorItemName</samp>
| Get a translated ''Error Item'' label.
|}
</dd>
</dl>
==Common data==
===Quality===
Each item has a quality level which (depending on the item type) may affect its price, health boost, etc. The valid qualities are:
{| class="wikitable"
|-
! quality
! value
! constant
|-
| normal
| <samp>0</samp>
| <samp>Object.lowQuality</samp>
|-
| silver
| <samp>1</samp>
| <samp>Object.medQuality</samp>
|-
| gold
| <samp>2</samp>
| <samp>Object.highQuality</samp>
|-
| iridium
| <samp>4</samp>
| <samp>Object.bestQuality</samp>
|}
===Categories===
Each item also has a category (represented by a negative integer). In code, you can get an item's category value from <samp>item.Category</samp>, and its translated name from <samp>item.getCategoryName()</samp>. Here are the valid categories:
{| class="wikitable sortable"
|-
! value
! internal constant
! [[#Context tags|context tag]]
! English translation
! Properties
|-
| -2
| <samp>Object.GemCategory</samp>
| <samp>category_gem</samp>
| Mineral
| Affected by [[Skills#Mining|Gemologist]] profession
|-
| -4
| <samp>Object.FishCategory</samp>
| <samp>category_fish</samp>
| Fish
| Affected by [[Skills#Fishing|Fisher]] and [[Skills#Fishing|Angler]] professions
|-
| -5
| <samp>Object.EggCategory</samp>
| <samp>category_egg</samp>
| Animal Product
| Affected by [[Skills#Farming|Rancher]] profession, can be used in a slingshot
|-
| -6
| <samp>Object.MilkCategory</samp>
| <samp>category_milk</samp>
| Animal Product
| Affected by [[Skills#Farming|Rancher]] profession
|-
| -7
| <samp>Object.CookingCategory</samp>
| <samp>category_cooking</samp>
| Cooking
|
|-
| -8
| <samp>Object.CraftingCategory</samp>
| <samp>category_crafting</samp>
| Crafting
| Is Placeable
|-
| -9
| <samp>Object.BigCraftableCategory</samp>
| <samp>category_big_craftable</samp>
|
| Is Placeable
|-
| -12
| <samp>Object.mineralsCategory</samp>
| <samp>category_minerals</samp>
| Mineral
| Affected by [[Skills#Mining|Gemologist]] profession
|-
| -14
| <samp>Object.meatCategory</samp>
| <samp>category_meat</samp>
| Animal Product
|
|-
| -15
| <samp>Object.metalResources</samp>
| <samp>category_metal_resources</samp>
| Resource
|
|-
| -16
| <samp>Object.buildingResources</samp>
| <samp>category_building_resources</samp>
| Resource
|
|-
| -17
| <samp>Object.sellAtPierres</samp>
| <samp>category_sell_at_pierres</samp>
|
|
|-
| -18
| <samp>Object.sellAtPierresAndMarnies</samp>
| <samp>category_sell_at_pierres_and_marnies</samp>
| Animal Product
| Affected by [[Skills#Farming|Rancher]] profession
|-
| -19
| <samp>Object.fertilizerCategory</samp>
| <samp>category_fertilizer</samp>
| Fertilizer
| Is Placeable, is always passable
|-
| -20
| <samp>Object.junkCategory</samp>
| <samp>category_junk</samp>
| Trash
|
|-
| -21
| <samp>Object.baitCategory</samp>
| <samp>category_bait</samp>
| Bait
| Can be attached to a fishing rod
|-
| -22
| <samp>Object.tackleCategory</samp>
| <samp>category_tackle</samp>
| Fishing Tackle
| Can be attached to a fishing rod, cannot stack
|-
| -23
| <samp>Object.sellAtFishShopCategory</samp>
| <samp>category_sell_at_fish_shop</samp>
|
|
|-
| -24
| <samp>Object.furnitureCategory</samp>
| <samp>category_furniture</samp>
| Decor
|
|-
| -25
| <samp>Object.ingredientsCategory</samp>
| <samp>category_ingredients</samp>
| Cooking
|
|-
| -26
| <samp>Object.artisanGoodsCategory</samp>
| <samp>category_artisan_goods</samp>
| Artisan Goods
| Affected by [[Skills#Farming|Artisan]] profession
|-
| -27
| <samp>Object.syrupCategory</samp>
| <samp>category_syrup</samp>
| Artisan Goods
| Affected by [[Skills#Foraging|Tapper]] profession
|-
| -28
| <samp>Object.monsterLootCategory</samp>
| <samp>category_monster_loot</samp>
| Monster Loot
|
|-
| -29
| <samp>Object.equipmentCategory</samp>
| <samp>category_equipment</samp>
|
|
|-
| -74
| <samp>Object.SeedsCategory</samp>
| <samp>category_seeds</samp>
| Seed
| Is Placeable, is always passable
|-
| -75
| <samp>Object.VegetableCategory</samp>
| <samp>category_vegetable</samp>
| Vegetable
| Affected by [[Skills#Farming|Tiller]] profession, can be used in a slingshot
|-
| -79
| <samp>Object.FruitsCategory</samp>
| <samp>category_fruits</samp>
| Fruit
| Affected by [[Skills#Farming|Tiller]] profession (if not foraged), can be used in a slingshot
|-
| -80
| <samp>Object.flowersCategory</samp>
| <samp>category_flowers</samp>
| Flower
| Affected by [[Skills#Farming|Tiller]] profession
|-
| -81
| <samp>Object.GreensCategory</samp>
| <samp>category_greens</samp>
| Forage
|
|-
| -95
| <samp>Object.hatCategory</samp>
| <samp>category_hat</samp>
|
|
|-
| -96
| <samp>Object.ringCategory</samp>
| <samp>category_ring</samp>
|
|
|-
| -97
| <samp>Object.bootsCategory</samp>
| <samp>category_boots</samp>
|
|
|-
| -98
| <samp>Object.weaponCategory</samp>
| <samp>category_weapon</samp>
|
|
|-
| -99
| <samp>Object.toolCategory</samp>
| <samp>category_tool</samp>
|
|
|-
| -100
| <samp>Object.clothingCategory</samp>
| <samp>category_clothing</samp>
|
|
|-
| -101
| <samp>Object.trinketCategory</samp>
| <samp>category_trinket</samp>
|
|
|-
| -102
| <samp>Object.booksCategory</samp>
|
|
|
|-
| -103
| <samp>Object.skillBooksCategory</samp>
|
|
|
|-
| -999
| <samp>Object.litterCategory</samp>
| <samp>category_litter</samp>
|
|
|}
{{collapse|Console commands|content=
With the {{nexus mod|3101|Console Code}} mod installed, you can run this command in the SMAPI console to see a list of objects by category:
<pre>cs return string.Join(`\n`, Game1.objectData.Keys.Select(key => new StardewValley.Object(key, 1)).GroupBy(item => item.Category, item => item.Name).OrderByDescending(p => p.Key).Select(p => $`{p.Key}: {string.Join(`, `, p.OrderBy(name => name))}`));</pre>
}}
===Context tags===
A ''context tag'' is an arbitrary data label like <code>category_gem</code> or <code>item_apple</code> attached to items. These provide metadata about items (''e.g.'' their color, quality, category, general groupings like alcohol or fish, etc), and may affect game logic (''e.g.'' machine processing).
See [[Modding:Context tags]] for more info.


==Objects==
==Objects==
Line 901: Line 216:
* Named [[buffs]] (like [[Oil of Garlic]], [[Life Elixir]], or [[Buffs#Tipsy|Tipsy]]) are implemented in code and can't be set in the food buff fields.
* Named [[buffs]] (like [[Oil of Garlic]], [[Life Elixir]], or [[Buffs#Tipsy|Tipsy]]) are implemented in code and can't be set in the food buff fields.
* The spritesheet and data have items that can't normally be found in the player inventory (like twigs and lumber), and some sprites have no corresponding item data. There are also multiple entries for ''weeds'' and ''stone'' corresponding to different sprites, but the player can only normally obtain one ''stone'' item (index 390) and no ''weeds'' items.
* The spritesheet and data have items that can't normally be found in the player inventory (like twigs and lumber), and some sprites have no corresponding item data. There are also multiple entries for ''weeds'' and ''stone'' corresponding to different sprites, but the player can only normally obtain one ''stone'' item (index 390) and no ''weeds'' items.
==Big craftables==
Big craftables are objects which can be placed in the world and are two tiles tall (instead of one like objects). See [[Modding:Big craftables]] for more info.
==Boots==
See [[Modding:Boots]] for more info.
==Pants==
See [[Modding:Pants]] for more info.
==Shirts==
See [[Modding:Shirts]] for more info.
==Furniture==
Furniture are decorative items which can be placed in the world, including chairs which the player can sit on.
See [[Modding:Furniture]] for more info.
==Hats==
Hats are items that can be equipped in the player's [[hats|hat]] slot.
See [[Modding:Hats]] for more info.
==Tools==
[[Tools]] are items that can be swung or used by the player to perform some effect (e.g. dig dirt, chop trees, etc).
See [[Modding:Tools]] for more info.
==Weapons==
[[Weapons]] are tools that can be used by the player to damage monsters.
See [[Modding:Weapons]] for more info.


==See also==
==See also==
* [[Modding:Index]] for related content like [[Modding:Crop data|crops]], [[Modding:Fish data|fish]], [[Modding:Gift taste data|gift tastes]], and [[Modding:Recipe data|recipes]]
* [[Modding:Index]] for related content like [[Modding:Crop data|crops]], [[Modding:Fish data|fish]], [[Modding:Gift taste data|gift tastes]], and [[Modding:Recipe data|recipes]]
==References==
<references />


==History==
==History==
Line 950: Line 230:


[[ru:Модификации:Объекты]]
[[ru:Модификации:Объекты]]
[[zh:模组:物品数据]]

Revision as of 17:35, 15 December 2024

← Items

This page explains how the game stores and parses item data. This is an advanced guide for mod developers.

Objects

Objects are the default type for items in inventories or placed in the world.

They have their data in Data/Objects (Data/ObjectInformation prior to 1.6), their icon sprites in Maps/springobjects, and their code in StardewValley.Object. See a table of sprites and their corresponding indexes.

Data format

The object data in Data/Objects consists of a string → model lookup, where...

  • The key is the unqualified item ID.
  • The value is a model with the fields listed below.

Basic info

field purpose
Name The internal item name.
DisplayName
Description
A tokenizable string for the item's in-game display name and description.
Type The item's general type, like Arch (artifact) or Minerals. The vanilla types are: Litter, Basic, Minerals, Quest, asdf, Crafting, Arch, fish, Cooking, Seeds, Ring, interactive
Category The item category.
Price (Optional) The price when sold by the player. This is not the price when bought from a shop. Default 0.

Appearance

field purpose
Texture The asset name for the texture containing the item's sprite. Defaults to Maps/springobjects.
SpriteIndex The sprite's index within the Texture, where 0 is the top-left sprite.

Edibility

field purpose
Edibility (Optional) A numeric value that determines how much energy (edibility × 2.5) and health (edibility × 1.125) is restored when this item is eaten. An item with an edibility of -300 can't be eaten, values from -299 to -1 reduce health and energy, and zero can be eaten but doesn't change health/energy. Default -300.
IsDrink (Optional) Whether to drink the item instead of eating it. Default false.
Buffs (Optional) The buffs to apply to the player when this item is eaten, if any. Default none.

This consists of a list of models with these fields:

field purpose
Id The unique string ID for this entry within the list.
Duration (Optional if BuffId is set) The buff duration measured in in-game minutes. This can be set to -2 for a buff that should last for the rest of the day.
BuffId (Optional) The unique ID of a buff from Data/Buffs to apply, or null to ignore Data/Buffs and set the ID to food or drink depending on the item's IsDrink field.

If a buff from Data/Buffs is applied and you also specify other fields, here's how the buff data is combined:

field result
Duration
IconTexture
SpriteIndex
GlowColor
If specified, the value in Data/Objects is used instead of the one in Data/Buffs. If omitted, defaults to the value from Data/Buffs.
CustomAttributes The values from both entries are combined (e.g. +1 speed in Data/Objects and +1 speed in Data/Buffs results in +2 speed).
IsDebuff The value in Data/Objects is used.
IsDebuff (Optional) Whether this buff counts as a debuff, so its duration should be halved when wearing a Sturdy Ring. Default false.
IconTexture (Optional) The asset name for the icon texture to load. This must contain one or more 16x16 icons in a grid of any size. If omitted, the game will draw a default icon based on the BuffId and CustomAttributes fields.
SpriteIndex (Optional) The buff's icon index within the IconTexture, where 0 is the top-left icon. Default 0.
GlowColor (Optional) The glow color to apply to the player. See color format. Default none.
CustomAttributes The custom buff attributes to apply, if any.

This consists of a model with any combination of these fields:

field purpose
FarmingLevel
FishingLevel
ForagingLevel
LuckLevel
MiningLevel
(Optional) An amount applied to the matching skill level while the buff is active. This can be negative for a debuff. Default 0.
Attack
Defense
MagneticRadius
MaxStamina
Speed
(Optional) An amount applied to the player's attack, defense, magnetic radius, maximum stamina, or speed while the buff is active. This can be negative for a debuff. Default 0.
CustomFields (Optional) The custom fields for this entry.

Geodes & artifact spots

field purpose
GeodeDrops
GeodeDropsDefaultItems
(Optional) The items that can be dropped when breaking open this item as a geode. Specifying either or both fields automatically enables geode behavior for this item.

You can specify one or both fields:

  • GeodeDrops can be set to the specific items to drop. Default none. This consists of a list of models with these fields:
    field purpose
    common fields See item spawn fields for the generic item fields supported by geode drops.

    If set to an item query which returns multiple items, one of them will be selected at random.

    Chance (Optional) The probability that the item will be dropped if the other fields match, as a decimal value between 0 (never) and 1 (always). Default 1.
    SetFlagOnPickup (Optional) The mail flag to set for the current player when this drop is picked up.
    Precedence (Optional) The order in which this entry should be checked, where lower values are checked first. This can be a negative value. Geode drops with the same precedence are checked in the order listed. Default 0.

    For consistency, vanilla drops mostly use these values:

    • -1000: special overrides like the Golden Helmet;
    • 0: normal items.
  • GeodeDropsDefaultItems chooses a predefined list of possible geode drops like clay, coal, copper, iridium, etc. Default false.

If both fields are specified, each geode will choose between them with an equal 50% chance. If GeodeDrops is specified but no entries match, the geode will use the GeodeDropsDefaultItems regardless of whether it's true.

ArtifactSpotChances (Optional) If this is an artifact (i.e. the Type field is Arch), the chance that it can be found by digging artifact spots in each location.

This consists of a string → model lookup, where:

  • the key is the internal location name;
  • the value is the probability the item will spawn if checked, as a decimal value between 0 (never) and 1 (always).

Context tags & exclusions

field purpose
ContextTags (Optional) The custom context tags to add for this item (in addition to the tags added automatically based on the other object data). This is formatted as a list; for example:
"ContextTags": [ "color_yellow", "fish_ocean", "fish_upright", "season_summer" ]
CanBeGivenAsGift (Optional) Whether this item can be gifted to NPCs. Default true.
CanBeTrashed (Optional) Whether this item can be trashed from the player's inventory. Default true.
ExcludeFromRandomSale (Optional) Whether to exclude this item from shops when selecting random items to sell. Default false.
ExcludeFromFishingCollection
ExcludeFromShippingCollection
(Optional) Whether to exclude this item from the fishing/shipping collection and their respective effect on the perfection score. Default false, in which case the normal requirements apply (e.g. artifacts are always excluded from the shipping collection).

Advanced

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

Notes

  • Prior to 1.6, items that have a number in index 6 (the "Crafting" field) showed buggy information in-game (e.g., Bean Hotpot prior to version 1.4). Items that had a number in the "Attack" field displayed the Attack icon and a number, but no description. It's unclear how these buffs work (if at all).
  • Adding custom items with the Arch type is inadvisable as it often leads to Artifact Spots becoming broken and not giving any items.
  • Named buffs (like Oil of Garlic, Life Elixir, or Tipsy) are implemented in code and can't be set in the food buff fields.
  • The spritesheet and data have items that can't normally be found in the player inventory (like twigs and lumber), and some sprites have no corresponding item data. There are also multiple entries for weeds and stone corresponding to different sprites, but the player can only normally obtain one stone item (index 390) and no weeds items.

See also

History

  • 1.6: Objects are now stored in Data/Objects rather than Data/ObjectInformation and have a new format.
  • 1.6: Field 4 of hats is now used for tags, rather than displayName.
  • 1.6: Display name field is now used for all languages.
  • 1.6: Added Texture & texture index fields to all object data.
  • 1.6: All types of items now use string IDs.