About HookDOTS API
From ThunderstoreProvides an API for mods to hook Unity DOTS systems.
HookDOTS API
HookDOTS is a modding library for hooking Unity DOTS games. By itself, it doesn't do anything.
Why use HookDOTS?
Harmony is an excellent tool, but it fails at one important thing: Hooking unmanaged systems in IL2CPP builds.\ HookDOTS was created to solve this problem.
Notable attributes provided (for plugin developers):
[EcsSystemUpdatePrefix(typeof(EquipItemSystem))][EcsSystemUpdatePostfix(typeof(EquipItemSystem))][WhenCreatedWorldsContainAny("Server", "Client_0")]
Installation
- Install BepInEx
- Extract
HookDOTS.API.dllinto(VRising folder)/BepInEx/plugins
Usage
For Server Operators
By itself, HookDOTS doesn't do anything. It is required by other plugins and should be kept up to date.
For Plugin Developers
How to use
1. Add a reference to the plugin.
>dotnet add package HookDOTS.API -v 1.*
2. Add the API plugin as a dependency via the BepInDependency attribute on your plugin class.
[BepInPlugin(MyPluginInfo.PLUGIN_GUID, MyPluginInfo.PLUGIN_NAME, MyPluginInfo.PLUGIN_VERSION)]
[BepInDependency("HookDOTS.API")]
public class ExamplePlugin : BasePlugin
3. Register hooks in your plugin's Load method.
public override void Load()
{
//... other initialization code
// Register your plugin's hooks with HookDOTS
_hookDOTS = new HookDOTS.API.HookDOTS(MyPluginInfo.PLUGIN_GUID, Log);
_hookDOTS.RegisterAnnotatedHooks();
}
4. Teardown in your plugin's Unload method.
public override bool Unload()
{
//... other unloading code
_hookDOTS.Dispose();
return true;
}
5. Set up prefix and postifx hooks for System OnUpdate calls. Both managed and unmanaged systems can be hooked.
public class ExamplePatch
{
// The hook must be `public` and `static`.
// If you want SystemState* passed in, an `unsafe` context is also required.
[EcsSystemUpdatePrefix(typeof(EquipItemSystem))]
unsafe public static bool ExamplePrefix(SystemState* systemState)
{
var world = systemState->World;
ExamplePlugin.LogInstance.LogInfo($"ExamplePrefix executing in world {world.Name}.");
// You can return false, to skip the hooked OnUpdate. Other prefix hooks will still run.
bool shouldSkipTheOriginal = true;
return !shouldSkipTheOriginal; // this will be returned, and is false. Therefore the original will be skipped.
}
[EcsSystemUpdatePrefix(typeof(EquipItemSystem))]
unsafe public static bool ExamplePrefixNoSkip(SystemState* systemState)
{
// Prefer to use the AfterDetours constants instead of true/false.
// return AfterDetours.SkipOriginalMethod;
return AfterDetours.OkToRunOriginalMethod;
}
[EcsSystemUpdatePostfix(typeof(EquipItemSystem))]
unsafe public static void ExamplePostfix(SystemState* systemState)
{
var world = systemState->World;
ExamplePlugin.LogInstance.LogInfo($"ExamplePostfix executing in world {world.Name}.");
// Unlike a prefix hook, a postfix hook cannot return false to skip anything.
// The only valid return type is `void`.
}
}
onlyWhenSystemRuns
You can set onlyWhenSystemRuns to false, and the hook will be called even if the system doesn't actually run.
[EcsSystemUpdatePrefix(typeof(EquipItemSystem), onlyWhenSystemRuns: false)]
public static void ExamplePrefix2()
{
// (this is commented out, because the log would be spammed every frame)
// ExamplePlugin.LogInstance.LogInfo($"ExamplePrefix2 executing");
}
Throttling
If you're using hooks to dump information and don't want to be flooded every frame, the Throttle attribute can be used.
// You can specify `days`, `hours`, `minutes`, `seconds`, and `milliseconds` to define the throttle interval.
// Internally, these are used to create a `System.TimeSpan`
[Throttle(seconds: 10)]
[EcsSystemUpdatePrefix(typeof(EquipItemSystem), onlyWhenSystemRuns: false)]
public static void ExamplePrefixThrottled()
{
ExamplePlugin.LogInstance.LogInfo($"ExamplePrefixThrottled executing (throttled to once every 10 seconds)");
}
Alternative ways to register hooks
Procedurally, using a HookRegistrar:
var hookDOTS = new HookDOTS.API.HookDOTS(MyPluginInfo.PLUGIN_GUID, Log);
//...
var hook = HookDOTS.Hooks.System_OnUpdate_Prefix.CreateHook(MyHookMethod);
hookDOTS.HookRegistrar.RegisterHook_System_OnUpdate_Prefix<TakeDamageInSunSystem_Server>(hook);
Builder style, using SetupHooks:
var hookDOTS = new HookDOTS.API.HookDOTS(MyPluginInfo.PLUGIN_GUID, Log);
//...
hookDOTS
.SetupHooks()
.BeforeSystemUpdates<EquipItemSystem>()
.ExecuteDetour(MyMethodA).Always()
.And()
.ExecuteDetour(MyMethodB).Always()
.Also()
.AfterSystemUpdates<TakeDamageInSunSystem_Server>()
.ExecuteAction(MyMethodC).Throttled(seconds: 2)
.Also()
.BeforeSystemUpdates<DropInventoryItemSystem>(onlyWhenSystemRuns: false)
.ExecuteDetour(MyMethodD).Throttled(seconds: 5)
.RegisterChain();
// be sure to call RegisterChain! Otherwise the entire chain will be discarded.
World Readiness triggers for Initialization
There are world readiness checks/triggers if you need to defer something until after worlds are created.
Worlds are immediately checked during hook registration, in case they were already set up.\
Highlights
From source dataLoaders
Runs on BepInEx.
Footprint
Rated a light load on a server.
Last update
Its author last shipped an update 12 mo ago.
HookDOTS API on Nxeon
From our catalogue- One-click install
- Not available. One-click install isn't available for this game's mods yet. Download it and upload it to your server in Files.
- Server type needed
- BepInEx
- Server load
- light
- Smallest plan we suggest
- V Rising — 6 GB (6 GB RAM). This follows our own load rating above, not a benchmark.
- Latest build
- 1.1.1, released 2025-10-22
Game versions by loader
| Loader | Game versions | Newest |
|---|---|---|
| BepInEx |
From 3 recorded builds of HookDOTS API.
Recent builds
| Build | Released | Game versions | Loaders |
|---|---|---|---|
| 1.1.1 | 2025-10-22 | n/a | BepInEx |
| 1.1.0 | 2025-07-15 | n/a | BepInEx |
| 1.0.0 | 2025-06-08 | n/a | BepInEx |
Dependencies
- Required: BepInExPack V Rising
Declared by the newest build that lists any. Required ones are installed with it on one-click installs.
Run HookDOTS API on a V Rising server
Deploy a server above, then upload the file in Files.
What kind of mod it is
From the catalogAdmin & protection
Permissions, moderation, anti-cheat and land protection for the people running the server.
Compatibility
- Game
- V Rising
- Loaders
- BepInEx
- Requires
- One-click install needs a BepInEx server.
Verified at the source
- ✓ThunderstoreOfficial listing, checked 2026-10-02Open ↗
- ✓Authorcheesasaurus, as published on Thunderstore
- ✓LicenseNot published by the sourceFree





