Skip to content

Supporting Paper too

A plugin that extends FeatherPlugin is Feather-only by default. On Paper it logs a red message and disables itself. To make it work on both FeatherMC and Paper servers, opt in with one method, then keep the FeatherMC-specific code behind a check.

Override allowPaper() and return true. Without this override the plugin stays Feather-only.

import dev.feathermc.feather.FeatherPlugin;
public final class MyPlugin extends FeatherPlugin {
@Override
protected boolean allowPaper() {
return true;
}
@Override
protected void onFeatherEnable() {
// runs on FeatherMC and on Paper
}
}

onFeatherEnable() and onFeatherDisable() still replace onEnable() and onDisable().

Branch on FeatherSupport.isFeather() for anything that uses the FeatherMC API (Feather, the events or the config classes). Paper does not have those classes, so loading them there throws a NoClassDefFoundError.

import dev.feathermc.feather.FeatherSupport;
@Override
protected void onFeatherEnable() {
if (FeatherSupport.isFeather()) {
// Register the FeatherMC listener only here, so Paper never loads it.
getServer().getPluginManager().registerEvents(new FeatherListener(), this);
getLogger().info("FeatherMC features enabled.");
} else {
getLogger().info("Running on Paper, FeatherMC features are off.");
}
}

Put all FeatherMC API use in separate classes, such as FeatherListener above, and only create or register them inside the isFeather() branch. A class that merely mentions an API type in a field, parameter or event handler can be loaded early and fail on Paper.

public final class FeatherListener implements Listener {
@EventHandler
public void onFlag(final AntiCheatFlagEvent event) {
// FeatherMC-only behaviour
}
}
build.gradle.kts
tasks.shadowJar {
include("dev/feathermc/feather/FeatherSupport*.class")
include("dev/feathermc/feather/FeatherPlugin*.class")
// also include your own plugin classes and resources
}

Use compileOnly for feather-api as in the setup guide. Shadow only includes what you list, so list your own packages too, for example include("com/example/**"), and your resources such as plugin.yml.

You wantDo this
Runs on FeatherMC onlyExtend FeatherPlugin and change nothing else.
Runs on FeatherMC and PaperOverride allowPaper(), bundle the two gate classes and guard FeatherMC code with FeatherSupport.isFeather().

Adapted from the PaperMC docs (CC BY-SA 4.0). About these docs.