Modding:Adding Code at Startup: Difference between revisions

Jump to navigation Jump to search
m
no edit summary
(Created the page)
 
mNo edit summary
 
(9 intermediate revisions by 2 users not shown)
Line 1: Line 1:
__NOTOC__
__NOTOC__
{{Modding Info}}
{{Modding Info}}{{Modding Topic Prerequisites | Modding:C Sharp Scripting}}
 
{{ambox
|type=This article presupposes some knowledge of [[Modding/C Sharp Scripting|C# scripting]].
|format=tiny}}
 
==Overview==
==Overview==


Line 20: Line 15:
* When the list of active mods changes
* When the list of active mods changes
|| Not specific to a particular game and won't be called again if the player loads a different save. Code runs only once when the main menu loads during executable startup and is not called again unless the player modifies their approved/active mods while the game is running. In that case, the new mod configuration is "hotloaded" and mod-sensitive cache code is called again.
|| Not specific to a particular game and won't be called again if the player loads a different save. Code runs only once when the main menu loads during executable startup and is not called again unless the player modifies their approved/active mods while the game is running. In that case, the new mod configuration is "hotloaded" and mod-sensitive cache code is called again.
|-
| '''Blueprint Preload''' ||
* When the main menu first loads
* When the list of active mods changes
|| Runs at the same time as Mod-Sensitive Cache code, but has a different load framework, as described below.
|-
|-
| '''Game-Based Cache''' ||
| '''Game-Based Cache''' ||
Line 25: Line 25:
* When an existing save is loaded
* When an existing save is loaded
|| Called every time the game context changes (i.e. new game or load game). Code is called before the player object exists and before world generation, so this option is not suitable if you need to manipulate the player.
|| Called every time the game context changes (i.e. new game or load game). Code is called before the player object exists and before world generation, so this option is not suitable if you need to manipulate the player.
|-
| '''Blueprint Preload''' ||
* When the main menu first loads
* When the list of active mods changes
|| Runs at the same time as Mod-Sensitive Cache code, but has a different load framework, as described below.
|-
|-
| '''PlayerMutator''' ||
| '''PlayerMutator''' ||
* After player is created for a New Game
* After player is created for a New Game
|| Code runs only once when a New Game starts, after the player object is first created. Is never called again. Useful if you want your code to run only once per save file. For example, you might add a custom part to the player that holds your code. For more information about this method, refer to [[Modding:Adding Code to the Player]].
|| Code runs only once when a New Game starts, after the player object is first created. Is never called again. Useful if you want your code to run only once per save file. For example, you might add a custom part to the player that holds your code. For more information about this method, refer to [[Modding:Adding Code to the Player]].
|-
| '''AfterGameLoaded Hook''' ||
* After a save game is loaded and the Player object exists
|| Code runs immediately after a save game is loaded, and when the Player object exists. Useful if your code needs to modify the player object after a save game load (similar to PlayerMutator for new games). For more information about this method, refer to [[Modding:Adding Code to the Player]].
|-
|-
| '''Harmony Injection''' ||
| '''Harmony Injection''' ||
* ''At any time in the code flow''
* ''At any time in the code flow''
|| {{betamoddingcontent}}
|| This is the most flexible method by far, because you can inject your code anywhere in the code flow. However, it is also the most difficult and technical of the options. Most mods do not need this and it is not recommended for modders who are new to C# scripting. For more information about this method, refer to [[Modding:Harmony]].
This is the most flexible method by far, because you can inject your code anywhere in the code flow. However, it is also the most difficult and technical of the options. Most mods do not need this and it is not recommended for modders who are new to C# scripting. For more information about this method, refer to [[Modding:Harmony Injection]].
|}
|}
==Game-Based Cache==
Tag any C# class with the <code>[HasGameBasedStaticCache]</code> attribute to indicate that the class includes game-sensitive code that the game should run each time a new game starts or a save game is loaded.
===Timing===
Game-based cache code is invoked by the <code>XRL.Core.XRLCore.ResetGameBasedStaticCaches()</code> method, which is called at the following times:
* Immediately after selecting "New Game" option from main menu (before the player object exists or world generation occurs)
* Immediately after loading a saved game (including scenarios such as a reload due to Precognition)
===Implementation===
Classes with <code>[HasGameBasedStaticCache]</code> attribute are treated as follows (in this order):
* If the class has any static fields with the <code>[GameBasedStaticCache]</code> attribute, those fields are (re)initialized to their default value (for value types) or set to a new instance via <code>Activator.CreateInstance</code> (for object types). Object types can specify <code>[GameBasedStaticCache(CreateInstance = false)]</code> to force the field to be set to null instead of creating a new instance.
* If the class has a static <code>Reset()</code> method, the game invokes that method.
* If the class has any other static methods with the <code>[GameBasedCacheInit]</code> attribute, the game invokes those methods.
===Example===
<syntaxhighlight lang="csharp">
[HasGameBasedStaticCache]
public static class Initialiser
{
    [GameBasedStaticCache]
    public static int Counter; // Reset to default int value whenever a new game is started or a save is loaded
    public static int OtherCounter; // Value is NOT automatically reset (though you could reset it in your Reset() method)
    public static void Reset()
    {
        // Called whenever a new game is started or a save is loaded - no attribute tag is needed
    }
    [GameBasedCacheInit]
    public static void AdditionalSetup()
    {
        // Called after Reset()
    }
}
</syntaxhighlight>


