The ByteLib bootstrapper is the core of ByteLib. It is responsible for:
configuring Google Guice dependency injection
handling plugin lifecycle hooks
registering commands
initializing the plugin runtime
In short, ByteLib lives and dies by its bootstrapper.
Bootstrap a Plugin
Bootstrapping a plugin simply means configuring your plugin to run with ByteLib. Because Paper plugins define their bootstrapper and loader through configuration, this setup must be done manually.
If you want to use ByteLib, the ByteLib bootstrapper is mandatory. It cannot be replaced or modified.
Bootstrapping Overview
Create a paper-plugin.yml and register ByteLib's bootstrapper and loader classes.
Extend ByteLibPlugin in your plugin's main class.
Create a Google Guice module that registers your plugin dependencies.
Create one or more Lifecycle classes implementing PluginLifecycle.
Create a wiring class to connect your Guice modules and lifecycle components.
The bootstrapper controls how the plugin is initialized. It is responsible for:
configuring internal Guice modules
performing initial dependency injection
initializing ByteLib internals
The bootstrapper requires your plugin's main class to extend ByteLibPlugin.
loader
The loader defines the runtime environment your plugin loads into.
According to Paper documentation, the loader is used to:
construct the plugin classpath
provide external dependencies
ByteLib's loader currently adds BoostedYAML and Google Guice to the plugin classpath.
2. Extend ByteLibPlugin
Your plugin's main class must extend ByteLibPlugin.
public final class DimensionPausePlugin extends ByteLibPlugin {
@Inject
public DimensionPausePlugin(Injector injector, PluginMeta meta, Path dataDir, ComponentLogger logger) {
super(injector, meta, dataDir, logger);
}
}
3. Create a Guice Module
Create a module responsible for configuring dependency bindings for your plugin. This module would be responsible for binding dependencies that are specific to your plugin.
Lifecycle classes allow you to execute code during plugin lifecycle events. Your lifecycle class must implement PluginLifecycle.
Just like Paper plugins, it can (but isn't required to) define onLoad, onEnable, and onDisable.
Example:
public class DimensionPauseLifecycle implements PluginLifecycle {
private final ComponentLogger logger;
@Inject
public DimensionPauseLifecycle(ComponentLogger logger) {
this.logger = logger;
}
@Override
public void onEnable() {
logger.info("Dimension Pause has been loaded");
}
@Override
public void onDisable() {
logger.info("Dimension Pause is shutting down");
}
}
5. Wire Guice Together
Finally, connect all modules and lifecycle components.
ByteLib supports three wiring conventions.
// Create a class named `[MainClass]Wiring.class` and implement PluginWiring
// Ensure it returns your Module you made in step 3
public static class DimensionPauseWiring implements PluginWiring {
@Override
public List<Module> modules(PluginMeta meta, Path dataDir, ComponentLogger logger) {
return List.of(
new DimensionPauseModule()
);
}
}
// Nest a `Wiring` class in your plugin's main class
public final class DimensionPausePlugin extends ByteLibPlugin {
@Inject
public DimensionPausePlugin(Injector injector, PluginMeta meta, Path dataDir, ComponentLogger logger) {
super(injector, meta, dataDir, logger);
}
@SuppressWarnings("unused")
public static class Wiring implements PluginWiring {
@Override
public List<Module> modules(PluginMeta meta, Path dataDir, ComponentLogger logger) {
return List.of(
new DimensionPauseModule()
);
}
}
}
// Create a class that implements PluginWiring, and allow the `ServiceLoader` to attempt to locate it (Not recommended)
public static class PluginWiringSetup extends PluginWiring {
@Override
public List<Module> modules(PluginMeta meta, Path dataDir, ComponentLogger logger) {
return List.of(
new DimensionPauseModule()
);
}
}
If this seems complex, that's because dependency injection introduces additional structure.
However, the benefit is strong decoupling, which makes large plugins significantly easier to maintain and test.
Next Steps
After bootstrapping your plugin, configure the remaining ByteLib systems: