Difference between revisions of "Modding:Migrate to SMAPI 2.0"

From Stardew Valley Wiki
Jump to navigation Jump to search
m (Pathoschild moved page User:Pathoschild/Updating deprecated SMAPI code to Modding:Updating deprecated SMAPI code: publish initial modding pages)
(fixes & cleanup)
Line 6: Line 6:
 
You don't need to comb through your code; SMAPI can tell you if you're using a deprecated interface:
 
You don't need to comb through your code; SMAPI can tell you if you're using a deprecated interface:
  
# Use the latest [https://github.com/Pathoschild/SMAPI/releases SMAPI for developers] download. This will show all deprecation messages in the console:<br />[[File:Modding - updating deprecated SMAPI code - deprecation warnings.png]]
+
# Use the latest [https://github.com/Pathoschild/SMAPI/releases SMAPI for developers] download. This will show deprecation messages in the console:<br />[[File:Modding - updating deprecated SMAPI code - deprecation warnings.png]]
 
# When you look at the code, you'll see a deprecation warning with a hint of how to fix it:<br />[[File:Modding - updating deprecated SMAPI code - deprecation intellisense.png]]
 
# When you look at the code, you'll see a deprecation warning with a hint of how to fix it:<br />[[File:Modding - updating deprecated SMAPI code - deprecation intellisense.png]]
 
# Optionally, you can refer to the following sections on how to replace specific interfaces.
 
# Optionally, you can refer to the following sections on how to replace specific interfaces.
Line 140: Line 140:
 
| <tt>SPlayer</tt> class
 
| <tt>SPlayer</tt> class
 
| use <tt>Game1.player</tt>.
 
| use <tt>Game1.player</tt>.
 +
|-
 +
| 1.0<br /><small><em>experimental API</em></small>
 +
| 1.9¹
 +
| <tt>IConfigFile</tt> and <tt>ConfigFile</tt>
 +
| reimplement if needed.
 
|-
 
|-
 
| 1.1
 
| 1.1
Line 165: Line 170:
 
| <tt>Constants.Version</tt>
 
| <tt>Constants.Version</tt>
 
| use <tt>Constants.ApiVersion</tt> <small>(changes type from <tt>Version</tt> to <tt>ISemanticVersion</tt>)</small>.
 
| use <tt>Constants.ApiVersion</tt> <small>(changes type from <tt>Version</tt> to <tt>ISemanticVersion</tt>)</small>.
|-
 
| 1.0<br /><small><em>experimental API</em></small>
 
| 1.9¹
 
| <tt>IConfigFile</tt> and <tt>ConfigFile</tt>
 
| reimplement if needed.
 
 
|}
 
|}
  
Line 178: Line 178:
  
 
===Mod entry method===
 
