Developer Quick Start

Build a minimal Java 17 Turboism plugin against the current Preview SDK.

The current source-backed development path is to add a plugin module to the Turboism repository. A standalone starter template and stable Maven coordinates are not published yet.

1. Create the module

plugins/hello/
├── build.gradle.kts
├── src/main/java/dev/example/plugin/HelloPlugin.java
├── src/main/resources/META-INF/turboism/plugin.json
└── src/test/java/dev/example/plugin/HelloPluginTest.java

Add it to the source repository's settings.gradle.kts:

include("plugins:hello")

2. Depend on the SDK only

plugins {
    `java-library`
}

dependencies {
    compileOnly(project(":sdk"))
    testImplementation(project(":sdk"))
}

compileOnly is intentional: Runtime provides the SDK. The plugin JAR must not copy dev/turboism/sdk/** classes.

Do not depend on Runtime, Bootstrap, com.live2d.*, another plugin's private implementation package, reflection bridges, host widgets, native handles, or the host ClassLoader.

3. Implement the entrypoint

package dev.example.plugin;

import dev.turboism.sdk.plugin.PluginContext;
import dev.turboism.sdk.plugin.TurboismPlugin;

public final class HelloPlugin implements TurboismPlugin {
    private PluginContext context;

    @Override
    public void init(final PluginContext context) {
        this.context = java.util.Objects.requireNonNull(context, "context");
        context.logger().info("HelloPlugin initialized");
    }

    @Override
    public void enable() {
        context.logger().info("HelloPlugin enabled");
    }

    @Override
    public void disable() {
        context.logger().info("HelloPlugin disabled");
    }

    @Override
    public void shutdown() {
        context.logger().info("HelloPlugin shutdown");
        context = null;
    }
}

The class must be public, implement TurboismPlugin or a subinterface, and expose a public no-argument constructor.

4. Add manifest v2

Create src/main/resources/META-INF/turboism/plugin.json:

{
  "format": "turboism.plugin.meta",
  "schemaVersion": 2,
  "id": "dev.example.plugin.hello",
  "name": "Hello Plugin",
  "version": "0.1.0",
  "description": "Minimal Turboism plugin lifecycle example.",
  "entrypoints": [
    "dev.example.plugin.HelloPlugin"
  ],
  "turboismApi": "[0.1.0,0.2.0)",
  "authors": [
    { "name": "Example Author" }
  ],
  "license": "MIT",
  "website": "https://example.org/hello-plugin",
  "resources": [],
  "i18n": {
    "baseName": "META-INF/turboism/i18n/messages",
    "locales": []
  },
  "dependencies": [],
  "permissions": [],
  "capabilities": [],
  "environment": {
    "requiresCubism": false,
    "ui": "none"
  }
}

Read Plugin Manifest and Packaging before adding permissions, resources, localization, dependencies, or multiple entrypoints.

5. Build and validate

./gradlew :plugins:hello:test :plugins:hello:jar validatePluginMeta \
  --no-daemon --console=plain

Build results are written under:

build/worktree/<worktreeId>/hello/libs/

The JAR in libs/ is the plugin release file; keep it unchanged when distributing.

A constructor-only test is sufficient for this lifecycle-only example.

Once the plugin registers actions, UI, events, configuration, or tasks, use a recording/fake PluginContext to verify registrations, failure handling, disable/shutdown behavior, and scope cleanup.

6. Distribute the JAR

Share the built JAR directly. There is no wrapper archive, no package script, and no separate packaging step.

7. Install it

Use Turboism plugin management and choose Install from JAR… to select the built JAR. Confirm the dialog that marks the JAR as a local/unverified source. The change is staged and applies after Cubism restarts.

For local development or fallback use, you can also install the JAR manually: fully close Cubism, copy the built JAR into the root of <turboism.home>/plugins/, make sure no older JAR with the same plugin ID remains, and restart with the same Turboism home.

Manual installation bypasses the managed safeguards (UI confirmation, preflight, staging, backup/restore); the JAR still goes through startup validation. See Plugin Management for the full manual procedure and the update/uninstall rules.

Next steps