Difference between revisions of "Modding:Modder Guide/APIs"
Pathoschild (talk | contribs) (→Console commands: moved to Modding:Modder Guide/APIs/Console) |
Pathoschild (talk | contribs) |
||
Line 227: | Line 227: | ||
</dd> | </dd> | ||
</dl> | </dl> | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− |
Revision as of 01:18, 28 May 2018
- Get started
- Game fundamentals
- Test & troubleshoot
- Release
- API reference
- Basic SMAPI APIs:
- Advanced SMAPI APIs:
- Specific guides
SMAPI provides a number of APIs for mods to use. Click a section on the right or below for more details.
Basic APIs
page | summary |
---|---|
Manifest | A file needed for every mod or content pack which describes the mod, lists dependencies, enables update checks, etc. |
Events | Respond when something happens in the game (e.g. when a save is loaded), and often include details about what happened. |
Mod configuration | Let players edit a config.json file to configure your mod. |
Content | Load images/maps/data, and edit or replace the game's images/maps/data. |
Logging | Write messages to the SMAPI console and log. |
Reflection | Access fields, properties, or methods which are normally inaccessible. |
Multiplayer | Provides methods for supporting multiplayer. |
Translation | Translate your mod text into any game language. |
Utilities | Use constants, contextual information, date logic, and semantic versions. |
Advanced APIs
page | summary |
---|---|
Content packs | Let other modders provide files for your mod to read, which players can install like any other mod. |
Console commands | Add custom commands to the SMAPI console. |
Mod integrations | Get information about loaded mods, and integrate with mods using mod-provided APIs. |
Mod APIs
Content packs
A content pack is a sub-mod containing files your mod can read. These are installed just like a regular SMAPI mod, but don't do anything on their own. These must specify your mod in their manifest.json. See Modding:Content packs for more info about content packs.
SMAPI provides a method to get content packs loaded for your mod, and each content pack has an API you can use to read its files:
foreach(IContentPack contentPack in this.Helper.GetContentPacks())
{
// read content pack manifest
this.Monitor.Log($"Reading content pack: {contentPack.Manifest.Name} {contentPack.Manifest.Version}");
// read a JSON file
YourDataFile data = contentPack.ReadJsonFile<YourDataFile>("content.json");
// load an asset or image
Texture2D image = contentPack.LoadAsset<Texture2D>("image.png");
}
Logging
Your mod can write messages to the console window and log file using the monitor. For example, this code:
this.Monitor.Log("a trace message", LogLevel.Trace);
this.Monitor.Log("a debug message", LogLevel.Debug);
this.Monitor.Log("an info message", LogLevel.Info);
this.Monitor.Log("a warning message", LogLevel.Warn);
this.Monitor.Log("an error message", LogLevel.Error);
will log something like this:
[18:00:00 TRACE Mod Name] a trace message
[18:00:00 DEBUG Mod Name] a debug message
[18:00:00 INFO Mod Name] an info message
[18:00:00 WARN Mod Name] a warning message
[18:00:00 ERROR Mod Name] an error message
Note that LogLevel.Trace messages won't appear in the console window by default, they'll only be written to the log file. Trace messages are for troubleshooting details that are useful when someone sends you their error log, but which the player normally doesn't need to see. (You can see trace messages in the console if you install the "SMAPI for developers" version.)
Reflection
SMAPI provides an API for robustly accessing fields, properties, or methods you otherwise couldn't access, such as private fields. You can use it from helper.Reflection in your entry method, or this.Helper.Reflection elsewhere in your entry class.
Here are a few examples of what this lets you do:
// did you pet your pet today?
bool wasPet = this.Helper.Reflection.GetField<bool>(pet, "wasPetToday").GetValue();
// what is the spirit forecast today?
string forecast = this.Helper.Reflection
.GetMethod(new TV(), "getFortuneForecast")
.Invoke<string>();
// randomise the mines
if(Game1.currentLocation is MineShaft)
this.Helper.Reflection.GetField<Random>(Game1.currentLocation, "mineRandom").SetValue(new Random());
This works with static or instance fields/methods, caches the reflection to improve performance, and will throw useful errors automatically when reflection fails.
If you need to do more, you can switch to C#'s underlying reflection API:
FieldInfo field = this.Helper.Reflection.GetField<string>(…).FieldInfo;
MethodInfo method = this.Helper.Reflection.GetMethod(…).MethodInfo;
Mod registry
Your mod can get information about loaded mods, or check if a particular mod is loaded. (All mods are loaded by the time your mod's Entry(…) method is called.)
// check if a mod is loaded
bool isLoaded = this.Helper.ModRegistry.IsLoaded("UniqueModID");
// get manifest info for a mod (name, description, version, etc.)
IManifest manifest = this.Helper.ModRegistry.Get("UniqueModID");
// get manifest info for all loaded mods
foreach(IManifest manifest in this.Helper.ModRegistry.GetAll()) { … }
Multiplayer
The multiplayer API provides methods to support modding in a multiplayer context:
// get a unique multiplayer ID (e.g. for animal IDs)
int uniqueID = this.Helper.Multiplayer.GetNewID();
// get the locations being sync'd from the main player
foreach (GameLocation location in this.Helper.Multiplayer.GetActiveLocations())
Translation
The translation API lets you translate your mod into the player's current language, accounting for locale fallback automatically (e.g. if a translation isn't available in pt-BR.json, SMAPI will check pt.json and default.json). Translations can be a simple string, or they can include tokens to inject values into the translation.
- File structure
- SMAPI reads translations from JSON files in a structure like this:
YourMod/ i18n/ default.json es.json pt.json manifest.json YourMod.dll
The default.json file should contain a flat key→value lookup with your default text. Each key is case-insensitive, and can contain alphanumeric, underscore, hyphen, and dot characters. Feel free to add JavaScript comments to organise or document your translations. For example:
{ // example translations "item-type.label": "Item type", "item-type.fruit-tree": "{{fruitName}} tree", }
You can then add translation files for each language you want to support, by copying the default.json file and translating its values. Each translation file should have one of these file names:
Language File name Chinese zh.json German de.json Japanese ja.json Portuguese pt.json Russian ru.json Spanish es.json - Reading translations
- Once your i18n files are set up, you can read translations for the current locale:
// read a simple translation string label = helper.Translation.Get("item-type.label"); // read a translation which uses tokens (accepts an anonymous object, dictionary, or model) string text = helper.Translation.Get("item-type.fruit-tree", new { fruitName = "apple" });
The helper.Translate(…) method returns a fluent interface — you can keep calling methods on its return value to customise the translation. (See IntelliSense for a description of the available methods.) To get the text, simply assign it to a string:
// use fluent chain string text = helper.Translate(key).Tokens(tokens).Tokens(moreTokens).Assert();
If your code has a lot of translation calls, you can make it less verbose by aliasing the translation helper:
var i18n = helper.Translation; i18n.Get("item-type.fruit-tree", new { fruitName = i18n.Get("apple") });
- Tips for translators
-
- Save i18n files with UTF-8 encoding to avoid broken symbols in-game.
- Type
reload_i18n
into the SMAPI console and hit enter to reload translations without exiting the game. (If a mod internally cached a translation, it may not be updated.)