Skip to content
On this page

Using Other Mods and Plugins

A script pack must declare every external mod or Paper plugin whose API it uses. The declaration controls runtime validation and classloading; your development project separately needs that API on its compile classpath.

Required Integration

This manifest accepts Create 6.x on Fabric or NeoForge:

json
{
  "id": "create_integration",
  "name": "Create Integration",
  "version": "1.0.0",
  "dependencies": [
    {
      "id": "create",
      "version": ">=6.0.0 <7.0.0",
      "required": true,
      "platforms": ["fabric", "neoforge"],
      "environment": "both"
    }
  ]
}

Katton validates only entries applicable to the current platform and side. If a required dependency is missing, disabled, or outside the accepted version range, the pack is excluded before compilation.

Supported version expressions include exact versions, comparisons, whitespace/comma-separated AND conditions, and || alternatives.

Optional Integration

Set required to false when the base pack can run without the integration:

json
{
  "dependencies": [
    {
      "id": "spark",
      "version": "*",
      "required": false,
      "platforms": ["fabric", "neoforge", "paper"],
      "environment": "server"
    }
  ]
}

Then branch before using the optional API:

kotlin
import top.katton.api.ServerPhase
import top.katton.api.ServerReadyContext
import top.katton.api.ServerScriptEntrypoint
import top.katton.api.dependencies

@ServerScriptEntrypoint(ServerPhase.READY)
fun optionalIntegration(context: ServerReadyContext) {
    if (!dependencies.isLoaded("spark")) {
        println("Spark integration is unavailable on ${context.platform}")
        return
    }

    println("Spark version: ${dependencies.version("spark")}")
}

dependencies.require(id) is useful after an explicit availability check or when a clearer runtime error is desired. It does not replace a required manifest declaration.

Typed Paper Plugin Calls

Paper dependencies use the plugin name known to PluginManager:

json
{
  "dependencies": [
    {
      "id": "PlaceholderAPI",
      "version": "*",
      "required": true,
      "platforms": ["paper"],
      "environment": "server"
    }
  ]
}

After declaring it, a world script can import and call the plugin API normally:

kotlin
import me.clip.placeholderapi.PlaceholderAPI
import org.bukkit.event.player.PlayerJoinEvent
import top.katton.api.ServerPhase
import top.katton.api.ServerScriptEntrypoint
import top.katton.api.event.managed.registerEvent

@ServerScriptEntrypoint(ServerPhase.READY)
fun placeholderApiIntegration() {
    registerEvent<PlayerJoinEvent> { event ->
        val message = PlaceholderAPI.setPlaceholders(
            event.player,
            "Welcome %player_name%!"
        )
        event.player.sendMessage(message)
    }
}

Katton compiles against the plugin's real jar or class directory and delegates runtime loading to its existing classloader. Typed calls do not use reflection per invocation. Paper dependencies are available only at ServerPhase.READY; do not use plugin classes from BOOTSTRAP.

Development Classpath

The manifest does not download an API for IntelliJ or Gradle. Use one of these approaches in the script-pack project:

kotlin
dependencies {
    // Preferred when the API has a Maven publication:
    compileOnly("group:artifact:version")

    // Or place the dependency jar in lib/:
    compileOnly(fileTree("lib") { include("*.jar") })
}

The template generator always creates the lib/*.jar compile-only fallback and lets you add world-pack dependencies before downloading the project. Its empty global pack starts with dependencies: []; add dependencies to that manifest later only if global scripts use them.

Platform Behavior

PlatformResolution and execution
FabricResolves mod IDs through Fabric Loader and includes required transitive mod dependencies.
NeoForgeResolves mod IDs through NeoForge and includes required transitive mod dependencies.
PaperResolves enabled plugins through PluginManager at ServerPhase.READY and delegates to their classloaders.

The receiving multiplayer client validates its own applicable dependencies. A server-side installation does not prove the matching client mod is present.

For the full schema and version syntax, see Manifest, Dependencies, and Signing.