API
Il mondo e i giocatori
Leggi e modifica blocchi, genera entità, parla con i giocatori. In CraftScript i nomi usano lo snake_case (block_at, max_health); in Kotlin e Java usano il camelCase (blockAt, maxHealth). Sono gli stessi oggetti.
Un esempio
command beacon requires "rubies.beacon" describe "Accendi un segnale dove ti trovi" {
if player == null { return "Solo per giocatori" }
let w = player.world
let at = player.location
w.set_block(at.block_x, at.block_y, at.block_z, "minecraft:lantern", { hanging: false })
w.spawn_particle("minecraft:flame", at, 30, 0.5, 0.02)
w.play_sound(at, "minecraft:block.lantern.place")
player.title("&eAcceso", "")
}object BeaconCommand {
fun register() {
Crafting.commands.command("beacon") {
permission = "rubies.beacon"
executes { c ->
val at = c.player.location
val world = c.player.world
world.setBlock(at.blockX, at.blockY, at.blockZ, Identifier.parse("minecraft:lantern"), mapOf("hanging" to false))
world.spawnParticle(Identifier.parse("minecraft:flame"), at, count = 30, spread = 0.5, speed = 0.02)
world.playSound(at, Identifier.parse("minecraft:block.lantern.place"))
c.player.title("&eAcceso")
}
}
}
}Mondo
world() in CraftScript (il mondo principale, oppure world("minecraft:the_nether")); Crafting.server?.world(id) o player.world in Kotlin.
| Membro | Cosa fa |
|---|---|
id, players, time, is_raining, data |
Id del mondo, giocatori, ora del giorno (lettura e scrittura), se sta piovendo, dati salvati. |
block_at(x, y, z) |
Il blocco in quella posizione. |
set_block(x, y, z, type) |
Piazza un blocco. |
set_block(x, y, z, type, states) |
Piazza un blocco con stati: { open: true }, { facing: "north" }. |
spawn(type, location) |
Genera un’entità. |
drop_item(location, stack) |
Lascia cadere un oggetto a terra. |
explode(location, power, fire?) |
Esplosione. |
strike_lightning(location) |
Fulmine. |
spawn_particle(id, location, count?, spread?, speed?) |
Particelle. |
spawn_particle(id, location, velocity) |
Una particella che va con quella velocità, in blocchi per tick. Alcune, come minecraft:enchant e minecraft:portal, vanno verso il punto in cui vengono generate: partono da location + velocity. |
play_sound(location, id, volume?, pitch?) |
Un suono in una posizione. |
light_at(x, y, z) |
Quanta luce c’è, da 0 a 15. |
container_at(x, y, z) |
L’inventario di una cassa, di un barile…, o null. |
set_sign_text(x, y, z, lines) |
Testo su un cartello. |
set_chunk_loaded(cx, cz, loaded) |
Mantiene un chunk caricato anche quando non c’è nessuno vicino. |
entities() |
Le entità nel mondo. |
living_near(location, radius) |
Le entità viventi vicino a un punto, dalla più vicina. |
shoot(projectile, from, velocity, shooter?, damage?) |
Lancia un proiettile, del gioco o di una mod. |
Giocatore
| Membro | Cosa fa |
|---|---|
name, uuid, is_op, has_crafting_client |
Identità; se il client ha Crafting installato. |
send(msg), action_bar(msg), title(title, subtitle?) |
Messaggi in chat, nella barra delle azioni e a schermo. Colori con &. |
inventory, held_item, give(stack) |
Inventario, l’oggetto in mano, dare un oggetto. |
set_held_item(stack) |
Mette un oggetto nella mano principale, al posto di quello che c’era; null la svuota. |
health, max_health, food_level, game_mode |
Salute, fame (lettura e scrittura) e modalità di gioco. |
is_sleeping |
Se il giocatore sta dormendo. |
data |
Dati salvati con il giocatore (vedi sotto). |
play_sound(id, volume?, pitch?) |
Un suono solo per quel giocatore. |
has_permission(p), kick(reason) |
Permessi; espellere. |
Un Player è anche un’entità vivente (vedi sotto).
Entità, blocchi e inventari
| Tipo | Membri |
|---|---|
| Entity | uuid, type, world, location, custom_name, is_alive, data, direction, vehicle; teleport, remove, set_rotation, add_tag, has_tag. |
| LivingEntity | Tutto ciò che ha Entity più health, max_health; damage, heal, set_ai, add_effect, remove_effect, has_effect, effects, add_modifier, remove_modifier, attribute, set_attribute, equipment, set_equipment (disattiva o riattiva il suo comportamento). |
| Block | type, x, y, z, world, location, is_solid, data; set_type, relative(dx, dy, dz). |
| Inventory | size; get(slot), set(slot, stack), add(stack), count(id), clear(). |
| Location | world, x, y, z, yaw, pitch, block_x, block_y, block_z; add(dx, dy, dz), distance_to(other). |
Un ItemStack contiene un id, una quantità, un nome, una descrizione (lore) e i dati della mod, e li conserva mentre si sposta tra inventari e casse. In CraftScript lo crei con item("rubies:ruby", 3); in Kotlin, con ItemStack.of("rubies:ruby", 3) o con il costruttore completo.
stack.enchantments è una mappa dall’id di ogni incantesimo al suo livello (minecraft:sharpness → 3); per un libro incantato, quelli che conferisce. In Kotlin, stack.withEnchantments(mapOf(Identifier.parse("minecraft:sharpness") to 3)) è lo stesso stack con quegli incantesimi. Uno stack letto dal gioco conserva tutto ciò che ha, anche ciò che l’API non nomina (il contenuto di una mappa, gli effetti di una pozione), quando una mod lo sposta o lo cambia con with_count o withEnchantments (il copy di Kotlin non lo conserva).
Effetti, attributi ed equipaggiamento
Effetti. Ogni entità viva può avere gli effetti del gioco. e.add_effect("minecraft:speed", 8, 3) prende l'id, i secondi e il livello (1 è I); un ultimo argomento facoltativo, true o false, indica se mostra le particelle. remove_effect(id), has_effect(id) e effects (una mappa da id a { level, seconds }) completano il quadro. In Kotlin: addEffect(Identifier.parse("minecraft:speed"), 8.0, 3) e ActiveEffect(level, seconds).
Una mod può dichiarare effetti propri (vedi Blocchi, oggetti e ricette); si danno e si leggono con questi stessi membri.
Attributi. attribute("minecraft:movement_speed") restituisce il valore attuale, con armatura ed effetti. set_attribute("minecraft:scale", 1.6) cambia il valore base: scale, attack_damage, max_health, jump_strength, armor… In Kotlin: attribute(id) e setAttribute(id, value).
command grow() {
let p = player
if p.attribute("minecraft:scale") > 1.2 { p.set_attribute("minecraft:scale", 1) } else { p.set_attribute("minecraft:scale", 1.6) }
}Modificatori. Un modificatore cambia un attributo senza sostituirne il valore di base, quindi più modificatori si sommano e ciascuno si può togliere. e.add_modifier("minecraft:movement_speed", "mymod:frozen_slow", -0.3, "percent_of_base") prende l’attributo, un id per il modificatore, la quantità e l’operazione; e.remove_modifier("minecraft:movement_speed", "mymod:frozen_slow") lo rimuove. Aggiungere di nuovo lo stesso id lo sostituisce. Le operazioni sono add (somma la quantità), percent_of_base (somma la quantità per il valore di base) e multiply_total (moltiplica il risultato per 1 più la quantità). In Kotlin: addModifier(attr, id, amount, ModifierOperation.PERCENT_OF_BASE).
command chill() {
player.add_modifier("minecraft:movement_speed", "mymod:chill", -0.3, "percent_of_base")
// later: player.remove_modifier("minecraft:movement_speed", "mymod:chill")
}Cavalcature ed effetti ad area. entity.vehicle è ciò che l’entità sta cavalcando, o null. world.living_near(location, radius) elenca le entità viventi attorno a un punto, dalla più vicina, che è ciò che serve agli effetti ad area:
command frostwave() {
let p = player
for other in p.world.living_near(p.location, 8) {
if other.type != "minecraft:player" { other.add_effect("mymod:frozen", 4, 1) }
}
}Equipaggiamento. e.equipment("head") è l'oggetto indossato in quella posizione, o null; e.set_equipment("main_hand", item("minecraft:iron_sword")) lo cambia. Gli slot sono main_hand, off_hand, head, chest, legs e feet. In Kotlin: EquipmentSlot.HEAD, equipment(slot) e setEquipment(slot, stack).
Direzione e tempi di ricarica. entity.direction è la direzione dello sguardo, un vettore lungo un blocco. player.set_cooldown(item, seconds) e player.has_cooldown(item) impostano un tempo di ricarica e lo controllano.
Dati salvati
Giocatori, entità, blocchi e mondi hanno data: un archivio chiave-valore che sopravvive ai riavvii. Memorizza stringhe, numeri, booleani, liste e mappe.
// Data that survives restarts. Keys start with the mod id: they're shared by every mod.
const VISITS = "rubies.visits"
fun visits(p: Player): number {
return p.data.get_int(VISITS) ?? 0
}
fun add_visit(p: Player): number {
let n = visits(p) + 1
p.data.set(VISITS, n)
return n
}package com.example.rubies.storage
object Visits {
private const val KEY = "rubies.visits" // shared by every mod: prefix it with the mod id
fun of(player: Player): Int = player.data.getInt(KEY) ?: 0
fun add(player: Player): Int = (of(player) + 1).also { player.data[KEY] = it }
}| CraftScript | Kotlin / Java | Cosa fa |
|---|---|---|
data.set(k, v) o data[k] = v |
data[k] = v |
Salva un valore (null lo elimina). |
data[k] |
data[k] |
Legge un valore com’è stato salvato, oppure null. |
data.get_int(k), get_number, get_string, get_boolean |
getInt(k), getNumber, getString, getBoolean |
Legge un valore di quel tipo, o null se non c’è. |
data.remove(k), data.clear(), data.keys |
remove(k), clear(), keys |
Elimina una chiave, elimina tutto, elenca le chiavi. |
- Le chiavi sono condivise da tutte le mod. Inizia ogni chiave con l’id della tua mod (
rubies.visits) così non sovrascrivi le chiavi di un’altra mod. - Quanto durano: i dati di un giocatore restano con il giocatore; quelli di un’entità spariscono quando muore; quelli di un blocco spariscono quando un giocatore lo rompe o quando viene sostituito tramite l’API.
- I numeri vengono salvati come decimali;
get_intli restituisce come interi. - Metti le chiavi e le loro funzioni in un unico file (
lib/storage.craft,storage/in Kotlin): il resto della mod non ha bisogno di conoscerle. Vedi Organizzare una mod.
Server
| Membro | Cosa fa |
|---|---|
players, worlds, motd, tps, is_dedicated |
Stato del server; tps è la media dei tick al secondo (20 è l’ideale). |
player(name), world(id) |
Trova un giocatore online o un mondo. |
broadcast(msg) |
Messaggio a tutti. |
stop() |
Salva e arresta il server. |
run_command(cmd) |
Via di fuga: esegue un comando del gioco (vedi sotto). |
Vie di fuga
Due funzioni accettano i formati propri del gioco: run_command (run(…) in CraftScript), che esegue un comando del gioco, e summon(type, location, nbt), che crea un’entità con dati nel formato interno del gioco. Esistono per ciò che l’API non copre ancora, ma quei formati appartengono a Minecraft e possono cambiare in una nuova versione, quindi una mod che ne dipende può rompersi. Usale il meno possibile e preferisci sempre l’API.
Niente di inventato. Nessun membro dell’API restituisce un valore fittizio. Se qualcosa non può funzionare nel gioco in esecuzione, solleva un errore che dice cosa e perché.