API

Blocchi, oggetti e ricette

Dichiari i contenuti come un elenco di proprietà. Crafting crea i veri oggetti del gioco al momento giusto e genera i modelli, le tabelle del bottino, i tag, le ricette e le traduzioni di cui hanno bisogno. Non scrivi nessun file di dati del gioco.

Oggetti

content/items.craftCraftScript
item "ruby" { rarity: "rare" }

item "ruby_apple" {
    food: { nutrition: 8, saturation: 1.2, always_edible: true }
    glint: true
}

item "ruby_pickaxe" { tool: { type: "pickaxe", tier: "diamond", speed: 9 }, tab: "tools_and_utilities" }
Proprietà Valori Predefinito
stack o max_stack 1–99 64
rarity common, uncommon, rare, epic (colore del nome) common
glint luccichio dell’incantesimo false
durability numero; impone stack: 1 0
fireproof non brucia nella lava o nel fuoco false
food numero, oppure { nutrition, saturation, always_edible } —
tool "pickaxe", oppure { type, tier, damage, speed }; type: pickaxe (piccone), axe (ascia), shovel (pala), hoe (zappa), sword (spada) —
tab scheda dell’inventario della modalità Creativa (vedi sotto) ingredients
texture percorso della texture item/<id>
on_use fun(player, stack); restituisce true se gestisce l’uso —
armor { slot, defense, toughness, knockback_resistance, texture } —
on_hit fun(attacker, target, stack) —
cooldown secondi 0

Armature, armi e tempi di ricarica

Un oggetto con armor si può indossare. slot è head, chest, legs o feet. defense, toughness e knockback_resistance (da 0 a 1) sono i valori di armatura del gioco: un pettorale di ferro ha 6 di difesa, il diamante 2 di tenacia.

content/armor.craftCraftScript
item "frost_helmet" { texture: "minecraft:item/iron_helmet", armor: { slot: "head", defense: 3, texture: "frost" } }
item "frost_chestplate" { armor: { slot: "chest", defense: 8, toughness: 2 }, durability: 400 }

texture è l'aspetto da indossata. frost significa textures/entity/equipment/humanoid/frost.png nella mod e, per le gambe, textures/entity/equipment/humanoid_leggings/frost.png, con la stessa struttura delle texture di armatura del gioco. Senza, l'armatura sembra di ferro.

on_hit viene eseguito quando l'oggetto è usato per colpire, da un giocatore o da un mob.

content/frost_blade.craftCraftScript
item "frost_blade" {
    texture: "minecraft:item/diamond_sword"
    tool: "sword"
    cooldown: 3
    on_hit: fun(attacker, target, stack) {
        target.add_effect("minecraft:slowness", 4, 4)
        target.world.spawn_particle("minecraft:snowflake", target.location.add(0, 1, 0), 20, 0.4, 0.02)
    }
}

cooldown (in secondi) blocca l'oggetto per quel tempo dopo ogni uso che il suo on_use ha gestito, e la barra rapida lo mostra. Da codice: player.set_cooldown("minecraft:feather", 2) e player.has_cooldown(id). In Kotlin: armor(EquipmentSlot.HEAD, defense = 3, texture = "frost") per le armature e onHit = { ctx -> … } per le armi (ctx.attacker, ctx.target, ctx.stack).

content/Armor.ktKotlin
item("frost_helmet") { armor(EquipmentSlot.HEAD, defense = 3, texture = "frost") }

Blocchi

content/ores.craftCraftScript
block "ruby_ore" {
    hardness: 3
    tool: "pickaxe"
    tier: "iron"
    loot: [
        { item: "rubies:ruby", count: [1, 2] },
        { item: "minecraft:diamond", chance: 0.1 }
    ]
}

block "ruby_block" { hardness: 5, light: 7, tool: "pickaxe", sound: "metal" }

block "ruby_lamp" { hardness: 0.3, light: 15, sound: "glass", transparent: true, tab: "functional_blocks" }

