Développement de plugins Minecraft
Utilisez cette compétence pour le travail sur les plugins de serveur Minecraft dans l'écosystème Paper, Spigot et Bukkit.
Cette compétence est particulièrement utile pour les plugins axés sur le gameplay tels que les systèmes de combat, les rencontres de vagues ou de boss, les modes guerre ou équipe, les arènes, les systèmes de kits, les capacités basées sur les cooldowns, les tableaux de bord et les règles de jeu pilotées par la configuration.
Pour des modèles d'implémentation fondés sur des plugins Paper réels, chargez ces références au besoin :
references/project-patterns.mdpour les modèles d'architecture de haut niveau observés dans les plugins gameplay réelsreferences/bootstrap-registration.mdpouronEnable, le câblage des commandes, l'enregistrement des listeners et les attentes d'arrêtreferences/state-sessions-and-phases.mdpour la modélisation des sessions de joueurs, les phases de jeu, l'état du match et la logique sûre en cas de reconnexionreferences/config-data-and-async.mdpour les gestionnaires de configuration, les données de joueur sauvegardées en base, les flushes asynchrones et les tâches de rafraîchissement UIreferences/maps-heroes-and-feature-modules.mdpour la rotation des cartes, les systèmes de héros ou de classes et la croissance modulaire des fonctionnalitésreferences/minigame-instance-flow.mdpour les instances d'arènes, les compteurs à rebours, les rafraîchissements de butin, les systèmes de vagues, l'isolation de visibilité et la propriété entité-jeureferences/persistent-progression-and-events.mdpour les serveurs PvP de longue durée avec profils, perks, buffs, quêtes, économie, événements de domaine personnalisé et registres d'extensionreferences/build-test-and-runtime-validation.mdpour l'empaquetage Maven ou Gradle, les dépendances shaded, les ressources générées, les dépendances souples, les commandes de validation de configuration et les plans de test serveur du premier tour
Portée
- Inclus : développement de plugins Paper, Spigot, Bukkit
- Inclus :
plugin.yml, commandes, complétion d'onglets, listeners, schedulers, configurations, permissions, texte Adventure, état du joueur, flux de minigame, instances d'arènes, copies de cartes, butin, vagues, profils persistants, perks, buffs, quêtes, économie et boucles de jeu PvP/PvE - Inclus : architecture de plugins serveur basée sur Java, débogage, refactorisation et implémentation de fonctionnalités
- Exclus par défaut : mods Fabric, mods Forge, mods client, add-ons Bedrock
Si l'utilisateur dit « plugin Minecraft » mais la pile n'est pas claire, déterminez d'abord si le projet est Paper/Spigot/Bukkit ou une pile de modding.
Style de travail par défaut
Quand cette compétence s'active :
- Identifiez l'API serveur et la version cible.
- Identifiez le système de compilation et la version Java.
- Inspectez
plugin.yml, la classe du plugin principal et l'enregistrement des commandes ou listeners. - Cartographiez le flux de gameplay avant de modifier le code :
- cycle de vie du joueur
- phases de jeu
- minuteurs et tâches programmées
- équipe, arène ou état du match
- configuration et persistance
- Effectuez le plus petit changement cohérent qui maintient l'enregistrement, la configuration et le comportement d'exécution alignés.
Si le plugin est gameplay-intensif ou stateful, consultez references/project-patterns.md et references/state-sessions-and-phases.md avant de modifier.
Si la tâche touche à l'isolation d'arène, aux instances de cartes, aux remplissages de coffres ou de ressources, à la génération de vagues, au vote d'itinéraires, à la visibilité des spectateurs ou au chat spécifique au jeu, consultez aussi references/minigame-instance-flow.md.
Si la tâche touche à la progression persistante des joueurs, aux sauvegardes de profils, aux récompenses économiques, aux perks, aux buffs, aux quêtes, aux événements de combat personnalisés ou aux serveurs PvP partagés de longue durée, consultez aussi references/persistent-progression-and-events.md.
Si la tâche touche aux fichiers de compilation, aux métadonnées plugin.yml, aux dépendances shaded, à la sortie des ressources générées, au déploiement sur un serveur de test, aux intégrations de plugins optionnels ou à la validation de sortie, consultez aussi references/build-test-and-runtime-validation.md.
Liste de vérification de la découverte de projet
Vérifiez ceux-ci en premier quand ils sont présents :
plugin.ymlpom.xml,build.gradleoubuild.gradle.kts- la classe principale du plugin étendant
JavaPlugin - les exécuteurs de commandes et les compléteurs d'onglets
- les classes listener
- le code de bootstrap de configuration pour
config.yml, messages, kits, arènes ou fichiers YAML personnalisés - la sortie des ressources générées telles que
target/classes,build/resourcesou les jars de plugin copiées - l'utilisation du scheduler via les APIs du scheduler Bukkit
- tout conteneur de données de joueur, état d'équipe, état d'arène ou état de match
Règles fondamentales
Préférez l'API serveur concrète du dépôt
- Si le projet cible déjà les APIs Paper, continuez à utiliser les APIs Paper-first plutôt que de rétrograder vers Bukkit générique sauf si la compatibilité est explicitement requise.
- Ne supposez pas qu'une API existe dans toutes les versions. Vérifiez d'abord la dépendance existante et le style du code environnant.
Gardez l'enregistrement synchronisé
Lors de l'ajout de commandes, de permissions ou de listeners, mettez à jour les points d'enregistrement pertinents dans le même changement :
plugin.yml- enregistrement du startup du plugin dans
onEnable - toutes les vérifications de permissions dans le code
- toutes les clés de configuration ou de messages associées
Respectez les limites du thread principal
- Ne touchez pas à l'état du monde, aux entités, aux inventaires, aux tableaux de bord ou à la plupart des objets de l'API Bukkit à partir de tâches asynchrones à moins que l'API ne l'autorise explicitement.
- Utilisez les tâches asynchrones pour les E/S externes, les calculs lourds ou le travail en base de données, puis revenez au thread principal avant d'appliquer les modifications du gameplay.
Modelez le gameplay comme état, pas des booléens éparpillés
Pour les plugins gameplay, préférez les objets d'état explicites aux flags dupliqués :
- phase de match ou de jeu
- rôle de joueur ou classe
- état de cooldown
- appartenance à une équipe
- affectation d'arène
- vivant, éliminé, spectateur ou état en attente
Quand la fonctionnalité affecte le gameplay de minigame lourd de match ou de combat persistant, cherchez d'abord les transitions d'état cachées avant de corriger les symptômes.
Pour les plugins multi-arènes, isolez la visibilité per-jeu, les destinataires de chat, les tableaux de bord, le butin et la propriété des entités. Ne laissez pas une arène observer ou muter une autre arène par accident.
Favorisez les valeurs pilotées par la configuration
Quand la fonctionnalité inclut des dégâts, des cooldowns, des récompenses, des durées, des messages, des paramètres de carte ou des bascules :
- préférez les valeurs sauvegardées en configuration au codage en dur
- fournissez des valeurs par défaut sensées
- gardez les noms de clés stables et lisibles
- validez ou assainissez les valeurs manquantes
Soyez attentif au comportement de rechargement
- Évitez de promettre un rechargement à chaud sûr à moins que le code ne le supporte déjà bien.
- Au rechargement de configuration, assurez-vous que les caches en mémoire, les tâches programmées et l'état du gameplay sont gérés de manière cohérente.
Modèles d'implémentation
Commandes
Pour les nouvelles commandes :
- ajoutez la commande à
plugin.yml - implémentez l'exécuteur et la complétion d'onglets si nécessaire
- validez le type de sender avant de caster en
Player - séparez l'analyse, les vérifications de permissions et la logique du gameplay
- envoyez un retour clair face au joueur pour une utilisation invalide
Forme d'enregistrement minimale :
commands:
arena:
description: Join or leave an arena
usage: /arena <join|leave>
@Override
public void onEnable() {
ArenaCommand command = new ArenaCommand(gameService);
PluginCommand arena = getCommand("arena");
if (arena != null) {
arena.setExecutor(command);
arena.setTabCompleter(command);
}
}
Listeners
Pour les event listeners :
- protégez tôt et retournez tôt
- vérifiez si le joueur, l'arène ou la phase de jeu actuels doivent gérer l'événement
- évitez de faire un travail cher dans les événements chauds tels que le déplacement, les dégâts ou les spams d'interaction
- centralisez les vérifications répétées si pratique
Tâches programmées
Pour les minuteurs, les tours, les compteurs à rebours, les cooldowns ou les vérifications périodiques :
- stockez les handles de tâches quand l'annulation importe
- annulez les tâches à la désactivation du plugin et quand un match ou une arène se termine
- évitez plusieurs tâches superposées pour le même problème de gameplay à moins qu'explicitement intentionnel
- préférez une boucle de jeu unique et faisant autorité à plusieurs tâches répétitives faiblement coordonnées
- assurez-vous que les tâches de compteur à rebours ou de remplissage s'auto-annulent quand le jeu quitte l'état attendu
Forme de passage de thread principal :
Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> {
PlayerData data = repository.load(playerId);
Bukkit.getScheduler().runTask(plugin, () -> {
Player player = Bukkit.getPlayer(playerId);
if (player != null && player.isOnline()) {
scoreboard.update(player, data);
}
});
});
État du joueur et du match
Pour l'état per-joueur ou per-match :
- définissez clairement la propriété
- nettoyez à la déconnexion, l'expulsion, la mort, la fin de match et la désactivation du plugin
- évitez les fuites mémoire des cartes obsolètes indexées par
Player - préférez
UUIDpour le suivi persistant à moins qu'un objet joueur en direct soit strictement nécessaire
Texte et messages
Quand le projet utilise Adventure ou MiniMessage :
- suivez l'approche de formatage existante
- évitez de mélanger les codes de couleur hérités et les styles Adventure sans raison
- gardez les modèles de messages configurables quand les messages font face au gameplay
Zones à risque élevé
Accordez une attention particulière lors de la modification :
- la gestion des dégâts et la logique de combat personnalisée
- la mort, la réapparition, le spectateur et le flux d'élimination
- le flux de jointure et de sortie d'arène
- les mises à jour de tableau de bord ou de barre de boss
- la mutation d'inventaire et la distribution de kits
- l'accès asynchrone à la base de données ou aux fichiers
- la mutation d'économie, quête, perk et profil
- la dispatch d'événement personnalisé ou les registres d'extension
- les appels API sensibles à la version
- l'arrêt et le nettoyage dans
onDisable - l'isolation de visibilité, chat et diffusion cross-arène
- la copie de carte, le déchargement et la suppression de dossier
- la propriété du mob, NPC, projectile ou entité temporaire
- les systèmes de remplissage de coffre ou de ressource
Attentes de sortie
Lors de l'implémentation ou de la révision du code du plugin :
- produisez du code Java exécutable, pas du pseudo-code, à moins que l'utilisateur demande un design uniquement
- mentionnez toute mise à jour requise pour
plugin.yml, les fichiers de configuration, les fichiers de compilation ou les ressources - indiquez explicitement les hypothèses de version
- signalez les risques de thread-safety ou de compatibilité API quand ils existent
- préservez les conventions existantes du projet et la structure des dossiers
Quand le changement demandé touche au startup du plugin, aux données asynchrones, au flux de match, aux systèmes de classe ou aux cartes rotatives, consultez le fichier de référence correspondant avant de modifier.
Liste de vérification de validation
Avant de terminer, vérifiez autant de points que la tâche le permet :
- la commande, le listener ou la fonctionnalité est enregistrée correctement
plugin.ymlcorrespond au comportement implémenté- les imports et les types d'API correspondent à la pile serveur ciblée
- l'utilisation du scheduler est sûre
- les clés de configuration référencées dans le code existent ou ont des valeurs par défaut
- les chemins de nettoyage d'état existent pour la fin de match, la déconnexion de joueur et la désactivation du plugin
- le chat, la visibilité, les tableaux de bord et les diffusions per-arène sont isolés
- les mondes temporaires, mobs, tâches et ressources générées sont nettoyées
- il n'y a aucun danger évident de null, cast ou cycle de vie
Pièges courants
- Caster
CommandSenderenPlayersans vérifier - Mettre à jour l'état Bukkit à partir de tâches asynchrones
- Oublier d'enregistrer les listeners ou de déclarer les commandes dans
plugin.yml - Utiliser les objets
Playercomme clés de carte longue durée quandUUIDest plus sûr - Laisser les tâches répétitives vivantes après une ronde, une arène ou une désactivation du plugin
- Coder en dur les constantes de gameplay qui doivent vivre en configuration
- Supposer les APIs Paper-only dans un plugin ciblé Spigot
- Traiter le rechargement comme gratuit même si les plugins stateful cassent souvent lors du rechargement
- Diffuser, montrer des joueurs ou appliquer des modifications de tableau de bord à travers des instances de jeu non liées
- Charger ou muter les blocs de coffre/conteneur avant que leurs chunks soient disponibles
- Oublier de désenregistrer les mobs générés ou les entités temporaires du jeu propriétaire
- Éditer les fichiers générés sous
target/classesoubuild/resourcesau lieu des fichiers sources soussrc/main/resources
Forme de réponse préférée
Pour les demandes substantielles, structurez le travail comme ceci :
- Contexte du plugin actuel et hypothèses
- Impact du gameplay ou du cycle de vie
- Modifications du code
- Mises à jour d'enregistrement ou de configuration requises
- Validation et risques restants
Pour les petites demandes, gardez la réponse concise mais mentionnez toujours les mises à jour nécessaires pour plugin.yml, la configuration ou le cycle de vie.