模组:迁移至SMAPI 3.0
![]() |
仍需完善
该页面内容由于以下原因仍需进一步完善。
|
← 模组:目录
本页面说明了如何更新你的模组代码以兼容 SMAPI 3.0。另请参阅迁移到星露谷物语 1.4。
概述
有什么变化?
事件可以说是 SMAPI 中最重要、最直观的部分,但自 SMAPI 0.40 以来,它们基本上没有改变。此后,新的事件被有机地添加进来,但事件系统一直与 SMAPI 的其余部分是分开的——它们不一致,有一些奇怪的行为(比如关闭菜单时不会触发 MenuEvents.MenuChanged),无法通过与其他所有 API 相同的辅助类来使用,并且可用的事件中存在一些明显的遗漏。
SMAPI 3.0 就是修复所有这些问题的版本。此版本……
- 完全重写了事件引擎,使事件更高效,并实现了以前不可能的事件。
- 使事件更加一致:它们现在完全符合[.NET 设计指南](https://docs.microsoft.com/en-us/dotnet/standard/design-guidelines/event),拥有可预测且描述性的名称,具有一致的事件处理程序签名,以及清晰的文档。
- 所有事件现在都可以通过 `helper.Events` 访问,因此它们像其他任何 SMAPI API 一样可以被发现。
- 奇怪的行为和重叠的事件已被消除。
- 添加了许多新事件。
- 事件现在有了相关的事件参数。
- 每个模组现在都有自己的事件实例,以支持诸如模组消息定向等功能。
SMAPI 3.0 还增加了与星露谷物语 1.4 的兼容性,移除了所有已弃用的 API,并进行了下面列出的许多其他更改。
这是模组末日吗?
不。尽管这是一次重大更新,但我们付出了巨大的努力来最小化其影响:
- 旧事件在很长一段时间内都受到支持,并在 SMAPI 控制台中就其弃用和移除发出了越来越醒目的警告;
- 提交了拉取请求来更新受影响的开源模组;
- 为在 SMAPI 3.0 发布时尚未正式更新的模组创建了非官方更新;
- 积极地向模组作者沟通和记录了这些变更。
此外,当前的目标是在 SMAPI 3.0 发布前,为开源模组实现至少95%的兼容性。所有这些都意味着,尽管变更范围很大,但 3.0 版本对模组兼容性的影响应该是最小的。
如何更新你的模组
你不需要手动梳理代码。SMAPI 会告诉你是否正在使用已弃用的接口:
- 使用最新的面向开发者的 SMAPI下载。这将在控制台中显示弃用消息:

- 当你查看代码时,你会看到一个弃用警告,并附有如何修复它的提示:

- 你可以参考以下部分,了解如何替换特定的接口。
变更
模组构建包已更新
更新模组构建包以兼容 SMAPI 3.0。
模组加载时机提前
以前,模组是在第一个 UpdateTicking 事件发生前加载的,这对于一些更改(如拦截核心资产)来说太晚了。SMAPI 3.0 将加载时机提前了很多,在游戏完全初始化之前。不要在你的 Entry 方法中依赖像 Game1.objectInformation 这样的游戏字段已有有效值! 你可以改用 GameLaunched 事件。更多信息请参阅模组结构#模组入口。
例如,假设你有这样的代码:
public override void Entry(IModHelper helper)
{
this.Config = helper.ReadConfig<ModConfig>();
CommunityCenter communityCenter = (CommunityCenter)Game1.getLocationFromName("CommunityCenter");
this.VaultRoomID = communityCenter.getAreaNumberFromName("Vault");
}
该代码在 SMAPI 3.0 中会失败,因为此时还没有加载任何位置。此代码可以像这样重写:
public override void Entry(IModHelper helper)
{
this.Config = helper.ReadConfig<ModConfig>();
helper.Events.GameLoop.GameLaunched += this.OnGameLaunched;
}
private void OnGameLaunched(object sender, GameLaunchedEventArgs args)
{
CommunityCenter communityCenter = (CommunityCenter)Game1.getLocationFromName("CommunityCenter");
this.VaultRoomID = communityCenter.getAreaNumberFromName("Vault");
}
API 变更
| 旧 API | → | 新 API | 转换说明 |
|---|---|---|---|
| helper.GetContentPacks | → | helper.ContentPacks.GetOwned | 用法相同。 |
| helper.CreateTransitionalContentPack | → | helper.ContentPacks.CreateTemporary | 用法相同。(这是一个用于过渡到SMAPI 内容包的临时方法,但一些模组有永久使用它的场景。) |
| assetData.AsDictionary<T, T>().Set | → | assetData.AsDictionary<T, T>().Data | Set 方法引起了很多困惑,且用处有限。你可以改用 Data 字段直接访问字典。 |
| SemanticVersion.Build | → | SemanticVersion.PrereleaseTag | 用法相同。 |
事件变更
旧的事件在 SMAPI 3.0 中被移除了。以下是如何将它们转换为 this.Helper.Events 下的新事件。此列表仅显示 SMAPI 3.0 中的等效事件;完整列表请参阅模组作者指南中的“事件”。
清单文件版本格式
manifest.json 不再允许使用以下格式的版本:
"Version": {
"MajorVersion": 1,
"MinorVersion": 0,
"PatchVersion": 0,
"Build": "beta"
}
版本应改用标准字符串格式书写:
"Version": "1.0.0-beta"
版本格式
SMAPI 在格式化版本时不再省略 .0 补丁号。例如,控制台现在显示 SMAPI 3.0.0 而不是 3.0。这更符合标准,提高了与外部工具的兼容性,并减少了玩家的困惑。
这不影响大多数模组代码。如果你使用 ISemanticVersion.ToString() 并将其输出与硬编码的两位版本字符串进行比较,则可能需要更新你的代码。


沪公网安备 31011002002714 号