API

Bloki, przedmioty i receptury

Zawartość deklarujesz jako listę właściwości. Crafting tworzy prawdziwe obiekty gry we właściwym momencie i generuje potrzebne im modele, tabele łupów, tagi, receptury i tłumaczenia. Nie piszesz żadnych plików danych gry.

Przedmioty

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" }
Właściwość Wartości Domyślnie
stack lub max_stack 1–99 64
rarity common, uncommon, rare, epic (kolor nazwy) common
glint połysk zaklęcia false
durability liczba; wymusza stack: 1 0
fireproof nie płonie w lawie ani w ogniu false
food liczba lub { nutrition, saturation, always_edible } —
tool "pickaxe" lub { type, tier, damage, speed }; type: pickaxe, axe, shovel, hoe, sword —
tab zakładka ekwipunku trybu kreatywnego (niżej) ingredients
texture ścieżka tekstury item/<id>
on_use fun(player, stack); zwraca true, jeśli obsługuje użycie —
armor { slot, defense, toughness, knockback_resistance, texture } —
on_hit fun(attacker, target, stack) —
cooldown sekundy 0

Zbroje, bronie i czasy odnowienia

Przedmiot z armor można nosić. slot to head, chest, legs lub feet. defense, toughness i knockback_resistance (od 0 do 1) to wartości pancerza z gry: żelazny napierśnik ma 6 obrony, diament 2 wytrzymałości.

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 to wygląd założonej zbroi. frost oznacza textures/entity/equipment/humanoid/frost.png w modzie, a dla nóg textures/entity/equipment/humanoid_leggings/frost.png, w takim samym układzie jak tekstury zbroi z gry. Bez niej zbroja wygląda jak żelazna.

on_hit uruchamia się, gdy przedmiotu użyto do uderzenia, przez gracza lub moba.

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 (w sekundach) blokuje przedmiot na ten czas po każdym użyciu, które obsłużył jego on_use, a pasek szybkiego wyboru to pokazuje. Z kodu: player.set_cooldown("minecraft:feather", 2) i player.has_cooldown(id). W Kotlinie: armor(EquipmentSlot.HEAD, defense = 3, texture = "frost") dla zbroi i onHit = { ctx -> … } dla broni (ctx.attacker, ctx.target, ctx.stack).

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

Bloki

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] }
Właściwość Wartości Domyślnie
hardness liczba; -1 = niezniszczalny 1.5
resistance odporność na wybuchy = hardness
light 0–15 0
light_when stan-przełącznik, np. "lit": blok świeci tylko wtedy, gdy jest włączony (zobacz Stany bloku) zawsze
sound stone, wood, gravel, grass, metal, glass, wool, sand stone
like blok, na wzór którego powstaje, z gry ("minecraft:end_stone") albo twój: jego twardość, odporność, dźwięk i to, czy potrzebne jest właściwe narzędzie, żeby cokolwiek upuścił, są takie jak tego bloku —
kind jeden z rodzajów z gry: schody, drzwi, skrzynia, uprawa… (zobacz Rodzaje bloków) cube
tool, tier narzędzie wymagane, żeby blok cokolwiek upuścił, i minimalny materiał tego narzędzia: wood, stone, iron, diamond, netherite —, wood
drops, drop_count jeden przedmiot: id; liczba lub [min, max] sam blok, 1
loot kilka przedmiotów: [{ item, count, chance, tool, fortune }, …]. Każdy jest losowany osobno; count to liczba lub [min, max], a chance to wartość od 0 do 1 (domyślnie 1). tool i fortune: zobacz Upuszczane przedmioty poniżej —
friction 0.6 zwykły, 0.98 lód 0.6
transparent widać przez niego (szkło, liście) false
has_item rejestruje też przedmiot bloku; bez niego blok nic nie upuszcza, chyba że drops lub loot mówią co true
tab zakładka ekwipunku trybu kreatywnego building_blocks
on_use fun(player, block); zwraca true, jeśli obsługuje użycie. Gracz, który się skrada z czymś w ręce, stawia to zamiast tego, jak w blokach gry —

Zakładki: building_blocks, colored_blocks, natural_blocks, functional_blocks, redstone_blocks, tools_and_utilities, combat, food_and_drinks, ingredients, spawn_eggs. W Kotlinie są w CreativeTabs.

