Skip to content

API Script Lifecycle

Piggo41 edited this page Oct 13, 2026 · 9 revisions

Script lifecycle

Lua API / Script lifecycle

On this page

Script discovery

BetaMoon discovers single .lua files directly inside the instance's .minecraft/betamoon/scripts directory. It also discovers directories and ZIP archives with betamoon.mod.json at their root. Other directories and ZIPs are ignored. Every discovered mod has one entrypoint and needs name and modInit after manifest and entrypoint metadata are combined.

Packaged mods

A packaged mod can select any contained .lua entrypoint and use private modules through ordinary Lua require. Package directories and ZIPs have the same lifecycle and dependency behavior as single-file mods. See Packaged Lua mods for the manifest, layout, module, asset, and distribution rules.

Metadata

Declare metadata at the entrypoint's top level, before initialization. A packaged mod may instead put these fields in its manifest. When both locations declare a field, their values must match.

name = "Example"
version = "1.0.0"
dependencies = { "Shared Materials" }
Field Type Default Meaning
name string Required Non-empty script name, unique among loaded scripts; used by dependencies and the Scripts screen.
version string "0.0.0" Display version. A semantic-version format is useful but not enforced.
description string Absent Description displayed in the Scripts screen.
image string Absent Image path relative to the loose-script root or packaged-mod root.
dependencies list of strings {} Names of scripts that must initialize first. Missing, failed or cyclic dependencies prevent dependent initialization.

Numeric content IDs do not establish load order. Declare a dependency whenever initialization requires another script's content or exported module.

modInit()

Initializes the script after its dependencies. Required function. Register content, subscriptions and module exports here.

function modInit()
    betamoon.chat:send("Example initialized")
end

Top-level code is evaluated while reading scripts; dependency ordering applies to initialization, so do not import dependency modules at the top level.

modUnload()

Optional cleanup function for the old script generation before it is reloaded. Tracked subscriptions, overrides and other reversible resources also receive automatic cleanup.

function modUnload()
    -- Release additional Lua-side state owned by this generation.
end

This is not a promise of a shutdown callback on every process exit. Structural scripts retained during reload do not undergo the ordinary unload/reinitialize cycle.

modReload()

Optional function called for the replacement generation after successful hot-reload initialization. It is not called on initial game startup.

function modReload()
    betamoon.chat:send("Reloaded")
end

Reload sequence

For reloadable scripts, BetaMoon calls the old modUnload(), removes that script's registrations, runs new modInit() calls in dependency order, then calls successful reload hooks. Syntax errors leave the previous scripts loaded. Initialization errors can occur after old registrations have been removed.

Reload on save is optional and disabled by default. Enable it with scripts.hotReloadOnFileChange=true in .minecraft/config/betamoon.cfg; the setting is read at startup. Saving a top-level Lua file then triggers reload after changes settle. Manual Reload remains available on the Scripts screen; the default gameplay shortcut is Ctrl+Shift+R. See Hot reload and compatibility.

Examples: Lifecycle signatures, reload lifecycle.

Clone this wiki locally