Modding:Modder Guide/APIs/Integrations

From Stardew Valley Wiki
< Modding:Modder Guide‎ | APIs
Revision as of 01:31, 28 May 2018 by Pathoschild (talk | contribs) (add intro and 'dependencies' section)
Jump to navigation Jump to search

Creating SMAPI mods SMAPI mascot.png


Modding:Index

A mod integration refers to two mods communicating or cooperating in some way. SMAPI provides two distinct features to support this.

Dependencies

You can define dependencies in your manifest.json file. These are other mods which are required to use this mod. SMAPI will load those mods first, and show a friendly message to the player if some dependencies are missing. See the manifest page for more info.

Mod-provided APIs

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:

  1. Add a normal class to your mod project with the methods and properties you want to expose.
    public class YourModApi
    {
        public string ExampleProperty { get; set; } = "Example value";
    
        public bool GetThing(string example)
        {
           return true;
        }
    }
    
    (You can use a constructor to initialise the API if desired.)
  2. Override GetApi in your mod's entry class and return an instance of your API:
       public override object GetApi()
       {
          return new YourModApi();
       }
    

That's it! SMAPI will get one instance of your API and cache it.

Notes:

  • GetApi is always called after Entry, 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 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.
  • Known issue: SMAPI doesn't currently support non-public API classes.

Using an API

You can use a mod-provided API by mapping it to an interface:

  1. 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.)
    internal interface ISomeModApi
    {
       bool GetThing(string example);
    }
    
  2. In your mod code (after Entry), you can get the API by specifying the interface you created in step 1, and the mod's unique ID:
    ISomeModApi api = helper.ModRegistry.GetApi<ISomeModApi>("other-mod-ID");
    if (api != null)
       bool result = api.GetThing("boop");
    

For a quick integration, you can also use reflection instead of creating an interface:

object api = helper.ModRegistry.GetApi("other-mod-id");
if (api != null)
   bool result = helper.Reflection.GetMethod(api, "GetThing").Invoke<bool>("boop");

Notes:

  • You can't call GetApi until all mods are initialised and their Entry methods called. You can use the GameEvents.FirstUpdateTick 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. GetApi will return null 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.