API

Mga nilalang

Gumagamit ang sariling nilalang ng katawan ng isang nilalang sa laro (ang model, animation, laki at paraan ng paggalaw nito) na may texture mo na nakapinta sa ibabaw, ang stats mo, ang behaviour mo at ang loot mo. Idinedeklara mo ito gaya ng iba mo pang content: listahan ng mga property.

Magdeklara ng nilalang

content/creatures.craftCraftScript
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] } ]
}
Katangian Mga value Default na halaga
body id ng isang nilalang sa laro: minecraft:zombie, minecraft:wolf, minecraft:cow… kailangan
texture path ng texture, ipinipinta sa ibabaw ng model ng katawan: ang entity/ghost ay ang textures/entity/ghost.png ng mod ang itsura ng katawan
model sarili mong 3D model: ang entity/robot ay ang models/entity/robot.json ng mod (sa ibaba) ang model ng katawan
size [width, height] sa mga block: ang binabanggaan nito at kung saan ito pinipindot (sa ibaba) ang sa katawan
health health points sa katawan
speed bilis ng paglakad (0.23 ang zombie, 0.3 ang wolf) sa katawan
attack damage ng melee attack sa katawan
follow_range ilang block ang layo kung saan nito nadedetect ang mga target nito sa katawan
behaviour listahan ng mga behaviour, mula pinakamahalaga hanggang pinakamababa (nasa ibaba) ang behaviour ng katawan
targets kung sino ang inaatake nito, ayon sa priority (nasa ibaba) wala
loot [{ item, count, chance }, …], gaya ng sa mga block: hiwalay na nira-roll ang bawat item wala
spawns mga biome kung saan ito kusang lumilitaw, may bigat at laki ng grupo (sa ibaba) hindi kusang lumilitaw
breed_item item na nagpapa-breed sa dalawa (sa ibaba) hindi nagpaparami
tame_item item na nagpapaamo rito (sa ibaba) hindi mapaamo
rideable hinahayaan ng true ang mga player na sakyan ito (sa ibaba) false

Mga behaviour

Ang listahan ang priority: kapag dalawa ang gustong kumilos nang sabay, ang nauna ang panalo. Isulat ang bawat isa bilang pangalan, bilang { name: number } para sa pangunahing setting nito, o bilang map na may lahat ng setting nito.

Behaviour Ano ang ginagawa nito Mga setting
"swim" Nananatiling nakalutang sa tubig.
"look_around" Tumitingin-tingin sa paligid kapag walang ginagawa.
"wander", { wander: 0.8 } Naglalakad-lakad. speed, default 1
"look_at_players", { look_at_players: 10 } Tumitingin sa mga player na malapit. range sa block, default 8
"melee_attack", { melee_attack: 1.2 } Hinahabol at tinatamaan ang target nito. speed, default 1
"panic", { panic: 1.5 } Tumatakbo palayo kapag nasaktan. speed, default 1.25
{ avoid: "minecraft:wolf", distance: 8, speed: 1.2 } Lumalayo sa nilalang na iyon. distance sa block, speed
{ follow: "minecraft:wheat", speed: 1 } Sinusundan ang sinumang may hawak ng item na iyon. speed
{ ranged_attack: "minecraft:snowball", interval: 20, range: 14, damage: 3 } Bumabaril ng projectile sa target nito (sa ibaba). projectile, interval, range, speed, power, damage
"breed", { breed: 1 } Nagpaparami kasama ang kauri nito kapag napakain na. speed
"follow_parent", { follow_parent: 1.1 } Dumidikit ang bata sa magulang nito. speed
{ follow_owner: 1.2, distance: 8 } Sumusunod ang pinaamong nilalang sa may-ari nito. speed, distance sa mga block
{ fly_around: 1 } Lumilipad-lipad; para sa mga katawang lumilipad (parrot, bubuyog, allay). speed
{ can_start: …, tick: … } Sarili mong code (sa ibaba). can_start, tick, keep_going, moves

Pinaparami ng mga numero ng bilis ang base speed ng nilalang: medyo mas mabagal kaysa sa paglakad nito ang paglalakad-lakad ng { wander: 0.8 }.

Mga target

Sinasabi ng targets kung sino ang inaatake nito, mula pinakamataas hanggang pinakamababang priority. Ang "hurt_by" ay ang sinumang nanakit dito; ang entity id ay ang pinakamalapit na entity ng ganoong uri ("minecraft:player" para sa mga player, "minecraft:pig" para sa mga baboy). Para mangyari ang atake, kailangan ng nilalang ng behaviour na gumagawa nito, gaya ng "melee_attack".

I-spawn ito

commands/haunt.craftCraftScript
command haunt requires "ghostmod.haunt" describe "Magpatawag ng multo kung saan ka nakatayo" {
    if player == null { return "Para sa mga player lang" }
    world().spawn("ghostmod:ghost", player.location)
    return "&7May lumitaw na multo…"
}

