Changes

update for SMAPI 2.3
Line 139: Line 139:  
! event !! summary
 
! event !! summary
 
|-
 
|-
| FirstUpdateTick || '''[SMAPI 2.3+]''' Raised after the game first updates its state. This happens once per game session (unrelated to loading saves).
+
| FirstUpdateTick || Raised after the game first updates its state. This happens once per game session (unrelated to loading saves).
 
|-
 
|-
 
| UpdateTick || Raised when the game updates its state (≈60 times per second).
 
| UpdateTick || Raised when the game updates its state (≈60 times per second).
Line 558: Line 558:     
===Reflection===
 
===Reflection===
SMAPI provides an API for robustly accessing the game's private fields or methods. You can use it from <tt>helper.Reflection</tt> in your entry method, or <tt>this.Helper.Reflection</tt> elsewhere in your entry class. It consists of three methods:
+
SMAPI provides an API for robustly accessing fields, properties, or methods you otherwise couldn't access, such as private fields. You can use it from <tt>helper.Reflection</tt> in your entry method, or <tt>this.Helper.Reflection</tt> elsewhere in your entry class.
 
  −
* <tt>GetPrivateValue<TValue>(...)</tt> returns the value of a private field.
  −
* <tt>GetPrivateField<TValue>(...)</tt> returns an object you can use to get or set a field's value.
  −
* <tt>GetPrivateMethod(...)</tt> returns an object you can use to invoke a method.
      
Here are a few examples of what this lets you do:
 
Here are a few examples of what this lets you do:
Line 568: Line 564:  
<source lang="c#">
 
<source lang="c#">
 
// did you pet your pet today?
 
// did you pet your pet today?
bool wasPet = this.Helper.Reflection.GetPrivateValue<bool>(pet, "wasPetToday");
+
bool wasPet = this.Helper.Reflection.GetField<bool>(pet, "wasPetToday").GetValue();
    
// what is the spirit forecast today?
 
// what is the spirit forecast today?
 
string forecast = this.Helper.Reflection
 
string forecast = this.Helper.Reflection
   .GetPrivateMethod(new TV(), "getFortuneForecast")
+
   .GetMethod(new TV(), "getFortuneForecast")
 
   .Invoke<string>();
 
   .Invoke<string>();
    
// randomise the mines
 
// randomise the mines
 
if(Game1.currentLocation is MineShaft)
 
if(Game1.currentLocation is MineShaft)
   this.Helper.Reflection.GetPrivateField<Random>(Game1.currentLocation, "mineRandom").SetValue(new Random());
+
   this.Helper.Reflection.GetField<Random>(Game1.currentLocation, "mineRandom").SetValue(new Random());
 
</source>
 
</source>
    
This works with static or instance fields/methods, caches the reflection to improve performance, and will throw useful errors automatically when reflection fails.
 
This works with static or instance fields/methods, caches the reflection to improve performance, and will throw useful errors automatically when reflection fails.
   −
If you need to do more, you can also switch to C#'s underlying reflection API:
+
If you need to do more, you can switch to [https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/reflection C#'s underlying reflection API]:
    
<source lang="c#">
 
<source lang="c#">
FieldInfo field = this.Helper.Reflection.GetPrivateField<string>(…).FieldInfo;
+
FieldInfo field = this.Helper.Reflection.GetField<string>(…).FieldInfo;
MethodInfo method = this.Helper.Reflection.GetPrivateMethod(…).MethodInfo;
+
MethodInfo method = this.Helper.Reflection.GetMethod(…).MethodInfo;
 
</source>
 
</source>
   Line 812: Line 808:     
==Mod-provided APIs==
 
==Mod-provided APIs==
{{SMAPI upcoming
+
Mods can provide their own APIs to other mods, even without a dependency or assembly reference. This can be used to integrate mods, provide custom information, or provide new framework APIs beyond those offered by SMAPI itself.
|version = 2.3
  −
|content = Mods can provide their own APIs to other mods, even without a dependency or assembly reference. This can be used to integrate mods, provide custom information, or provide new framework APIs beyond those offered by SMAPI itself.
      
===Providing an API===
 
===Providing an API===
Line 876: Line 870:  
* You can't call <tt>GetApi</tt> until all mods are initialised and their <tt>Entry</tt> methods called. You can use the <tt>GameEvents.FirstUpdateTick</tt> [[#Events|event]] if you need to access mod APIs early; this is guaranteed to happen after all mods are initialised.
 
* You can't call <tt>GetApi</tt> until all mods are initialised and their <tt>Entry</tt> methods called. You can use the <tt>GameEvents.FirstUpdateTick</tt> [[#Events|event]] if you need to access mod APIs early; this is guaranteed to happen after all mods are initialised.
 
* You should always null-check APIs you consume. <tt>GetApi</tt> will return <tt>null</tt> if the API isn't available (e.g. because the mod isn't already installed or doesn't have one), or if an error occurs fetching the API.
 
* You should always null-check APIs you consume. <tt>GetApi</tt> will return <tt>null</tt> if the API isn't available (e.g. because the mod isn't already installed or doesn't have one), or if an error occurs fetching the API.
}}
      
[[Category:Modding]]
 
[[Category:Modding]]
translators
8,403

edits