API
Événements
Un événement décrit quelque chose qui s’est passé dans le jeu : un joueur s’est connecté, un bloc s’est cassé, quelque chose a subi des dégâts. Il ne décrit pas quel code interne du jeu s’est exécuté : c’est pour ça qu’un mod qui écoute join continue de fonctionner même quand ce code change.
Écouter un événement
import { give_rubies } from "/lib/rewards"
import { SETTINGS } from "/settings"
on break(e) {
let p = e.player
if p == null { return }
if e.block.type == "minecraft:diamond_ore" and chance(SETTINGS["bonus_chance"]) {
give_rubies(p, 1)
p.play_sound("rubies:ruby_chime")
p.world.spawn_particle("rubies:ruby_spark", e.block.location, 12, 0.4, 0.02)
}
}package com.example.rubies.events
object MiningEvents {
fun register(config: RubiesConfig) {
Crafting.events.on<BlockBreakEvent> { e ->
val player = e.player ?: return@on
if (e.block.type.path == "diamond_ore" && Math.random() < config.dropChance) {
player.give(ItemStack.of(Items.RUBY))
player.playSound(Identifier.parse(Sounds.CHIME))
player.world.spawnParticle(Identifier.parse(Particles.SPARK), e.block.location, count = 12, spread = 0.4, speed = 0.02)
}
}
}
}En CraftScript, les propriétés de l’événement sont disponibles sous forme de variables (player, block…) ou via le nom que tu lui donnes (on break(e)). Tu peux écouter chaque événement depuis autant de fichiers que tu veux : mets chaque règle dans le fichier de son thème.
Tous les événements
Ils se déclenchent tous dans le vrai jeu, côté client ou serveur selon le cas. En CraftScript, tu peux utiliser le nom court ou le nom long en snake_case (join ou player_join).
| CraftScript | Kotlin | Propriétés | Annulable |
|---|---|---|---|
server_starting |
ServerStartingEvent |
server | |
start |
ServerStartedEvent |
server | |
stop |
ServerStoppingEvent |
server | |
tick |
ServerTickEvent |
server, tick, phase | |
client_tick |
ClientTickEvent |
tick, phase | |
world_load |
WorldLoadEvent |
world | |
world_unload |
WorldUnloadEvent |
world | |
join |
PlayerJoinEvent |
player, join_message | |
quit, leave |
PlayerQuitEvent |
player, quit_message | |
chat |
PlayerChatEvent |
player, message | Oui |
respawn |
PlayerRespawnEvent |
player, location | |
death |
PlayerDeathEvent |
player, death_message, keep_inventory | |
interact |
PlayerInteractBlockEvent |
player, block, hand, item | Oui |
interact_entity |
PlayerInteractEntityEvent |
player, entity, hand, item | Oui |
attack |
PlayerAttackEvent |
player, target | Oui |
key |
PlayerKeyEvent |
player, key | |
use_item |
PlayerUseItemEvent |
player, item, hand | Oui |
command |
PlayerCommandEvent |
player, command | Oui |
break |
BlockBreakEvent |
player (peut être null), block, drop_items | Oui |
place |
BlockPlaceEvent |
player (peut être null), block, placed | Oui |
spawn |
EntitySpawnEvent |
entity | Oui |
damage |
EntityDamageEvent |
entity, damage_type, amount (modifiable), attacker | Oui |
entity_death |
EntityDeathEvent |
entity, drops | |
hit |
ProjectileHitEvent |
projectile, shooter, entity or block | Oui |
ready |
ModsLoadedEvent |
mod_ids | |
plugin_reload |
PluginReloadEvent |
plugin_id |
Changer ce qui se passe
Certaines propriétés peuvent être modifiées, et le jeu en tient compte :
| Événement | Propriété | Effet |
|---|---|---|
chat |
message |
Le joueur dit le nouveau texte. |
command |
command |
La nouvelle commande s’exécute, au nom de ce joueur. |
join, quit |
join_message, quit_message |
Annoncé à tout le monde, en plus du message du jeu. |
respawn |
location |
Le joueur réapparaît à cet endroit. |
break |
drop_items = false |
Le bloc ne lâche rien. |
damage |
amount |
Les dégâts subis prennent la nouvelle valeur. |
entity_death |
drops.add(…) |
Les objets ajoutés tombent là où l’entité est morte, en plus de son butin normal. |
on entity_death(e) {
if e.entity.type == "minecraft:zombie" and chance(0.05) {
e.drops.add(item("rubies:ruby", 1))
}
}interact_entity est un clic droit sur une entité : annulé, il ne se passe rien (ni traite, ni échange, ni monte). attack est un joueur qui frappe une entité : annulé, il n'y a pas de coup. damage donne attacker, celui qui est derrière les dégâts : l'attaquant ou le tireur d'un projectile. key s'exécute quand un joueur appuie sur une touche d'un mod (voir Interface).
on interact_entity(e) {
if e.entity.type == "minecraft:cow" { e.player.send("This cow won't be milked"); e.cancel() }
}
on attack(e) {
if e.target.type == "minecraft:pig" { e.player.action_bar("This pig is protected"); e.cancel() }
}Pas encore appliqué. Dans death, modifier death_message ou keep_inventory n’a pas encore d’effet. Crafting le signale une fois dans le journal au lieu de l’ignorer sans rien dire.
Priorité et annulation
Ordre : highest, high, normal, low, lowest et monitor. Quand un écouteur annule l’événement, les suivants ne s’exécutent pas, sauf les écouteurs monitor (et en Kotlin, ceux qui passent ignoreCancelled = true). Un écouteur monitor ne fait qu’observer : il ne doit pas modifier l’événement.
on damage(e) priority high {
if e.damage_type == "minecraft:fall" {
e.amount = e.amount / 2 // des atterrissages plus doux
}
}object ChatEvents {
fun register() {
Crafting.events.on<PlayerChatEvent>(EventPriority.HIGHEST) { e ->
if (e.message.startsWith("!")) e.cancel()
}
Crafting.events.on<PlayerChatEvent>(EventPriority.MONITOR) { e ->
if (!e.isCancelled) Crafting.runtime.logger("chat").info("${e.player.name}: ${e.message}")
}
}
}Quand quelque chose échoue
- Un écouteur qui lève une erreur est consigné avec le nom de son mod, et les autres écouteurs continuent de s’exécuter.
/crafting profile(deux fois : démarrer, puis afficher) montre combien de temps chaque mod passe dans ses événements.- Un événement que personne n’écoute n’est même pas construit : écouter peu d’événements ne coûte donc rien.