block "ruby_bricks" { hardness: 2, tool: "pickaxe", drops: "ruby", drop_count: [2, 4] }
Proprietà Valori Predefinito
hardness numero; -1 = indistruttibile 1.5
resistance resistenza alle esplosioni = hardness
light 0–15 0
light_when uno stato interruttore, come "lit": il blocco illumina solo quando è acceso (vedi Stati del blocco) sempre
sound stone, wood, gravel, grass, metal, glass, wool, sand stone
like un blocco con cui viene fatto uguale, del gioco ("minecraft:end_stone") o tuo: la sua durezza, resistenza, suono e se serve lo strumento giusto per rilasciare qualcosa sono quelli di quel blocco —
kind uno dei tipi del gioco: scale, porta, baule, coltivazione… (vedi Tipi di blocco) cube
tool, tier strumento necessario perché il blocco rilasci qualcosa, e il materiale minimo di quello strumento: wood (legno), stone (pietra), iron (ferro), diamond (diamante), netherite (netherite) —, wood
drops, drop_count un solo oggetto: id; numero o [min, max] il blocco stesso, 1
loot più oggetti: [{ item, count, chance, tool, fortune }, …]. Ognuno viene estratto separatamente; count è un numero o [min, max] e chance va da 0 a 1 (predefinito 1). tool e fortune: vedi Drop: strumenti e fortuna più sotto —
friction 0.6 normale, 0.98 ghiaccio 0.6
transparent ci si vede attraverso (vetro, foglie) false
has_item registra anche l’oggetto del blocco; senza, il blocco non rilascia nulla a meno che drops o loot dicano cosa true
tab scheda dell’inventario della modalità Creativa building_blocks
on_use fun(player, block); restituisce true se gestisce l’uso. Un giocatore che si accovaccia con qualcosa in mano lo piazza al suo posto, come con i blocchi del gioco —

Schede: building_blocks, colored_blocks, natural_blocks, functional_blocks, redstone_blocks, tools_and_utilities, combat, food_and_drinks, ingredients, spawn_eggs. In Kotlin si trovano in CreativeTabs.

Per far rilasciare qualcosa in più a una creatura quando muore, aggiungilo a e.drops nell’evento entity_death (vedi Eventi).

I blocchi che non sono cubi, i blocchi dei tipi del gioco, le creature, i minerali, i suoni e le particelle si dichiarano allo stesso modo e hanno le loro pagine: Forme dei blocchi, Tipi di blocco, Creature, Generazione del mondo, Suoni e particelle.

Drop: strumenti e fortuna

Un drop in loot può richiedere uno strumento, e la fortuna può darne di più:

content/drops.craftCraftScript
block "ruby_ore" {
    kind: "ore"
    tool: "pickaxe"
    tier: "iron"
    xp: [1, 4]
    loot: [
        { item: "ruby", count: [1, 2], fortune: true },
        { item: "ruby_ore", tool: "silk_touch" }
    ]
}

block "frost_leaves" {
    kind: "leaves"
    loot: [
        { item: "frost_leaves", tool: "shears" },
        { item: "frost_sapling", chance: 0.05, fortune: true }
    ]
}
  • tool: "silk_touch": viene rilasciato solo quando il blocco è rotto con il tocco di velluto. tool: "shears": solo con le cesoie o il tocco di velluto, come le foglie e i rampicanti del gioco rilasciano sé stessi.
  • Quando alcuni drop richiedono uno strumento, quelli che non lo richiedono avvengono solo quando quello strumento non viene usato: il minerale qui sopra rilascia sé stesso con il tocco di velluto e i suoi rubini altrimenti.
  • fortune: true: la fortuna ne dà di più, più del suo count come con i minerali del gioco, o una chance migliore come con le piantine rilasciate dalle foglie.

In Kotlin: drop("ruby", 1..2, tool = null, fortune = true) e drop("ruby_ore", tool = DropTool.SILK_TOUCH).

