API
몹
사용자 정의 몹은 게임 속 몹의 몸(모델, 애니메이션, 크기, 움직이는 방식)을 사용하고, 그 위에 당신의 텍스처를 입히고, 당신의 능력치, 행동, 전리품을 더합니다. 나머지 콘텐츠처럼 속성 목록으로 선언합니다.
몹 선언하기
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] } ]
}| 속성 | 값 | 기본값 |
|---|---|---|
body |
게임 속 몹의 id: minecraft:zombie, minecraft:wolf, minecraft:cow… |
필수 |
texture |
몸의 모델 위에 입히는 텍스처 경로: entity/ghost는 모드의 textures/entity/ghost.png |
몸의 원래 모습 |
model |
나만의 3D 모델: entity/robot은 모드의 models/entity/robot.json(아래 참고) |
몸의 모델 |
size |
블록 단위의 [width, height]: 충돌하는 범위와 클릭되는 범위(아래 참고) |
몸의 값 |
health |
체력 | 몸의 값 |
speed |
걷는 속도(좀비는 0.23, 늑대는 0.3) | 몸의 값 |
attack |
근접 공격 피해 | 몸의 값 |
follow_range |
몇 블록 떨어진 대상까지 감지하는지 | 몸의 값 |
behaviour |
가장 중요한 것부터 순서대로 놓은 행동 목록(아래 참고) | 몸의 행동 |
targets |
우선순위대로 정한 공격 대상(아래 참고) | 없음 |
loot |
[{ item, count, chance }, …], 블록과 같습니다. 각 아이템은 따로 추첨됩니다 |
없음 |
spawns |
저절로 나타나는 바이옴, 가중치와 그룹 크기 포함 (아래) | 저절로 나타나지 않음 |
breed_item |
두 마리를 번식시키는 아이템 (아래) | 번식하지 않음 |
tame_item |
길들이는 아이템 (아래) | 길들일 수 없음 |
rideable |
true이면 플레이어가 탈 수 있음 (아래) |
false |
행동
목록의 순서가 곧 우선순위입니다. 두 행동이 동시에 하려 하면 앞에 있는 것이 이깁니다. 각 행동은 이름으로, 주요 설정을 담은 { 이름: 숫자 }로, 또는 모든 설정을 담은 맵으로 적습니다.
| 행동 | 하는 일 | 설정 |
|---|---|---|
"swim" |
물 위에 떠 있습니다. | |
"look_around" |
할 일이 없을 때 주위를 둘러봅니다. | |
"wander", { wander: 0.8 } |
이리저리 돌아다닙니다. | speed, 기본값 1 |
"look_at_players", { look_at_players: 10 } |
근처 플레이어를 바라봅니다. | range(블록 단위), 기본값 8 |
"melee_attack", { melee_attack: 1.2 } |
대상을 쫓아가 때립니다. | speed, 기본값 1 |
"panic", { panic: 1.5 } |
피해를 입으면 도망칩니다. | speed, 기본값 1.25 |
{ avoid: "minecraft:wolf", distance: 8, speed: 1.2 } |
그 몹을 피합니다. | distance(블록 단위), speed |
{ follow: "minecraft:wheat", speed: 1 } |
그 아이템을 든 사람을 따라갑니다. | speed |
{ ranged_attack: "minecraft:snowball", interval: 20, range: 14, damage: 3 } |
목표를 향해 투사체를 쏩니다 (아래). | projectile, interval, range, speed, power, damage |
"breed", { breed: 1 } |
먹이를 먹으면 같은 종류와 번식합니다. | speed |
"follow_parent", { follow_parent: 1.1 } |
새끼가 부모 곁에 머뭅니다. | speed |
{ follow_owner: 1.2, distance: 8 } |
길들여진 몹이 주인을 따라다닙니다. | speed, distance(블록 수) |
{ fly_around: 1 } |
날아다닙니다. 나는 몸(앵무새, 벌, 알레이)용입니다. | speed |
{ can_start: …, tick: … } |
직접 작성한 코드 (아래). | can_start, tick, keep_going, moves |
속도 숫자는 몹의 기본 속도에 곱해집니다. { wander: 0.8 }은 걷는 속도보다 조금 느리게 돌아다닙니다.
공격 대상
targets는 누구를 공격할지 우선순위가 높은 순서대로 정합니다. "hurt_by"는 자신에게 피해를 준 대상이고, 엔티티 id는 그 종류 중 가장 가까운 엔티티입니다(플레이어는 "minecraft:player", 돼지는 "minecraft:pig"). 실제로 공격하려면 "melee_attack"처럼 공격을 수행하는 행동이 필요합니다.
소환하기
command haunt requires "ghostmod.haunt" describe "서 있는 자리에 유령 소환" {
if player == null { return "플레이어만 사용할 수 있습니다" }
world().spawn("ghostmod:ghost", player.location)
return "&7유령이 나타났습니다…"
}id는 내 모드의 것입니다: ghostmod:ghost. 게임 명령어 /summon ghostmod:ghost도 작동합니다.
저절로 나타나게 하기
spawns를 추가하면 게임의 몹처럼 몹이 월드에 저절로 나타납니다.
creature "ghost" {
body: "minecraft:zombie"
spawns: [ { biomes: ["minecraft:dark_forest", "#minecraft:is_forest"], weight: 20, group: [1, 2] } ]
}각 항목에는 나타날 biomes(id, 또는 바이옴 그룹 전체를 뜻하는 #태그), weight(가중치: 그 바이옴의 다른 몹에 비해 얼마나 자주 나타나는지. 소는 8, 좀비는 95), 그리고 group 크기 범위를 적습니다.
몸의 스폰 규칙을 따릅니다. 좀비 몸이면 어두운 곳에, 소 몸이면 밝은 풀밭에 나타납니다. 월드를 생성할 때도, 그 이후에도 마찬가지입니다.
스폰 알. 모든 몹에는 id 뒤에 _spawn_egg를 붙인 스폰 알(ghost_spawn_egg)이 크리에이티브 스폰 알 탭에 생깁니다. 모드에 textures/item/ghost_spawn_egg.png가 있으면 그것이 텍스처가 되고, 없으면 몸의 스폰 알과 같은 모습입니다.
Kotlin에서:
content.creature("ghost") {
body = "minecraft:zombie"
spawn("minecraft:dark_forest", "#minecraft:is_forest", weight = 20, group = 1..2)
}코드로 몹 조종하기
선언한 몹과 다른 모든 몹은 Creature입니다. 이벤트, 명령어, 타이머에서 명령을 내릴 수 있습니다.
| 멤버 | 하는 일 |
|---|---|
target |
공격 중인 대상. 읽거나 설정할 수 있습니다. |
moveTo(location, speed), move_to |
지정한 위치까지 걸어갑니다. speed는 평소 속도에 곱해집니다. |
stop() |
걷기를 멈춥니다. |
isMoving, is_moving |
어딘가로 걸어가는 중인지 여부. |
lookAt(location), look_at |
지정한 위치를 바라봅니다. |
canSee(entity), can_see |
그 엔티티까지 시야가 트여 있는지 여부. |
isBaby |
새끼인지 여부. |
ownerId |
길들여진 뒤 주인의 id. |
tame(player) |
그 플레이어를 주인으로 삼습니다. |
isSitting |
앉아 있는지 여부. |
playAnimation(name), play_animation |
모델의 애니메이션 하나를 재생합니다 (아래 참고). |
모든 엔티티에는 틱당 블록 수로 나타내는 Vector인 velocity가 있습니다. 읽거나 설정해서 엔티티를 밀어낼 수 있습니다. entity.velocity = vector(0, 0.6, 0)은 위로 쏘아 올립니다.
CraftScript에서는 타입을 붙인 let이 엔티티를 몹으로 좁혀 줍니다. 실행할 때 검사됩니다.
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!"
}나만의 행동
준비된 행동으로 부족하면 직접 코드로 작성하세요. 다른 행동처럼 behaviour 목록에 넣으며, 위치가 곧 우선순위입니다.
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: 몇 틱마다 호출됩니다. 시작해야 하는지 반환하세요.tick: 행동이 활성인 동안 매 틱 실행됩니다.keep_going: 계속할지 알려 줍니다. 생략하면can_start와 같습니다.moves: 기본값은true입니다. 움직이는 행동은 다른 움직이는 행동과 함께 실행되지 않으며, 목록에서 앞에 있는 것이 이깁니다. 보기만 하거나 반응만 하는 행동에는false를 쓰세요.
Kotlin에서: Behaviour.Custom(canStart = { … }, tick = { … }, keepGoing = …, moves = true)
동물: 번식, 길들이기, 타기, 날기
몇 가지 속성과 행동으로 몹을 동물로 만들 수 있습니다. 이 몹은 사과로 번식하고, 뼈로 길들일 수 있으며, 탈 수 있습니다.
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 }]
}- 번식.
breed_item과 행동"breed": 그 아이템을 먹이면 같은 종류 두 마리가 그 종류의 새끼를 낳습니다. 동물 몸(소, 늑대, 닭 등)이 필요합니다. 새끼는"follow_parent"로 부모 곁에 머뭅니다. - 길들이기.
tame_item: 세 번 시도하면 한 번 성공합니다. 주인이 기억되고, 길들여진 몹은 주인을 절대 공격 대상으로 삼지 않습니다. 웅크린 채 빈손으로 사용하면 앉거나 일어납니다.{ follow_owner: 1.2, distance: 8 }은 주인을 따라다니게 합니다. - 타기.
rideable: true: 빈손으로 사용해 올라탑니다(길들인 뒤에는 주인만 가능). 이동 키와 마우스로 조종하고, 웅크리면 내립니다. - 날기. 나는 몸(앵무새, 벌, 알레이)에는
{ fly_around: 1 }.rideable인 나는 몸의 몹은 탄 사람이 위를 보면 올라가고 아래를 보면 내려갑니다.
Kotlin에서: breedItem = …, tameItem = …, rideable = true, 그리고 행동 Behaviour.Breed(), Behaviour.FollowParent(), Behaviour.FollowOwner(speed, distance), Behaviour.FlyAround().
나만의 투사체
게임의 투사체 외에도 모드가 자체 투사체를 선언할 수 있습니다. 피해, 중력, 어딘가에 맞았을 때의 동작을 직접 정합니다.
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: 맞은 대상에게 주는 피해.gravity:false면 직선으로 날아갑니다.on_hit:fun(e). 맞았을 때 호출되며,hit이벤트와 같은e를 받습니다:e.projectile,e.shooter, 그리고e.entity또는e.block.texture: 투사체는 그 아이템의 모습으로 날아가므로 기본적으로textures/item/<id>.png를 씁니다. 다른 것을 쓰려면texture를 지정하세요.
다른 투사체처럼 사용합니다: world.shoot("mymod:frost_bolt", from, velocity, shooter), 몹에서는 { ranged_attack: "mymod:frost_bolt" }. Kotlin에서:
content.projectile("frost_bolt") {
damage = 4.0
gravity = false
onHit = { e -> /* … */ }
}원거리 공격과 투사체
행동 ranged_attack은 몹이 투사체를 쏘게 합니다. 목표가 사거리 안에 들어오고 시야에 보일 때까지 다가간 뒤 발사합니다.
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
}
}| 설정 | 의미 |
|---|---|
ranged_attack |
ranged_attack: 투사체(minecraft:arrow, minecraft:snowball, minecraft:small_fireball, minecraft:wind_charge 등). |
interval |
interval: 발사 사이의 틱 수. |
range |
range: 쏘기 시작하는 거리(블록). |
speed |
speed: 다가갈 때의 걷기 속도. |
power |
power: 투사체가 날아가는 속도. |
damage |
damage: 명중 시 추가 피해. |
코드에서 쏘려면(몹이든 플레이어의 능력이든) world().shoot(projectile, from, velocity, shooter, damage)를 사용하세요.
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)hit 이벤트(ProjectileHitEvent)는 투사체가 무언가에 맞았을 때 발생합니다. e.projectile, e.shooter, 그리고 맞은 대상에 따라 e.entity 또는 e.block이 있습니다. 취소하면 투사체가 그대로 통과합니다. 이벤트를 참고하세요.
알아 두면 좋은 점
- 몸마다 한계가 있습니다. 어떤 몹은 특정 능력치가 없습니다. 예를 들어 소에는 공격 피해가 없습니다. 이를 설정하면 무시되고 Crafting이 로그에 경고합니다.
- 걷지 않는 몸. 스스로 경로를 찾지 못하는 몸은 걷는 행동(돌아다니기, 쫓기, 도망치기, 따라가기, 피하기)을 무시하고, 나머지는 작동합니다.
behaviour가 없으면 몹은 사용하는 몸처럼 행동합니다. 목록을 적는 순간, 목록에 있는 것만 합니다.- 모델은 겉모습만 바꿉니다. 움직임과 행동은 언제나 몸의 것이고, 크기도
size를 지정하지 않으면 몸의 것입니다. - 사용자 정의 몹은 다른 것과 똑같은 생명체 엔티티입니다.
spawn,damage,entity_death이벤트를 받고,data를 가지며, 월드와 플레이어에 있는 기능으로 다룹니다.
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)
}
}
}행동: Behaviour.Swim, LookAround, Wander(speed), LookAtPlayers(range), MeleeAttack(speed), Panic(speed), Avoid(entity, distance, speed), Follow(item, speed). 공격 대상: TargetRule.HurtBy와 TargetRule.Nearest(id). 전리품은 블록과 마찬가지로 drop(item, count, chance)로 추가합니다.
나만의 3D 모델
model을 추가하면 몹이 몸의 모델 대신 당신의 모델로 그려집니다. 크기, 움직임, 행동은 여전히 몸에서 가져오며, 모델은 겉모습만 바꿉니다.
creature "robot" {
body: "minecraft:pig"
model: "entity/robot"
texture: "entity/robot"
behaviour: ["swim", { wander: 0.8 }, { look_at_players: 10 }]
}모델은 모드의 models/entity/robot.json이고 텍스처는 textures/entity/robot.png입니다. Kotlin에서는 creature("robot") { body = "minecraft:pig"; model = "entity/robot"; texture = "entity/robot" }. 형식은 게임 버전이 바뀌어도 같습니다.
{ "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" } }크기는 픽셀 단위(16이 블록 하나)이고, y는 몹의 발에서 위쪽을 가리킵니다.
- 본(bone):
name, 선택 사항인parent(함께 움직임),pivot(회전의 중심점),cubes. - 큐브:
origin(가장 낮은 모서리),size,uv(이미지에서 텍스처가 시작되는 위치). 배치는 흔히 쓰는 상자 전개도 방식입니다. 너비 w, 높이 h, 깊이 d인 큐브는 2(w+d) × (d+h) 픽셀의 영역을 사용합니다. - 애니메이션은 본마다 이름 하나 또는 이름 목록으로 지정합니다:
| 애니메이션 | 하는 일 |
|---|---|
look |
몹이 바라보는 쪽으로 돌립니다. 머리용. |
walk, walk_opposite |
걸을 때 흔들립니다. 두 번째는 반대 위상으로, 반대편 팔다리용. |
idle |
살짝 흔들립니다. |
spin |
계속 돕니다. |
모델을 그릴 수 없으면 몹은 몸의 모습으로 나타나고 로그에 이유가 남습니다.
크기
몹은 몸과 같은 크기입니다. 모델이 더 작거나 크다면 size: [width, height]를 블록 단위로 지정해, 충돌하는 범위와 클릭되는 범위를 플레이어에게 보이는 모습에 맞추세요.
creature "drake" {
body: "minecraft:bee"
model: "entity/drake"
texture: "entity/drake"
size: [1.4, 1.1]
}Kotlin에서: size = 1.4 to 1.1.
키프레임 애니메이션
준비된 애니메이션 이상의 움직임이 필요하면 bones, animations 옆에 clips 섹션을 추가하세요.
{ "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] } } } }
} }- 각 클립에는 초 단위의
length(길이)가 있고, 본마다 최대 세 개의 채널이 있습니다.rotation(도),position(픽셀, y가 위),scale(숫자 또는[x, y, z])입니다. - 키는 초 단위 시간입니다. 키 사이의 값은 직선으로 섞입니다. 클립에
"interpolation": "smooth"를 추가하면 대신 키를 지나는 곡선으로 섞입니다. 채널은 클립 전체에 하나의 값만 둘 수도 있습니다.
| 클립 | 재생되는 때 |
|---|---|
walk |
걷는 동안 발걸음에 맞춰 반복됩니다. |
idle |
가만히 서 있는 동안 반복됩니다. |
attack |
공격할 때 재생됩니다. |
| 그 밖의 이름 | 코드가 요청할 때 재생됩니다: c.play_animation("roar"). Crafting을 사용하는 근처 플레이어에게 보입니다. |
"idle": { "length": 1.2, "interpolation": "smooth", "bones": {
"left_wing": { "rotation": { "0": [0, 0, -20], "0.6": [0, 0, 25], "1.2": [0, 0, -20] } } } }코드에서 시작한 클립은 walk, idle, attack을 대체하지 않고 그 위에서 재생되며 서로 더해집니다. 몹이 걸으면서 울부짖을 수 있습니다.
자체 모델을 가진 몹의 새끼는 절반 크기로 그려집니다.
텍스처
모델이 없으면 텍스처는 선택한 몸(좀비, 늑대…)의 것과 같은 배치를 가지므로, 그 몸의 템플릿에서 시작해 위에 그리면 됩니다. 아이템과 블록 텍스처처럼 모드 안에 넣습니다.
| 모드 | 위치 |
|---|---|
| CraftScript(폴더) | mods/ghostmod/textures/entity/ghost.png |
| Kotlin 또는 Java | src/main/resources/assets/ghostmod/textures/entity/ghost.png |