Addon API - clockworktownsmp/clockwork-bosses GitHub Wiki

Addon API

Want to give your boss an attack we haven't included? The addon API lets you add an action and its settings through your own Fabric mod. Clockwork Bosses still handles phases, subphase order, who's in the arena, targeting, player support, and rewards.

Status: experimental revision 1, included in stable 0.2.0 and local beta.6. The older 0.1 jar contains neither this API nor optional-client fallback. Clients installing the core must match the server build. An API included in a stable core release still has no stable binary compatibility promise. Beta.6 has native automated checks; addon-specific real multiplayer and interruption tests remain separate. See Versions and release status.

Read this overview first, then follow the lightning addon walkthrough. Use the API reference for exact methods and limits.

What an API is

API means Application Programming Interface: a documented way for one program to use another. Here, that means Java interfaces and methods inside Minecraft. You don't need a web request, API key or separate service.

An addon is an ordinary Fabric mod with its own jar. Installing it adds the code; selecting its action in a template configures that code. A template alone can't create a new mechanic.

Term Meaning in this project
Class Code describing an action, such as lightning.
Instance One running copy of that class, belonging to one action execution.
Method A named operation such as start().
Interface The methods a class agrees to provide.
Implements A class follows an interface, such as BossAction.
Callback An addon method that Clockwork Bosses calls at a defined time.
Registry The startup catalog of available action definitions.
Factory Instructions for creating a fresh action instance.
Context Live information and services for the current execution.
UUID An identifier used to find a player or entity again.

What addons can add today

  • Actions with a start, ongoing update, completion and interruption lifecycle.
  • Number fields, boolean choices and text fields or dropdowns in the standard editor.
  • Listeners for activation, membership, phase transitions, accepted hits and encounter endings.
  • Mechanics using the current boss controller and its declared capabilities.

Core combat, melee, Sonic Boom, recovery, roar and burrow use the same registrations and lifecycle. Their Warden animation details live behind the controller boundary.

Custom targeting strategies, condition/trigger APIs, arbitrary boss-mob registration and custom client widgets are not public extension points yet. The backend currently controls Wardens. A separate published API dependency is also future work.

Who controls what

Clockwork Bosses owns The addon supplies
Activation, health phases and encounter termination A new mechanic.
Subphase order and transition after completion What happens during its action and when it returns complete.
Arena membership and eligible-player helpers Its choice among eligible participants.
Existing native targeting, attack enable flags and cooldowns Its action's permission to coexist with native attacks.
Standard controls and server validation Setting labels, help, defaults, types and limits.
Runtime closure and registered resource cleanup Ownership declarations and any additional restoration.

These responsibilities depend on the core and addon following the same contract. Installed Java addons are trusted code, not a security sandbox. Direct Minecraft access does not stop an addon from bypassing helpers; authors should use the public contract instead of private core classes.

Startup and execution are different

During startup, Fabric discovers the addon's clockwork_bosses entrypoint. Clockwork Bosses calls its register(...) method, adds the definition, then freezes the action catalog before templates are loaded. Registration makes the mechanic available to choose. It doesn't run an attack.

An ID such as clockwork_lightning_example:lightning has an addon namespace before the colon and an action name after it. The registrar checks ownership and rejects duplicate IDs. Restart after installing an addon; /boss reload cannot load new Java code.

When a subphase selects the action, its factory creates a fresh object for that execution. Each object should have its own target and timing fields. The core doesn't check that the instance is fresh, so returning a shared mutable object can mix state between bosses. Always return a new instance.

The action lifecycle

  1. Create: the runtime establishes ownership of a fresh instance.
  2. Choose native behavior: pausesNativeBehaviors() is sampled once. Its default pauses behavior execution and navigation; sensors and memory expiry continue.
  3. Start: start(context) selects targets and registers resources or restoration.
  4. Update: tick(context) runs from the existing boss AI callback. Return RUNNING to continue or COMPLETE to advance the existing sequence.
  5. Stop: stop(context, reason) runs once, including after a partially failed start.
  6. Clean up: registered callbacks run in reverse acquisition order, then runtime references are cleared.

Game ticks still drive ongoing actions; the API reuses the existing boss callback rather than adding another global watcher. Twenty ticks is about one second at normal server speed. Server slowdown changes elapsed real time.

To permit native attacks alongside an action, return false from pausesNativeBehaviors() and allow the appropriate ID through allowsNativeAttack(id). Phase enable flags, target checks and existing charge/recovery/cooldown rules still apply.

Context and ownership

Context method Purpose
settings() Read validated settings without reparsing JSON every tick.
elapsedTicks() Time since this execution began.
target() Resolve the current valid native target, when one exists.
participants() / isParticipant(player) Resolve eligible arena participants and recheck eligibility.
controller() Access the boss and supported controller operations.
level() Access the server world on the server thread.
damage(...) Recheck eligibility and attempt native damage with encounter notifications.
ownEntity(...) Register cleanup and disable persistence for a temporary entity this action created.
onCleanup(...) Register other short restoration work before making a temporary change.

If an action waits before acting, store the player's UUID and look them up again when it's time to act. A player can disconnect, die, respawn, leave the arena or change dimension. Do not put live contexts in static collections, background jobs or timers. Live context getters reject a different thread before reading encounter/world state. Copy immutable settings or capture an immutable snapshot on the server thread if a worker needs data.

Entity ownership is for temporary entities created by the action, not players, bosses or another mod's existing entities. Register ownership before adding an entity to the world. Cleanup discards the exact owned entity if loaded, and never loads chunks to find it. The native save guard is intended to prevent an unloaded temporary entity from becoming a saved orphan. Owned entities also reject portals and cross-dimension teleport, because Minecraft creates a replacement entity outside the original cleanup identity. Same-world teleport remains available. Runtime verification remains pending.

For temporary attributes, prefer removing only your own namespaced modifier. Restoring an old base value without checking could overwrite a change another mod made in the meantime. Persistent mutations need a recovery plan because a process crash cannot run cleanup callbacks. Core burrow uses a saved surface/flags journal for that reason.

Interruptions and failures

A phase/subphase change, reload, death, removal, unload or shutdown closes the owned execution. Closure happens before callbacks, so reentrant cleanup cannot reopen it. Each execution has a generation counter; an old execution cannot finish a newer subphase. If a stop callback changes or removes the boss, the outer transition abandons its stale work. Replacement actions wait until outgoing cleanup returns. Snapshot-capture failure cannot skip resource release.

Recoverable runtime errors are logged and cleanup is attempted. The failed execution stays stopped until a transition or reload. It doesn't restart every tick. This may leave its action paused and still requires diagnosis. Fatal VM errors are not swallowed.

Missing action IDs fail template validation instead of substituting another mechanic or deleting saved settings. Restore the addon or select a registered action. Duplicate/invalid registration or a failing entrypoint can prevent initialization, which is a different failure from an interrupted running attack.

Settings and editor integration

Define your addon's settings once with BossSetting: the key, display label, description, default, type and validation. The server compiler, generated file comments and standard editor controls all use that definition.

The server sends descriptions to the client, not executable addon Java. A server-only addon using native Minecraft visuals can expose ordinary controls to clients with Clockwork Bosses. With the latest core server source, native-only actions can also run for players without the core client, who have no editor or custom presentation. The core adapter covers its own Warden metadata through native tracking; it cannot make an addon custom registry or direct packet format optional. New client assets, renderers, entities/items or custom networking may require installing the addon on clients too. Optional-client multiplayer checks remain pending.

The server validates saves against its own catalog. For registered actions, action_settings is optional: leave it out or use {} for the declared defaults. If present, it must be an object, not null, an array or a scalar. Missing or null declared scalar fields inside that object use their defaults. Unknown keys are preserved but are not arbitrary editable/executable fields. Changing action Type resets its action_settings to that mechanic's defaults. Native combat inheritance remains separate from addon settings.

Compatibility promises

Revision 1 is experimental. Its revision constant and jar metadata identify the contract. They don't enforce compatibility or mean that every release is interchangeable.

Before declaring a stable API, define what stays compatible across supported releases: public Java methods, setting IDs and keys, lifecycle behavior, event timing and supported Minecraft/Fabric versions. Adding an optional method or setting can preserve compatibility; removing a method or changing the meaning of an existing setting can break addons.

Current example source identifies addon 0.1.8. Its build reads the core's configured version and pins that exact version in runtime metadata (currently 0.3.0-beta.6). This is source inspection, not a newly verified packaged addon. Inspect the actual jar metadata and rebuild after changing core versions; a shared API revision does not promise binary compatibility.

Maintenance map

Paths below refer to the development source checkout and may not yet be published.

Concern First source to read
Public methods and supported settings src/main/java/clockwork/bosses/api/
Startup discovery ClockworkBosses.onInitialize()
Core action definitions ClockworkBossActions.java
Per-execution ownership, calls and cleanup ClockworkBossActionRuntime.java
Warden animation and burrow relocation ClockworkBossWardenController.java
Safe emergence search ClockworkBossBurrowDestination.java
Editor schema and validation ClockworkBossActionEditor.java, ClockworkBossEditorSchema.java
A standalone addon using only the contract examples/lightning-addon/src/main/java/clockwork/example/LightningAddon.java

Implementation files listed without a directory are under src/main/java/clockwork/bosses/. Read the walkthrough before following the reference into every method.

Safety and resource limits

The API review on 2026-10-10 added the safeguards above and checked operator-only editor permissions, session tokens, file revisions and server-owned action descriptions. No permission bypass was found in those reviewed paths. This is source-review evidence, not a guarantee about every addon or mod combination.

  • Installed addons are trusted Java. They can directly access Minecraft and files. This API cannot sandbox a malicious addon or safely stop a callback that loops forever.
  • Register event listeners once. Fabric retains them for the process lifetime. Registering per fight grows the listener array; capturing a live world/player/context can retain it after an encounter ends.
  • Keep callbacks short. Avoid disk/network work on the server thread. Catching exceptions won't keep a slow callback from holding up the server.
  • Declare ownership before mutation. Adopt each temporary entity and register restoration for other resources. Direct replacement/persistence overrides in another mod can bypass cooperative guards. A hard process stop cannot run cleanup callbacks.
  • Validate domain inputs. Text length/choices do not make a file path or URL safe. Whole-number setting definitions must fit a signed 32-bit integer, matching integer(key).

The review above recorded compilation/source checks rather than gameplay, latency or heap tests. On 2026-10-12 the example's build/runtime dependencies were corrected and addon 0.1.1 compiled against core 0.2.0-beta.3. The API remains experimental. Use the playtest checklist for registration, server-only editor fields, execution and interruption cleanup.