Skip to content

Modding

Modding is currently unofficially supported and is made possible with the BloodThief Mod Loader by Olvior. It was initially developed for the demo, but it works just fine with the full game. Functions on both Windows and Linux.

The mod loader also supports importing custom textures into Trenchbroom, BloodThief's custom mapping tool of choice. Learn more in the modloader readme.

Tip

To disable mods, rename override.cfg to anything else. You can find it alongside the Bloodthief executable.

Where to get mods

The best place for this at present is the modding discord, but there are mods floating around that you can install. Hopefully a more centralised location can be decided upon once the modding community grows.

Install mods by dropping the zip into the Bloodthief/mods folder in your steam directory. The modloader should auto-create this.

The following are a selection of useful/fun mods that should work with the current version of the game. Feel free to suggest more.

How to create your own mods

Info

To effectively create your own mods, you will want to obtain a copy of the BloodThief source code. The technique for this will not be disclosed in this guide.

Mods should be packed up as a .zip file, and should contain the following two files as a minimum.

Minimal Example

manifest.json
{
    "name": "Modname",
    "name_pretty": "Mod Name",
    "namespace": "ns",
    "version_number": "1.0.0",
    "description": "Mod Description",
    "dependencies": [],
    "incompatibilities": [],
    "authors": ["Author1"],
    "tags": ["cheats"],
    "description_rich": "Detailed Mod Description"
}
mod_main.gd
extends "res://addons/ModLoader/mod_node.gd"

func init():
    ModLoader.mod_log(name_pretty + " mod loaded")

Working mod_main.gd example

A more complete mod_main.gd file would look like this. Source

In the cases where you only have to set/inspect globally available variables, this approach is fine, if a little unoptimised.

mod_main.gd
extends "res://addons/ModLoader/mod_node.gd"

var stoneskin_enabled = Setting.new(self, "StoneSkin Enabled", Setting.SETTING_FLOAT, 1, Vector2(0, 1))

func init():
    ModLoader.mod_log(name_pretty + " mod loaded")

    settings = {
        "settings_page_name" = "Infinite StoneSkin",
        "settings_list" = [
            stoneskin_enabled
        ]
    }

func _process(_delta):
    if is_instance_valid(GameManager.player):
        if stoneskin_enabled.value == 0.0:
            return
        GameManager.player.stone_skin_active = true

Mod Override Example

In cases where you have to override local variables, or even functions, you will have to override the BloodThief code itself. As a simple example we will use the zeroLHBloodCost mod.

The code for the scythe looks something like this post-nerf:

scythe_interaction_behaviour.gd
func can_dash(player: Player):
    return player.blood_amount >= 0.3 and _can_dash and not _dash_on_cooldown and !player.is_on_floor() and player.on_ground_ray.get_collider() == null
Pre-nerf, the scythe (life harvester) did not have the blood cost shown as player.blood_amount >= 0.3. In this case, one solution to revert this nerf would be to overwrite this function like so:
scythe_interaction_behaviour_override.gd
extends "res://scripts/components/scythe_interaction_behavior.gd"

func can_dash(player: Player):
    return _can_dash and not _dash_on_cooldown and !player.is_on_floor() and player.on_ground_ray.get_collider() == null

By overwriting this script in this way, we completely remove the player blood check, leaving everything else in the function intact.

The extends path denotes the location of the script in the BloodThief source code to be overwritten. Only this function will be changed, leaving the rest of the file intact.

To actually overwrite this function, some extra code is required in main.gd

main.gd
extends "res://addons/ModLoader/mod_node.gd"

func init():
    ModLoader.mod_log(name_pretty + " mod loaded")
    var scythe_interaction_behaviour_override = load(path_to_dir+"/scythe_interaction_behaviour_override.gd")
    scythe_interaction_behaviour_override.take_over_path("res://scripts/components/scythe_interaction_behavior.gd")

Tip

Only change what you need, and try your best not to lazily include whole files in your overrides. This keeps file sizes small and shouldn't attract copyright infringement fairies.

Warning

At the moment if a source file contains a class_name, that file cannot be over-ridden. This is due to a bug in the godot engine from 4.x onwards.

Custom Scenes Example

  • Under construction

External Plugins Example

  • Under construction

The best way to learn is to inspect the mods of others and to dive into your own projects. If you have any questions, just pop into the Bloodthief modding server.

External Mod-Making Resources

Where do I publish my mods?

The current default place is the modding discord in the mods channel, but this is subject to change.