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

From Stardew Valley Wiki
Jump to navigation Jump to search
(copy from canimod.com with permission, dual-licensed CC BY-NC-SA for compatibility with wiki. Only author is Pathoschild.)
 
m (Text replacement - "tt>" to "samp>")
 
(17 intermediate revisions by 3 users not shown)
Line 1: Line 1:
<pre>
+
←[[Modding:Index|Index]]
---
 
layout: default
 
title: Updating a SMAPI mod
 
intro: >
 
  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
 
  <a href="https://en.wikipedia.org/wiki/Deprecation">deprecated</a> and supported
 
  long enough to let mods update at their own pace.
 
permalink: /for-devs/updating-a-smapi-mod
 
redirect_from:
 
    - /guides/updating-a-smapi-mod
 
---
 
  
## How to update your mod
+
{{Modder compatibility header}}
You don't need to comb through your code; SMAPI can tell you if you're using a deprecated interface:
+
This page explains how to update your SMAPI mod code for compatibility with SMAPI 1.9 (released alongside Stardew Valley 1.2 in April 2017) and 2.0 (released in October 2017).
  
1. Use the latest [SMAPI for developers](https://github.com/Pathoschild/SMAPI/releases) download.
+
==Overview==
  This will show all deprecation messages in the console:
+
===What's changing and how much does it impact mods?===
 +
[[File:SMAPI compatibility.png|thumb|SMAPI compatibility over time. The SMAPI 2.0 release in October 2017 appears as a small bump.]]
  
  > ![console message for a deprecated interface](images/updating-a-smapi-mod/deprecated-console.png)
+
The last major breaking change was in SMAPI 0.40 (April 2016). Since then 23 SMAPI releases were published with almost full backwards compatibility. SMAPI has matured significantly since version 0.40, and its APIs have converged towards better consistency. Older APIs have been [[wikipedia:Deprecation|deprecated]] with full support, but this introduces significant maintenance overhead. A few rarely-used APIs were dropped in SMAPI 1.9 (when Stardew Valley 1.2 broke many mods), and SMAPI 2.0 is the release which finally drops support for these old APIs.
  
2. When you look at the code, you'll see a deprecation warning with a hint of how to fix it:
+
Although this is a major change, significant effort was undertaken to minimise the impact on mods: (a) the APIs were supported for a long time with increasingly prominent warnings in the SMAPI console about their deprecation and removal; (b) dozens of pull requests were submitted to update affected mods; (c) unofficial updates were created for mods which haven't updated officially yet; and (d) the changes were actively communicated and documented to modders. This means that SMAPI 2.0 has a minimal impact on mod compatibility (see chart on the right).
  
  > ![intellisense for an obsolete property](images/updating-a-smapi-mod/deprecated-intellisense.png)
+
===How to update your mod===
 
+
You don't need to comb through your code manually. SMAPI can tell you if you're using a deprecated interface:
3. Optionally, you can refer to the following sections on how to replace specific interfaces.
 
  
## How deprecated interfaces are phased out
+
# Use the latest [https://smapi.io/ SMAPI for developers] download. This will show deprecation messages in the console:<br />[[File:Modding - updating deprecated SMAPI code - deprecation warnings.png]]
Deprecated interfaces are fully supported until their removal. They'll slowly move through these
+
# 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]]
phases:
+
# Optionally, you can refer to the following sections on how to replace specific interfaces.
  
severity          | description
+
==Major changes==
:---------------- | :----------
+
===Removed APIs===
_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.
+
The following APIs were removed in SMAPI 1.9 and 2.0.
_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.
+
{| class="wikitable"
 
+
|-
## Deprecated interfaces
+
! deprecated
 
+
! removed
### Overview
+
! old APIs
These are currently deprecated:
+
! replacement
 
+
|-
since  | interfaces                | severity | replacement
+
| 0.39.3
:----- | :------------------------ | :------- | :----------
+
| 1.9¹
1.0   | `Config` class           | _info_ | see _[mod configuration](#mod-configuration)_.
+
| <samp>SObject</samp> class
1.0   | `Mod.BaseConfigPath`      | _info_ | see _[mod configuration](#mod-configuration)_.
+
| reimplement if needed.
1.0   | `Mod.PathOnDisk`          | _info_ | see _[mod configuration](#mod-configuration)_ or use `this.Helper.DirectoryPath`.
+
|-
1.0   | `Mod.PerSaveConfigFolder` | _info_ | use [per-save JSON files](/for-devs/creating-a-smapi-mod-advanced-config) instead.
+
| 0.39.3
1.0   | `Mod.PerSaveConfigPath`  | _info_ | use [per-save JSON files](/for-devs/creating-a-smapi-mod-advanced-config) instead.
+
| 1.9¹
1.0   | `Mod.Entry(object[])`    | _info_ | see _[mod entry method](#mod-entry-method)_.
+
| <samp>Extensions.ToSingular(…)</samp>
1.1   | `Log` class               | _info_ | use the `this.Monitor.Log` mod method.
+
| use <samp>string.Join</samp>.
1.6   | `PlayerEvents.FarmerChanged` | _info_ | serves no purpose.
+
|-
1.6   | `PlayerEvents.LoadedGame` | _info_ | use `SaveEvents.AfterLoad`.
+
| 1.0
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¹
1.9   | `Command` class           | _info_ | use `this.Helper.ConsoleCommands`.
+
| <samp>Authour</samp> in <samp>manifest.json</samp>
1.10   | `GameEvents.Initialize` | _info_ | move any code into your `Entry` method.
+
| use <samp>Author</samp>.
1.10  | `GameEvents.LoadContent` | _info_ | move any code into your `Entry` method.
+
|-
 
+
| 1.0
These have been removed:
+
| 1.9¹
 
+
| <samp>Extensions</samp> class
deprecated | removed | interfaces | replacement
+
| reimplement if needed, or use an extensions library.
:--------- | :------ | :--------- | :----------
+
|-
0.39.3    | 1.9¹    | `SObject` class | reimplement if needed.
+
| 1.0
0.39.3    | 1.9¹    | `Extensions.ToSingular(…)` | use `string.Join`.
+
| 1.9¹
1.0        | 1.9¹    |  `Authour` in `manifest.json` | use `Author`.
+
| <samp>LogWriter</samp> class
1.0       | 1.9¹    | `Extensions` class | reimplement if needed, or use an extensions library.
+
| use <samp>this.Monitor.Log</samp>.
1.0        | 1.9¹    | `LogWriter` class | use `this.Monitor.Log`.
+
|-
1.0        | 1.9¹    | `SPlayer` class | use `Game1.player`.
+
| 1.0
1.1        | 1.9¹    | `Command.CallCommand(string)` | use `this.Helper.ConsoleCommands`.
+
| 1.9¹
1.1        | 1.9¹    | `Mod.Entry(ModHelper)` | change `ModHelper` to `IModHelper`.
+
| <samp>SPlayer</samp> class
1.5        | 1.9¹    | `Version` class | use `SemanticVersion`.
+
| use <samp>Game1.player</samp>.
1.5        | 1.9¹    | `Mod.Manifest` | use `Mod.ModManifest` <small>(changes type from `Manifest` to `IManifest`)</small>.
+
|-
1.5        | 1.9¹    | `Constants.Version` | use `Constants.ApiVersion` <small>(changes type from `Version` to `ISemanticVersion`)</small>.
+
| 1.0<br /><small><em>experimental API</em></small>
1.0<br /><small><em>experimental API</em></small> | 1.| `IConfigFile` and `ConfigFile` | reimplement if needed.
+
| 1.9¹
 +
| <samp>IConfigFile</samp> and <samp>ConfigFile</samp>
 +
| reimplement if needed.
 +
|-
 +
| 1.1
 +
| 1.9¹
 +
| <samp>Command.CallCommand(string)</samp>
 +
| use <samp>this.Helper.ConsoleCommands</samp>.
 +
|-
 +
| 1.1
 +
| 1.9¹
 +
| <samp>Mod.Entry(ModHelper)</samp>
 +
| change <samp>ModHelper</samp> to <samp>IModHelper</samp>.
 +
|-
 +
| 1.5
 +
| 1.9¹
 +
| <samp>Version</samp> class
 +
| use <samp>SemanticVersion</samp>.
 +
|-
 +
| 1.5
 +
| 1.9¹
 +
| <samp>Mod.Manifest</samp>
 +
| use <samp>Mod.ModManifest</samp> <small>(changes type from <samp>Manifest</samp> to <samp>IManifest</samp>)</small>.
 +
|-
 +
| 1.5
 +
| 1.9¹
 +
| <samp>Constants.Version</samp>
 +
| use <samp>Constants.ApiVersion</samp> <small>(changes type from <samp>Version</samp> to <samp>ISemanticVersion</samp>)</small>.
 +
|-
 +
| 1.0
 +
| 2.0
 +
| <samp>Config</samp> class
 +
| see [[#Mod configuration|mod configuration]].
 +
|-
 +
| 1.0
 +
| 2.0
 +
| <samp>Mod.BaseConfigPath</samp>
 +
| see [[#Mod configuration|mod configuration]].
 +
|-
 +
| 1.0
 +
| 2.0
 +
| <samp>Mod.PathOnDisk</samp>
 +
| see [[#Mod configuration|mod configuration]] or use <samp>this.Helper.DirectoryPath</samp>.
 +
|-
 +
| 1.0
 +
| 2.0
 +
| <samp>Mod.PerSaveConfigFolder</samp>
 +
| use [[Modding:Modder Guide/APIs/Config|per-save JSON files]] instead.
 +
|-
 +
| 1.0
 +
| 2.0
 +
| <samp>Mod.PerSaveConfigPath</samp>
 +
| use [[Modding:Modder Guide/APIs/Config|per-save JSON files]] instead.
 +
|-
 +
| 1.0
 +
| 2.0
 +
| <samp>Mod.Entry(object[])</samp>
 +
| see [[#Mod entry method|mod entry method]].
 +
|-
 +
| 1.1
 +
| 2.0
 +
| <samp>Log</samp> class
 +
| use the <samp>this.Monitor.Log</samp> mod method.
 +
|-
 +
| 1.6
 +
| 2.0
 +
| <samp>PlayerEvents.FarmerChanged</samp>
 +
| serves no purpose.
 +
|-
 +
| 1.6
 +
| 2.0
 +
| <samp>PlayerEvents.LoadedGame</samp>
 +
| use <samp>SaveEvents.AfterLoad</samp>.
 +
|-
 +
| 1.6
 +
| 2.0
 +
| <samp>TimeEvents.OnNewDay</samp>
 +
| unreliable and don't do what you think; use <samp>TimeEvents.AfterDayChanged</samp> or <samp>SaveEvents.BeforeSave</samp> instead.
 +
|-
 +
| 1.9
 +
| 2.0
 +
| <samp>Command</samp> class
 +
| use <samp>this.Helper.ConsoleCommands</samp>.
 +
|-
 +
| 1.10
 +
| 2.0
 +
| <samp>GameEvents.Initialize</samp><br /><samp>GameEvents.LoadContent</samp>
 +
| move any code into your <samp>Entry</samp> method.
 +
|-
 +
| 1.13
 +
| 2.0
 +
| <samp>GameEvents.GameLoaded</samp>
 +
| move any code into your <samp>Entry</samp> method.
 +
|-
 +
| 1.14
 +
| 2.0
 +
| <samp>TimeEvents.DayOfMonthChanged</samp><br /><samp>TimeEvents.SeasonOfYearChanged</samp><br /><samp>TimeEvents.YearOfGameChanged</samp>
 +
| unreliable and don't do what you think; use <samp>TimeEvents.AfterDayChanged</samp> or <samp>SaveEvents.BeforeSave</samp> instead.
 +
|}
  
 
<small>¹ Stardew Valley 1.2 broke many existing mods, so SMAPI 1.9 used the opportunity to remove the most rarely-used deprecated APIs.</small>
 
<small>¹ Stardew Valley 1.2 broke many existing mods, so SMAPI 1.9 used the opportunity to remove the most rarely-used deprecated APIs.</small>
  
### Migration guides
+
===Mod entry method===
This section provides more information for some migrations mentioned in the previous section.
+
''For the latest documentation, see [[Modding:Modder Guide/Get Started]].''
 
 
#### Mod entry method
 
_For the latest documentation, see [creating a SMAPI mod: writing your mod code](/for-devs/creating-a-smapi-mod#writing-your-mod-code)._
 
  
 
Change your mod's entry class from this:
 
Change your mod's entry class from this:
  
```c#
+
<syntaxhighlight lang="c#">
 
/// <summary>Initialise the mod.</summary>
 
/// <summary>Initialise the mod.</summary>
 
public override void Entry(params object[] objects)
 
public override void Entry(params object[] objects)
Line 95: Line 174:
 
     // your code
 
     // your code
 
}
 
}
```
+
</syntaxhighlight>
  
 
to this:
 
to this:
  
```c#
+
<syntaxhighlight lang="c#">
/// <summary>Initialise the mod.</summary>
+
/// <summary>The mod entry point, called after the mod is first loaded.</summary>
/// <param name="helper">Provides methods for interacting with the mod directory, such as read/writing a config file or custom JSON files.</param>
+
/// <param name="helper">Provides simplified APIs for writing mods.</param>
 
public override void Entry(IModHelper helper)
 
public override void Entry(IModHelper helper)
 
{
 
{
 
     // your code
 
     // your code
 
}
 
}
```
+
</syntaxhighlight>
  
#### Mod configuration
+
===Mod configuration===
_For the latest documentation, see [creating a SMAPI mod: configuration](/for-devs/creating-a-smapi-mod#configuration)._
+
''For the latest documentation, see [[Modding:Modder Guide/APIs/Config]].''
  
If you use `config.json`, it's much easier in 1.0.
+
If you use <samp>config.json</samp>, it's much easier in 1.0.
  
1. Find your subclass of `StardewModdingAPI.Config`, which probably looks something like this:
+
<ol>
 +
<li>Find your subclass of <samp>StardewModdingAPI.Config</samp>, which probably looks something like this:
  
  ```c#
+
<syntaxhighlight lang="c#">
  class SampleConfig : StardewModdingAPI.Config
+
class SampleConfig : StardewModdingAPI.Config
 +
{
 +
  public bool ExampleBoolean { get; set; }
 +
  public float ExampleFloat { get; set; }
 +
 
 +
  public override T GenerateDefaultConfig<T>()
 
   {
 
   {
       public bool ExampleBoolean { get; set; }
+
       this.ExampleBoolean = true;
       public float ExampleFloat { get; set; }
+
       this.ExampleFloat = 0.5;
 +
      return this as T;
 +
  }
 +
}
 +
</syntaxhighlight></li>
  
      public override T GenerateDefaultConfig<T>()
+
<li>Edit this class as follows:
      {
+
* Move default values into the constructor or property setters.
        this.ExampleBoolean = true;
+
* Remove <samp>StardewModdingAPI.Config</samp>.
        this.ExampleFloat = 0.5;
+
* Remove all <samp>override</samp> methods.
        return this as T;
+
</li>
      }
 
  }
 
  ```
 
  
2. Edit this class as follows:
+
<li>Your class should now look something like this:
  * 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:
+
<syntaxhighlight lang="c#">
 +
class SampleConfig
 +
{
 +
  public bool ExampleBoolean { get; set; } = true;
 +
  public float ExampleFloat { get; set; } = 0.5;
 +
}
 +
</syntaxhighlight>
  
  ```c#
+
or like this if you used a constructor:
  class SampleConfig
 
  {
 
      public bool ExampleBoolean { get; set; } = true;
 
      public float ExampleFloat { get; set; } = 0.5;
 
  }
 
  ```
 
  
   or like this if you used a constructor:
+
<syntaxhighlight lang="c#">
 +
class SampleConfig
 +
{
 +
   public bool ExampleBoolean { get; set; }
 +
  public float ExampleFloat { get; set; }
  
   ```c#
+
   public SampleConfig()
  class SampleConfig
 
 
   {
 
   {
       public bool ExampleBoolean { get; set; }
+
       this.ExampleBoolean = true;
       public float ExampleFloat { get; set; }
+
       this.ExampleFloat = 0.5;
 +
  }
 +
}
 +
</syntaxhighlight></li>
  
      public SampleConfig()
+
<li>In your <samp>Mod</samp> class, change anything that looks like this:
      {
 
        this.ExampleBoolean = true;
 
        this.ExampleFloat = 0.5;
 
      }
 
  }
 
  ```
 
4. In your `Mod` class, change anything that looks like this:
 
  
  ```
+
<syntaxhighlight lang="c#">
  var config = new SampleConfig().InitializeConfig(this.BaseConfigPath);
+
var config = new SampleConfig().InitializeConfig(this.BaseConfigPath);
  ```
+
</syntaxhighlight>
  
  to this:
+
to this:
  
  ```
+
<syntaxhighlight lang="c#">
  var config = helper.ReadConfig<SampleConfig>();
+
var config = helper.ReadConfig<SampleConfig>();
  ```
+
</syntaxhighlight></li>
  
5. If you use other methods, here's how to migrate them:
+
<li>If you use other methods, here's how to migrate them:
  
  before 1.0 | after 1.0
+
{| class="wikitable"
  :--------- | :--------
+
|-
  `new SampleConfig().GenerateDefaultConfig()`<br />`new SampleConfig().Instance()` | `new SampleConfig()`
+
! before 1.0
  `new SampleConfig().InitializeConfig(this.BaseConfigPath)`<br />`config.UpdateConfig()`<br />`config.LoadConfig(this.BaseConfigPath)`<br />`config.ReloadConfig()` | `helper.ReadConfig<SampleConfig>()`
+
! after 1.0
  `config.WriteConfig()| `helper.WriteConfig(config)`
+
|-
 +
| <samp>new SampleConfig().GenerateDefaultConfig()</samp><br /><samp>new SampleConfig().Instance()</samp>
 +
| <samp>new SampleConfig()</samp>
 +
|-
 +
| <samp>new SampleConfig().InitializeConfig(this.BaseConfigPath)</samp><br /><samp>config.UpdateConfig()</samp><br /><samp>config.LoadConfig(this.BaseConfigPath)</samp><br /><samp>config.ReloadConfig()</samp>
 +
| <samp>helper.ReadConfig<SampleConfig>()</samp>
 +
|-
 +
| <samp>config.WriteConfig()</samp>
 +
| <samp>helper.WriteConfig(config)</samp>
 +
|}
 +
</li>
 +
</ol>
  
For more information, see [creating a SMAPI mod: configuration](/for-devs/creating-a-smapi-mod#configuration).
+
For more information, see [[Modding:Modder Guide/APIs/Config]].
For help with more advanced configuration (including custom JSON files and per-save configuration),
 
see [advanced SMAPI mod configuration](/for-devs/creating-a-smapi-mod-advanced-config).
 
</pre>
 
  
 
[[Category:Modding]]
 
[[Category:Modding]]

Latest revision as of 18:48, 4 November 2021

Index

This page is for mod authors. Players: see Modding:Mod compatibility instead.

This page explains how to update your SMAPI mod code for compatibility with SMAPI 1.9 (released alongside Stardew Valley 1.2 in April 2017) and 2.0 (released in October 2017).

Overview

What's changing and how much does it impact mods?

SMAPI compatibility over time. The SMAPI 2.0 release in October 2017 appears as a small bump.

The last major breaking change was in SMAPI 0.40 (April 2016). Since then 23 SMAPI releases were published with almost full backwards compatibility. SMAPI has matured significantly since version 0.40, and its APIs have converged towards better consistency. Older APIs have been deprecated with full support, but this introduces significant maintenance overhead. A few rarely-used APIs were dropped in SMAPI 1.9 (when Stardew Valley 1.2 broke many mods), and SMAPI 2.0 is the release which finally drops support for these old APIs.

Although this is a major change, significant effort was undertaken to minimise the impact on mods: (a) the APIs were supported for a long time with increasingly prominent warnings in the SMAPI console about their deprecation and removal; (b) dozens of pull requests were submitted to update affected mods; (c) unofficial updates were created for mods which haven't updated officially yet; and (d) the changes were actively communicated and documented to modders. This means that SMAPI 2.0 has a minimal impact on mod compatibility (see chart on the right).

How to update your mod

You don't need to comb through your code manually. 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.

Major changes

Removed APIs

The following APIs were removed in SMAPI 1.9 and 2.0.

deprecated removed old APIs 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).
1.0 2.0 Config class see mod configuration.
1.0 2.0 Mod.BaseConfigPath see mod configuration.
1.0 2.0 Mod.PathOnDisk see mod configuration or use this.Helper.DirectoryPath.
1.0 2.0 Mod.PerSaveConfigFolder use per-save JSON files instead.
1.0 2.0 Mod.PerSaveConfigPath use per-save JSON files instead.
1.0 2.0 Mod.Entry(object[]) see mod entry method.
1.1 2.0 Log class use the this.Monitor.Log mod method.
1.6 2.0 PlayerEvents.FarmerChanged serves no purpose.
1.6 2.0 PlayerEvents.LoadedGame use SaveEvents.AfterLoad.
1.6 2.0 TimeEvents.OnNewDay unreliable and don't do what you think; use TimeEvents.AfterDayChanged or SaveEvents.BeforeSave instead.
1.9 2.0 Command class use this.Helper.ConsoleCommands.
1.10 2.0 GameEvents.Initialize
GameEvents.LoadContent
move any code into your Entry method.
1.13 2.0 GameEvents.GameLoaded move any code into your Entry method.
1.14 2.0 TimeEvents.DayOfMonthChanged
TimeEvents.SeasonOfYearChanged
TimeEvents.YearOfGameChanged
unreliable and don't do what you think; use TimeEvents.AfterDayChanged or SaveEvents.BeforeSave instead.

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

Mod entry method

For the latest documentation, see Modding:Modder Guide/Get Started.

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:Modder Guide/APIs/Config.

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:Modder Guide/APIs/Config.