Skip to content

Creating a Mod

ESTONlA edited this page Sep 6, 2026 · 2 revisions

Creating a Mod

Create one folder per mod:

mods/my-first-mod/
  manifest.json
  main.lua

Example manifest:

{
  "id": "my-first-mod",
  "name": "My First Mod",
  "version": "1.0.0",
  "author": "Your Name",
  "entry": "main.lua",
  "hostOnly": true
}

Example script:

htf.on("creature_killed", function(creature_name)
  htf.chat("Defeated " .. creature_name)
end)

htf.command("hello", function(args)
  htf.chat("Hello from Lua.")
end)

Reload from the Lua Mods Pause-menu page after editing. A failed script is isolated and reported in BepInEx output.

IDs must contain 1-64 lowercase ASCII letters, digits, underscores, or hyphens and start with a letter or digit. The entry must be a relative .lua path inside the mod folder. Linked files/folders and entries larger than 256 KiB are rejected.

Optional "dependencies": ["another-mod"] loads the named mod first. Dependencies use exact IDs, without version ranges. Missing dependencies, load errors, and cycles block the dependent mod; check BepInEx output. Each mod has its own Lua state.

Startup code runs immediately, even at the main menu. An optional global on_load() function runs after successful startup. Host-only timers and events wait for hosting, but on_load() is not a session-start event.

Reload removes callbacks, commands, native action buttons, and timers, but preserves data. It does not undo money already awarded. A runtime error disables the failed mod and its dependents until reload. Previously dead or hooked objects are not counted again just because scripts were reloaded.

Clone this wiki locally