==Mod-Sensitive Cache==
==Mod-Sensitive Cache==
Line 88: Line 49:


===Implementation===
===Implementation===
The mod-sensitive cache is implemented in a similar fashion to the game-sensitive cache, but there is no special handling for a <code>Reset()</code> method and there are a few other subtle differences.
The mod-sensitive cache is implemented in a similar fashion to the game-sensitive cache (see section below), but there is no special handling for a <code>Reset()</code> method and there are a few other subtle differences.


Classes with <code>[HasModSensitiveStaticCache]</code> attribute are treated as follows (in this order):
Classes with <code>[HasModSensitiveStaticCache]</code> attribute are treated as follows (in this order):
Line 152: Line 113:
         }
         }
         //...
         //...
    }
}
</syntaxhighlight>
==Game-Based Cache==
Tag any C# class with the <code>[HasGameBasedStaticCache]</code> attribute to indicate that the class includes game-sensitive code that the game should run each time a new game starts or a save game is loaded.
===Timing===
Game-based cache code is invoked by the <code>XRL.Core.XRLCore.ResetGameBasedStaticCaches()</code> method, which is called at the following times:
* Immediately after selecting "New Game" option from main menu (before the player object exists or world generation occurs)
* Immediately after loading a saved game (including scenarios such as a reload due to Precognition)
===Implementation===
Classes with <code>[HasGameBasedStaticCache]</code> attribute are treated as follows (in this order):
* If the class has any static fields with the <code>[GameBasedStaticCache]</code> attribute, those fields are (re)initialized to their default value (for value types) or set to a new instance via <code>Activator.CreateInstance</code> (for object types). Object types can specify <code>[GameBasedStaticCache(CreateInstance = false)]</code> to force the field to be set to null instead of creating a new instance.
* If the class has a static <code>Reset()</code> method, the game invokes that method.
* If the class has any other static methods with the <code>[GameBasedCacheInit]</code> attribute, the game invokes those methods.
===Example===
<syntaxhighlight lang="csharp">
[HasGameBasedStaticCache]
public static class Initialiser
{
    [GameBasedStaticCache]
    public static int Counter; // Reset to default int value whenever a new game is started or a save is loaded
    public static int OtherCounter; // Value is NOT automatically reset (though you could reset it in your Reset() method)
    public static void Reset()
    {
        // Called whenever a new game is started or a save is loaded - no attribute tag is needed
    }
    [GameBasedCacheInit]
    public static void AdditionalSetup()
    {
        // Called after Reset()
     }
     }
}
}
Line 160: Line 158:
The pre-game cache is an additional load point that is similar to the game-based cache. The overall order in which cache code runs is as follows:
The pre-game cache is an additional load point that is similar to the game-based cache. The overall order in which cache code runs is as follows:
# Mod-sensitive cache code
# Mod-sensitive cache code
# Pre-game cache code
# Pre-game cache code ''(including Blueprint preload)''
# Game-based cache code
# Game-based cache code


Line 169: Line 167:
{{Modding Navbox}}
{{Modding Navbox}}


[[Category:Modding]][[Category:Guides]]
[[Category:Script Modding]]
2,158

edits

Navigation menu