content/Drops.ktKotlin
block("ruby_ore") {
    kind = BlockKind.ORE
    xp = 1..4
    drop("ruby", 1..2, tool = null, fortune = true)
    drop("ruby_ore", tool = DropTool.SILK_TOUCH)
}

Ricette

content/recipes.craftCraftScript
recipe shaped "ruby_block" {
    pattern: ["RRR", "RRR", "RRR"]
    keys: { R: "ruby" }
    result: "ruby_block"
}

recipe shapeless "rubies_from_block" { ingredients: ["ruby_block"], result: "ruby", count: 9 }

recipe smelting "ruby_from_ore" { input: "ruby_ore", result: "ruby", xp: 1.0 }

Comportamento all’uso

on_use è l’unica logica che vive accanto ai dati. Se supera un paio di righe, scrivi la funzione in lib/ e importala:

content/wands.craftCraftScript
import { lift } from "/lib/teleport"

item "lift_wand" { stack: 1, rarity: "uncommon", on_use: lift }
lib/teleport.craftCraftScript
fun lift(player, stack) {
    player.teleport(player.location.add(0, 10, 0))
    return true
}

Blocchi che reagiscono

Un blocco può eseguire codice quando succede qualcosa a lui o intorno a lui. Ogni gestore riceve il blocco e, dove serve, l'entità.

Proprietà Viene eseguito quando
on_step: fun(block, entity) un'entità cammina sul blocco.
on_inside: fun(block, entity) un'entità si trova dentro il blocco. Il blocco deve lasciar passare le entità: un portale, una pianta o una forma non solida.
on_random_tick: fun(block) ogni tanto, a caso, come la crescita delle colture: circa ogni 68 secondi per blocco.
on_tick: fun(block) è passato il tempo richiesto con block.schedule(ticks) (20 tick = 1 secondo).
on_neighbor_change: fun(block) è cambiato un blocco adiacente: è stato piazzato, rotto o alimentato.
on_placed: fun(block, entity) qualcuno ha piazzato il blocco; entity è chi.
content/reactions.craftCraftScript
block "jump_pad" { on_step: fun(b, e) { e.velocity = vector(0, 1.1, 0) } }

block "blinker" {
    light: 7
    on_tick: fun(b) {
        b.world.spawn_particle("minecraft:end_rod", b.location.add(0.5, 1.2, 0.5), 4, 0.1, 0.01)
        b.schedule(20)
    }
    on_neighbor_change: fun(b) { b.schedule(1) }
}

In Kotlin i gestori sono onStep, onInside, onRandomTick, onTick, onNeighborChange e onPlaced. Ognuno riceve un BlockEventContext con block e, se c'è, entity:

content/Reactions.ktKotlin
block("pad") { onStep = { ctx -> ctx.entity?.velocity = Vector(0.0, 1.1, 0.0) } }

Portali

Un blocco con portal porta chi si trova al suo interno in un'altra dimensione. Indica la dimensione di destinazione, oppure to e back per scegliere dove porta da lì:

content/portals.craftCraftScript
block "sky_gate" { portal: "gatemod:sky", light: 11 }

block "sky_gate_two_way" { portal: { to: "gatemod:sky", back: "minecraft:overworld" } }

L'entità arriva a terra nelle stesse x e z e lì trova un blocco portale per tornare; se non ce n'è uno vicino, ne viene piazzato uno accanto all'arrivo. Le entità aspettano un momento prima di usare di nuovo un portale. I blocchi portale lasciano passare le entità. La dimensione si dichiara con dimension (vedi @dim@). In Kotlin:

content/Portals.ktKotlin
block("sky_gate") { portal("gatemod:sky") }

Stati del blocco

states dà a un blocco valori che ricorda e può mostrare:

