Modding:Modder Guide/APIs/Content Packs: Difference between revisions
imported>RetroEdit m Replace deprecated <source> tags with <syntaxhighlight> tags |
imported>Margotbean rm underscores, shorten external link |
||
| (7 intermediate revisions by 6 users not shown) | |||
| Line 2: | Line 2: | ||
A '''content pack''' is a special type of mod that isn't run by SMAPI directly, but contains files your own mod can read. | A '''content pack''' is a special type of mod that isn't run by SMAPI directly, but contains files your own mod can read. | ||
Note that a custom content pack format is not required to provide integration with content mods; the most common method is to provide a [[Modding:Modder Guide/APIs/Content#Add a new asset|custom game asset]] that other mods (including Content Patcher packs) can edit. The advantage of custom assets is that both other C# mods and Content Patcher packs can edit them via the content pipeline, with the latter benefiting from convenient features such as tokens, conditional loading and targeted edits, removing the need to implement similar features in your mod. | |||
See the wiki page for [[Modding:Modder Guide/APIs/Content|loading and editing content]], as well as the external tutorial for [https://stardewmodding.wiki.gg/wiki/Tutorial:_Making_Framework_Mods making framework mods] for more info. The rest of this page details instructions for defining custom content packs formats. | |||
__TOC__ | __TOC__ | ||
==Content pack format== | ==Content pack format== | ||
A content pack is a folder containing a < | A content pack is a folder containing a <samp>manifest.json</samp> file which specifies your mod in its <samp>ContentPackFor</samp> field (see [[../Manifest|manifest]]). The format beyond that is up to you to define. For example, {{nexus mod|1915|Content Patcher}} requires a <samp>content.json</samp> file, but that's not validated by SMAPI itself. Instead, SMAPI provides an API you can use to read any other file you need from the content pack. | ||
See [[Modding:Content packs]] for more info about content packs. | See [[Modding:Content packs]] for more info about content packs. | ||
| Line 11: | Line 15: | ||
==Content pack API== | ==Content pack API== | ||
===Get owned content packs=== | ===Get owned content packs=== | ||
To get the content packs installed for your mod (including a < | To get the content packs installed for your mod (including a <samp>Manifest</samp> field with the content pack's [[Modding:Modder Guide/APIs/Manifest|full manifest info]]): | ||
<syntaxhighlight lang="c#"> | <syntaxhighlight lang="c#"> | ||
foreach(IContentPack contentPack in this.Helper.ContentPacks.GetOwned()) | foreach(IContentPack contentPack in this.Helper.ContentPacks.GetOwned()) | ||
| Line 24: | Line 28: | ||
===Check if a file exists=== | ===Check if a file exists=== | ||
You can check if a file exists in the content pack folder using < | You can check if a file exists in the content pack folder using <samp>HasFile</samp>. You can specify a relative path like <samp>data/content.json</samp>. | ||
<syntaxhighlight lang="c#"> | <syntaxhighlight lang="c#"> | ||
| Line 36: | Line 40: | ||
===Read a JSON file=== | ===Read a JSON file=== | ||
You can read a JSON file from a content pack folder into [[Modding:Modder Guide/APIs/Data#Data model|a data model]] (< | You can read a JSON file from a content pack folder into [[Modding:Modder Guide/APIs/Data#Data model|a data model]] (<samp>YourDataModel</samp> in the example below) using <samp>ReadJsonFile</samp>. You can specify a relative path like <samp>data/content.json</samp>. This will return <samp>null</samp> if the file doesn't exist. | ||
<syntaxhighlight lang="c#"> | <syntaxhighlight lang="c#"> | ||
| Line 43: | Line 47: | ||
===Write a JSON file=== | ===Write a JSON file=== | ||
You can write a JSON file in a content pack folder using < | You can write a JSON file in a content pack folder using <samp>WriteJsonFile</samp>, using a [[Modding:Modder Guide/APIs/Data#Data model|data model]] (<samp>YourDataModel</samp> in the example below). You can specify a relative path like <samp>data/content.json</samp> (subdirectories will be created automatically if needed). This will create the file if it doesn't exist, or overwrite it if it does. | ||
'''Note:''' this is best used for generated files. Overwriting the original files isn't recommended, since a bug in your mod which changes an original file might permanently break the content pack and require the player to reinstall it. | '''Note:''' this is best used for generated files. Overwriting the original files isn't recommended, since a bug in your mod which changes an original file might permanently break the content pack and require the player to reinstall it. | ||
| Line 53: | Line 57: | ||
===Read content asset=== | ===Read content asset=== | ||
You can read [[Modding:Modder Guide/APIs/Content|a content asset]] from the content pack folder using < | You can read [[Modding:Modder Guide/APIs/Content|a content asset]] from the content pack folder using <samp>LoadAsset</samp>. You can optionally specify a relative path to read from a subfolder. | ||
<syntaxhighlight lang="c#"> | <syntaxhighlight lang="c#"> | ||
Texture2D image = contentPack. | Texture2D image = contentPack.ModContent.Load<Texture2D>("image.png"); | ||
</syntaxhighlight> | </syntaxhighlight> | ||
If you need to pass an asset name to game code, you can use the < | If you need to pass an asset name to game code, you can use the <samp>GetActualAssetKey</samp> method: | ||
<syntaxhighlight lang="c#"> | <syntaxhighlight lang="c#"> | ||
tilesheet.ImageSource = contentPack.GetActualAssetKey("image.png"); | tilesheet.ImageSource = contentPack.GetActualAssetKey("image.png"); | ||
| Line 64: | Line 68: | ||
===Get translations=== | ===Get translations=== | ||
You can read translations from the content pack's < | You can read translations from the content pack's <samp>i18n</samp> folder. This is identical to the [[Modding:Modder Guide/APIs/Translation|translation API]], but accessed through <samp>contentPack.Translations</samp>: | ||
<syntaxhighlight lang="c#"> | <syntaxhighlight lang="c#"> | ||
string text = contentPack.Translation.Get("item-type.label"); | string text = contentPack.Translation.Get("item-type.label"); | ||
| Line 78: | Line 82: | ||
// create with given manifest fields | // create with given manifest fields | ||
IContentPack contentPack = this.Helper.ContentPacks. | IContentPack contentPack = this.Helper.ContentPacks.CreateTemporary( | ||
directoryPath: Path.Combine(this.Helper.DirectoryPath, "content-pack"), | directoryPath: Path.Combine(this.Helper.DirectoryPath, "content-pack"), | ||
id: Guid.NewGuid().ToString("N"), | id: Guid.NewGuid().ToString("N"), | ||
| Line 87: | Line 91: | ||
); | ); | ||
</syntaxhighlight> | </syntaxhighlight> | ||
[[ru:Модификации:Руководство мододела/API/Контент-паки]] | |||
[[zh:模组:制作指南/APIs/Content Packs]] | |||
Latest revision as of 05:16, 21 May 2026
- Get started
- Game fundamentals
- Test & troubleshoot
- Release
- API reference
- Basic SMAPI APIs:
- Advanced SMAPI APIs:
- Specific guides
A content pack is a special type of mod that isn't run by SMAPI directly, but contains files your own mod can read.
Note that a custom content pack format is not required to provide integration with content mods; the most common method is to provide a custom game asset that other mods (including Content Patcher packs) can edit. The advantage of custom assets is that both other C# mods and Content Patcher packs can edit them via the content pipeline, with the latter benefiting from convenient features such as tokens, conditional loading and targeted edits, removing the need to implement similar features in your mod.
See the wiki page for loading and editing content, as well as the external tutorial for making framework mods for more info. The rest of this page details instructions for defining custom content packs formats.
Content pack format
A content pack is a folder containing a manifest.json file which specifies your mod in its ContentPackFor field (see manifest). The format beyond that is up to you to define. For example, Content Patcher requires a content.json file, but that's not validated by SMAPI itself. Instead, SMAPI provides an API you can use to read any other file you need from the content pack.
See Modding:Content packs for more info about content packs.
Content pack API
Get owned content packs
To get the content packs installed for your mod (including a Manifest field with the content pack's full manifest info):
foreach(IContentPack contentPack in this.Helper.ContentPacks.GetOwned())
{
this.Monitor.Log($"Reading content pack: {contentPack.Manifest.Name} {contentPack.Manifest.Version} from {contentPack.DirectoryPath}");
}
Content packs are listed in load order, so they're already sorted for dependencies. For example, if content pack B requires A, they'll be listed in the order A → B.
As a note, this can be done as early as ModEntry, although mods often choose to perform this step in the GameLoad or SaveLoaded event.
Check if a file exists
You can check if a file exists in the content pack folder using HasFile. You can specify a relative path like data/content.json.
if (!contentPack.HasFile("content.json"))
{
// show 'required file missing' error
}
It is often a good idea to alert the player (and modders who may be using your mod) if the file is missing on deployment.
Read a JSON file
You can read a JSON file from a content pack folder into a data model (YourDataModel in the example below) using ReadJsonFile. You can specify a relative path like data/content.json. This will return null if the file doesn't exist.
YourDataModel data = contentPack.ReadJsonFile<YourDataFile>("content.json");
Write a JSON file
You can write a JSON file in a content pack folder using WriteJsonFile, using a data model (YourDataModel in the example below). You can specify a relative path like data/content.json (subdirectories will be created automatically if needed). This will create the file if it doesn't exist, or overwrite it if it does.
Note: this is best used for generated files. Overwriting the original files isn't recommended, since a bug in your mod which changes an original file might permanently break the content pack and require the player to reinstall it.
YourDataModel data = new YourDataModel();
contentPack.WriteJsonFile("content.json", data);
Read content asset
You can read a content asset from the content pack folder using LoadAsset. You can optionally specify a relative path to read from a subfolder.
Texture2D image = contentPack.ModContent.Load<Texture2D>("image.png");
If you need to pass an asset name to game code, you can use the GetActualAssetKey method:
tilesheet.ImageSource = contentPack.GetActualAssetKey("image.png");
Get translations
You can read translations from the content pack's i18n folder. This is identical to the translation API, but accessed through contentPack.Translations:
string text = contentPack.Translation.Get("item-type.label");
Create a fake content pack
In specialised cases, you can create a temporary content pack for a given directory path:
// create with random manifest data
IContentPack contentPack = this.Helper.ContentPacks.CreateFake(
directoryPath: Path.Combine(this.Helper.DirectoryPath, "content-pack"),
);
// create with given manifest fields
IContentPack contentPack = this.Helper.ContentPacks.CreateTemporary(
directoryPath: Path.Combine(this.Helper.DirectoryPath, "content-pack"),
id: Guid.NewGuid().ToString("N"),
name: "temporary content pack",
description: "...",
author: "...",
version: new SemanticVersion(1, 0, 0)
);