Paper + Velocity plugin from a single codebase. Shared logic lives in common,
platform modules are thin adapters. Built with Gradle (Kotlin DSL), Java 25,
Adventure 5 MiniMessage, Configurate and Incendo Cloud v2.
| Module | Contents |
|---|---|
api |
Public SPI for other plugins (TemplateApi, Templates holder). No platform deps. |
common |
Core: config, messages, commands, example feature, unit tests. No Bukkit/Velocity imports. |
paper |
JavaPlugin + PluginBootstrap + PluginLoader, paper-plugin.yml, runServer. |
velocity |
@Plugin entrypoint, BuildConstants version injection, runVelocity. |
One command tree (/template ping|version|reload) is defined once in
common/.../command/TemplateCommands and registered on both platforms.
- JDK 25 to build (Gradle downloads the toolchain automatically if missing).
- Paper 26.3+ for the paper jar, Velocity 4.2+ for the velocity jar.
./gradlew build # tests + both shaded jars
./gradlew :paper:runServer # Paper dev server on :25565, debugger on :5005
./gradlew :velocity:runVelocityArtifacts: paper/build/libs/multiloader-template-paper-<version>.jar,
velocity/build/libs/multiloader-template-velocity-<version>.jar.
| Command | Permission |
|---|---|
/template ping |
template.command.ping |
/template version |
template.command.version |
/template reload |
template.command.reload |
Commands are registered by Cloud itself — do not list them in paper-plugin.yml.
config.yml is created from bundled defaults on first start. Missing keys heal
themselves on reload; a broken file keeps the last good config and logs a warning.
The schema is versioned (config-version key): old files migrate automatically
on load, new migrations go into ConfigMigrations.
settings.gradle.kts—rootProject.name.gradle.properties—group,version,description.- Package
kz.bejiihiu.template→ your own (rename dirs +main/bootstrapper/loaderinpaper-plugin.yml,@Plugin(id)in velocity). paper-plugin.yml/@Plugin—authors,website,name..github/CODEOWNERS,.github/FUNDING.yml— your username.LICENSE— copyright holder.
- Conventional Commits, SemVer (
X.Y.Ztags → GitHub releases via CI). - Shared code in
commonis covered by JUnit 5 tests at public seams. - User input reaches MiniMessage only via
Placeholder.unparsed/parsed— never by concatenation. apiexposesTemplateApi; platform modules register the core on enable and unregister on disable.
Structure inspired by milkdrinkers/Minecraft-Plugin-Template. Libraries: Adventure, Configurate, Cloud, run-task.
MIT — see LICENSE.