全站通知:

模组:迁移至SMAPI 2.0

来自星露谷物语维基
跳到导航 跳到搜索

模组:目录

当前页面编写的内容面向模组的开发者。模组玩家请阅读模组:模组兼容性

本页面说明了如何更新你的 SMAPI 模组代码,以兼容 SMAPI 1.9(于 2017 年 4 月随星露谷物语 1.2 发布)和 2.0(于 2017 年 10 月发布)。

概述

有哪些变化,对模组影响多大?

SMAPI 兼容性随时间的变化。2017 年 10 月发布的 SMAPI 2.0 表现为一个小的凸起。

上一次重大的破坏性更新是在 SMAPI 0.40(2016 年 4 月)中。自那以后,SMAPI 发布了 23 个版本,几乎都完全向后兼容。从 0.40 版本以来,SMAPI 已显著成熟,其 API 也已趋于更好的一致性。旧的 API 已被弃用,但仍提供全面支持,但这引入了巨大的维护开销。在 SMAPI 1.9(星露谷物语 1.2 破坏了许多模组时)中移除了一些很少使用的 API,而 SMAPI 2.0 则是最终放弃支持这些旧 API 的版本。

尽管这是一次重大更新,但我们付出了巨大的努力来最小化对模组的影响:(a) 这些 API 在很长一段时间内都受到支持,并在 SMAPI 控制台中就其弃用和移除发出了越来越醒目的警告;(b) 提交了数十个拉取请求来更新受影响的模组;(c) 为尚未正式更新的模组创建了非官方更新;(d) 积极地向模组作者沟通和记录了这些变更。这意味着 SMAPI 2.0 对模组兼容性的影响极小(见右图)。

如何更新你的模组

你不需要手动梳理代码。SMAPI 会告诉你是否正在使用已弃用的接口:

  1. 使用最新的 面向开发者的 SMAPI 下载。这将在控制台中显示弃用消息:
    Modding - updating deprecated SMAPI code - deprecation warnings.png
  2. 当你查看代码时,你会看到一个弃用警告,并附有如何修复它的提示:
    Modding - updating deprecated SMAPI code - deprecation intellisense.png
  3. 或者,你可以参考以下部分,了解如何替换特定的接口。

主要变更

已移除的 API

以下 API 在 SMAPI 1.9 和 2.0 中被移除。

弃用版本 移除版本 旧 API 替代方案
0.39.3 1.9¹ SObject 如果需要,请重新实现。
0.39.3 1.9¹ Extensions.ToSingular(…) 使用 string.Join
1.0 1.9¹ manifest.json 中的 Authour 使用 Author
1.0 1.9¹ Extensions 如果需要,请重新实现,或使用扩展库。
1.0 1.9¹ LogWriter 使用 this.Monitor.Log
1.0 1.9¹ SPlayer 使用 Game1.player
1.0
实验性 API
1.9¹ IConfigFileConfigFile 如果需要,请重新实现。
1.1 1.9¹ Command.CallCommand(string) 使用 this.Helper.ConsoleCommands
1.1 1.9¹ Mod.Entry(ModHelper) ModHelper 改为 IModHelper
1.5 1.9¹ Version 使用 SemanticVersion
1.5 1.9¹ Mod.Manifest 使用 Mod.ModManifest (类型从 Manifest 变为 IManifest
1.5 1.9¹ Constants.Version 使用 Constants.ApiVersion (类型从 Version 变为 ISemanticVersion
1.0 2.0 Config 请参阅模组配置
1.0 2.0 Mod.BaseConfigPath 请参阅模组配置
1.0 2.0 Mod.PathOnDisk 请参阅模组配置或使用 this.Helper.DirectoryPath
1.0 2.0 Mod.PerSaveConfigFolder 改用每个存档使用一个 JSON 文件
1.0 2.0 Mod.PerSaveConfigPath 改用每个存档使用一个 JSON 文件
1.0 2.0 Mod.Entry(object[]) 请参阅模组入口方法
1.1 2.0 Log 使用 this.Monitor.Log 模组方法。
1.6 2.0 PlayerEvents.FarmerChanged 无实际用途。
1.6 2.0 PlayerEvents.LoadedGame 使用 SaveEvents.AfterLoad
1.6 2.0 TimeEvents.OnNewDay 不可靠,且效果可能与你预想的不符;请改用 TimeEvents.AfterDayChangedSaveEvents.BeforeSave
1.9 2.0 Command 使用 this.Helper.ConsoleCommands
1.10 2.0 GameEvents.Initialize
GameEvents.LoadContent
将所有代码移动到你的 Entry 方法中。
1.13 2.0 GameEvents.GameLoaded 将所有代码移动到你的 Entry 方法中。
1.14 2.0 TimeEvents.DayOfMonthChanged
TimeEvents.SeasonOfYearChanged
TimeEvents.YearOfGameChanged
不可靠,且效果可能与你预想的不符;请改用 TimeEvents.AfterDayChangedSaveEvents.BeforeSave

¹ 星露谷物语 1.2 破坏了许多现有模组的兼容性,因此 SMAPI 1.9 借此机会移除了那些最不常用的已弃用 API。

模组入口方法

有关最新文档,请参阅入门指南

将你的模组入口类从此格式:

/// <summary>初始化模组。</summary>
public override void Entry(params object[] objects)
{
    // 你的代码
}

改为此格式:

/// <summary>模组入口点,在模组首次加载后调用。</summary>
/// <param name="helper">为编写模组提供简化的 API。</param>
public override void Entry(IModHelper helper)
{
    // 你的代码
}

模组配置

有关最新文档,请参阅配置 API

如果你使用 config.json,在 1.0 中会简单得多。

  1. 找到你的 StardewModdingAPI.Config 子类,它可能看起来像这样:
    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. 按如下方式编辑此类:
    • 将默认值移入构造函数或属性设置器中。
    • 移除 StardewModdingAPI.Config
    • 移除所有 override 方法。
  3. 你的类现在应该看起来像这样:
    class SampleConfig
    {
       public bool ExampleBoolean { get; set; } = true;
       public float ExampleFloat { get; set; } = 0.5;
    }
    

    或者,如果你使用了构造函数,则像这样:

    class SampleConfig
    {
       public bool ExampleBoolean { get; set; }
       public float ExampleFloat { get; set; }
    
       public SampleConfig()
       {
          this.ExampleBoolean = true;
          this.ExampleFloat = 0.5;
       }
    }
    
  4. 在你的 Mod 类中,将任何类似这样的代码:
    var config = new SampleConfig().InitializeConfig(this.BaseConfigPath);
    

    改为这样:

    var config = helper.ReadConfig<SampleConfig>();
    
  5. 如果你使用其他方法,可以这样迁移它们:
    1.0 之前 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)

更多信息,请参阅配置 API