Sa mod mo ang id: ghostmod:ghost. Gumagana rin ang command ng laro na /summon ghostmod:ghost.

Kusang lumitaw

Magdagdag ng spawns at kusang lalabas ang nilalang sa mundo, tulad ng mga nilalang ng laro.

content/ghost.craftCraftScript
creature "ghost" {
    body: "minecraft:zombie"
    spawns: [ { biomes: ["minecraft:dark_forest", "#minecraft:is_forest"], weight: 20, group: [1, 2] } ]
}

Inilalista ng bawat entry ang mga biomes kung saan ito lumilitaw (isang id, o isang #tag para sa buong grupo ng biome), isang weight (bigat: gaano kadalas, kumpara sa ibang nilalang ng biome na iyon; ang baka ay 8, ang zombie ay 95) at isang saklaw ng laki ng group (grupo).

Sinusunod nito ang mga patakaran ng paglitaw ng katawan nito: kapag katawan ng zombie, lumilitaw ito sa dilim; kapag katawan ng baka, sa damuhan na may liwanag. Totoo ito pareho kapag ginagawa ang mundo at pagkatapos.

Spawn egg. Bawat nilalang ay may spawn egg din, ang id nito at _spawn_egg (ghost_spawn_egg), sa creative tab ng mga spawn egg. Ang texture nito ay ang textures/item/ghost_spawn_egg.png ng mod kung mayroon; kung wala, kamukha ito ng itlog ng katawan nito.

Sa Kotlin:

content/Creatures.ktKotlin
content.creature("ghost") {
    body = "minecraft:zombie"
    spawn("minecraft:dark_forest", "#minecraft:is_forest", weight = 20, group = 1..2)
}

Pagkontrol ng nilalang mula sa code

Ang mga nilalang na idineklara mo, at anumang ibang mob, ay isang Creature. Mula sa isang event, command o timer, maaari mo silang utusan:

Miyembro Ginagawa nito
target Kung sino ang inaatake nito. Maaaring basahin o itakda.
moveTo(location, speed), move_to Naglalakad papunta sa isang lokasyon. Ang speed ay nagpaparami sa normal na bilis nito.
stop() Humihinto sa paglalakad.
isMoving, is_moving Kung naglalakad ito papunta sa kung saan.
lookAt(location), look_at Lumilingon para tumingin sa isang lokasyon.
canSee(entity), can_see Kung malinaw ang tanaw nito sa entity na iyon.
isBaby Kung bata ito.
ownerId Ang id ng may-ari nito, kapag napaamo na.
tame(player) Ginagawang may-ari nito ang player na iyon.
isSitting Kung nakaupo ito.
playAnimation(name), play_animation Nagpapatugtog ng isa sa mga animation ng model nito (tingnan sa ibaba).

Ang bawat entity ay may velocity, isang Vector sa mga block bawat tick. Basahin o itakda ito para itulak ang entity: entity.velocity = vector(0, 0.6, 0) ay ibinabato ito pataas.

Sa CraftScript, ang let na may uri ay nagpapaliit ng entity bilang nilalang. Sinusuri ito kapag tumatakbo:

commands/pup.craftCraftScript
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!"
}

Sarili mong mga behaviour

Kapag hindi sapat ang mga handa na, sumulat ng isa gamit ang sarili mong code. Napupunta ito sa listahan ng behaviour tulad ng iba, kaya ang posisyon nito ang prayoridad nito.

content/herder.craftCraftScript
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: tinatanong kada ilang tick; ibalik kung dapat na itong magsimula.
  • tick: tumatakbo kada tick habang aktibo ang behaviour.
  • keep_going: nagsasabi kung dapat magpatuloy. Kapag wala, kapareho ito ng can_start.
  • moves: true bilang default. Ang behaviour na gumagalaw ay hindi tumatakbo kasabay ng isa pang gumagalaw; nananalo ang nauuna sa listahan. Gamitin ang false para sa mga tumitingin o tumutugon lang.

Sa Kotlin: Behaviour.Custom(canStart = { … }, tick = { … }, keepGoing = …, moves = true)

Mga hayop: magparami, magpaamo, sumakay at lumipad

Ginagawang hayop ng ilang property at behaviour ang isang nilalang. Ang isang ito ay dumarami gamit ang mansanas, napapaamo ng buto at maaaring sakyan:

content/mooble.craftCraftScript
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 }]
}
  • Magparami. breed_item kasama ang behaviour na "breed": kapag napakain ng item na iyon, ang dalawang magkauri ay magkakaanak ng batang kauri nila. Kailangan nito ng katawan ng hayop (baka, lobo, manok…). Ginagamit ng mga bata ang "follow_parent" para manatili malapit sa magulang.
  • Magpaamo. tame_item: tatlong beses na subok, isang beses ang tagumpay. Natatandaan ang may-ari, at hindi kailanman tina-target ng pinaamong nilalang ang may-ari nito. Mag-sneak at gamitin gamit ang walang laman na kamay para paupuin o patayuin ito. Ang { follow_owner: 1.2, distance: 8 } ay nagpapasunod dito sa may-ari.
  • Sumakay. rideable: true: gamitin gamit ang walang laman na kamay para umakyat (kapag napaamo na, ang may-ari lang). Kontrolin gamit ang mga movement key at mouse; mag-sneak para bumaba.
  • Lumipad. { fly_around: 1 } para sa mga katawang lumilipad (parrot, bubuyog, allay). Ang rideable na nilalang na may lumilipad na katawan ay umaakyat kapag tumingin pataas ang sumasakay at sumisid kapag tumingin ito pababa.

Sa Kotlin: breedItem = …, tameItem = …, rideable = true at ang mga behaviour na Behaviour.Breed(), Behaviour.FollowParent(), Behaviour.FollowOwner(speed, distance) at Behaviour.FlyAround().

Sariling mga projectile

Bukod sa mga projectile ng laro, ang isang mod ay maaaring magdeklara ng sarili nito. May sarili itong damage, gravity at nangyayari kapag bumagsak ito:

content/frost_bolt.craftCraftScript
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: damage sa tinatamaan nito.
  • gravity: ang false ay nagpapalipad dito nang tuwid.
  • on_hit: fun(e), tinatawag kapag bumagsak ito, kasama ang parehong e ng event na hit: e.projectile, e.shooter at e.entity o e.block.
  • texture: lumilipad ang projectile na kamukha ng item nito, kaya sa default ay gumagamit ito ng textures/item/<id>.png; itakda ang texture para gumamit ng iba.

Gamitin ito tulad ng anumang ibang projectile: world.shoot("mymod:frost_bolt", from, velocity, shooter), o sa isang nilalang, { ranged_attack: "mymod:frost_bolt" }. Sa Kotlin:

content/FrostBolt.ktKotlin
content.projectile("frost_bolt") {
    damage = 4.0
    gravity = false
    onHit = { e -> /* … */ }
}

Mga pag-atake mula sa malayo at mga projectile

Pinabaril ng behaviour na ranged_attack ang isang nilalang. Lumalapit ito hanggang sa abot at tanaw na ang target, saka bumabaril.

content/frost_spirit.craftCraftScript
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
    }
}
Setting Kahulugan
ranged_attack ranged_attack: ang projectile (minecraft:arrow, minecraft:snowball, minecraft:small_fireball, minecraft:wind_charge…).
interval interval: mga tick sa pagitan ng mga putok.
range range: layo sa mga block kung saan ito bumabaril.
speed speed: bilis ng paglalakad habang lumalapit.
power power: gaano kabilis lumipad ang projectile.
damage damage: dagdag na pinsala kapag tumama.

Para bumaril mula sa code, para sa mga nilalang o sa kakayahan ng isang player, gamitin ang world().shoot(projectile, from, velocity, shooter, damage).

Sa Kotlin:

content/FrostSpirit.ktKotlin
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)

Ang event na hit (ProjectileHitEvent) ay nagaganap kapag may tinamaan ang projectile. Mayroon itong e.projectile, e.shooter at alinman sa e.entity o e.block, depende sa tinamaan. I-cancel ito at tatagos ang projectile. Tingnan ang Mga event.

Mabuting malaman

  • May limitasyon ang bawat katawan. May mga nilalang sa laro na kulang ng stat: walang attack damage ang cow. Kung itatakda mo ito, hindi ito papansinin at magbababala ang Crafting sa log.
  • Mga katawang hindi naglalakad. Hindi pinapansin ng mga katawang hindi kayang maghanap ng daan nang mag-isa ang mga behaviour ng paglakad (wander, paghabol, panic, follow, avoid); gumagana ang iba.
  • Kung walang behaviour, kumikilos ang nilalang gaya ng katawang ginagamit nito. Sa sandaling isulat mo ang listahan, ang nasa loob lang nito ang ginagawa nito.
  • Itsura lang ang binabago ng model. Ang galaw at behaviour ay laging galing sa katawan, pati ang laki maliban kung itakda mo ang size.
  • Ang sariling nilalang ay living entity gaya ng iba: natatanggap nito ang mga event na spawn, damage at entity_death, may data ito, at hinahawakan mo ito gamit ang nasa Ang mundo at ang mga manlalaro.

Sa Kotlin

content/Creatures.ktKotlin
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)
        }
    }
}