Żeby stworzenie upuszczało coś dodatkowego po śmierci, dodaj to do e.drops w zdarzeniu entity_death (zobacz Zdarzenia).

Bloki niebędące sześcianami, bloki rodzajów z gry, stworzenia, rudy, dźwięki i cząsteczki deklaruje się tak samo i mają własne strony: Kształty bloków, Rodzaje bloków, Stworzenia, Generowanie świata, Dźwięki i cząsteczki.

Upuszczane przedmioty: narzędzia i szczęście

Przedmiot w loot może wymagać narzędzia, a szczęście może dać go więcej:

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": wypada tylko wtedy, gdy blok zniszczono z jedwabnym dotykiem. tool: "shears": tylko z nożycami lub jedwabnym dotykiem, tak jak liście i pnącza z gry wypadają same.
  • Gdy część upuszczanych przedmiotów wymaga narzędzia, te bez wymagań wypadają tylko wtedy, gdy tego narzędzia nie użyto: powyższa ruda wypada sama z jedwabnym dotykiem, a bez niego daje swoje rubiny.
  • fortune: true: szczęście daje go więcej, albo więcej jego count, jak w rudach z gry, albo lepszą chance, jak w sadzonkach z liści.

W Kotlinie: drop("ruby", 1..2, tool = null, fortune = true) i 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)
}

Receptury

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 }

Zachowanie przy użyciu

on_use to jedyna logika, która mieszka obok danych. Jeśli rozrośnie się ponad kilka wierszy, napisz funkcję w lib/ i ją zaimportuj:

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
}

Bloki, które reagują

Blok może uruchomić kod, gdy coś dzieje się z nim lub wokół niego. Każda procedura otrzymuje blok i, jeśli to ma sens, encję.

Właściwość Uruchamia się, gdy
on_step: fun(block, entity) encja wchodzi na blok.
on_inside: fun(block, entity) encja znajduje się wewnątrz bloku. Blok musi przepuszczać encje: portal, roślina lub niepełny kształt.
on_random_tick: fun(block) co jakiś czas, losowo, jak wzrost upraw: mniej więcej raz na 68 sekund na blok.
on_tick: fun(block) upłynął czas zamówiony przez block.schedule(ticks) (20 ticków = 1 sekunda).
on_neighbor_change: fun(block) zmienił się sąsiedni blok: został postawiony, zniszczony lub zasilony.
on_placed: fun(block, entity) ktoś postawił blok; entity to ten, kto to zrobił.
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) }
}

W Kotlinie procedury nazywają się onStep, onInside, onRandomTick, onTick, onNeighborChange i onPlaced. Każda dostaje BlockEventContext z block i, jeśli jest, entity:

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

Portale

Blok z portal przenosi każdego, kto w nim stoi, do innego wymiaru. Podaj wymiar docelowy albo to i back, aby wybrać, dokąd prowadzi stamtąd:

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

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

Encja ląduje na ziemi w tych samych współrzędnych x i z i znajduje tam blok portalu, którym wróci; jeśli w pobliżu nie ma żadnego, obok miejsca przybycia stawiany jest nowy. Encje czekają chwilę, zanim znów użyją portalu. Bloki portalu przepuszczają encje. Sam wymiar deklarujesz przez dimension (zobacz @dim@). W Kotlinie:

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

Stany bloku

states daje blokowi wartości, które zapamiętuje i może pokazywać:

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": północ, wschód, południe lub zachód. Ustawia się twarzą do gracza, który go stawia, a model obraca się razem z nim.
  • "lit": sama nazwa to przełącznik włączony/wyłączony, domyślnie wyłączony. { lit: true } włącza go domyślnie.
  • { stage: 3 }: liczba od 0 do podanego maksimum (od 1 do 15).
  • "facing_all": jak "facing", ale także w górę i w dół. Ustawia się twarzą do gracza, który go stawia, a model jest przewracany dla góry i dołu.
  • { shape: ["top", "middle", "bottom"] }: jedna z kilku nazw, domyślnie pierwsza. Nazwy to małe litery, cyfry i _.

Odczytujesz i zmieniasz je przez block.state("lit") i block.set_state("lit", true). Działają też na blokach gry, na przykład facing i lit pieca.

