Scripting Lua : Pour Commencer
Ce que vous apprendrez
Cette page vous apprend a ecrire votre premier pouvoir Lua pour EliteMobs, d'un fichier vide jusqu'a une capacite de boss fonctionnelle. A la fin, vous comprendrez les hooks, le context, les temps de recharge et la structure generale de chaque fichier de pouvoir Lua.
Une fois a l'aise avec les bases, continuez avec les pages complementaires :
- Hooks et Cycle de Vie -- noms des hooks, ordre d'execution et disponibilite du context
- Boss et Entites -- les APIs
context.boss,context.player,context.playersetcontext.entities - Monde et Environnement -- particules, sons, eclairs, apparition et l'API
context.world - Zones et Ciblage -- zones Lua natives, utilitaires de script pour le ciblage et les APIs
context.zones/context.script - Exemples et Modeles -- pouvoirs complets et fonctionnels a etudier et adapter
- Enums et Valeurs -- liens vers les Javadocs Spigot pour Particle, Material, PotionEffectType et autres constantes
- Depannage -- erreurs courantes, conseils de debogage et la checklist QC
Les fichiers de pouvoir Lua sont actuellement experimentaux. Les noms de hooks, methodes auxiliaires et comportements peuvent encore changer au fur et a mesure que EliteMobs evolue, alors testez soigneusement avant de les utiliser sur un serveur de production.
Lua ne remplace pas le systeme YAML eliteScript: existant.
- Utilisez EliteScript quand vous souhaitez un scripting declaratif base sur YAML avec les pages existantes d'Actions, Cibles, Zones, Conditions, Temps de Recharge et Vecteurs Relatifs.
- Utilisez les fichiers de pouvoir Lua quand vous avez besoin de variables, boucles, selection aleatoire, fonctions auxiliaires reutilisables, etat persistant par boss et un flux de programmation plus traditionnel.
Lua possede son propre systeme de ciblage et de zones qui utilise les memes noms d'enum et concepts que vous connaissez deja d'EliteScript. L'API Script Utilities (context.script) vous permet de creer des zones, cibles et vecteurs relatifs avec les memes noms de champs documentes dans les pages EliteScript.
Ce que sont les pouvoirs Lua
Les pouvoirs Lua sont des fichiers .lua autonomes situes dans l'arborescence normale powers d'EliteMobs et references exactement comme les fichiers de pouvoir normaux.
Ce a quoi les pouvoirs Lua excellent
Les pouvoirs Lua brillent quand vous avez besoin de :
- Rotations d'attaque et selecteurs de mouvements aleatoires
- Etat persistant entre les hooks avec
context.state - Actions retardees et repetees sans tout construire avec des attentes YAML
- Fonctions auxiliaires personnalisees partagees dans un fichier
- Branchements complexes qui seraient maladroits en EliteScript pur
- Logique de boss souhaitant reutiliser les definitions de ciblage et de zones de style EliteScript
Si votre pouvoir est principalement "declencher un evenement, executer quelques actions scriptees", les docs EliteScript existants restent le moyen le plus rapide et clair de le construire. Si votre pouvoir necessite un veritable flux de programme, Lua est l'outil pour ce travail.
A qui s'adresse cette page
Cette page est ecrite pour trois types de lecteurs :
- Quelqu'un qui connait deja EliteScript et veut apprendre Lua sans apprendre la "vraie programmation" d'un seul coup
- Quelqu'un de nouveau dans le scripting EliteMobs qui a besoin d'une reference complete avec des noms exacts
- Quelqu'un qui utilise l'IA pour rediger des pouvoirs et a besoin de suffisamment de details pour detecter quand l'IA a invente quelque chose de faux
Vous n'avez pas besoin de devenir un developpeur Lua complet avant d'ecrire des pouvoirs utiles. Pour la plupart des pouvoirs pratiques EliteMobs, vous avez seulement besoin de :
- Comment placer un hook valide dans la table retournee
- Comment lire les valeurs du
context - Comment s'arreter tot avec
if ... then return end - Comment appeler quelques methodes auxiliaires correctement
- Comment copier les bonnes specifications de cibles et de zones depuis les docs EliteScript existants
Modele Mental : EliteScript vs. Lua
Si vous connaissez EliteScript, cette comparaison est le moyen le plus rapide de comprendre les pouvoirs Lua :
| Si vous pensez en termes EliteScript | En Lua cela signifie generalement |
|---|---|
| Events | Noms de hooks comme on_spawn ou on_boss_damaged_by_player |
| Cooldowns | context.cooldowns (voir context.cooldowns ci-dessous) |
| Actions | Appels de methodes directs comme context.world:spawn_particle_at_location(...) ou context.script:damage(...) |
| Cibles | context.script:target({...}) -- utilise les noms de champs EliteScript Target |
| Zones | context.script:zone({...}) ou les aides natives context.zones -- voir Zones et Ciblage |
| Vecteurs relatifs | context.script:relative_vector({...}) ou context.vectors |
| Flux du script | Vos propres instructions if Lua, fonctions auxiliaires, minuteries et etat |
La plus grande difference est celle-ci :
- EliteScript dit ce qui devrait se passer en YAML.
- Lua vous permet de decider quand, pourquoi et quelle branche devrait s'executer en utilisant du code.
Si EliteScript ressemble a de la "configuration", Lua ressemble a "configuration plus prise de decision".
Petit guide Lua pour les auteurs EliteMobs
Voici la syntaxe Lua minimale dont la plupart des auteurs de pouvoirs ont besoin.
Variables
Utilisez local pour stocker une valeur :
local cooldown_key = "fire_burst"
local damage_multiplier = 1.5
local signifie que la variable appartient uniquement a ce fichier ou bloc.
Fonctions
Les fonctions sont des blocs de logique reutilisables :
local function warn_player(player)
player:send_message("&cMove!")
end
Plus tard, vous pouvez l'appeler :
warn_player(context.player)
Verifications if
Utilisez if quand quelque chose ne doit se produire que parfois :
if context.player == nil then
return
end
Cela signifie "s'il n'y a pas de joueur pour ce hook, s'arreter ici".
nil
nil signifie "aucune valeur". C'est la version Lua de "il n'y a rien ici".
Vous verifierez souvent nil avec :
if context.event ~= nil then
-- faire quelque chose avec l'evenement
end
~= signifie "n'est pas egal a".
Tables
Lua utilise des tables pour plusieurs usages :
- Listes
- Objets avec des cles nommees
- La definition finale du pouvoir retournee
Exemple d'une table avec des cles nommees :
local particle = {
particle = "FLAME",
amount = 1,
speed = 0.05
}
Retourner la definition du pouvoir
A la fin du fichier, vous retournez une table :
return {
api_version = 1,
on_spawn = function(context)
end
}
Cette table retournee est le fichier de pouvoir.
Commentaires
Utilisez -- pour ecrire une note pour les humains :
-- Ce cooldown empeche l'attaque de se declencher a chaque coup
context.cooldowns:set_local(60, "fire_burst")
Votre premier pouvoir fonctionnel, construit progressivement
Si vous etes completement nouveau, c'est la meilleure progression pour la "premiere victoire".
Avant l'Etape 1 : Enregistrez-le et attachez-le a un boss
Enregistrez le fichier Lua dans le dossier normal des pouvoirs EliteMobs, par exemple :
plugins/
EliteMobs/
powers/
first_test.lua
Puis ajoutez ce nom de fichier a la configuration du boss en utilisant la liste normale powers: :
powers:
- first_test.lua
La boucle complete pour debutant est donc :
- Enregistrer le fichier dans
plugins/EliteMobs/powers/ - Ajouter le nom de fichier
.luaa la listepowers:du boss - Faire apparaitre ou recharger ce boss
- Tester le hook que vous construisez actuellement
Si vous avez besoin de plus de contexte sur les fichiers de boss, les listes de pouvoirs ou la structure des boss personnalises, consultez Creer des Boss Personnalises. Cette page couvre la configuration des boss en detail, y compris le fonctionnement de la liste powers:.
Etape 1 : Faire charger le fichier
return {
api_version = 1,
on_spawn = function(context)
end
}
Si cela charge sans erreur, vous avez deja prouve :
- Le fichier est du Lua valide
- EliteMobs l'a trouve
- La forme de la table retournee est correcte
on_spawnest un nom de hook valide
Etape 2 : Faire faire quelque chose de visible au boss
return {
api_version = 1,
on_spawn = function(context)
context.boss:play_sound_at_self("entity.blaze.ambient", 1.0, 1.0)
end
}
Maintenant vous avez la preuve la plus importante pour debutant : votre hook se declenche.
Etape 3 : Reagir au coup d'un joueur
return {
api_version = 1,
on_boss_damaged_by_player = function(context)
if context.player == nil then
return
end
context.player:send_message("&eYou hit the boss.")
end
}
Cela enseigne trois idees fondamentales :
on_boss_damaged_by_playerest le nom du hookcontext.playerest le joueur implique dans ce hookreturnsort tot quand les donnees necessaires sont manquantes
Etape 4 : Prevenir le spam avec un temps de recharge
return {
api_version = 1,
on_boss_damaged_by_player = function(context)
if context.player == nil then
return
end
if not context.cooldowns:local_ready("hello_message") then
return
end
context.player:send_message("&eYou woke up the boss.")
context.cooldowns:set_local(60, "hello_message")
end
}
C'est le premier modele veritablement utile dont la plupart des auteurs ont besoin. Si vous comprenez ce modele, vous pouvez deja construire de nombreux pouvoirs pratiques.
Etape 5 : Ajouter un vrai effet
return {
api_version = 1,
on_boss_damaged_by_player = function(context)
if context.player == nil then
return
end
if not context.cooldowns:local_ready("shock") then
return
end
context.player:send_message("&cStatic jumps from the boss into your armor!")
context.world:strike_lightning_at_location(context.player.current_location)
context.cooldowns:set_local(100, "shock")
end
}
A ce stade, vous ecrivez deja un vrai pouvoir.
Premier vrai flux de travail
Lors de la construction d'un nouveau pouvoir Lua, utilisez cet ordre :
- Creer le fichier et faire fonctionner
on_spawn. - Passer au hook souhaite.
- Confirmer que le hook contient les donnees attendues, comme
context.playeroucontext.event. - Ajouter d'abord un message ou un son, avant les degats ou les particules.
- Ajouter les temps de recharge.
- Ajouter un effet de gameplay.
- Seulement apres cela, ajouter des aides, l'etat, la logique du planificateur ou les zones.
Cet ordre rend le debogage considerablement plus facile car une seule chose change a la fois.
Ou se trouvent les fichiers Lua
Placez les fichiers .lua dans la meme arborescence que les fichiers de pouvoir .yml normaux :
plugins/
EliteMobs/
powers/
mycoolpower.lua
attack_push.yml
subfolder/
myotherpower.lua
Les pouvoirs Lua sont decouverts automatiquement depuis les repertoires de pouvoirs que EliteMobs charge deja.
Comment les boss referencent les pouvoirs Lua
Les fichiers de boss utilisent toujours la liste normale powers: :
powers:
- attack_push.yml
- mycoolpower.lua
Aucun champ special n'est requis. Les pouvoirs Lua ne sont pas charges via eliteScript:.
Regles de nommage des fichiers
- Les boss referencent les pouvoirs Lua par nom de fichier, pas par chemin de dossier.
- EliteMobs enregistre actuellement les pouvoirs Lua decouverts par nom de base uniquement.
- Evitez les noms en double comme
powers/fire.luaetpowers/bosses/fire.lua, car l'un peut ecraser l'autre lors de la decouverte.
Pouvoirs Lua prefabriques
EliteMobs est livre avec des dizaines de pouvoirs Lua prefabriques dans le dossier powers, comme attack_fire.lua, frost_cone.lua, meteor_shower.lua et bien d'autres. Ce sont d'excellentes references a etudier -- ouvrez simplement n'importe quel fichier .lua dans votre repertoire plugins/EliteMobs/powers/. Pour la retrocompatibilite, les pouvoirs prefabriques sont egalement enregistres sous leurs anciens noms .yml.
Contrat minimal du fichier
Chaque pouvoir Lua doit retourner une table avec return. Cette table est intentionnellement stricte.
Champs de niveau superieur requis et optionnels
| Champ | Requis | Type | Notes |
|---|---|---|---|
api_version | Oui | Number | Doit actuellement etre 1 |
priority | Non | Number | Priorite d'execution. Les valeurs plus basses s'executent en premier. Par defaut 0 |
| Cles de hook supportees | Non | Function | Doit utiliser l'un des noms de hook exacts listes dans la Reference des Hooks |
Regles de validation
- Le fichier doit retourner une table.
api_versionest requis et doit actuellement etre1.prioritydoit etre numerique si present.- Chaque cle de niveau superieur supplementaire doit etre un nom de hook supporte.
- Chaque cle de hook doit pointer vers une fonction.
- Les cles de niveau superieur inconnues sont rejetees.
Cela signifie que les fonctions auxiliaires et constantes locales doivent se trouver au-dessus du return final, pas a l'interieur de la table retournee sauf s'il s'agit de veritables hooks.
Modeles a copier-coller
Plus petit pouvoir Lua valide
return {
api_version = 1,
on_spawn = function(context)
end
}
Modele de depart recommande
local ATTACK_COOLDOWN = "my_attack"
local function can_run_attack(context)
return context.cooldowns:local_ready(ATTACK_COOLDOWN)
and context.cooldowns:global_ready()
end
local function run_attack(context)
context.boss:play_sound_at_self("entity.blaze.shoot", 1.0, 1.0)
context.cooldowns:set_local(100, ATTACK_COOLDOWN)
context.cooldowns:set_global(20)
end
return {
api_version = 1,
priority = 0,
on_boss_damaged_by_player = function(context)
if context.player == nil then
return
end
if not can_run_attack(context) then
return
end
run_attack(context)
end
}
Disposition pour fichiers plus grands
local CONSTANT_NAME = "value"
local function helper_function(context)
end
local function another_helper(context, value)
end
return {
api_version = 1,
priority = 0,
on_spawn = function(context)
end,
on_enter_combat = function(context)
end,
on_boss_damaged_by_player = function(context)
end,
on_exit_combat = function(context)
end
}
Hooks
Les hooks sont des fonctions specialement nommees dans la table que vous retournez. EliteMobs les appelle quand quelque chose se produit -- le boss apparait, subit des degats, entre en combat, etc. Vous avez deja vu on_spawn et on_boss_damaged_by_player dans le tutoriel ci-dessus.
Les hooks les plus courants pour commencer sont on_spawn, on_boss_damaged_by_player, on_enter_combat et on_exit_combat. Pour la liste complete de tous les hooks, quelles cles de context sont disponibles dans chacun et comment fonctionne l'ordre d'execution, consultez Hooks et Cycle de Vie.
Qu'est-ce que context ?
Chaque fonction de hook recoit un argument appele context. Pensez-y comme une boite a outils que EliteMobs vous remet chaque fois que quelque chose se produit -- elle contient tout ce dont vous avez besoin pour interagir avec le boss, le joueur, le monde, les temps de recharge et plus encore.
on_boss_damaged_by_player = function(context)
-- context.boss = le boss qui a ete frappe
-- context.player = le joueur qui l'a frappe
-- context.world = outils pour generer des particules, sons, etc.
-- context.cooldowns = gestion des temps de recharge
-- context.state = votre propre stockage persistant
end
Vous ne creez pas context vous-meme -- EliteMobs le cree et le transmet a votre hook. Vous lisez simplement ses valeurs et appelez des methodes dessus.
context est cree a neuf pour chaque appel de hook, sauf context.state qui persiste pendant toute la duree de vie du boss. Cela signifie que vous pouvez stocker des donnees dans context.state et les relire plus tard dans un hook different.
APIs cles de context
Voici les APIs les plus importantes que vous utiliserez depuis context :
-
context.state-- Une simple table Lua qui persiste pendant la duree de vie du boss. Utilisez-la pour stocker les numeros de phase, IDs de tache, drapeaux et tout ce que vous devez retenir entre les hooks. Seulcontext.statepersiste -- toutes les autres tables de context sont creees a neuf a chaque appel. -
context.log-- Journalisation en console aveclog:info(msg),log:warn(msg)etlog:debug(msg). Inestimable pendant le developpement. -
context.cooldowns-- Temps de recharge locaux par pouvoir et globaux par boss. La methode cle estcooldowns:check_local(key, ticks)qui verifie ET definit un cooldown de maniere atomique. Consultez la page Hooks et Cycle de Vie pour l'API complete des cooldowns. -
context.scheduler-- Taches retardees et repetees avecscheduler:run_after(ticks, callback)etscheduler:run_every(ticks, callback). Les callbacks recoivent un context frais -- utilisez toujours le parametre du callback, pas lecontextexterne. Annulez les taches repetees danson_exit_combat. Consultez Hooks et Cycle de Vie pour les details. -
context.boss/context.player-- Le boss et le joueur impliques dans l'evenement actuel. Consultez Boss et Entites pour tous les champs et methodes. -
context.world-- Generer des particules, entites, sons, eclairs, blocs. Consultez Monde et Environnement. -
context.zones/context.script-- Geometrie de zones, ciblage, degats, particules. Consultez Zones et Ciblage.
Syntaxe des methodes : : vs. .
En Lua, object:method(arg) est un raccourci pour object.method(object, arg). L'API EliteMobs accepte les deux formes, donc les deux fonctionnent :
context.cooldowns:set_local(60, "test")
context.cooldowns.set_local(60, "test") -- meme chose
Toute la documentation utilise : de maniere coherente.
Prochaines etapes
Maintenant que vous connaissez les bases, explorez le reste de la documentation de scripting Lua :
- Hooks et Cycle de Vie -- noms des hooks, ordre d'execution et quelles cles de context sont disponibles dans chaque hook
- Boss et Entites --
context.boss,context.player,context.players,context.entitiesetcontext.event - Monde et Environnement -- particules, sons, eclairs, apparition et
context.world - Zones et Ciblage -- zones Lua natives, utilitaires de script pour ciblage/zones/particules et vecteurs relatifs
- Exemples et Modeles -- pouvoirs complets et fonctionnels avec explications
- Enums et Valeurs -- liens vers les Javadocs Spigot pour Particle, Material, PotionEffectType et plus
- Depannage -- erreurs courantes, conseils de debogage et checklist QC
Pour le scripting base sur YAML, les pages EliteScript restent la reference canonique :