===Mod entry method===
''For the latest documentation, see [[Modding:Creating a SMAPI mod#Writing your mod code]].''
+
''For the latest documentation, see [[Modding:Creating a SMAPI mod#Write the code]].''
  
 
Change your mod's entry class from this:
 
Change your mod's entry class from this:

Revision as of 06:24, 4 May 2017

Index

In rare cases, SMAPI needs to change the interfaces it exposes to mods. (This doesn't happen often, because SMAPI strives to expose abstract interfaces that aren't tightly coupled to changes in the game.) When an interface does need to change, the old interface is deprecated and supported long enough to let mods update at their own pace.

How to update your mod

You don't need to comb through your code; SMAPI can tell you if you're using a deprecated interface:

  1. Use the latest SMAPI for developers download. This will show deprecation messages in the console:
    Modding - updating deprecated SMAPI code - deprecation warnings.png
  2. When you look at the code, you'll see a deprecation warning with a hint of how to fix it:
    Modding - updating deprecated SMAPI code - deprecation intellisense.png
  3. Optionally, you can refer to the following sections on how to replace specific interfaces.

How deprecated interfaces are phased out

Deprecated interfaces are fully supported until their removal. They'll slowly move through these phases:

severity description
notice The interface is deprecated, but mod authors have time to update their mods. Nothing is reported to the console, though deprecation messages are shown in the log file.
info Mods should no longer use the interface. Debug-level deprecation messages are shown in the console.
pending removal Mods should no longer use the interface. Warning-level deprecation messages in the console indicate the mod will break soon if it doesn't update.

The interface will then be removed entirely.

Deprecated interfaces

These are currently deprecated:

since interfaces severity replacement
1.0 Config class info see mod configuration.
1.0 Mod.BaseConfigPath info see mod configuration.
1.0 Mod.PathOnDisk info see mod configuration or use this.Helper.DirectoryPath.
1.0 Mod.PerSaveConfigFolder info use per-save JSON files instead.
1.0 Mod.PerSaveConfigPath info use per-save JSON files instead.
1.0 Mod.Entry(object[]) info see mod entry method.
1.1 Log class info use the this.Monitor.Log mod method.
1.6 PlayerEvents.FarmerChanged info serves no purpose.
1.6 PlayerEvents.LoadedGame info use SaveEvents.AfterLoad.
1.6 TimeEvents.OnNewDay info unreliable and doesn't do what you think; use TimeEvents.DayOfMonthChanged to detect a day change, and SaveEvents.BeforeSave + SaveEvents.AfterSave to detect saves.
1.9 Command class info use this.Helper.ConsoleCommands.
1.10 GameEvents.Initialize info move any code into your Entry method.
1.10 GameEvents.LoadContent info move any code into your Entry method.

These have been removed:

deprecated removed interfaces replacement
0.39.3 1.9¹ SObject class reimplement if needed.
0.39.3 1.9¹ Extensions.ToSingular(…) use string.Join.
1.0 1.9¹ Authour in manifest.json use Author.
1.0 1.9¹ Extensions class reimplement if needed, or use an extensions library.
1.0 1.9¹ LogWriter class use this.Monitor.Log.
1.0 1.9¹ SPlayer class use Game1.player.
1.0
experimental API
1.9¹ IConfigFile and ConfigFile reimplement if needed.
1.1 1.9¹ Command.CallCommand(string) use this.Helper.ConsoleCommands.
1.1 1.9¹ Mod.Entry(ModHelper) change ModHelper to IModHelper.
1.5 1.9¹ Version class use SemanticVersion.
1.5 1.9¹ Mod.Manifest use Mod.ModManifest (changes type from Manifest to IManifest).
1.5 1.9¹ Constants.Version use Constants.ApiVersion (changes type from Version to ISemanticVersion).

¹ Stardew Valley 1.2 broke many existing mods, so SMAPI 1.9 used the opportunity to remove the most rarely-used deprecated APIs.

Migration guides

This section provides more information for some migrations mentioned in the previous section.

Mod entry method

For the latest documentation, see Modding:Creating a SMAPI mod#Write the code.

Change your mod's entry class from this:

/// <summary>Initialise the mod.</summary>
public override void Entry(params object[] objects)
{
    // your code
}

to this:

/// <summary>The mod entry point, called after the mod is first loaded.</summary>
/// <param name="helper">Provides simplified APIs for writing mods.</param>
public override void Entry(IModHelper helper)
{
    // your code
}

Mod configuration

For the latest documentation, see Modding:Creating a SMAPI mod#Configuration.

If you use config.json, it's much easier in 1.0.

  1. Find your subclass of StardewModdingAPI.Config, which probably looks something like this:
    class SampleConfig : StardewModdingAPI.Config
    {
       public bool ExampleBoolean { get; set; }
       public float ExampleFloat { get; set; }
    
       public override T GenerateDefaultConfig<T>()
       {
          this.ExampleBoolean = true;
          this.ExampleFloat = 0.5;
          return this as T;
       }
    }
    
  2. Edit this class as follows:
    • Move default values into the constructor or property setters.
    • Remove StardewModdingAPI.Config.
    • Remove all override methods.
  3. Your class should now look something like this:
    class SampleConfig
    {
       public bool ExampleBoolean { get; set; } = true;
       public float ExampleFloat { get; set; } = 0.5;
    }
    

    or like this if you used a constructor:

    class SampleConfig
    {
       public bool ExampleBoolean { get; set; }
       public float ExampleFloat { get; set; }
    
       public SampleConfig()
       {
          this.ExampleBoolean = true;
          this.ExampleFloat = 0.5;
       }
    }
    
  4. In your Mod class, change anything that looks like this:
    var config = new SampleConfig().InitializeConfig(this.BaseConfigPath);
    

    to this:

    var config = helper.ReadConfig<SampleConfig>();
    
  5. If you use other methods, here's how to migrate them:
    before 1.0 after 1.0
    new SampleConfig().GenerateDefaultConfig()
    new SampleConfig().Instance()
    new SampleConfig()
    new SampleConfig().InitializeConfig(this.BaseConfigPath)
    config.UpdateConfig()
    config.LoadConfig(this.BaseConfigPath)
    config.ReloadConfig()
    helper.ReadConfig<SampleConfig>()
    config.WriteConfig() helper.WriteConfig(config)

For more information, see Modding:Creating a SMAPI mod#Configuration.