Changes

Jump to navigation Jump to search
+ mod-provided APIs in SMAPI 2.3
Line 810: Line 810:     
Note that game versions before 1.2.0 and some mod versions are non-standard (e.g. Stardew Valley 1.11 comes ''before'' 1.2). All SMAPI versions are standard.
 
Note that game versions before 1.2.0 and some mod versions are non-standard (e.g. Stardew Valley 1.11 comes ''before'' 1.2). All SMAPI versions are standard.
 +
 +
==Mod-provided APIs==
 +
{{SMAPI upcoming
 +
|version = 2.3
 +
|content = Mods can provide their own APIs to other mods, even without a dependency or assembly reference. This can be used to integrate mods, provide custom information, or provide new framework APIs beyond those offered by SMAPI itself.
 +
 +
===Providing an API===
 +
To provide an API for other mods to use:
 +
<ol>
 +
<li>Add a normal class to your mod project with the methods and properties you want to expose.
 +
<source lang="c#">
 +
internal class YourModApi
 +
{
 +
    public string ExampleProperty { get; set; } = "Example value";
 +
 +
    public bool GetThing(string example)
 +
    {
 +
      return true;
 +
    }
 +
}
 +
</source>
 +
(You can use a [https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/constructors constructor] to initialise the API if desired.)</li>
 +
<li>Override <tt>GetApi</tt> in your mod's entry class and return an instance of your API:
 +
<source lang="c#">
 +
  public override object GetApi()
 +
  {
 +
      return new YourModApi();
 +
  }
 +
</source></li>
 +
</ol>
 +
 +
That's it! SMAPI will get one instance of your API and cache it.
 +
 +
Notes:
 +
* <tt>GetApi</tt> is always called after <tt>Entry</tt>, so it's safe to pass in your mod's initialised fields.
 +
* Be careful when changing your API! If you make a breaking change, other mods may need an update before they can access your API again.
 +
* You can optionally add a public [https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/interface interface] to your API. If a mod directly references your mod DLL, they'll be able to use your interface instead of creating their own.
 +
 +
===Using an API===
 +
You can use a mod-provided API by mapping it to an [https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/interface interface]:
 +
<ol>
 +
<li>Create an interface with only the properties and methods you want to access. (If you directly reference the mod DLL and it provides a public API interface, you can use that instead.)
 +
<source lang="C#">
 +
internal interface ISomeModApi
 +
{
 +
  bool GetThing(string example);
 +
}
 +
</source></li>
 +
<li>In your mod code (after <tt>Entry</tt>), you can get the API by specifying the interface you created in step 1, and the [[#Basic fields|mod's unique ID]]:
 +
<source lang="c#">
 +
ISomeModApi api = helper.ModRegistry.GetApi<ISomeModApi>("other-mod-ID");
 +
if (api != null)
 +
  bool result = api.GetThing("boop");
 +
</source></li>
 +
</ol>
 +
 +
For a quick integration, you can also use reflection instead of creating an interface:
 +
<source lang="c#">
 +
object api = helper.ModRegistry.GetApi("other-mod-id");
 +
if (api != null)
 +
  bool result = helper.Reflection.GetMethod(api, "GetThing").Invoke<bool>("boop");
 +
</source>
 +
 +
Notes:
 +
* You can't call <tt>GetApi</tt> until all mods are initialised and their <tt>Entry</tt> methods called. You can use the <tt>GameEvents.FirstUpdateTick</tt> [[#Events|event]] if you need to access mod APIs early; this is guaranteed to happen after all mods are initialised.
 +
* You should always null-check APIs you consume. <tt>GetApi</tt> will return <tt>null</tt> if the API isn't available (e.g. because the mod isn't already installed or doesn't have one), or if an error occurs fetching the API.
 +
}}
    
[[Category:Modding]]
 
[[Category:Modding]]
translators
8,403

edits

Navigation menu