Skip to content

ModLoaderMod🔗

Inherits: Object

This Class provides helper functions to build mods.


Constants🔗

• LOG_NAME: "ModLoader:Mod"🔗


Method Descriptions🔗

• void install_script_extension(child_script_path: String) static🔗

Description:🔗

Installs a script extension that extends a vanilla script.

Parameters:🔗

  • child_script_path (String): The path to the mod's extender script.

Returns:

  • No return value

This is the preferred way of modifying a vanilla Script
Since Godot 4, extensions can cause issues with scripts that use class_name and should be avoided if present.
See add_hook() for those cases.

The child_script_path should point to your mod's extender script.
Example: "MOD/extensions/singletons/utils.gd"
Inside the extender script, include extends {target} where {target} is the vanilla path.
Example: extends "res://singletons/utils.gd".

Note

Your extender script doesn't have to follow the same directory path as the vanilla file, but it's good practice to do so.


• void install_script_hooks(vanilla_script_path: String, hook_script_path: String) static🔗

Description:🔗

Adds all methods from a file as hooks.

Parameters:🔗

  • vanilla_script_path (String): The path to the script which will be hooked.
  • hook_script_path (String): The path to the script containing hooks.

Returns:

  • No return value

The file needs to extend Object.
The methods in the file need to have the exact same name as the vanilla method they intend to hook, all mismatches will be ignored.
See: add_hook()

Examples:🔗

GDScript
1
2
3
4
ModLoaderMod.install_script_hooks(
    "res://tools/utilities.gd",
    extensions_dir_path.path_join("tools/utilities-hook.gd")
)

• void add_hook(mod_callable: Callable, script_path: String, method_name: String) static🔗

Description:🔗

Adds a hook, a custom mod function, to a vanilla method.

Parameters:🔗

  • mod_callable (Callable): The function that will executed when the vanilla method is executed. When writing a mod callable, make sure that it always receives a ModLoaderHookChain object as first argument, which is used to continue down the hook chain (see: ModLoaderHookChain.execute_next()) and allows manipulating parameters before and return values after the vanilla method is called.
  • script_path (String): Path to the vanilla script that holds the method.
  • method_name (String): The method the hook will be applied to.

Returns:

  • No return value

Opposed to script extensions, hooks can be applied to scripts that use class_name without issues.
If possible, prefer install_script_extension().

Examples:🔗

Given the following vanilla script main.gd

GDScript
1
2
3
4
5
6
7
8
9
class_name MainGame
extends Node2D

var version := "vanilla 1.0.0"


func _ready():
    $CanvasLayer/Control/Label.text = "Version: %s" % version
    print(Utilities.format_date(15, 11, 2024))
It can be hooked in mod_main.gd like this
GDScript
func _init() -> void:
    ModLoaderMod.add_hook(change_version, "res://main.gd", "_ready")
    ModLoaderMod.add_hook(time_travel, "res://tools/utilities.gd", "format_date")
    # Multiple hooks can be added to a single method.
    ModLoaderMod.add_hook(add_season, "res://tools/utilities.gd", "format_date")


# The script we are hooking is attached to a node, which we can get from reference_object
# then we can change any variables it has
func change_version(chain: ModLoaderHookChain) -> void:
    # Using a typecast here (with "as") can help with autocomplete and avoiding errors
    var main_node := chain.reference_object as MainGame
    main_node.version = "Modloader Hooked!"
    # _ready, which we are hooking, does not have any arguments
    chain.execute_next()


# Parameters can be manipulated easily by changing what is passed into .execute_next()
# The vanilla method (Utilities.format_date) takes 3 arguments, our hook method takes
# the ModLoaderHookChain followed by the same 3
func time_travel(chain: ModLoaderHookChain, day: int, month: int, year: int) -> String:
    print("time travel!")
    year -= 100
    # Just the vanilla arguments are passed along in the same order, wrapped into an Array
    var val = chain.execute_next([day, month, year])
    return val


# The return value can be manipulated by calling the next hook (or vanilla) first
# then changing it and returning the new value.
func add_season(chain: ModLoaderHookChain, day: int, month: int, year: int) -> String:
    var output = chain.execute_next([day, month, year])
    match month:
        12, 1, 2:
            output += ", Winter"
        3, 4, 5:
            output += ", Spring"
        6, 7, 8:
            output += ", Summer"
        9, 10, 11:
            output += ", Autumn"
    return output


• void register_global_classes_from_array(new_global_classes: Array) static🔗

Description:🔗

Registers an array of classes to the global scope since Godot only does that in the editor.

Parameters:🔗

  • new_global_classes (Array): An array of class definitions to be registered.

Returns:

  • No return value

Format: { "base": "ParentClass", "class": "ClassName", "language": "GDScript", "path": "res://path/class_name.gd" }

Tip

You can find these easily in the project.godot file under _global_script_classes (but you should only include classes belonging to your mod)


• void add_translation(resource_path: String) static🔗

Description:🔗

Adds a translation file.

Parameters:🔗

  • resource_path (String): The path to the translation resource file.
    Returns:

  • No return value

Note

The .translation file should have been created by the Godot editor already, usually when importing a CSV file. The translation file should named name.langcode.translation -> mytranslation.en.translation.


• void refresh_scene(scene_path: String) static🔗

Description:🔗

Marks the given scene for to be refreshed. It will be refreshed at the correct point in time later.

Parameters:🔗

  • scene_path (String): The path to the scene file to be refreshed.
    Returns:

  • No return value

Version

This function requires Godot 4.3 or higher.

This function is useful if a script extension is not automatically applied. This situation can occur when a script is attached to a preloaded scene. If you encounter issues where your script extension is not working as expected, try to identify the scene to which it is attached and use this method to refresh it. This will reload already loaded scenes and apply the script extension.


• void extend_scene(scene_vanilla_path: String, edit_callable: Callable) static🔗

Description:🔗

Extends a specific scene by providing a callable function to modify it.

Parameters:🔗

  • scene_vanilla_path (String): The path to the vanilla scene file.
  • edit_callable (Callable): The callable function to modify the scene.

Returns:

  • No return value

The callable receives an instance of the "vanilla_scene" as the first parameter.


• ModData get_mod_data(mod_id: String) static🔗

Description:🔗

Gets the ModData from the provided namespace.

Parameters:🔗

  • mod_id (String): The ID of the mod.

Returns:

  • ModData: The ModData associated with the provided mod_id, or null if the mod_id is invalid.

• Dictionary get_mod_data_all() static🔗

Description:🔗

Gets the ModData of all loaded Mods as Dictionary.

Returns:


• String get_unpacked_dir() static🔗

Description:🔗

Returns the path to the directory where unpacked mods are stored.

Returns:

  • String: The path to the unpacked mods directory.

• bool is_mod_loaded(mod_id: String) static🔗

Description:🔗

Returns true if the mod with the given mod_id was successfully loaded.

Parameters:🔗

  • mod_id (String): The ID of the mod.

Returns:

  • bool: true if the mod is loaded, false otherwise.

• bool is_mod_active(mod_id: String) static🔗

Description:🔗

Returns true if the mod with the given mod_id was successfully loaded and is currently active.
Parameters: - mod_id (String): The ID of the mod.
Returns: - bool: true if the mod is loaded and active, false otherwise.