API
Créatures
Une créature personnalisée utilise le corps d’une créature du jeu (son modèle, ses animations, sa taille et sa façon de se déplacer) avec ta texture peinte par-dessus, tes statistiques, ton comportement et ton butin. Tu la déclares comme le reste de ton contenu : une liste de propriétés.
Déclarer une créature
creature "ghost" {
body: "minecraft:zombie"
texture: "entity/ghost"
health: 40
speed: 0.3
attack: 4
behaviour: ["swim", "melee_attack", { wander: 0.8 }, { look_at_players: 10 }, "look_around"]
targets: ["hurt_by", "minecraft:pig"]
loot: [ { item: "ghostmod:ecto", count: [1, 2] } ]
}| Propriété | Valeurs | Par défaut |
|---|---|---|
body |
id d’une créature du jeu : minecraft:zombie, minecraft:wolf, minecraft:cow… |
obligatoire |
texture |
chemin de la texture, peinte sur le modèle du corps : entity/ghost est le fichier textures/entity/ghost.png du mod |
l’apparence du corps |
model |
ton propre modèle 3D : entity/robot est le fichier models/entity/robot.json du mod (voir plus bas) |
le modèle du corps |
size |
[largeur, hauteur] en blocs : ce avec quoi elle entre en collision et où on peut cliquer dessus (plus bas) |
celle du corps |
health |
points de vie | ceux du corps |
speed |
vitesse de marche (un zombie se déplace à 0.23, un loup à 0.3) | celle du corps |
attack |
dégâts d’attaque au corps à corps | ceux du corps |
follow_range |
à combien de blocs elle détecte ses cibles | celle du corps |
behaviour |
liste de comportements, du plus au moins important (voir plus bas) | le comportement du corps |
targets |
qui elle attaque, par ordre de priorité (voir plus bas) | personne |
loot |
[{ item, count, chance }, …], comme pour les blocs : chaque objet est tiré séparément |
rien |
spawns |
biomes où elle apparaît seule, avec poids et taille de groupe (ci-dessous) | n’apparaît pas seule |
breed_item |
objet qui fait se reproduire deux d’entre elles (ci-dessous) | ne se reproduit pas |
tame_item |
objet qui l’apprivoise (ci-dessous) | ne peut pas être apprivoisée |
rideable |
true permet aux joueurs de la monter (ci-dessous) |
false |
Comportements
La liste fixe la priorité : quand deux comportements veulent agir en même temps, le premier l’emporte. Écris chacun sous forme de nom, de { nom: nombre } pour son réglage principal, ou de map avec tous ses réglages.
| Comportement | Ce qu’il fait | Réglages |
|---|---|---|
"swim" |
Reste à la surface de l’eau. | |
"look_around" |
Regarde autour d’elle quand elle ne fait rien. | |
"wander", { wander: 0.8 } |
Se promène au hasard. | speed, 1 par défaut |
"look_at_players", { look_at_players: 10 } |
Regarde les joueurs proches. | range en blocs, 8 par défaut |
"melee_attack", { melee_attack: 1.2 } |
Poursuit sa cible et la frappe. | speed, 1 par défaut |
"panic", { panic: 1.5 } |
S’enfuit quand elle subit des dégâts. | speed, 1.25 par défaut |
{ avoid: "minecraft:wolf", distance: 8, speed: 1.2 } |
Se tient à l’écart de cette créature. | distance en blocs, speed |
{ follow: "minecraft:wheat", speed: 1 } |
Suit celui qui tient cet objet. | speed |
{ ranged_attack: "minecraft:snowball", interval: 20, range: 14, damage: 3 } |
Tire un projectile sur sa cible (ci-dessous). | projectile, interval, range, speed, power, damage |
"breed", { breed: 1 } |
Se reproduit avec une autre de son espèce une fois nourrie. | speed |
"follow_parent", { follow_parent: 1.1 } |
Un petit reste près de son parent. | speed |
{ follow_owner: 1.2, distance: 8 } |
Une créature apprivoisée suit son maître. | speed, distance en blocs |
{ fly_around: 1 } |
Vole çà et là ; pour les corps volants (perroquet, abeille, allay). | speed |
{ can_start: …, tick: … } |
Ton propre code (ci-dessous). | can_start, tick, keep_going, moves |
Les nombres de vitesse multiplient la vitesse de base de la créature : { wander: 0.8 } se promène un peu plus lentement qu’elle ne marche.
Cibles
targets dit qui elle attaque, de la priorité la plus haute à la plus basse. "hurt_by" est celui qui lui inflige des dégâts ; un id d’entité désigne l’entité de ce type la plus proche ("minecraft:player" pour les joueurs, "minecraft:pig" pour les cochons). Pour que l’attaque ait lieu, la créature a besoin d’un comportement qui l’effectue, comme "melee_attack".
La faire apparaître
command haunt requires "ghostmod.haunt" describe "Fait apparaître un fantôme là où tu te trouves" {
if player == null { return "Réservé aux joueurs" }
world().spawn("ghostmod:ghost", player.location)
return "&7Un fantôme apparaît…"
}L’id est celui de ton mod : ghostmod:ghost. La commande du jeu /summon ghostmod:ghost fonctionne aussi.
Apparaître toutes seules
Ajoute spawns et la créature apparaît d’elle-même dans le monde, comme les créatures du jeu.
creature "ghost" {
body: "minecraft:zombie"
spawns: [ { biomes: ["minecraft:dark_forest", "#minecraft:is_forest"], weight: 20, group: [1, 2] } ]
}Chaque entrée indique les biomes où elle apparaît (un id, ou un #tag pour tout un groupe de biomes), un weight (poids : la fréquence, par rapport aux autres créatures de ce biome ; une vache vaut 8, un zombie 95) et une plage de taille de group (groupe).
Elle suit les règles d’apparition de son corps : avec un corps de zombie, elle apparaît dans le noir ; avec un corps de vache, sur l’herbe, à la lumière. Cela vaut à la génération du monde comme après.
Œuf d’apparition. Chaque créature reçoit aussi un œuf d’apparition, son id plus _spawn_egg (ghost_spawn_egg), dans l’onglet créatif des œufs d’apparition. Sa texture est textures/item/ghost_spawn_egg.png du mod s’il existe ; sinon il ressemble à l’œuf de son corps.
En Kotlin :
content.creature("ghost") {
body = "minecraft:zombie"
spawn("minecraft:dark_forest", "#minecraft:is_forest", weight = 20, group = 1..2)
}Diriger une créature depuis le code
Les créatures que tu déclares, et tout autre mob, sont une Creature. Depuis un événement, une commande ou un minuteur, tu peux leur donner des ordres :
| Membre | Ce qu’il fait |
|---|---|
target |
Qui elle attaque. À lire ou à définir. |
moveTo(location, speed), move_to |
Marche jusqu’à une position. La vitesse multiplie sa vitesse normale. |
stop() |
Arrête de marcher. |
isMoving, is_moving |
Si elle se rend quelque part. |
lookAt(location), look_at |
Se tourne pour regarder une position. |
canSee(entity), can_see |
Si elle a une ligne de vue dégagée vers cette entité. |
isBaby |
Si c’est un petit. |
ownerId |
L’id de son maître, une fois apprivoisée. |
tame(player) |
Fait de ce joueur son maître. |
isSitting |
Si elle est assise. |
playAnimation(name), play_animation |
Joue l’une des animations de son modèle (voir ci-dessous). |
Toute entité a une velocity, un Vector en blocs par tick. Lis-la ou définis-la pour pousser l’entité : entity.velocity = vector(0, 0.6, 0) la propulse vers le haut.
En CraftScript, un let typé restreint une entité à une créature. C’est vérifié à l’exécution :
command pup requires "dogmod.pup" describe "Get a pet dog" {
if player == null { return "Players only" }
let dog: Creature = world().spawn("dogmod:dog", player.location)
dog.tame(player)
dog.look_at(player.location)
dog.velocity = vector(0, 0.6, 0) // a little hop
return "&7Good dog!"
}Tes propres comportements
Quand ceux qui existent ne suffisent pas, écris-en un avec ton code. Il va dans la liste behaviour comme les autres : sa position est donc sa priorité.
creature "herder" {
body: "minecraft:wolf"
targets: ["minecraft:pig"]
behaviour: [
"swim",
{
can_start: fun(c) { return c.target != null && c.can_see(c.target) },
tick: fun(c) {
if c.target != null {
c.look_at(c.target.location)
if !c.is_moving { c.move_to(c.target.location, 1.2) }
}
}
},
{ wander: 1 }
]
}can_start: demandé tous les quelques ticks ; renvoie s’il doit commencer.tick: s’exécute à chaque tick tant que le comportement est actif.keep_going: dit s’il doit continuer. Si omis, c’est identique àcan_start.moves:truepar défaut. Un comportement qui bouge ne s’exécute pas en même temps qu’un autre qui bouge ; celui qui est plus haut dans la liste l’emporte. Utilisefalsepour ceux qui ne font que regarder ou réagir.
En Kotlin : Behaviour.Custom(canStart = { … }, tick = { … }, keepGoing = …, moves = true)
Animaux : élever, apprivoiser, monter et voler
Quelques propriétés et comportements transforment une créature en animal. Celle-ci se reproduit avec des pommes, s’apprivoise avec un os et peut être montée :
creature "mooble" {
body: "minecraft:cow"
tame_item: "minecraft:bone"
breed_item: "minecraft:apple"
rideable: true
behaviour: ["swim", { breed: 1 }, { follow_parent: 1.1 }, { follow_owner: 1.2, distance: 8 }, { wander: 0.8 }]
}- Élever.
breed_itemplus le comportement"breed": nourries avec cet objet, deux créatures de la même espèce donnent un petit de cette espèce. Il faut un corps d’animal (vache, loup, poule…). Les petits utilisent"follow_parent"pour rester près de leurs parents. - Apprivoiser.
tame_item: chaque essai réussit une fois sur trois. Le maître est mémorisé, et une créature apprivoisée ne cible jamais son maître. Accroupi, utilise à main vide pour la faire s’asseoir ou se lever.{ follow_owner: 1.2, distance: 8 }la fait suivre son maître. - Monter.
rideable: true: utilise à main vide pour grimper (une fois apprivoisée, seul son maître le peut). On la dirige avec les touches de déplacement et la souris ; accroupis-toi pour descendre. - Voler.
{ fly_around: 1 }pour les corps volants (perroquet, abeille, allay). Une créaturerideableau corps volant monte quand son cavalier regarde vers le haut et pique quand il regarde vers le bas.
En Kotlin : breedItem = …, tameItem = …, rideable = true et les comportements Behaviour.Breed(), Behaviour.FollowParent(), Behaviour.FollowOwner(speed, distance) et Behaviour.FlyAround().
Tes propres projectiles
En plus de ceux du jeu, un mod peut déclarer ses propres projectiles. Il a ses propres dégâts, sa gravité et ce qui se passe quand il atterrit :
projectile "frost_bolt" {
damage: 4
gravity: false
on_hit: fun(e) {
let at = e.entity?.location ?? e.block?.location
if at != null { e.projectile.world.spawn_particle("minecraft:snowflake", at.add(0.5, 1, 0.5), 12, 0.4, 0.02) }
}
}damage: les dégâts infligés à ce qu’il touche.gravity:falsele fait voler en ligne droite.on_hit:fun(e), appelée quand il atterrit, avec le mêmeeque l’événementhit:e.projectile,e.shooterete.entityoue.block.texture: le projectile vole avec l’apparence de son objet ; par défaut il utilise donctextures/item/<id>.png; renseignetexturepour en utiliser une autre.
Utilise-le comme n’importe quel autre projectile : world.shoot("mymod:frost_bolt", from, velocity, shooter), ou, dans une créature, { ranged_attack: "mymod:frost_bolt" }. En Kotlin :
content.projectile("frost_bolt") {
damage = 4.0
gravity = false
onHit = { e -> /* … */ }
}Attaques à distance et projectiles
Le comportement ranged_attack fait tirer une créature. Elle s’approche jusqu’à ce que sa cible soit à portée et en vue, puis tire.
creature "frost_spirit" {
body: "minecraft:snow_golem"
behaviour: [{ ranged_attack: "minecraft:snowball", interval: 20, range: 14, damage: 3 }, { wander: 0.6 }]
targets: ["minecraft:zombie", "hurt_by"]
}
on hit(e) {
if e.shooter?.type == "frostmod:frost_spirit" && e.entity != null {
e.entity.velocity = vector(0, 0.2, 0) // knocked up
}
}| Réglage | Signification |
|---|---|
ranged_attack |
ranged_attack : le projectile (minecraft:arrow, minecraft:snowball, minecraft:small_fireball, minecraft:wind_charge…). |
interval |
interval : ticks entre deux tirs. |
range |
range : distance en blocs à partir de laquelle elle tire. |
speed |
speed : vitesse de marche pendant qu’elle s’approche. |
power |
power : vitesse de vol du projectile. |
damage |
damage : dégâts supplémentaires au toucher. |
Pour tirer depuis le code, pour des créatures ou pour la capacité d’un joueur, utilise world().shoot(projectile, from, velocity, shooter, damage).
En Kotlin :
creature("frost_spirit") {
body = "minecraft:snow_golem"
behaviour(Behaviour.RangedAttack(Identifier.parse("minecraft:snowball"), interval = 20, range = 14.0, damage = 3.0))
target(TargetRule.Nearest(Identifier.parse("minecraft:zombie")))
}
// From code, e.g. a player's ability:
world.shoot(Identifier.parse("minecraft:small_fireball"), from, Vector(0.0, 0.0, 1.5), shooter = player, damage = 4.0)L’événement hit (ProjectileHitEvent) se déclenche quand un projectile touche. Il a e.projectile, e.shooter et e.entity ou e.block, selon ce qui a été touché. Annule-le et le projectile traverse. Voir Événements.
Bon à savoir
- Chaque corps a ses limites. Certaines créatures du jeu n’ont pas toutes les statistiques : une vache n’a pas de dégâts d’attaque. Si tu en définis, ils sont ignorés et Crafting prévient dans le journal.
- Les corps qui ne marchent pas. Les corps qui ne savent pas trouver un chemin seuls ignorent les comportements de déplacement (wander, poursuite, panic, follow, avoid) ; les autres fonctionnent.
- Sans
behaviour, la créature se comporte comme le corps qu’elle utilise. Dès que tu écris la liste, elle ne fait que ce qu’elle contient. - Le modèle ne change que l’apparence. Le déplacement et le comportement viennent toujours du corps, et la taille aussi, sauf si tu définis
size. - Une créature personnalisée est une entité vivante comme les autres : elle reçoit les événements
spawn,damageetentity_death, a desdata, et tu la manipules avec ce qui se trouve dans Le monde et les joueurs.
En Kotlin
package com.example.rubies.content
object Creatures {
fun register(content: ContentBuilder) {
content.creature("ruby_golem") {
body = "minecraft:zombie"
texture = "entity/ruby_golem"
health = 60.0
speed = 0.25
attackDamage = 6.0
behaviour(Behaviour.Swim)
behaviour(Behaviour.MeleeAttack())
behaviour(Behaviour.Wander(0.6))
behaviour(Behaviour.LookAtPlayers(12f))
behaviour(Behaviour.LookAround)
target(TargetRule.HurtBy)
target(TargetRule.Nearest(Identifier.parse("minecraft:player")))
drop(Items.RUBY, 2..4)
}
}
}Comportements : Behaviour.Swim, LookAround, Wander(speed), LookAtPlayers(range), MeleeAttack(speed), Panic(speed), Avoid(entity, distance, speed), Follow(item, speed). Cibles : TargetRule.HurtBy et TargetRule.Nearest(id). Ajoute du butin avec drop(item, count, chance), comme pour les blocs.
Ton propre modèle 3D
Ajoute model et la créature est dessinée avec ton modèle au lieu de celui du corps. Le corps lui donne toujours sa taille, son déplacement et son comportement ; le modèle ne change que son apparence.
creature "robot" {
body: "minecraft:pig"
model: "entity/robot"
texture: "entity/robot"
behaviour: ["swim", { wander: 0.8 }, { look_at_players: 10 }]
}Le modèle est le fichier models/entity/robot.json du mod et sa texture est textures/entity/robot.png. En Kotlin : creature("robot") { body = "minecraft:pig"; model = "entity/robot"; texture = "entity/robot" }. Le format est le même d’une version du jeu à l’autre.
{ "texture_size": [64, 64],
"bones": [
{ "name": "body", "pivot": [0, 6, 0], "cubes": [ { "origin": [-5, 6, -3], "size": [10, 10, 6], "uv": [0, 0] } ] },
{ "name": "head", "parent": "body", "pivot": [0, 16, 0], "cubes": [ { "origin": [-4, 16, -4], "size": [8, 8, 8], "uv": [0, 16] } ] },
{ "name": "left_leg", "pivot": [2.5, 6, 0], "cubes": [ { "origin": [1, 0, -1.5], "size": [3, 6, 3], "uv": [32, 0] } ] },
{ "name": "right_leg", "pivot": [-2.5, 6, 0], "cubes": [ { "origin": [-4, 0, -1.5], "size": [3, 6, 3], "uv": [32, 16] } ] }
],
"animations": { "head": "look", "left_leg": "walk", "right_leg": "walk_opposite", "body": "idle" } }Les tailles sont en pixels (16 correspond à un bloc), avec y qui monte à partir des pieds de la créature.
- Os :
name, unparentfacultatif (il bouge avec lui),pivot(le point autour duquel il tourne) etcubes. - Cube :
origin(son coin le plus bas),sizeetuv(l’endroit où sa texture commence dans l’image). La disposition est celle des boîtes habituelles : un cube de largeur w, hauteur h et profondeur d utilise une zone de 2(w+d) sur (d+h) pixels. - Les animations se placent par os, sous forme d’un nom ou d’une liste de noms :
| Animation | Ce qu’elle fait |
|---|---|
look |
Se tourne là où regarde la créature ; pour les têtes. |
walk, walk_opposite |
Se balance pendant la marche ; la seconde en opposition de phase, pour l’autre membre. |
idle |
Un léger balancement. |
spin |
Tourne sans arrêt. |
Si un modèle ne peut pas être dessiné, la créature ressemble à son corps et le journal explique pourquoi.
Taille
Une créature a la taille de son corps. Quand ton modèle est plus petit ou plus grand, renseigne size: [largeur, hauteur] en blocs pour que ce avec quoi elle entre en collision et l’endroit où l’on clique correspondent à ce que voient les joueurs :
creature "drake" {
body: "minecraft:bee"
model: "entity/drake"
texture: "entity/drake"
size: [1.4, 1.1]
}En Kotlin : size = 1.4 to 1.1.
Animations par images clés
Pour des mouvements au-delà des animations prêtes à l’emploi, ajoute une section clips à côté de bones et animations :
{ "bones": [ … ],
"animations": { … },
"clips": {
"idle": { "length": 2.0, "bones": { "head": { "position": { "0": [0, 0, 0], "1": [0, 0.6, 0], "2": [0, 0, 0] } } } },
"walk": { "length": 1.0, "bones": { "body": { "rotation": { "0": [0, 0, -6], "0.5": [0, 0, 6], "1": [0, 0, -6] } } } },
"roar": { "length": 1.5, "bones": {
"head": { "rotation": { "0": [0, 0, 0], "0.4": [-35, 0, 0], "1.1": [-35, 0, 0], "1.5": [0, 0, 0] },
"scale": { "0": 1, "0.4": 1.35, "1.1": 1.35, "1.5": 1 } },
"body": { "position": { "0": [0, 0, 0], "0.3": [0, 4, 0], "0.6": [0, 0, 0] } } } }
} }- Chaque clip a une
length(durée) en secondes et, par os, jusqu’à trois canaux :rotationen degrés,positionen pixels (y vers le haut) etscale(un nombre ou[x, y, z]). - Les clés sont des instants en secondes. Les valeurs se mélangent en ligne droite entre les clés ; ajoute
"interpolation": "smooth"à un clip et il passe par ses clés en suivant une courbe. Un canal peut aussi être une seule valeur pour tout le clip.
| Clip | Quand il se joue |
|---|---|
walk |
Boucle tant qu’elle marche, au rythme de ses pattes. |
idle |
Boucle tant qu’elle reste immobile. |
attack |
Se joue quand elle frappe. |
| Tout autre nom | Se joue quand le code le demande : c.play_animation("roar"). Les joueurs proches qui ont Crafting la voient. |
"idle": { "length": 1.2, "interpolation": "smooth", "bones": {
"left_wing": { "rotation": { "0": [0, 0, -20], "0.6": [0, 0, 25], "1.2": [0, 0, -20] } } } }Un clip lancé depuis le code se joue par-dessus walk, idle et attack au lieu de les remplacer, et ils s’additionnent : une créature peut rugir tout en marchant.
Les petits d’une créature avec son propre modèle sont dessinés à moitié taille.
Textures
Sans modèle, la texture a la même disposition que celle du corps choisi (un zombie, un loup…), tu peux donc partir d’un modèle de texture pour ce corps et peindre par-dessus. Elle va dans le mod, comme les textures des objets et des blocs :
| Mod | Où |
|---|---|
| CraftScript (dossier) | mods/ghostmod/textures/entity/ghost.png |
| Kotlin ou Java | src/main/resources/assets/ghostmod/textures/entity/ghost.png |