Skip to content

Executing mod code

Indraneel Mahendrakumar edited this page Jul 28, 2022 · 2 revisions

Modot includes the ability to execute code from C# assemblies at runtime (see Defining mods for details on how to include assemblies with a mod).

This is done using the ModStartupAttribute class ([ModStartup]) in the Godot.Modding namespace. This can be applied to static methods in mod assemblies, and these methods will be executed after mod has been loaded. For example:

[ModStartup]
private static void OnModStartup()
{
    // code here
}

Note that such methods need not be public - they can have any access modifier. It is also not mandatory for an assembly to have any methods marked with this attribute.

Mods that require the [ModStartup] attribute will have to include Modot as a dependency - either through NuGet or by referencing a local assembly path.

Supplying parameters

It is even possible to supply parameters to code using the [ModStartup] attribute (though they must be compile-time constants):

[ModStartup(1, "test")]
private static void OnModStartup(int x, string y)
{
    // code here
}

It is important to note that this is not type-safe. Neither the C# compiler nor Modot will check whether the supplied parameter count and types actually match the expected count and types, and an exception will be thrown if they do not match.

Exceptions in mod code

Modot blindly attempts to execute code annotated with [ModStartup]. It does not check whether the methods are actually static, whether supplied parameters (if any) are of the right types and count, and it does not attempt to catch any exceptions that may be thrown by said code.

This means that the program will crash if something goes wrong while attempting to execute code from external mods. Modot uses GDLogger, so a fatal exception will be recorded to the log file (at user://Log.txt by default).

Security

While the ability to execute external code is immensely useful and opens up a plethora of possibilities for modding, it also comes with the risk of executing potentially malicious code.

This is unfortunately an issue that has no easy solution, as it is fairly difficult to accurately detect whether an assembly contains harmful code.

As such, it is important to note that Modot does not bear the responsibility of checking for potentially malicious code in a mod's assembly.

However, it does provide the option to ignore a mod's assemblies, preventing any code from being executed. The ModLoader.LoadMods() and ModLoader.LoadMod() methods both accept a bool argument which specifies whether code from mod assemblies should be executing after mod loading. This is true by default, but if called with false, code from mod assemblies will not be executed.

Along with the ability to load mods individually, this can be used to ensure that only trusted mods can execute their code.

Another way to prevent executing malicious code is by restricting the source of mods to websites that thoroughly scan and verify uploaded user content, such as Steam. As mentioned earlier though, it is not Modot's responsibility to implement such checks.

Clone this wiki locally