Module System (bootstrap package)
Navigation: Documentation Home · Contents · Core Concepts · API Overview · Toolkit · Glossary · Diagnostic Codes
QinhCoreLib (QCL) splits its capabilities into Modules, which the ModuleManager registers uniformly, loads by priority, reports health for, and isolates via degradation. This page covers the module lifecycle, the 22 core modules, the degradation mechanism, how to write custom modules, plus the accompanying diagnostic model and startup probing.
The Module Interface
| Member | Description |
|---|---|
name | Module name |
priority | Priority, defaults to 0, loaded in ascending order |
load() | Load phase |
enable() | Enable phase |
disable() | Disable phase |
unload() | Unload phase |
AbstractModule(name) provides default empty implementations of the above methods, so you only need to override the hooks you care about.
class MyModule : AbstractModule("MyModule") {
override val priority: Int = 50
override fun load() {
// Prepare resources, read configuration
}
override fun enable() {
// Register listeners and commands
}
override fun disable() {
// Unregister listeners
}
override fun unload() {
// Release resources
}
}ModuleManager
| Method | Description |
|---|---|
register(module) | Register a module |
unregister(module) | Unregister a module |
getModule(name) | Get a module by name |
statuses(): List<ModuleStatus> | Get the status of all modules |
healthReport(): HealthReport | Health report |
loadAll() | load then enable all modules in ascending priority order |
unloadAll() | Unload all modules |
reloadAll() | Reload all modules |
Load Order and Degradation
loadAll()runs in ascendingpriorityorder: it firstloads all modules, thenenables all modules.- Degradation isolation: when a single module throws an exception, only that module is marked
available = false/enabled = false; other modules are not affected. This means that if a bridge (such as scripting or economy) is missing or errors out, the core does not crash entirely but degrades locally. - Modules can be toggled on/off via the config's
modules.*switches.
CoreModules.registerAll registers all 22 core modules to the ModuleManager in one go.
The 22 Core Modules (loaded in ascending priority order)
Modules are registered uniformly by
CoreModules.registerAlland go throughload→enablein ascendingpriorityorder. Infrastructure types (database, config, text) have the lowest priority and load first; the bridges and business types that depend on them load afterward. The table below is a conceptual layering (the actual numbers follow the sourceCoreModules) to help you understand the load order and dependencies.
| Layer | Typical module responsibilities |
|---|---|
| Infrastructure (first) | Config, database, debug/logging, text |
| Unified pipelines | Item source management, attribute pipeline, economy, placeholders |
| External bridges | CraftEngine block bridge, ModelEngine model bridge, various item source bridges (MMOItems/NeigeItems/QinhItems/MythicMobs/CustomFishing/MagicGem/ItemsAdder/Nexo, etc.) |
| Scripting | Script engine (GraalVM) |
| Business/UI (last) | GUI, commands, startup report, etc. |
Tip: if a bridge module's corresponding soft dependency is not installed, it is skipped via a reflection bridge and marked
NO_HOOK. This is normal degradation, not an error. See Diagnostic Codes for details.
The Correct Way to Integrate Sub-Plugins
Although developers can implement a custom Module and register it to QinhCoreLib.moduleManager, this is usually not recommended.
Sub-plugins should generally use their own plugin main class (JavaPlugin), initialize in their own onEnable, and collaborate with QCL's public APIs and services (item sources, attribute pipeline, scheduling, text, etc.). Only when a capability truly needs to be brought into QCL's unified lifecycle / health reporting should you consider registering it as a QCL module.
// Recommended: a sub-plugin uses its own main class
class MySubPlugin : JavaPlugin() {
override fun onEnable() {
// Call QCL's public APIs / tools directly
}
}// Optional: register as a module when it really must be part of the QCL lifecycle
QinhCoreLib.moduleManager.register(MyModule())Diagnostic Model
QCL's diagnostic model provides structured status and result objects, making troubleshooting and health reporting easier.
ModuleStatus
| Field | Description |
|---|---|
name | Module name |
enabled | Whether enabled |
available | Whether available |
message | Status message |
BridgeStatus
| Field | Description |
|---|---|
name | Bridge name |
available | Whether available |
enabled | Whether enabled |
source | Source |
message | Message |
recoverable | Whether recoverable |
HealthReport
| Field / Method | Description |
|---|---|
ok | Whether healthy |
code | Health code (OK / NO_HOOK / DEGRADED) |
message | Message |
suggestion | Suggestion |
healthy() | Build a healthy report |
degraded(code, message, suggestion) | Build a degraded report |
DiagnosticResult<T>
A unified diagnostic result container.
| Field / Method | Description |
|---|---|
success | Whether successful |
value | Result value |
code | Result code |
message | Message |
source | Source |
recoverable | Whether recoverable |
suggestion | Suggestion |
traceId | Trace ID |
ok(...) | Build a success result |
fail(...) | Build a failure result |
val result: DiagnosticResult<ItemStack> = parseItem(ref)
if (result.success) {
val item = result.value
} else {
logger.warning("解析失败[${result.code}]:${result.message},建议:${result.suggestion}")
}Trace* (debug tracing)
TraceModels provides: TraceEvent, TraceReport, TraceBuilder, DebugTraceRegistry, used to record and replay the internal steps of an operation, making deep troubleshooting easier.
BridgeStatusRegistry
Centrally records the current status of each external bridge; commands such as /qcl status aggregate from this.
| Method | Description |
|---|---|
register(status) | Record a bridge status |
unregister(name) | Remove |
get(name) | Get the status of a bridge |
all() | Get all |
clear() | Clear |
Startup Probing and Reporting
EcosystemStartupProbe
At startup, probes the available item sources, economies, and plugin hooks, and builds a platform status summary.
| Method | Description |
|---|---|
availableItemSources() | Available item sources |
availableEconomies() | Available economies |
probePluginHooks() | Probe plugin hooks |
buildPlatformStatus() | Build platform status |
formatSummary() | Format the summary |
StartupReporter
Aggregates and prints the startup summary.
| Method | Description |
|---|---|
reset() | Reset |
setGuiCount(n) | Set the GUI count |
hookedItemSource(...) | Record a hooked item source |
hookedBridge(...) | Record a hooked bridge |
hookedEconomy(...) | Record a hooked economy |
printSummary() | Print the summary |
Continue Reading
- Core Concepts — Conceptual foundations of modules, bridges, item sources, etc.
- Toolkit — General-purpose tool APIs
- API Overview — Map of public APIs
- Diagnostic Codes — Health codes and the code tables for each subsystem
- Documentation Home · Contents