行 1: |
行 1: |
| {{模组:制作指南/header}} | | {{模组:制作指南/header}} |
− | {{Stub|页面严重过时}}
| + | |
− | 要为游戏创建 SMAPI 模组 ?教程就在这儿。要使用模组, 请参阅 [[模组: 使用指南/入门|使用指南]] 。要创建 内容包模组 ,请参阅 [[ 模组:Content Patcher]]。
| + | '''如果您是第一次制作 模组''' 请参阅 [[模组: 目录#创建模组]] 来了解 C# 模组和 内容包模组 之间差异的简短描述。 |
| + | |
| + | 您想使用 C# 创建“SMAPI 模组 ”吗?”本指南适合您! |
| | | |
| ==介绍== | | ==介绍== |
| ===什么是 SMAPI 模组?=== | | ===什么是 SMAPI 模组?=== |
− | SMAPI 模组 使用 改装 接口来扩展游戏逻辑。 可以在 游戏中发生某些情 况 时 做出响应 (例如 ,将 对象放置在世界中),定期运行代码(例如每个更新周期一次),更改游戏的资源和数据等。SMAPI 模组使用 C # 编写,使用 .NET Framework 和 Stardew Valley 将 XNA / MonoGame 用于游戏 逻辑(绘制到屏幕 , 用户输入等)。 | + | SMAPI 模组使用 [https://smapi.io/ SMAPI] 编辑 接口来扩展游戏逻辑。 当 游戏中发生某些 事 情时(例如 当一个 对象 被 放置在世界中 时 ) ,该模组可以做出响应 ,定期运行代码(例如每个更新周期 运行 一次),更改游戏的资源和数据等。SMAPI 模组 是 使用 .NET 的 C# 编写 的 , 游戏 使用 MonoGame 运行 逻辑(绘制到屏幕 、 用户输入等) 。 |
| + | |
| + | .NET 的另一种语言 Visual Basic 也可以用于编写模组,如果您了解该语言的对应语法即可使用它。得益于 .NET 新版本的特性,从游戏版本 1.5.5 开始使用该语言编写模组也可以直接跨平台运行,社区中已经存在使用该语言的模组并且运行正常,也许您正在运行它们。本文中会提及一些代码示例 。 |
| | | |
| ===为什么模组使用 SMAPI?=== | | ===为什么模组使用 SMAPI?=== |
| SMAPI 可以做许多事情,例如: | | SMAPI 可以做许多事情,例如: |
− | | + | # 将 你的 模组加载到游戏中。 如果 没有 SMAPI 来 加载代码模组 ,则不可能实现它们 。 |
− | # 将模组加载到游戏中。没有 SMAPI 就无法 加载代码模组。 | + | # 提供接口和事件,以 原本无法实现的 方式与游戏 进行交 互。 例如 游戏资源 或 数据 更改、 玩家配置 、翻译、 反 射 等 的简化接口 。这些内容将在指南后面介绍。 |
− | # 提供接口和事件, 能够 以 其他 方式与游戏互 动 。 有一些简化的接口,可用于更改 游戏资源/ 数据 , 玩家配置 ,转换, 反 映 等。这些内容将在 本 指南 的 后面 部分 介绍。 | + | # 加载时重写模组以实现 跨平台兼容 性。 这 让您而 不必担心游戏在 Linux/Mac/Windows 版本之间的差异。 |
− | # 在 跨平台兼容 时进行重构, 这 样一来就 不必担心游戏在 Linux/Mac/Windows 版本之间的差异。 | + | # 重 写 模组 来 更新它 。SMAPI 可 检测并修复 常见情况下因 游戏更新 而损 坏的模组代码。 |
− | # 重 构 模组 以 更新它 。在常见情况下,SMAPI 会 检测并修复游戏更新 所破 坏的模组代码。 | + | # 拦截错误。如果模组崩溃或 导致 错误,SMAPI 将拦截错误,在控制台窗口中显示错误详细信息,并在大多数情况下自动恢复游戏。这意味着 模组不会意外导致 游戏崩溃,并且可以更轻松地 排除 错误。 |
− | # 拦截错误。如果模组崩溃或 发生 错误,SMAPI 将拦截 该 错误,在控制台窗口中显示错误详细信息,并 且 在大多数情况下自动恢复游戏。这意味着 减少 游戏 意外 崩溃,并且可以更轻松地 解决 错误。 | + | # 提供更新检查。当 模组 有新版本可用时,SMAPI 会自动提醒玩家。 |
− | # 提供更新检查。当有新版本可用时,SMAPI 会自动提醒玩家。 | + | # 提供兼容性检查。SMAPI 会自动检测模组何时不兼容,并在导致问题之前将其禁用, 这样玩家就不会遇到损坏的 游戏。 |
− | # 提供兼容性检查。SMAPI 会自动检测模组何时不兼容,并在 它 导致问题之前将其禁用, 以防止 游戏 爆炸 。 | |
| | | |
| ===我能制作一个模组吗?=== | | ===我能制作一个模组吗?=== |
| 是的!本指南将帮助你逐步创建一个简单的模组。然后你可以继续学习,让它做您想做的事即可。 | | 是的!本指南将帮助你逐步创建一个简单的模组。然后你可以继续学习,让它做您想做的事即可。 |
| + | |
| 如果你是编程新手,许多模组开发人员开始时几乎没有或完全没有编程经验。如果你下定决心,当然可以沿途学习,但是您应该为陡峭的学习曲线做好准备。刚开始时不要太过于自信,弄清楚它的时候,最好从一个小的模组开始。一开始很容易变得不知所措并放弃。模组社区非常热情,所以不要害怕问问题! | | 如果你是编程新手,许多模组开发人员开始时几乎没有或完全没有编程经验。如果你下定决心,当然可以沿途学习,但是您应该为陡峭的学习曲线做好准备。刚开始时不要太过于自信,弄清楚它的时候,最好从一个小的模组开始。一开始很容易变得不知所措并放弃。模组社区非常热情,所以不要害怕问问题! |
| | | |
行 25: |
行 29: |
| | | |
| ===我可以不使用 SMAPI 来制作模组吗?=== | | ===我可以不使用 SMAPI 来制作模组吗?=== |
− | 当然。许多的 SMAPI 模组支持 [[模组:内容包|内容包]],可以让你提供它们所使用的 JSON 文本文件、图像等。例如,你可以 [[模组:Content Patcher|使用 Content Patcher]] 来编辑游戏的贴图并且不需要任何编程技术。本指南的其余部分是关于创建新的 SMAPI 模组的。有关内容包,请参阅 [[模组:Content Patcher]] (或模组的文档(如果为其 他mod 创建内容包)). | + | 当然。许多的 SMAPI 模组支持 [[模组:内容包|内容包]],可以让你提供它们所使用的 JSON 文本文件、图像等。例如,你可以 [[模组:Content Patcher|使用 Content Patcher]] 来编辑游戏的贴图并且不需要任何编程技术。本指南的其余部分是关于创建新的 SMAPI 模组的。有关内容包,请参阅 [[模组:Content Patcher]] (或模组的文档(如果为其 他模组 创建内容包)). |
| | | |
| ===我在哪里可以得到帮助?=== | | ===我在哪里可以得到帮助?=== |
− | <span id="help"></span>星露谷 模组社区 欢迎你的到来. Feel free to ask for help in [[Modding:Community#Discord|#making-mods on the Stardew Valley Discord]]. | + | <span id="help"></span>星露谷 官方聊天室 欢迎你的到来 :[https://stardewvalleywiki.com/Modding:Community#Discord Stardew Valley Discord] |
| | | |
| ==开始== | | ==开始== |
行 34: |
行 38: |
| 由于模组是用 C# 编写的,因此最好先熟悉它。无需记住所有内容,但是掌握基础知识(例如字段、方法、变量和类)将使其他所有内容都变得更加容易。 | | 由于模组是用 C# 编写的,因此最好先熟悉它。无需记住所有内容,但是掌握基础知识(例如字段、方法、变量和类)将使其他所有内容都变得更加容易。 |
| | | |
− | 一些有用的资源: | + | 一些有用的资源 : |
− | * [https://docs.microsoft.com/en-us/dotnet/csharp/quick-starts/ ''C# 快速 学习''] 通过交互式 示例讲解C#的 基础知识。 | + | * [https://docs.microsoft.com/en-us/dotnet/csharp/quick-starts/ ''C# 快速 开始''] 通过交互式 学习 C# 基础知识。 |
− | * [https://mva.microsoft.com/en-us/training-courses/c-fundamentals-for-absolute-beginners-16169 ''C# 绝对初学者的基础知识''] 视频指南将引导您完成 C # 从基本概念到事件驱动 的 编程(这是 SMAPI 模组经常使用的 内容)。 | + | * [https://mva.microsoft.com/en-us/training-courses/c-fundamentals-for-absolute-beginners-16169 ''C# Fundamentals for Absolute Beginners''] 是一个 视频指南 , 将引导您完成 C#, 从基本概念到事件驱动编程(这是 SMAPI 模组 最常用的)。 |
| + | * 已经知道如何编程? 请访问 [https://learnxinyminutes.com/docs/csharp/ LearnXinYMinutes] 快速了解 C# 语法和概念。 |
| + | |
| + | SMAPI 经常使用的 几个概念 |
| + | * [https://learn.microsoft.com/en-us/dotnet/csharp/fundamentals/types/generics ''泛型''] |
| + | * [https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/events/''基于事件的编程''] |
| + | * 对于序列化,SMAPI 通常使用 [https://www.newtonsoft.com/json ''NewtonSoft''] |
| | | |
| ===要求=== | | ===要求=== |
− | 在你开始之前: | + | 在你开始之前 : |
| # 熟悉 [[模组:使用指南/入门|模组的使用]],本指南的其余部分假定你已经熟悉使用模组。 | | # 熟悉 [[模组:使用指南/入门|模组的使用]],本指南的其余部分假定你已经熟悉使用模组。 |
| # 安装游戏 | | # 安装游戏 |
| # 安装 [[模组:使用指南/入门#安装SMAPI|SMAPI]] | | # 安装 [[模组:使用指南/入门#安装SMAPI|SMAPI]] |
| # 安装开发环境 | | # 安装开发环境 |
− | #* 在 Linux 上:安装 [http://www.monodevelop.com/ MonoDevelop] | + | #* 在 Linux 上:安装 [http://www.monodevelop.com/ MonoDevelop] 或 [https://www.jetbrains.com/rider/ Rider] |
− | #* 在 Mac 上:安装 [https://visualstudio.microsoft.com/vs/mac/ Visual Studio for Mac]. (This is a rebranded MonoDevelop.) | + | #* 在 Mac 上:安装 [https://visualstudio.microsoft.com/vs/mac/ Visual Studio for Mac] (这是一个重新命名的 MonoDevelop ) |
− | #* 在 Windows 上:安装 [https://visualstudio.microsoft.com/vs/community/ Visual Studio Community]. 在 安装程序 中的 工作负载 中 选择 .NET 桌面开发 | + | #* 在 Windows 上:安装 [https://visualstudio.microsoft.com/vs/community/ Visual Studio Community] ,当 安装程序 询问 工作负载 时, 选择 “.NET 桌面开发 ” |
| + | # 安装 [https://dotnet.microsoft.com/en-us/download/dotnet/6.0 NET 6.0 SDK](x64版本,也可以直接在 Visual Studio Community 单个组件中选择) |
| | | |
− | 如果 你 不熟悉 Visual Studio (on Windows/Mac) 或者 MonoDevelop (on Linux), [[模组:IDE 参考]] 解释了如何完成本指南所需的重要工作 。 | + | 如果不熟悉 Visual Studio (Windows/Mac ) 或者 MonoDevelop (Linux),在 [[模组:IDE 参考]] 页面 解释了如何完成本指南所需的重要工作 |
| | | |
− | ==创建一个基 础的 模组== | + | ==创建一个基 本 模组== |
− | ===快速 开始=== | + | ===快速 启动=== |
− | 如果 你 有足够的经验 来 跳过本教程, 则此部分 的 简 要 概述如下 : | + | 如果 您 有足够的经验 可以 跳过本教程, 以下是本节 的 摘 要: |
− | {{collapse|快速开始|content=  | + | {{collapse| 展开以查看 快速开始|content=  |
− | # 创建一个 空的 C#类库 项目 | + | # 创建一个 C#类库 项目 (注意不要选择成 .NET Framework 的那个,或者你可以使用另一种语言) |
− | # 目标框架选择 .NET Framework 4.5 或者 4.5.1, 建议使用 4.5.2 | + | # 目标框架选择 .NET 6.0 |
− | # 参考 [https://smapi.io/package/readme <samp>Pathoschild.Stardew.ModBuildConfig</samp> NuGet package] 根据要在其上编译模组的平台自动添加正确的引用。 | + | # 添加 [https://smapi.io/package/readme <samp>Pathoschild.Stardew.ModBuildConfig</samp>] NuGet 包 |
− | # 创建一个 <samp>ModEntry</samp> 类, 该类 将 <samp>StardewModdingAPI.Mod</samp> 子类化 | + | # 创建一个 <samp>ModEntry</samp> 类,将 它继承自 <samp>StardewModdingAPI.Mod</samp> |
− | # 覆写 <samp>Entry</samp> 方法,并使用 [[#Mod APIs|SMAPI events and APIs]] 编写代码 | + | # 覆写 <samp>Entry</samp> 方法,并使用 [[#Mod APIs|SMAPI 事件和 API]] 编写代码 |
− | # 创建一个 [[# 添加你的清单|<samp>manifest.json</samp> 文件]] 来描述 了 你的 SMAPI 模组 | + | # 创建一个 [[#Add your manifest|<samp>manifest.json</samp>]] 文件来描述你的模组 |
| # 创建 [[#发布你的模组|一个包含模组文件的zip压缩包]] 来发布 | | # 创建 [[#发布你的模组|一个包含模组文件的zip压缩包]] 来发布 |
| }} | | }} |
| | | |
| ===创建解决方案=== | | ===创建解决方案=== |
− | 一个 SMAPI 模组是具有 SMAPI 调用入口方法的动态链接库(DLL),因此要对其进行设置
| |
| | | |
− | # 打开 Visual Studio 或 者 MonoDevelop. | + | SMAPI 模组是一个动态链接库(DLL),具有由 SMAPI 调用的入口方法 |
− | # 创建 类库 项目 ,选择 .NET Framework 框架 ( 参阅 [[模组:IDE 参考#创建项目|如何创建 一个 项目]])。确保你 选择 的是 .NET Framework 而不 是 .NET Core 或者 .NET Standard | + | |
− | # 选择 目标框架 版本 为 .NET Framework 5 ( 参阅 [[模组:IDE 参考#选择目标框架|如何改 变 目标框架]]) | + | # 打开 Visual Studio 或 MonoDevelop |
− | # 添加 [https://www.nuget.org/packages/Pathoschild.Stardew.ModBuildConfig <samp>Pathoschild.Stardew.ModBuildConfig</samp> NuGet 包] ( 参阅 [[模组:IDE 参考#添加 NuGet 包|如何添加 NuGet 包]]). | + | # 使用“ 类库 ” 项目 创建解决方案(请 参阅[[模组:IDE 参考#创建项目|如何创建项目]] )(不要 选择 “类库(.NET Framework )”!那 是 在游戏 1.5.4 以及之前版本中所使用的) |
− | # 安装完包 之后重新启动 Visual Studio 或者 MonoDevelop | + | # 目标框架 设置 为 .NET 6(请 参阅 [[模组:IDE 参考#选择目标框架|如何 更 改目标框架]] )您可能需要 [https://dotnet.microsoft.com/en-us/download/dotnet/6.0 安装 SDK]。这是游戏安装和使用的版本 |
| + | # 添加 [https://www.nuget.org/packages/Pathoschild.Stardew.ModBuildConfig <samp>Pathoschild.Stardew.ModBuildConfig</samp> NuGet 包] (请 参阅 [[模组:IDE 参考#添加 NuGet 包| 如何添加 NuGet 包]] ) |
| + | #* 如果报错“找不到类型或命名空间名称“StardewModdingAPI””,则可能没有检测到游戏路径,需要将 GamePath 属性设置为游戏的目录。这可以通过将“GamePath”属性添加到项目文件(“.csproj”或“.vbproj”)中的“PropertyGroup”节点下来完成 |
| + | # 之后重新启动 Visual Studio 或者 MonoDevelop |
| | | |
| ===添加代码=== | | ===添加代码=== |
− | 接下来 让我们 添加 一些将运行的 SMAPI 代码 | + | 接下来添加代码 |
| | | |
| <ol> | | <ol> |
行 103: |
行 116: |
| //this 表示本对象,也就是当前的 ModEntry 类 | | //this 表示本对象,也就是当前的 ModEntry 类 |
| } | | } |
− |
| |
| | | |
| /********* | | /********* |
行 127: |
行 139: |
| 以下是该代码的功能细分: | | 以下是该代码的功能细分: |
| | | |
− | # <code>using X;</code> (参阅 [https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/using-directive using directive]) 使该命名空间中的类在你的代码中可用 | + | # <code>using X</code> (参阅 [https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/using-directive using directive]) 使该命名空间中的类在你的代码中可用 |
− | # <code>namespace YourProjectName</code> ( 参阅 [https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/namespace namespace keyword]) 定义 代码的范围 ,入门时不必担心,因为在新建类文件时 Visual Studio 或 MonoDevelop 会自动添加它 | + | # <code>namespace YourProjectName</code> ( 参阅 [https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/namespace namespace keyword] ) 定义 命名空间 ,入门时不必担心,因为在新建类文件时 Visual Studio 或 MonoDevelop 会自动添加它 |
− | # <code>public class ModEntry : Mod</code> (参阅 [https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/class class keyword]) 创建你的模组的主类文件,并继承 SMAPI 的 <samp>Mod</samp> 类。SMAPI 将自动检测你的 <samp>Mod</samp> 子类,而 <samp>Mod</samp> 使你可访问 SMAPI 的接口 | + | # <code>public class ModEntry : Mod</code> (参阅 [https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/class class keyword]) 创建你的模组的主类文件,并继承 SMAPI 的 <samp>Mod</samp> 类。SMAPI 将自动检测你的 <samp>Mod</samp> 子类,而 <samp>Mod</samp> 对象 使你可访问 SMAPI 的接口 |
| # <code>public override void Entry(IModHelper helper)</code> 是将模组加载到游戏中时 SMAPI 将调用的方法。这里的 <code>helper</code> 对象提供了对许多 SMAPI 接口的便捷访问 | | # <code>public override void Entry(IModHelper helper)</code> 是将模组加载到游戏中时 SMAPI 将调用的方法。这里的 <code>helper</code> 对象提供了对许多 SMAPI 接口的便捷访问 |
− | # <code>helper.Events.Input.ButtonPressed += this.OnButtonPressed;</code> 添加了一个 ' 事件绑定' (''i.e.,'' a method to call) 到当按下按钮的事件发生时. 换句话说,当一个按钮被按下 (也就是 <samp>helper.Events.Input.ButtonPressed</samp> 事件触发了), SMAPI 会调用你的 <samp>this.OnButtonPressed</samp> 方法。参阅 [[模组:Modder Guide/APIs/Events|SMAPI 中的事件]] 获取更多信息 | + | # <code>helper.Events.Input.ButtonPressed += this.OnButtonPressed</code> 添加了一个事件绑定到当按下按钮的事件发生时 。 换句话说,当一个按钮被按下 (也就是 <samp>helper.Events.Input.ButtonPressed</samp> 事件触发了), SMAPI 会调用你的 <samp>this.OnButtonPressed</samp> 方法。参阅 [[模组: 使用指南/APIs/ 事件|SMAPI 中的事件]] 获取更多信息 |
| + | |
| + | 如果您使用的是 Visual Basic 语言,以下是使用该语言的 Entry 示例,实现了和上面的 C# 代码相同的步骤和功能 |
| + | <ol><syntaxhighlight lang="vb"> |
| + | Imports StardewModdingAPI |
| + | Imports StardewModdingAPI.Events |
| + | Imports StardewValley |
| + | |
| + | Namespace YourProjectName |
| + | Public Class ModEntry |
| + | Inherits [Mod] |
| + | |
| + | Public Overrides Sub Entry(helper As IModHelper) |
| + | AddHandler helper.Events.Input.ButtonPressed, AddressOf OnButtonPressed |
| + | End Sub |
| + | |
| + | Public Sub OnButtonPressed(sender As Object, e As ButtonPressedEventArgs) |
| + | If Not Context.IsWorldReady Then Exit Sub |
| + | Monitor.Log($"{Game1.player.Name} 按下了 {e.Button}.", LogLevel.Debug) |
| + | End Sub |
| + | End Class |
| + | End Namespace |
| + | </syntaxhighlight></ol> |
| | | |
| ===添加你的清单=== | | ===添加你的清单=== |
行 144: |
行 178: |
| "Author": "<你的名字>", | | "Author": "<你的名字>", |
| "Version": "1.0.0", | | "Version": "1.0.0", |
− | "Description": "<一句话简单描述你的模组是干什么的>", | + | "Description": "<一句话简单描述你的模组是干什么的>", //(可选) |
| "UniqueID": "<你的名字>.<模组的名字>", | | "UniqueID": "<你的名字>.<模组的名字>", |
| "EntryDll": "<你的解决方案的名字>.dll", | | "EntryDll": "<你的解决方案的名字>.dll", |
− | "MinimumApiVersion": "3.0.0", | + | "MinimumApiVersion": "4.0.0", |
− | "UpdateKeys": [] | + | "UpdateKeys": [] //(可选)常用的更新键:"Nexus:???", "Gtihub:user/repository", "Moddrop:???" |
| } | | } |
| </syntaxhighlight></li> | | </syntaxhighlight></li> |
行 154: |
行 188: |
| </ol> | | </ol> |
| | | |
− | 当游戏启动时,它将在控制台中输出。更多信息请参阅 [[模组:Modder Guide/APIs/Manifest|清单文档]] | + | 当游戏启动时,它将在控制台中输出。更多信息请参阅 [[模组: 使用指南/APIs/ 清单|清单文档]] |
| + | |
| + | ===试试你的模组=== |
| + | # 构建项目。<br /><small>如果正确执行了“[[#创建项目|创建项目]]”步骤,这会自动将模组添加到游戏的 <samp>Mods</ samp> 文件夹。</small> |
| + | # 通过 SMAPI 运行游戏。 |
| + | |
| + | 到目前为止,只要您在游戏中按下某个键时该模组就会向控制台窗口发送一条消息。 |
| + | |
| + | '''更改控制台文本颜色''' |
| + | |
| + | 控制台中默认文本颜色的设置方式可能会导致它们不可读。 要更改文本颜色: |
| + | |
| + | *'''Steam''':打开 Steam 并右键单击库中的游戏。单击“管理”下的“浏览本地文件”,然后打开“/Stardew Valley/smapi-internal/”文件夹中的 <samp>config.json</samp> 文件,搜索“ConsoleColors”,然后编辑“Trace”和“Debug”颜色,以便它们在控制台中可见。 |
| | | |
− | ===构建你的模组===
| + | *'''Linux''' :linux上的默认路径是 <samp>~/.local/share/Steam/steamapps/common/Stardew Valley/smapi-internal/config.json</samp> ,除非 你已经 安装 您 的游戏 位于不同 的 驱动器或者标准 Steam 库 文件夹 之外。 |
− | # 构建项目<br \>如果你不知道怎么构建:在开发工具的菜单栏中选择 ''' 项目''',然后选择 '''生成'''<br \> 如果 你已经 做了 [[#创建解决方案|创建解决方案]] 这一步,在构建时你 的 模组会自动安装到 游戏的 <samp>Mods</samp> 文件夹 中
| |
− | # 通过 SMAPI 启动游戏
| |
| | | |
− | 到目前 为 止 , 每当按下 游戏 中 的 一个键时,该模组会向控制台窗口发送一条消息 | + | *'''Windows''':Windows 上的默认路径应 为 “C:\Program files (x86)\Steam\steamapps\common\Stardew Valley\smapi-internal\config.json” , 除非 游戏 在不同 的 驱动器或 Steam 库文件夹之外。 |
| | | |
| ===疑难解答=== | | ===疑难解答=== |
行 174: |
行 218: |
| ==常见问题== | | ==常见问题== |
| ===SMAPI 的文档在哪里?=== | | ===SMAPI 的文档在哪里?=== |
− | 这只是“入门”教程。更多信息请参阅 [[Modding:Modder Guide/APIs|SMAPI reference]] 和 [[Modding:Index|topics listed on the index page]]. | + | 这只是“入门”教程。更多信息请参阅 [[ 模组: 制作指南/APIs|SMAPI 接口说明]] |
| + | |
| + | ===我可以看看其他模组的代码吗?=== |
| + | 是的,近 70% 的 SMAPI 模组都是开源的。要找到他们的代码: |
| + | |
| + | # 打开 [https://smapi.io/mods/ 模组兼容性页面] |
| + | # 单击搜索框下方的“show advanced info” |
| + | # 在“code”列中查找链接 |
| | | |
| ===我如何使我的模组跨平台工作?=== | | ===我如何使我的模组跨平台工作?=== |
行 182: |
行 233: |
| <li>使用 [https://smapi.io/package/readme 跨平台构建配置] 包以自动设置您的项目引用,这使跨平台兼容性变得更容易,并使代码可以在任何平台上进行编译。(如果遵循上述指南,那么就没问题了)</li> | | <li>使用 [https://smapi.io/package/readme 跨平台构建配置] 包以自动设置您的项目引用,这使跨平台兼容性变得更容易,并使代码可以在任何平台上进行编译。(如果遵循上述指南,那么就没问题了)</li> |
| | | |
− | <li>使用 <samp>Path.Combine</samp> 构建文件 路径, 请 不 要对路径分隔符进行硬编码 ,因为 它们 不 能在 所 有平台上都可 使用 | + | <li>使用 <samp>Path.Combine</samp> 方法来拼接 路径, 而 不 是使用斜杠或者除号 ,因为不 同的操作系统 所使用 的分隔符是不一样的 |
| | | |
| <syntaxhighlight lang="c#"> | | <syntaxhighlight lang="c#"> |
行 192: |
行 243: |
| </syntaxhighlight></li> | | </syntaxhighlight></li> |
| | | |
− | <li>使用 <samp>this.Helper.DirectoryPath</samp>,请勿尝试自行确定模组路径 | + | <li>使用 <samp>this.Helper.DirectoryPath</samp> 来获取当前模组文件夹路径 ,请勿尝试自行确定模组路径 |
| | | |
| <syntaxhighlight lang="c#"> | | <syntaxhighlight lang="c#"> |
| // ✘ 不要这样做!如果 SMAPI 重写了程序集(例如对其进行了更新或跨平台),它将崩溃 | | // ✘ 不要这样做!如果 SMAPI 重写了程序集(例如对其进行了更新或跨平台),它将崩溃 |
− | string modFolder = Assembly .GetCallingAssembly().Location; | + | string modFolder = Assembly.GetCallingAssembly().Location; |
| | | |
| // ✓ 这样就没问题 | | // ✓ 这样就没问题 |
| string modFolder = this.Helper.DirectoryPath; | | string modFolder = this.Helper.DirectoryPath; |
| </syntaxhighlight></li> | | </syntaxhighlight></li> |
| + | |
| + | <li>“资源名称”标识可以通过 <code><nowiki>Game1.content.Load<T>("asset name")</nowiki></code> 等内容 API 加载的资产。这“不是”文件路径,并且资源名称并不总是与文件路径匹配。比较资源名称时,请确保使用 <code>PathUtilities.NormalizeAssetName("some/path")</code> 而不是 path helpers |
| + | |
| + | <syntaxhighlight lang="c#"> |
| + | // ✘ 不要这样做! 它不适用于 Windows。 |
| + | bool isAbigail = (asset.Name == Path.Combine("Characters", "Abigail")); |
| + | bool isAbigail2 = (asset.Name == PathUtilities.NormalizePath("Characters", "Abigail")); |
| + | |
| + | // ✓ 这样就可以了 |
| + | bool isAbigail = (asset.Name == PathUtilities.NormalizeAssetName("Characters", "Abigail")); |
| + | </syntaxhighlight> |
| + | |
| + | 请注意,无需标准化传递给 SMAPI API 的资源名称,SMAPI API 会自动标准化它们(尽管这样做也没什么坏处): |
| + | <syntaxhighlight lang="c#"> |
| + | // ✓ 这样就可以了 |
| + | helper.Content.Load<Texture2D>("Characters/Abigail"); |
| + | helper.Content.Load<Texture2D>(@"Characters\Abigail"); |
| + | </syntaxhighlight> |
| + | </li> |
| </ol> | | </ol> |
| | | |
| ===如何反编译游戏代码?=== | | ===如何反编译游戏代码?=== |
− | 观察游戏代码的工作方式通常对开发很有用。游戏的代码都编译在 <samp>StardewValley.exe</samp> 文件中, 但是 可以对其进行反编译 , 以获得原始代码的近似可读性。(由于反编译 器 的 限制 , 此功能 可能无法 完全发挥作用 ,但 是能 够看到它在做什么。) | + | 观察游戏代码的工作方式通常对开发很有用。游戏的代码都编译在 <samp>StardewValley.dll</samp> 文件中,可以对其进行反编译以获得原始代码的近似可读性。(由于反编译 和生成优化 的 问题 ,可能无法 准确还原逻辑 ,但 已经足 够看到它在做什么。) |
| | | |
− | 要反编译游戏代码... | + | 要反编译游戏代码 : |
| | | |
− | ; 在 Windows 上:
| + | :# 首次 步 骤: |
− | :# 第一 步: | + | :## 在 Windows 上 安装 {{github|icsharpcode/ILSpy/releases|ILSpy}} (在 Release 的 Assets 下获取“ILSpy_binaries”文件),或在 Linux 和 macOS 上安装 [https://github.com/icsharpcode/AvaloniaILSpy/releases Avalonia ILSpy] |
− | :## 安装 最新版本的 {{github|icsharpcode/ILSpy/releases|ILSpy}} | |
| :## 打开 ILSpy | | :## 打开 ILSpy |
− | :## 点 击 ''视图 > 选项''滑 动 至 底部的 "其他" 选项, 并 启用 “始终限定成员引用 ” | + | :## 单 击 “View > Options”,滚 动 到 底部的 “Other”部分,然后 启用 “Always qualify member references ” |
− | :# 在 ILSpy 打开 <samp>StardewValley.dll</samp> | + | :# 在 ILSpy 中 打开 <samp>Stardew Valley.dll</samp> |
− | :# 右键 ''Stardew Valley'' 并选择 ''保存代码'' 创建 反编译的项目, 可以在 Visual Studio 中打开 | + | :# 确保在语言下拉列表中选择“C#”(不是 IL、IL with C# 或 ReadyToRun) |
| + | :# 右键 单击“Stardew Valley ” 并选择 “Save Code”以 创建可以在 Visual Studio 中打开 的反编译项目 |
| + | :## 如果您使用 Avalonia ILSpy,请确保将 <samp>.csproj</samp> 文件扩展名添加到保存对话框中的文件名中,如下所示:<samp>Stardew-Valley.csproj</samp> (否则该项目将无法正确反编译) |
| | | |
− | ; On Linux/MacOS:
| + | 另外有一个很不错的反编译工具但已经不再维护了:{{github|dnSpy/dnSpy/releases|dnSpy}} |
− | :# Install [https://code.visualstudio.com/download Visual Studio Code].
| |
− | :# Get the [https://marketplace.visualstudio.com/items?itemName=icsharpcode.ilspy-vscode ILSpy .NET Decompiler] plugin for VSCode.
| |
− | :# Open the Visual Studio Code Command Palette (<code>Command+Shift+P</code>), then type <code>ilspy</code> to show the two commands.
| |
− | :# Choose ''Decompile IL Assembly (pick file)'', then choose the <samp>StardewValley.exe</samp> in your [[Modding:Player Guide/Getting Started#Find your game folder|game folder]].
| |
− | :# A tree view named <samp>ILSPY DECOMPILED MEMBERS</samp> should appear in the Explorer view. This lets you expand and select various nodes to see the decompiled C# code in the editor.
| |
| | | |
| 要解包 XNB 数据或图像文件,请参阅 [[模组:编辑 XNB 文件]] | | 要解包 XNB 数据或图像文件,请参阅 [[模组:编辑 XNB 文件]] |
| + | |
| + | ===“目标 .NET 6.0”是什么意思?=== |
| + | |
| + | 这里有多种不同的东西 |
| + | |
| + | * 目标版本:这是编译二进制文件所针对的 .NET 版本,最新版本的游戏必须以 .NET 6.0 为目标 |
| + | * SDK 版本:这是安装的 .NET 版本,可以定位低于 SDK 版本的任何版本。如果在 VS 2022 中安装了 .NET 7.0,仍然可以使用 .NET 6.0 |
| + | * C# 版本:语言的版本与 .NET 版本分开(尽管存在对应关系),可以在项目中使用 <code><langversion></code> 属性来指定语言版本 |
| | | |
| [[Category:模组]] | | [[Category:模组]] |
行 231: |
行 305: |
| [[fr:Modding:Guide du Moddeur/Commencer]] | | [[fr:Modding:Guide du Moddeur/Commencer]] |
| [[pt:Modificações:Guia do Modder/Começando]] | | [[pt:Modificações:Guia do Modder/Começando]] |
| + | [[ru:Модификации:Моддер гайд/Приступая к работе]] |