Line 5: |
Line 5: |
| __TOC__ | | __TOC__ |
| ==Content pack format== | | ==Content pack format== |
− | A content pack is a folder containing a <tt>manifest.json</tt> file which specifies your mod in its <tt>ContentPackFor</tt> field (see [[../Manifest|manifest]]). The format beyond that is up to you to define. For example, {{nexus mod|1915|Content Patcher}} requires a <tt>content.json</tt> 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. | + | 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 11: |
| ==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 <tt>Manifest</tt> field with the content pack's [[Modding:Modder Guide/APIs/Manifest|full manifest info]]): | + | 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]]): |
− | <source lang="c#"> | + | <syntaxhighlight lang="c#"> |
| foreach(IContentPack contentPack in this.Helper.ContentPacks.GetOwned()) | | foreach(IContentPack contentPack in this.Helper.ContentPacks.GetOwned()) |
| { | | { |
| this.Monitor.Log($"Reading content pack: {contentPack.Manifest.Name} {contentPack.Manifest.Version} from {contentPack.DirectoryPath}"); | | this.Monitor.Log($"Reading content pack: {contentPack.Manifest.Name} {contentPack.Manifest.Version} from {contentPack.DirectoryPath}"); |
| } | | } |
− | </source> | + | </syntaxhighlight> |
| + | |
| + | 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=== | | ===Check if a file exists=== |
− | {{SMAPI upcoming|3.0}}
| + | 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>. |
− | | |
− | You can check if a file exists in the content pack folder using <tt>HasFile</tt>. You can specify a relative path like <tt>data/content.json</tt>. | |
| | | |
− | <source lang="c#"> | + | <syntaxhighlight lang="c#"> |
| if (!contentPack.HasFile("content.json")) | | if (!contentPack.HasFile("content.json")) |
| { | | { |
| // show 'required file missing' error | | // show 'required file missing' error |
| } | | } |
− | </source> | + | </syntaxhighlight> |
| + | |
| + | 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=== | | ===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]] (<tt>YourDataModel</tt> in the example below) using <tt>ReadJsonFile</tt>. You can specify a relative path like <tt>data/content.json</tt>. This will return <tt>null</tt> if the file doesn't exist. | + | 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. |
| | | |
− | <source lang="c#"> | + | <syntaxhighlight lang="c#"> |
| YourDataModel data = contentPack.ReadJsonFile<YourDataFile>("content.json"); | | YourDataModel data = contentPack.ReadJsonFile<YourDataFile>("content.json"); |
− | </source> | + | </syntaxhighlight> |
| | | |
| ===Write a JSON file=== | | ===Write a JSON file=== |
− | You can write a JSON file in a content pack folder using <tt>WriteJsonFile</tt>, using a [[Modding:Modder Guide/APIs/Data#Data model|data model]] (<tt>YourDataModel</tt> in the example below). You can specify a relative path like <tt>data/content.json</tt> (subdirectories will be created automatically if needed). This will create the file if it doesn't exist, or overwrite it if it does. | + | 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. |
| | | |
− | <source lang="c#"> | + | <syntaxhighlight lang="c#"> |
| YourDataModel data = new YourDataModel(); | | YourDataModel data = new YourDataModel(); |
| contentPack.WriteJsonFile("content.json", data); | | contentPack.WriteJsonFile("content.json", data); |
− | </source> | + | </syntaxhighlight> |
| | | |
| ===Read content asset=== | | ===Read content asset=== |
− | You can read [[Modding:Modder Guide/APIs/Content|a content asset]] from the content pack folder using <tt>LoadAsset</tt>. You can optionally specify a relative path to read from a subfolder. | + | 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. |
− | <source lang="c#"> | + | <syntaxhighlight lang="c#"> |
− | Texture2D image = contentPack.LoadAsset<Texture2D>("image.png"); | + | Texture2D image = contentPack.ModContent.Load<Texture2D>("image.png"); |
− | </source> | + | </syntaxhighlight> |
| | | |
− | If you need to pass an asset name to game code, you can use the <tt>GetActualAssetKey</tt> method: | + | If you need to pass an asset name to game code, you can use the <samp>GetActualAssetKey</samp> method: |
− | <source lang="c#"> | + | <syntaxhighlight lang="c#"> |
| tilesheet.ImageSource = contentPack.GetActualAssetKey("image.png"); | | tilesheet.ImageSource = contentPack.GetActualAssetKey("image.png"); |
− | </source> | + | </syntaxhighlight> |
| | | |
| ===Get translations=== | | ===Get translations=== |
− | {{SMAPI upcoming|3.0}}
| + | 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#"> |
− | You can read translations from the content pack's <tt>i18n</tt> folder. This is identical to the [[Modding:Modder Guide/APIs/Translation|translation API]], but accessed through <tt>contentPack.Translations</tt>: | |
− | <source lang="c#"> | |
| string text = contentPack.Translation.Get("item-type.label"); | | string text = contentPack.Translation.Get("item-type.label"); |
− | </source> | + | </syntaxhighlight> |
| | | |
| ===Create a fake content pack=== | | ===Create a fake content pack=== |
| In specialised cases, you can create a temporary content pack for a given directory path: | | In specialised cases, you can create a temporary content pack for a given directory path: |
− | <source lang="c#"> | + | <syntaxhighlight lang="c#"> |
| // create with random manifest data | | // create with random manifest data |
− | IContentPack contentPack = this.Helper.ContentPack.CreateFake( | + | IContentPack contentPack = this.Helper.ContentPacks.CreateFake( |
| directoryPath: Path.Combine(this.Helper.DirectoryPath, "content-pack"), | | directoryPath: Path.Combine(this.Helper.DirectoryPath, "content-pack"), |
| ); | | ); |
| | | |
| // create with given manifest fields | | // create with given manifest fields |
− | IContentPack contentPack = this.Helper.ContentPack.CreateFake( | + | 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 84: |
Line 86: |
| version: new SemanticVersion(1, 0, 0) | | version: new SemanticVersion(1, 0, 0) |
| ); | | ); |
− | </source> | + | </syntaxhighlight> |
− | | |
− | {{modding guide footer
| |
− | |prev = [[Modding:Modder Guide/APIs|SMAPI reference]]
| |
− | |next =
| |
− | }}
| |