Saltearse al contenido

Buenas prácticas

Un módulo, una subcarpeta

Siempre escribe archivos en plugin.getModuleFolder("<id>"), nunca en la raíz de plugins/CoreBau/. Esto evita colisiones de config.yml entre módulos.

File file = new File(plugin.getModuleFolder("welcome"), "config.yml");

Recursos con namespace

Los recursos del JAR van bajo resources/<id>/... y se leen con la ruta "<id>/archivo.yml". El host los redirige a tu subcarpeta cuando llamas saveResource(...).

No shadear lo que provee la plataforma

LibreríaEstrategia
paper-apicompileOnly
Adventure / MiniMessagecompileOnly
PlaceholderAPIcompileOnly
packetevents / ProtocolLibcompileOnly
HikariCP / bStats / driversimplementation + relocate

Shadear Adventure rompe el classloader del servidor.

Relocar todo lo que sí se shadea

Si dos módulos traen Hikari, sin reloca acaban en com.zaxxer.hikari y chocan. Únifica versión en gradle.properties y reloca a cl.xgamers.libs.<algo>.

Una sola versión de paper-api

Definida en gradle.properties (paperApiVersion). No la sobreescribas por módulo.

Comandos en un solo lugar

Todos los comandos basados en plugin.yml se declaran en el plugin.yml fusionado del módulo paper. Si tu módulo registra comandos por reflection / commandMap (como Baúl), no hace falta declararlos.

Capturar errores por módulo

CoreBauPlugin ya envuelve enable() / disable() en try/catch, pero no dejes que una excepción se propague sin antes loguearla con contexto:

@Override
public void enable(CoreBauPlugin plugin) {
this.plugin = plugin;
try {
cargarConfig();
registrarListeners();
} catch (Exception ex) {
plugin.getLogger().severe("[welcome] no se pudo arrancar: " + ex.getMessage());
throw ex; // que CoreBauPlugin lo aísle
}
}

Deshabilitar en orden inverso

Si el módulo A depende de B, registra A después de B. El apagado se hace en orden inverso: A se cierra antes que B.

Conservar paquetes y nombres de tabla al portar

Renombrar invalida datos guardados, configs de usuarios y NamespacedKeys. Regla número uno.

Persistencia: prefiere async

Toda escritura SQL pasada por Hikari debe ir por el pool async del módulo. Bloquear el main thread con queries síncronas es la causa número uno de TPS drops.

plugin.getServer().getScheduler().runTaskAsynchronously(plugin, () -> {
try (Connection c = pool.getConnection()) {
// INSERT / UPDATE
} catch (SQLException ex) { /* log */ }
});

Mensajes: MiniMessage, nunca legacy

CoreBau usa MiniMessage (Adventure). No introduzcas ChatColor.GOLD ni §6. Todos los mensajes deben ir por el MiniMessage.miniMessage() del módulo o el helper Mini del Baúl (dev.blancocl.util.Mini).

Glifos: namespace estable

Cualquier módulo que renderice texto debe permitir <font:corebau:default> o el namespace que defina el resourcepack en producción. Ver Glifos.