Stan inny niż domyślny może wyglądać inaczej. Dodaj teksturę w textures/block/<id>_<nazwa>.png (włączony przełącznik) lub <id>_<nazwa><n>.png (liczba) lub <id>_<wartość>.png (nazwa) albo model w models/block/<id>_<nazwa>.json. Najpierw próbowana jest cała kombinacja (<id>_lit_stage2), potem każdy stan osobno. W przykładzie lamp.json i lamp_lit.json to dwa modele moda, na przykład z rodzicem minecraft:block/orientable i teksturami przodu, boku i góry.

Światło zależne od stanu. light_when: "lit" sprawia, że light bloku świeci tylko wtedy, gdy ten przełącznik jest włączony, jak w lampie:

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 }
}

W Kotlinie: facing(), facingAll(), toggle("lit"), number("stage", 3), choice("shape", "top", "middle", "bottom") oraz block.state(…) i block.setState(…) w kodzie:

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

Efekty

Mod może dodawać własne efekty statusu. Pojawiają się na ekranie gracza tak jak efekty z gry i nadaje się je oraz odczytuje tak samo.

content/frozen.craftCraftScript
effect "frozen" {
    color: "#88CCFF"
    kind: "harmful"
    on_tick: fun(e, level) { e.damage(level) }
}
  • color: kolor jego cząsteczek i tła ikony.
  • kind: beneficial, harmful lub neutral.
  • on_tick: fun(e, level), uruchamiana co sekundę, dopóki byt ma ten efekt, z jego poziomem (1 to I).
  • Ikona to plik textures/mob_effect/<id>.png moda.

Nadajesz go przez e.add_effect("mymod:frozen", 3, 1) (id, sekundy, poziom), a sprawdzasz przez e.has_effect("mymod:frozen"), tak jak efekty z gry (zobacz Świat i gracze). W Kotlinie:

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 sprawia, że blok wysyła sygnał o sile równej jego stanowi power, liczbie od 0 do 15 dodawanej automatycznie. b.set_state("power", 15) włącza go, a okoliczne przewody, lampy i drzwi za nim podążają. block.redstone_power to moc, którą blok otrzymuje z otoczenia, a on_neighbor_change uruchamia się, gdy ta się zmienia (korzysta z tego powyższa lampa).

W Kotlinie: redstone = true i block.redstonePower.

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

Ekwipunki

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

inventory: 27 daje blokowi tyle miejsc (od 9 do 54, w rzędach po 9). Zachowuje przedmioty po restarcie, użycie otwiera ekran skrzyni (chyba że jego on_use przejęło kliknięcie), a zniszczenie wyrzuca to, co zawiera. Od 1 do 8 miejsc nie ma ekranu: mod sam wkłada przedmioty i je wyjmuje.

W kodzie block.inventory (działa też dla skrzyń i beczek gry) oferuje set(slot, item(…)), get(slot), count(id) i add(…). W Kotlinie: inventory = 27.

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

Przedmioty pokazane na bloku. shows_item: 14 sprawia, że przedmiot z pierwszego miejsca bloku unosi się nad nim, obracając się, tyle pikseli nad jego spodem. Widzą go wszyscy gracze, a znika, gdy miejsce się opróżni lub blok zostanie zniszczony. Piedestał bierze przedmiot z ręki gracza i oddaje go z powrotem:

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) wkłada przedmiot do głównej ręki gracza albo ją opróżnia przez null. W Kotlinie: showsItem = 14 i 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
    }
}

Tekstury

Tekstury są dostarczane w modzie; nikt nie musi instalować paczki zasobów. Nazwa pliku to id:

Mod Gdzie
CraftScript (folder) mods/rubies/textures/item/ruby.png, mods/rubies/textures/block/ruby_ore.png
Kotlin lub Java src/main/resources/assets/rubies/textures/item/ruby.png

Jeśli mod dostarcza własne modele, receptury lub tabele łupów w tych samych folderach, Crafting ich używa.

W Kotlinie

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. Bez przestrzeni nazw id należy do twojego moda ("ruby" to rubies:ruby). Dla zawartości gry podaj przestrzeń nazw: "minecraft:diamond". Nie możesz rejestrować zawartości w przestrzeni nazw minecraft.