content/states.craftCraftScript
block "lamp" {
    model: "block/lamp"
    states: ["facing", "lit"]
    on_use: fun(p, b) { b.set_state("lit", !b.state("lit")); return true }
    on_neighbor_change: fun(b) { b.set_state("lit", b.redstone_power > 0) }
}

block "crop" { states: [{ stage: 3 }, { wet: true }] }
  • "facing": nord, est, sud od ovest. Si orienta verso il giocatore che lo piazza, e il modello ruota con lui.
  • "lit": un nome da solo è un interruttore acceso/spento, spento di default. { lit: true } lo rende acceso di default.
  • { stage: 3 }: un numero da 0 al massimo indicato (da 1 a 15).
  • "facing_all": come "facing", ma anche verso l’alto e verso il basso. Si orienta verso il giocatore che lo piazza, e il modello viene inclinato per l’alto e il basso.
  • { shape: ["top", "middle", "bottom"] }: uno tra pochi nomi, il primo di default. I nomi sono lettere minuscole, cifre e _.

Si leggono e si cambiano con block.state("lit") e block.set_state("lit", true). Funzionano anche con i blocchi del gioco, per esempio il facing e il lit di una fornace.

Uno stato diverso dal valore predefinito può avere un aspetto diverso. Aggiungi una texture in textures/block/<id>_<nome>.png (un interruttore acceso) o <id>_<nome><n>.png (un numero) o <id>_<valore>.png (un nome), oppure un modello in models/block/<id>_<nome>.json. Si prova prima la combinazione completa (<id>_lit_stage2), poi ogni stato da solo. Nell'esempio, lamp.json e lamp_lit.json sono i due modelli del mod, ad esempio con il parent minecraft:block/orientable e texture per fronte, lato e sopra.

Luce in base allo stato. light_when: "lit" fa sì che la light del blocco illumini solo mentre quell’interruttore è acceso, come in una lampada:

content/lamp.craftCraftScript
block "lamp" {
    light: 15
    light_when: "lit"
    states: ["lit"]
    on_use: fun(p, b) { b.set_state("lit", !b.state("lit")); return true }
}

In Kotlin: facing(), facingAll(), toggle("lit"), number("stage", 3), choice("shape", "top", "middle", "bottom"), e block.state(…) e block.setState(…) nel codice:

content/States.ktKotlin
block("lamp") {
    model = "block/lamp"
    facing()
    toggle("lit")
    number("stage", 3)
}

Effetti

Una mod può aggiungere effetti di stato propri. Appaiono sullo schermo del giocatore come quelli del gioco e si danno e si leggono allo stesso modo.

content/frozen.craftCraftScript
effect "frozen" {
    color: "#88CCFF"
    kind: "harmful"
    on_tick: fun(e, level) { e.damage(level) }
}
  • color: il colore delle sue particelle e dello sfondo della sua icona.
  • kind: beneficial, harmful o neutral.
  • on_tick: fun(e, level), viene eseguita ogni secondo finché un’entità ha l’effetto, con il suo livello (1 è I).
  • L’icona è il file textures/mob_effect/<id>.png della mod.

Si dà con e.add_effect("mymod:frozen", 3, 1) (id, secondi, livello) e si controlla con e.has_effect("mymod:frozen"), come gli effetti del gioco (vedi Il mondo e i giocatori). In Kotlin:

content/Frozen.ktKotlin
content.effect("frozen") {
    color = 0x88CCFF
    kind = EffectKind.HARMFUL
    onTick = { e, level -> /* … */ }
}

Redstone

content/battery.craftCraftScript
block "battery" {
    texture: "minecraft:block/copper_block"
    redstone: true
    on_use: fun(p, b) { if b.state("power") > 0 { b.set_state("power", 0) } else { b.set_state("power", 15) }; return true }
}

redstone: true fa emettere al blocco un segnale forte quanto il suo stato power, un numero da 0 a 15 aggiunto automaticamente. b.set_state("power", 15) lo accende, e fili, lampade e porte intorno lo seguono. block.redstone_power è la potenza che il blocco riceve dall'intorno, e on_neighbor_change viene eseguito quando cambia (la lampada qui sopra lo usa).

