Changes

m
Mark sender object as nullable. This prevents the code showing a warning. Note: other wiki pages like https://stardewvalleywiki.com/Modding:Modder_Guide/APIs/Events#How_do_I_use_them.3F have correct code snippets.
Line 1: Line 1:  
{{../header}}
 
{{../header}}
   −
Do you want to create SMAPI mods for Stardew Valley? This guide is for you! '''For using mods, see [[Modding:Player Guide/Getting Started|Modding:Player Guide]]. For creating Content Patcher packs, see [[Modding:Content Patcher]].'''
+
'''If you're making a mod for the first time,''' see [[Modding:Index#Creating mods]] for a short description of the differences between C# mods and content packs. '''You don't need to use C# to make mods.'''
   −
If you're confused and want to look at a picture of what kinds of modding is possible, see [[Modding:Modder Guide/Get Started/Pictorial Guide]]
+
Do you want to create '''SMAPI mods for Stardew Valley with C#?''' This guide is for you!
    
==Intro==
 
==Intro==
Line 28: Line 28:     
===Can I make a mod ''without SMAPI''?===
 
===Can I make a mod ''without SMAPI''?===
Yep. Many SMAPI mods support '[[Modding:Content_packs|content packs]]', which let you provide JSON text files, images, etc which they use. For example, you can [[Modding:Content Patcher|use Content Patcher]] to edit the game's images and data with zero programming needed. The rest of this guide is about creating a new SMAPI mod; for content packs, see [[Modding:Content Patcher]] or [[Modding:Content pack frameworks]] for information on other available frameworks (or the mod documentation if creating a content pack for a different mod).
+
Yep. Many SMAPI mods support '[[Modding:Content packs|content packs]]', which let you provide JSON text files, images, etc which they use. For example, you can [[Modding:Content Patcher|use Content Patcher]] to edit the game's images and data with zero programming needed. The rest of this guide is about creating a new SMAPI mod; for content packs, see [[Modding:Content Patcher]] or [[Modding:Content pack frameworks]] for information on other available frameworks (or the mod documentation if creating a content pack for a different mod).
    
===Where can I get help?===
 
===Where can I get help?===
Line 41: Line 41:  
* [https://mva.microsoft.com/en-us/training-courses/c-fundamentals-for-absolute-beginners-16169 ''C# Fundamentals for Absolute Beginners''] is a video guide which will walk you through C#, from the basic concepts to event-driven programming (which is what SMAPI mods mostly use).
 
* [https://mva.microsoft.com/en-us/training-courses/c-fundamentals-for-absolute-beginners-16169 ''C# Fundamentals for Absolute Beginners''] is a video guide which will walk you through C#, from the basic concepts to event-driven programming (which is what SMAPI mods mostly use).
 
* Already know how to program? Get a quick overview of C# syntax and concepts at [https://learnxinyminutes.com/docs/csharp/ LearnXinYMinutes.]
 
* Already know how to program? Get a quick overview of C# syntax and concepts at [https://learnxinyminutes.com/docs/csharp/ LearnXinYMinutes.]
 +
 +
A couple of concepts SMAPI uses frequently
 +
* [https://learn.microsoft.com/en-us/dotnet/csharp/fundamentals/types/generics ''Generics'']
 +
* [https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/events/ ''Event-based programming'']
 +
* For serialization, SMAPI usually uses [https://www.newtonsoft.com/json ''NewtonSoft'']
    
===Requirements===
 
===Requirements===
Line 48: Line 53:  
# Install [[Modding:Player Guide/Getting Started#Install SMAPI|SMAPI]].
 
# Install [[Modding:Player Guide/Getting Started#Install SMAPI|SMAPI]].
 
# Install the IDE (''integrated development environment'').
 
# Install the IDE (''integrated development environment'').
#* On Linux: install [http://www.monodevelop.com/ MonoDevelop].
+
#* On Linux: install [http://www.monodevelop.com/ MonoDevelop] or [https://www.jetbrains.com/rider/ Rider].
 
#* On Mac: install [https://visualstudio.microsoft.com/vs/mac/ Visual Studio for Mac]. (This is a rebranded MonoDevelop.)
 
#* On Mac: install [https://visualstudio.microsoft.com/vs/mac/ Visual Studio for Mac]. (This is a rebranded MonoDevelop.)
 
#* On Windows: install [https://visualstudio.microsoft.com/vs/community/ Visual Studio Community]. When the installer asks about workloads, enable ''.NET Desktop Development''.  
 
#* On Windows: install [https://visualstudio.microsoft.com/vs/community/ Visual Studio Community]. When the installer asks about workloads, enable ''.NET Desktop Development''.  
# Install the [https://dotnet.microsoft.com/en-us/download/dotnet/5.0 NET 5.0 SDK (x64 version)].
+
# Install the [https://dotnet.microsoft.com/en-us/download/dotnet/6.0 NET 6.0 SDK (x64 version)].
    
If you're not familiar with Visual Studio (on Windows/Mac) or MonoDevelop (on Linux), [[Modding:IDE reference]] explains how to do the important stuff you need for this guide.
 
If you're not familiar with Visual Studio (on Windows/Mac) or MonoDevelop (on Linux), [[Modding:IDE reference]] explains how to do the important stuff you need for this guide.
Line 60: Line 65:  
{{collapse|expand for quick start|content= 
 
{{collapse|expand for quick start|content= 
 
# Create an empty ''Class Library'' project. (Don't select ''Class Library (.NET Framework)''!)
 
# Create an empty ''Class Library'' project. (Don't select ''Class Library (.NET Framework)''!)
# Target .NET 5.
+
# Target .NET 6.
 
# Reference the [https://smapi.io/package/readme <samp>Pathoschild.Stardew.ModBuildConfig</samp> NuGet package] to automatically add the right references depending on the platform the mod is being compiled on.
 
# Reference the [https://smapi.io/package/readme <samp>Pathoschild.Stardew.ModBuildConfig</samp> NuGet package] to automatically add the right references depending on the platform the mod is being compiled on.
 
# Create a <samp>ModEntry</samp> class which subclasses <samp>StardewModdingAPI.Mod</samp>.
 
# Create a <samp>ModEntry</samp> class which subclasses <samp>StardewModdingAPI.Mod</samp>.
Line 73: Line 78:  
# Open Visual Studio or MonoDevelop.
 
# Open Visual Studio or MonoDevelop.
 
# Create a solution with a ''Class Library'' project (see [[Modding:IDE reference#create-project|how to create a project]]). (Don't select ''Class Library (.NET Framework)''! That's a separate thing with a similar name.)
 
# Create a solution with a ''Class Library'' project (see [[Modding:IDE reference#create-project|how to create a project]]). (Don't select ''Class Library (.NET Framework)''! That's a separate thing with a similar name.)
# Target .NET 5 (see [[Modding:IDE reference#set-target-framework|how to change target framework]]).You may need to [https://dotnet.microsoft.com/en-us/download/dotnet/5.0 install the SDK]. <br /> <small>That's the version installed and used by the game. Newer versions may not be installed for players, and SMAPI may not be able to load them. Yes we know it's EOL.</small>
+
# Target .NET 6 (see [[Modding:IDE reference#set-target-framework|how to change target framework]]).You may need to [https://dotnet.microsoft.com/en-us/download/dotnet/6.0 install the SDK]. <br /> <small>That's the version installed and used by the game. Newer versions may not be installed for players, and SMAPI may not be able to load them. [[#What does "target NET 6.0" mean?|Yes we know it's EOL]].</small>
 
# Reference the [https://www.nuget.org/packages/Pathoschild.Stardew.ModBuildConfig <samp>Pathoschild.Stardew.ModBuildConfig</samp> NuGet package] (see [[Modding:IDE reference#add-nuget|how to add the package]]).
 
# Reference the [https://www.nuget.org/packages/Pathoschild.Stardew.ModBuildConfig <samp>Pathoschild.Stardew.ModBuildConfig</samp> NuGet package] (see [[Modding:IDE reference#add-nuget|how to add the package]]).
 
#* If you are getting an error stating ''The type or namespace name "StardewModdingAPI" could not be found'', then it's possible that your game path is not being detected. You will need to set the GamePath property to the game's executable directory. This can be done by adding a ''GamePath'' property to the ''PropertyGroup'' in your ''.csproj'' settings.
 
#* If you are getting an error stating ''The type or namespace name "StardewModdingAPI" could not be found'', then it's possible that your game path is not being detected. You will need to set the GamePath property to the game's executable directory. This can be done by adding a ''GamePath'' property to the ''PropertyGroup'' in your ''.csproj'' settings.
Line 96: Line 101:  
{
 
{
 
     /// <summary>The mod entry point.</summary>
 
     /// <summary>The mod entry point.</summary>
     public class ModEntry : Mod
+
     internal sealed class ModEntry : Mod
 
     {
 
     {
 
         /*********
 
         /*********
Line 115: Line 120:  
         /// <param name="sender">The event sender.</param>
 
         /// <param name="sender">The event sender.</param>
 
         /// <param name="e">The event data.</param>
 
         /// <param name="e">The event data.</param>
         private void OnButtonPressed(object sender, ButtonPressedEventArgs e)
+
         private void OnButtonPressed(object? sender, ButtonPressedEventArgs e)
 
         {
 
         {
 
             // ignore if player hasn't loaded a save yet
 
             // ignore if player hasn't loaded a save yet
Line 136: Line 141:  
# <code>public override void Entry(IModHelper helper)</code> is the method SMAPI will call when your mod is loaded into the game. The <code>helper</code> provides convenient access to many of SMAPI's APIs.
 
# <code>public override void Entry(IModHelper helper)</code> is the method SMAPI will call when your mod is loaded into the game. The <code>helper</code> provides convenient access to many of SMAPI's APIs.
 
# <code>helper.Events.Input.ButtonPressed += this.OnButtonPressed;</code> adds an 'event handler' (''i.e.,'' a method to call) when the button-pressed event happens. In other words, when a button is pressed (the <samp>helper.Events.Input.ButtonPressed</samp> event), SMAPI will call your <samp>this.OnButtonPressed</samp> method. See [[Modding:Modder Guide/APIs/Events|events in the SMAPI reference]] for more info.
 
# <code>helper.Events.Input.ButtonPressed += this.OnButtonPressed;</code> adds an 'event handler' (''i.e.,'' a method to call) when the button-pressed event happens. In other words, when a button is pressed (the <samp>helper.Events.Input.ButtonPressed</samp> event), SMAPI will call your <samp>this.OnButtonPressed</samp> method. See [[Modding:Modder Guide/APIs/Events|events in the SMAPI reference]] for more info.
 +
 +
Note: if you get compile errors along the lines of "Feature XX is not available in C# <number>. Please use language version <number> or greater", add <samp>&lt;LangVersion&gt;Latest&lt;/LangVersion&gt;</samp> to your <samp>.csproj</samp>.
    
===Add your manifest===
 
===Add your manifest===
Line 165: Line 172:     
The mod so far will just send a message to the console window whenever you press a key in the game.
 
The mod so far will just send a message to the console window whenever you press a key in the game.
 +
 +
'''Changing console text color'''
 +
 +
The default text-colors in the console may be set in a way that makes them unreadable. To change text color:
 +
 +
*'''Steam''': Open Steam and right-click the game in your library. Click "Browse local files" under "Manage" and then open the <samp>config.json</samp> file in your "/Stardew Valley/smapi-internal/" folder, search for "ConsoleColors" and then edit the "Trace" and "Debug" colours so that they become visible within your console.
 +
 +
*'''Linux''': The default path on linux is <samp>~/.local/share/Steam/steamapps/common/Stardew Valley/smapi-internal/config.json</samp>, unless you have installed your game on a different drive/outside the standard steam library folder.
 +
 +
*'''Windows''': The default path on Windows should be "C:\Program files (x86)\Steam\steamapps\common\Stardew Valley\smapi-internal\config.json", unless you have installed your game on a different drive/outside the standard steam library folder.
    
===Troubleshoot===
 
===Troubleshoot===
Line 233: Line 250:  
</ol>
 
</ol>
   −
===How do I decompile the game code?===
+
===How do I decompile the game code?<span id="decompile"></span>===
 
It's often useful to see how the game code works. The game code is compiled into <samp>StardewValley.dll</samp> (''i.e.,'' converted to a machine-readable format), but you can decompile it get a mostly-readable approximation of the original code. (This might not be fully functional due to decompiler limitations, but you'll be able to see what it's doing.)
 
It's often useful to see how the game code works. The game code is compiled into <samp>StardewValley.dll</samp> (''i.e.,'' converted to a machine-readable format), but you can decompile it get a mostly-readable approximation of the original code. (This might not be fully functional due to decompiler limitations, but you'll be able to see what it's doing.)
   Line 243: Line 260:  
:## Click ''View > Options'', scroll to the "Other" section at the bottom, and enable "Always qualify member references".
 
:## Click ''View > Options'', scroll to the "Other" section at the bottom, and enable "Always qualify member references".
 
:# Open <samp>Stardew Valley.dll</samp> in ILSpy.
 
:# Open <samp>Stardew Valley.dll</samp> in ILSpy.
 +
:# Make sure ''C#'' is selected in the language drop-down (not IL, IL with C#, or ReadyToRun).
 
:# Right-click on ''Stardew Valley'' and choose ''Save Code'' to create a decompiled project you can open in Visual Studio.
 
:# Right-click on ''Stardew Valley'' and choose ''Save Code'' to create a decompiled project you can open in Visual Studio.
 +
:## If you're using Avalonia ILSpy, make sure to add the <samp>.csproj</samp> file extension to the filename in the save dialog, like so: <samp>Stardew-Valley.csproj</samp> (Otherwise, the project won't decompile properly.)
    
To unpack the XNB data/image/map files, see [[Modding:Editing XNB files]].
 
To unpack the XNB data/image/map files, see [[Modding:Editing XNB files]].
 +
 +
===What does "target NET 6.0" mean?===
 +
 +
There are multiple different things here.
 +
 +
* target version: this is the version of .NET your binary is compiled against. You have to target net 6.0 for stardew (and in general, you can at maximum use the version of .NET the person loading you uses.)
 +
* sdk version: this is the version of the .NET you installed. You can target any version less than your sdk version. If I have net 7.0 installed with VS 2022, I can still target net 6.0.
 +
* C# version - guess what? the language is versioned separately from the .NET version (although there is a correspondence) and you can pick your language version with <code><langversion></code> in the .csproj.
    
[[es:Modding:Guía del Modder/Introducción]]
 
[[es:Modding:Guía del Modder/Introducción]]