How it works
Annotate
Mark classes with a bean scope and functions with @AutoInvoke. Constructor parameters are the dependencies.
Build
The VersatiaAPI KSP processor validates the graph and generates a descriptor next to your main class. Cycles and ambiguity stop the build.
Run
VersatiaCore reads the descriptor when the plugin enables, creates the beans in dependency order and calls your functions.
Dependency injection
Constructor injection with three scopes: @LocalBean, @ExposeSingleton and @ExposePrototype. Beans can be shared between plugins; @Qualifier and @Primary resolve ambiguity.
Lifecycle hooks
@AutoInvoke(phase) runs a function at plugin start, reload or stop with its parameters injected. There is nothing to override in the main class.
Errors at build time
Dependency cycles, ambiguous injections and beans that cannot be constructed fail the build with a message pointing at the line. Nothing broken reaches a server.
Compile-time checks →Encapsulation kept
Beans, constructors and functions may be private. Generated code calls visible members directly and falls back to reflection only where it has to.
Utilities over Paper
Strict configuration getters, deep-merging maps, scheduler and logging shorthands, primary-thread checks and reflection helpers, usable without the runtime.
Utilities →Extensible core
Annotations are enhancements interpreted by processors, and scopes can be inherited to define your own. The descriptor format is a versioned contract.
Enhancements and processors →