Addons API
Download the SIR+ API, wire it into your project, and use it to create real addon jars for the SIR+ runtime.
Download the current API
These compiled SIR+ API artifacts are generated directly from the standalone SIRApi project.
API Downloads
Select a published API version
Changing the selected version updates the download files below instantly without reloading the page.
Generated from the standalone `SIRApi` project.
Introduces the canonical `com.bitaspire.sir.channel.*` channel contracts and keeps the legacy `com.bitaspire.sir.ChatChannel` bridge for compatibility.
Binary Jar
SIR-Plus-Api-0.3.2.jar
Use this artifact as your `compileOnly` dependency when building an addon.
Sources Jar
SIR-Plus-Api-0.3.2-sources.jar
Attach this jar in your IDE for source navigation and better autocomplete context.
Javadoc Jar
SIR-Plus-Api-0.3.2-javadoc.jar
Use this when your IDE supports attached javadocs for inline API documentation.
Add To Project
Choose your build tool
The snippet below updates instantly for version 0.3.2.
Gradle Kotlin DSL
Ideal if your addon uses `build.gradle.kts`.
build.gradle.kts
dependencies {
compileOnly(files("libs/SIR-Plus-Api-0.3.2.jar"))
}Download the selected API jar and place it in a local `libs/` folder inside your addon project.
This keeps the API available only at compile time while SIR+ provides the real classes at runtime.
The runtime loader expects addon.yml at the root of your jar. If that file is missing, SIR+ skips the addon.
What the API is for
SIRApi exists so you can extend SIR+ without forking the base plugin. The API gives you access to:
- the SIR+ plugin instance and managers
- addon lifecycle hooks
- command-provider integration
- user data wrappers
- helper utilities for listeners, files, placeholders, and chat toggles
The normal addon workflow is:
- compile against the API jar with
compileOnly - implement a class that extends
SIRAddon - ship
addon.yml - optionally ship
commands.yml - drop the jar into
plugins/SIR-Plus/addons
Add the API to your project
Use the build-tool selector in the download box above to switch between Gradle Kotlin, Gradle Groovy, Maven, and a manual IDE-style setup. The snippet updates automatically for the selected API version.
Suggested project layout
my-addon/
src/main/java/...
src/main/resources/
addon.yml
commands.yml
config.ymlOnly addon.yml is mandatory. The rest depends on what your addon does.
addon.yml reference
Typical addon descriptor:
main: com.example.sirplus.ExampleAddon
name: example-addon
title: Example Addon
description:
- Adds custom behavior on top of SIR+.
depend: []
soft-depend:
- PlaceholderAPIField meaning
| Field | Required | Meaning |
|---|---|---|
main | Yes | Fully qualified entrypoint class |
name | No but recommended | Stable addon key used by the runtime |
title | No but recommended | Friendly display name |
description | No | Description lines for menus or metadata |
depend | No | Hard dependency on other addons |
soft-depend | No | Soft dependency on other addons |
Remember that depend and soft-depend here refer to addons, not Bukkit plugins. Bukkit plugin dependencies are better represented with PluginDependant.
Minimal addon class
package com.example.sirplus;
import com.bitaspire.sir.SIRApi;
import com.bitaspire.sir.addon.SIRAddon;
public final class ExampleAddon extends SIRAddon {
@Override
public boolean register() {
saveResource("config.yml", false);
SIRApi.instance().getPlugin().getLogger().info(getName() + " loaded successfully.");
return true;
}
@Override
public boolean unregister() {
SIRApi.instance().getPlugin().getLogger().info(getName() + " unloaded.");
return true;
}
}This is enough for SIR+ to:
- instantiate the addon
- create its data folder
- extract resources you save with
saveResource(...) - register the addon in the addon manager
Addon commands with CommandProvider
If your addon should contribute commands, implement CommandProvider and ship a commands.yml descriptor in the jar root.
Minimal provider example:
import com.bitaspire.sir.addon.SIRAddon;
import com.bitaspire.sir.command.CommandProvider;
import com.bitaspire.sir.command.SIRCommand;
import java.util.Collections;
import java.util.Set;
public final class ExampleAddon extends SIRAddon implements CommandProvider {
@Override
public Set<SIRCommand> getCommands() {
return Collections.singleton(new ExampleCommand());
}
}commands.yml reference
main: com.example.sirplus.ExampleAddon
name: ExampleAddon
title: Example Addon
description:
- Example addon command provider.
commands:
example:
permission: sir.example
aliases: [ex]
description: "Example command"
usage: "/example <arg>"
permission-message: "You do not have permission"
sub-commands:
reload: sir.example.reload
depends:
enabled: false
parent: "other"What SIR+ reads from commands.yml
| Field | Meaning |
|---|---|
commands.{name}.permission | Base permission node |
aliases | Alternative labels |
description | Help and metadata text |
usage | Usage string |
permission-message | Fallback denial message |
sub-commands | Derived or explicit subcommand permissions |
depends.enabled and depends.parent | Declares child commands that depend on a parent command |
This is the same command model used by the built-in providers, so addon commands can feel native to the platform.
Useful API types
The public API jar includes much more than SIRAddon. These are the types you will reach for most often.
| Type | Why you would use it |
|---|---|
SIRApi | Global entrypoint for managers, plugin instance, scheduler, and shared services |
SIRAddon | Base class for addon lifecycle |
AddonManager | Runtime addon lookup and addon-facing integration points |
com.bitaspire.sir.channel.ChatChannel | The current channel contract used by SIR+ for routing, audience, formatting, and logging |
Access, Audience, Style, Logging, and Click | Break a channel into readable subcontracts instead of forcing one flat interface |
CommandProvider | Lets the addon expose SIR-aware commands |
SIRCommand | Base class for commands with permission and completion helpers |
SettingsService | Per-user toggle state backing features such as chat toggles |
PluginDependant | Declares Bukkit plugin dependencies |
Listener | Safer listener registration and unregistration helper |
PAPIExpansion | Helper base for PlaceholderAPI expansions |
UserFormatter<T> | Formatter contract for user-aware text processing |
ExtensionFile and Config | File and config helper abstractions |
SIRUser and UserManager | User data wrappers for mute, ignore, channels, and related state |
ChatToggleable | Per-user toggle contract for chat-like features |
Package map
The current API jar exposes classes under:
com.bitaspire.sir.*com.bitaspire.sir.channel.*com.bitaspire.sir.addon.*com.bitaspire.sir.command.*com.bitaspire.sir.module.*com.bitaspire.sir.user.*
That means addon code can interact with addon management, command management, module metadata, and user data without reflecting into the main plugin jar.
ChatChannel changes in 0.3.2
API 0.3.2 formalizes the new channel model used by the modern channels module and by SIR+:
- the canonical interface is now
com.bitaspire.sir.channel.ChatChannel - channel behavior is grouped into
Access,Audience,Style,Logging, andClick - channel routing is no longer exposed as one giant flat interface
- the old
com.bitaspire.sir.ChatChannelstill exists only as a deprecated compatibility bridge for pre-0.3.2addons
If you are writing a new addon, import the new package directly.
import com.bitaspire.sir.channel.ChatChannel;
import com.bitaspire.sir.channel.Access;
import com.bitaspire.sir.channel.Audience;
import com.bitaspire.sir.channel.Style;
import com.bitaspire.sir.channel.Logging;Typical migration examples:
- old
channel.getLocalAccess()-> newchannel.getAccess() - old
channel.getRadius()-> newchannel.getAudience().getRadius() - old
channel.getChatFormat()-> newchannel.getStyle().getFormat() - old
channel.getLogFormat()-> newchannel.getLogging().getFormat() - old
channel.getClickAction()-> newchannel.getStyle().getClick()
This is the main API change you need to account for when upgrading addon code from the previous public builds.
Common extension patterns
Plugin-aware loading
Implement PluginDependant when your addon expects a plugin such as PlaceholderAPI or Vault.
That lets SIR+ defer or validate loading around external plugin availability.
Per-user toggles
Implement ChatToggleable when your addon owns a user toggle and you want to store that state through SIR's settings flow.
Placeholder expansions
Extend PAPIExpansion if your addon also ships placeholders.
Custom formatting
Implement UserFormatter<T> when your addon should expose formatter behavior that other addon-aware code can resolve through the addon manager.
Event listeners
Extend com.bitaspire.sir.Listener when you want the convenience registration helpers instead of raw Bukkit boilerplate.
Build and deploy
- Compile the addon jar against the selected API jar, currently
SIR-Plus-Api-0.3.2.jar. - Make sure
addon.ymlis at the jar root. - If the addon exposes commands, include
commands.ymltoo. - Copy the jar into
plugins/SIR-Plus/addons/. - Start the server.
- Use
/sir addonsto verify that the addon is visible. - Enable or disable it with
/sir addons [name] [enable/disable/toggle]as needed.
If the jar loads but its commands do not appear, the usual culprit is a missing or malformed commands.yml.
Troubleshooting
Check these first when an addon does not behave as expected:
addon.ymlexists at the jar root- the main class extends
SIRAddon - addon hard dependencies in
dependare present - plugin dependencies declared through
PluginDependantare installed - the addon is enabled in
addons/states.yml - if commands are missing,
commands.ymlexists and the addon implementsCommandProvider
For the runtime side of loading and state persistence, continue with Addon Runtime.
Addon Runtime
Understand how SIR+ loads addon jars, reads `addon.yml`, persists addon state, and wires addon commands.
Migration Guide
Migration reference for moving from Legacy SIR, Modern SIR, EssentialsX, or CMI into SIR+.
Last updated on