Mga behaviour: Behaviour.Swim, LookAround, Wander(speed), LookAtPlayers(range), MeleeAttack(speed), Panic(speed), Avoid(entity, distance, speed), Follow(item, speed). Mga target: TargetRule.HurtBy at TargetRule.Nearest(id). Magdagdag ng loot gamit ang drop(item, count, chance), gaya ng sa mga block.

Sarili mong 3D model

Idagdag ang model at ang nilalang ay iguguhit gamit ang model mo sa halip na sa katawan. Ang katawan pa rin ang nagbibigay ng laki, galaw at behaviour nito; itsura lang ang binabago ng model.

content/robot.craftCraftScript
creature "robot" {
    body: "minecraft:pig"
    model: "entity/robot"
    texture: "entity/robot"
    behaviour: ["swim", { wander: 0.8 }, { look_at_players: 10 }]
}

Ang model ay ang models/entity/robot.json ng mod at ang texture nito ay ang textures/entity/robot.png. Sa Kotlin: creature("robot") { body = "minecraft:pig"; model = "entity/robot"; texture = "entity/robot" }. Pareho ang format sa lahat ng bersyon ng laro.

models/entity/robot.jsonJSON
{ "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" } }

Nasa pixel ang mga sukat (16 ang isang block), at ang y ay pataas mula sa paa ng nilalang.

  • Bone: name, opsyonal na parent (sumasama ito sa galaw nito), pivot (ang punto kung saan ito umiikot) at cubes.
  • Cube: origin (ang pinakamababang sulok nito), size at uv (kung saan nagsisimula ang texture nito sa larawan). Ang layout ay ang karaniwan sa kahon: ang cube na may lapad w, taas h at lalim d ay gumagamit ng lugar na 2(w+d) by (d+h) pixel.
  • Ang mga animation ay bawat bone, bilang pangalan o listahan ng mga pangalan:
Animation Ginagawa nito
look Iniikot kung saan tumitingin ang nilalang; para sa mga ulo.
walk, walk_opposite Umiindayog habang naglalakad; ang pangalawa ay kabaligtaran ang phase, para sa kabilang paa.
idle Bahagyang pag-indayog.
spin Patuloy na umiikot.

Kung hindi maiguhit ang isang model, magmumukhang katawan nito ang nilalang at sasabihin ng log kung bakit.

Laki

Kasinlaki ng katawan nito ang isang nilalang. Kapag mas maliit o mas malaki ang iyong model, itakda ang size: [width, height] sa mga block para tumugma ang binabanggaan nito at kung saan ito pinipindot sa nakikita ng mga player:

content/drake.craftCraftScript
creature "drake" {
    body: "minecraft:bee"
    model: "entity/drake"
    texture: "entity/drake"
    size: [1.4, 1.1]
}

Sa Kotlin: size = 1.4 to 1.1.

Mga animation na may keyframe

Para sa galaw na higit sa mga handang animation, magdagdag ng seksyong clips sa tabi ng bones at animations:

models/entity/robot.jsonJSON
{ "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] } } } }
  } }
  • May length (haba) sa segundo ang bawat clip at, bawat buto, hanggang tatlong channel: rotation sa degree, position sa pixel (y pataas) at scale (isang numero o [x, y, z]).
  • Ang mga key ay mga oras sa segundo. Ang mga value ay tuwid na naghahalo sa pagitan ng mga key; magdagdag ng "interpolation": "smooth" sa isang clip at dadaan ito sa mga key nito sa isang kurba. Ang isang channel ay maaari ring iisang value para sa buong clip.
Clip Kailan ito tumutugtog
walk Inuulit habang naglalakad ito, kasabay ng mga paa nito.
idle Inuulit habang nakatayo lang ito.
attack Tumutugtog kapag sumasalakay ito.
Anumang ibang pangalan Tumutugtog kapag hiniling ng code: c.play_animation("roar"). Nakikita ito ng mga kalapit na player na may Crafting.
Smooth clipJSON
"idle": { "length": 1.2, "interpolation": "smooth", "bones": {
  "left_wing": { "rotation": { "0": [0, 0, -20], "0.6": [0, 0, 25], "1.2": [0, 0, -20] } } } }

Ang clip na sinimulan mula sa code ay tumutugtog sa ibabaw ng walk, idle at attack sa halip na palitan ang mga ito, at nagsasama-sama sila: puwedeng umungol ang nilalang habang naglalakad.

Ang mga bata ng nilalang na may sariling model ay iginuguhit sa kalahating laki.

Mga texture

Kung walang model, pareho ang layout ng texture sa napiling katawan (zombie, wolf…), kaya puwede kang magsimula sa template para sa katawang iyon at pintahan ito. Nasa loob ito ng mod, gaya ng mga texture ng item at block:

Mod Saan
CraftScript (folder) mods/ghostmod/textures/entity/ghost.png
Kotlin o Java src/main/resources/assets/ghostmod/textures/entity/ghost.png