Aller au contenu principal

Scripting Lua : Pour Commencer

webapp_banner.jpg

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.players et context.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
Fonctionnalite Experimentale

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.

Relation avec EliteScript

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 EliteScriptEn Lua cela signifie generalement
EventsNoms de hooks comme on_spawn ou on_boss_damaged_by_player
Cooldownscontext.cooldowns (voir context.cooldowns ci-dessous)
ActionsAppels de methodes directs comme context.world:spawn_particle_at_location(...) ou context.script:damage(...)
Ciblescontext.script:target({...}) -- utilise les noms de champs EliteScript Target
Zonescontext.script:zone({...}) ou les aides natives context.zones -- voir Zones et Ciblage
Vecteurs relatifscontext.script:relative_vector({...}) ou context.vectors
Flux du scriptVos 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 :

  1. Enregistrer le fichier dans plugins/EliteMobs/powers/
  2. Ajouter le nom de fichier .lua a la liste powers: du boss
  3. Faire apparaitre ou recharger ce boss
  4. 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_spawn est 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_player est le nom du hook
  • context.player est le joueur implique dans ce hook
  • return sort 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 :

  1. Creer le fichier et faire fonctionner on_spawn.
  2. Passer au hook souhaite.
  3. Confirmer que le hook contient les donnees attendues, comme context.player ou context.event.
  4. Ajouter d'abord un message ou un son, avant les degats ou les particules.
  5. Ajouter les temps de recharge.
  6. Ajouter un effet de gameplay.
  7. 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.lua et powers/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

ChampRequisTypeNotes
api_versionOuiNumberDoit actuellement etre 1
priorityNonNumberPriorite d'execution. Les valeurs plus basses s'executent en premier. Par defaut 0
Cles de hook supporteesNonFunctionDoit utiliser l'un des noms de hook exacts listes dans la Reference des Hooks

Regles de validation

  • Le fichier doit retourner une table.
  • api_version est requis et doit actuellement etre 1.
  • priority doit 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.

info

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. Seul context.state persiste -- toutes les autres tables de context sont creees a neuf a chaque appel.

  • context.log -- Journalisation en console avec log:info(msg), log:warn(msg) et log:debug(msg). Inestimable pendant le developpement.

  • context.cooldowns -- Temps de recharge locaux par pouvoir et globaux par boss. La methode cle est cooldowns: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 avec scheduler:run_after(ticks, callback) et scheduler:run_every(ticks, callback). Les callbacks recoivent un context frais -- utilisez toujours le parametre du callback, pas le context externe. Annulez les taches repetees dans on_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.entities et context.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 :