Plugin class structure - TiberiumFusion/TTPlugins GitHub Wiki

This section provides an overview of HPlugin interface (actually a class) that your plugins will use.


Static and instance components

Plugins have both static and instance components. The static side of your plugin is the group of static patch method(s) that are applied to Terraria. The instance side of your plugin is everything it inherits from its base type, which is the self-management code that tells the plugin framework how to apply the plugin's static patch methods.

This means that any communication between the instance-bound self-management code and the static patch code must occur via statics. For example, if one of your patch methods needs to read from your plugin's persistent savedata, you must make the value of the savedata available via a static field or property in your plugin class, or make your plugin's instance visible via a static field or property. Only one instance of your plugin will be created by the plugin framework, so you can define a singleton to expose your plugin instance to its static patch methods.


Base Type

All plugins must extend from HPlugin in order to be recognized by the plugin framework. HPlugin provides 3 properties and 3 virtual methods for your plugin to utilize:

Property Identity

This is a purely informational object which describes your plugin. Identity is used to identify your plugin to the user while their game is running and has 4 properties that you can set:

  • Property PluginName
    • The human-friendly name of your plugin. For example: Cool Terraria Dude's Crazy Spawns Plugin
  • Property PluginDescription
    • A short description of what your plugin does. For example: Randomly spawns mobs around the player with customizable timings and distances.
  • Property PluginAuthor
    • Credit to the creator of the plugin. For example: Cool Terraria Dude
  • Property PluginVersion
    • A Version object that you set to indicate the version of your plugin. For example: new Version("1.0.0.0")

You can ignore Identity, but it is recommended that you assign the 4 properties listed above. If you do not, it will be more difficult to identify problematic plugins that may be causing errors.

Property Configuration

This object contains configuration information that is specific to your plugin. Currently, there is only one property in Configuration that your plugin can work with:

NOTE: Configuration will be null or empty before ConfigurationLoaded() is called on your plugin.

This is a boolean flag which your plugin must set in Initialize(). If true, the plugin framework will load a persistent savedata element from the user's executing Tweak List and make it available to your plugin via Configuration.Savedata. If false, Configuration.Savedata will be supplied with empty defaults.

By default, HasPersistentSavedata is set to false.

IMPORTANT: If your plugin uses persistent savedata, it MUST set HasPersistentSavedata = true in Initialize().

Method Initialize()

This is a virtual method which is called very shortly after the plugin framework creates an instance of your plugin. Your plugin should override Initialize() to define its Identity and set HasPersistentSavedata.

Example:

public override void Initialize()
{
	Identity.PluginName = "Cool Terraria Dude's Crazy Spawns Plugin";
	Identity.PluginDescription = "Randomly spawns mobs around the player with customizable timings and distances.";
	Identity.PluginAuthor = "Cool Terraria Dude";
	Identity.PluginVersion = new Version("1.0.0.0");
	HasPersistentSavedata = true;
}

NOTE: If your plugin does not define an override for Initialize(), then Identity will contain generic defaults and HasPersistentSavedata will be set to false.

Initialize() is a good place for your plugin to establish any kind of structures or objects it needs.

This is a virtual method which is called after the plugin framework has loaded configuration data (including persistent savedata, if applicable) for your plugin. The successfulConfigLoadFromDisk parameter will be true if the configuration loaded successfully (or did not exist and fresh configuration was generated). If it is false, then an error occurred while loading the configuration data and a blank configuration was substituted in. In either case, Configuration is valid and can be safely accessed. Your plugin should override ConfigurationLoaded() to process its persistent savedata (if applicable).

Example for a plugin that uses persistent savedata:

private static float SpeedBoost = 0f;
public override void ConfigurationLoaded(bool successfulConfigLoadFromDisk)
{
	XElement savedataSpeedBoost = Configuration.Savedata.Element("speedBoost");
	if (savedataSpeedBoost != null)
		float.TryParse(savedataSpeedBoost.Value, out SpeedBoost);
}

NOTE: For precompiled plugins with embedded assembly resources, ConfigurationLoaded() is good place to load embedded resources using the GetPluginAssemblyResourceBytes() method. Refer to the Asset Handling section of the Helper methods article for more info.

Method PrePatch()

This is a virtual method which is called immediately before the plugin framework performs any patch operations that your plugin has defined. For more information on defining patch operations, please refer to the article Writing stub patch methods. Your plugin should override PrePatch() to define its patch operations using any of the various CreateHPatchOperation() overloads.

Example:

public override void PrePatch()
{
	// Postfix patch Terraria.Player.ResetEffects with a static stub method named MyCustomPostfixPatch (defined somewhere else in our plugin class)
	CreateHPatchOperation("Terraria.Player", "ResetEffects", "MyCustomPostfixPatch", HPatchLocation.Postfix);
}

Helpful inherited members

The HPlugin base type provides several helpful instance members that your plugin can use.
Please refer to the Helpful inherited members article for more information.


Execution order

The plugin framework uses the following process:

  1. An instance of your plugin is created.
  2. Your plugin's Initialize() is called. If your plugin throws an exception, it will immediately be skipped.
  3. The framework reads HasPersistentSavedata from your plugin and loads plugin configuration & savedata accordingly.
  4. Your plugin's ConfigurationLoaded() is called. If your plugin throws an exception, it will immediately be skipped.
  5. Your plugin's PrePatch() is called. If your plugin throws an exception, it will immediately be skipped.
  6. The plugin framework will perform all patch operations defined by your plugin. If your plugin has an invalid patch operation (e.g. patching a null method, patching a restricted type, etc.), that operation will be skipped, a report will be logged, and the framework will simply move onto the next patch operation.

Next

Read the Writing stub patch methods article to learn how to write stub patch methods and define patch operations.

⚠️ **GitHub.com Fallback** ⚠️