In Kotlin: redstone = true e block.redstonePower.

content/Battery.ktKotlin
block("battery") {
    texture = "minecraft:block/copper_block"
    redstone = true
    // in a handler: ctx.block.redstonePower
}

Inventari

content/crate.craftCraftScript
block "crate" { texture: "minecraft:block/barrel_side", inventory: 27 }

inventory: 27 dà al blocco quel numero di slot (da 9 a 54, in file da 9). Conserva gli oggetti ai riavvii, usarlo apre una schermata da baule (a meno che il suo on_use abbia preso il clic) e rompendolo lascia cadere ciò che contiene. Da 1 a 8 slot non c’è nessuna schermata: è la mod stessa a mettere e togliere gli oggetti.

Dal codice, block.inventory (funziona anche con i bauli e i barili del gioco) offre set(slot, item(…)), get(slot), count(id) e add(…). In Kotlin: inventory = 27.

content/Crate.ktKotlin
block("crate") {
    texture = "minecraft:block/barrel_side"
    inventory = 27
}

Oggetti mostrati su un blocco. shows_item: 14 fa fluttuare l’oggetto del primo slot del blocco sopra di esso, ruotando, a tanti pixel sopra la sua base. Lo vedono tutti i giocatori, e sparisce quando lo slot si svuota o il blocco viene rotto. Un piedistallo prende l’oggetto dalla mano del giocatore e glielo restituisce:

content/pedestal.craftCraftScript
block "pedestal" {
    shape: [[2, 0, 2, 14, 12, 14]]
    inventory: 1
    shows_item: 14
    on_use: fun(p, b) {
        let inv = b.inventory
        if inv.get(0) == null and p.held_item != null {
            inv.set(0, p.held_item)
            p.set_held_item(null)
        } else if inv.get(0) != null {
            p.give(inv.get(0))
            inv.set(0, null)
        }
        return true
    }
}

player.set_held_item(stack) mette un oggetto nella mano principale del giocatore, o la svuota con null. In Kotlin: showsItem = 14 e player.setHeldItem(stack).

content/Pedestal.ktKotlin
block("pedestal") {
    box(2, 0, 2, 14, 12, 14)
    inventory = 1
    showsItem = 14
    onUse { ctx ->
        val inv = ctx.block.inventory!!
        val held = ctx.player.heldItem
        val shown = inv[0]
        if (shown == null && held != null) { inv[0] = held; ctx.player.setHeldItem(null) }
        else if (shown != null) { ctx.player.give(shown); inv[0] = null }
        true
    }
}

Texture

Le texture sono incluse nella mod; nessuno deve installare un pacchetto di risorse. Il nome del file è l’id:

Mod Dove
CraftScript (cartella) mods/rubies/textures/item/ruby.png, mods/rubies/textures/block/ruby_ore.png
Kotlin o Java src/main/resources/assets/rubies/textures/item/ruby.png

Se una mod include i propri modelli, ricette o tabelle del bottino in quelle stesse cartelle, Crafting li usa.

In Kotlin

content/Blocks.ktKotlin
package com.example.rubies.content

object Blocks {
    fun register(content: ContentBuilder) {
        content.block("ruby_ore") {
            hardness = 3f
            requiresTool = ToolType.PICKAXE
            minTier = ToolTier.IRON
            drop("ruby", 1..2)
            drop("minecraft:diamond", chance = 0.1)
        }
        content.block("ruby_block") { hardness = 5f; luminance = 7; sound = SoundGroup.METAL }
    }
}

Id. Senza namespace, un id appartiene alla tua mod ("ruby" è rubies:ruby). Per i contenuti del gioco, scrivi il namespace: "minecraft:diamond". Non puoi registrare contenuti nel namespace minecraft.