У каждого моба в аддоне есть файл поведения. Он решает, сколько у моба здоровья, как он двигается, на кого нападает и как меняется со временем. На этой странице мы разберём этот файл по частям на примере рубинового голема.
Если ты ещё никогда не делал моба, начни с гайда Твой первый моб. Здесь мы глубже разбираемся в том, как устроен файл.
Файлы
Файл поведения лежит в папке entities пакета поведения. Название файла выбираешь ты, но если назвать его по имени моба, будет аккуратнее.
BP/
entities/
ruby_golem.json
spawn_rules/
ruby_golem.jsonКак моб выглядит, задаётся во втором файле, в пакете ресурсов. Смотри Файл клиентской сущности.
Четыре части
Внутри minecraft:entity может быть до четырёх блоков. Обязателен только description, но почти каждый моб использует все четыре.
| Часть | Что в ней |
|---|---|
description | ID моба и несколько переключателей: может ли у него быть яйцо призыва, может ли его создать /summon, какие свойства он хранит |
components | То, что у моба есть всегда: здоровье, движение, хитбокс, базовое поведение |
component_groups | Именованные наборы компонентов, которые потом включаются и выключаются, например "детёныш" или "злой" |
events | Именованные действия, которые включают и выключают эти наборы |
Вот пустая заготовка:
{
"format_version": "1.26.50",
"minecraft:entity": {
"description": {},
"components": {},
"component_groups": {},
"events": {}
}
}format_version сообщает игре, по какой версии правил написан твой файл. Используй свежую версию, например ту же, что у ванильных сущностей.
Часть 1: description
"description": {
"identifier": "wiki:ruby_golem",
"is_spawnable": true,
"is_summonable": true
}| Поле | Что делает |
|---|---|
identifier | ID моба в виде namespace:name. Он должен в точности совпадать с файлом пакета ресурсов. Никогда не используй пространство имён minecraft для своих мобов. |
is_spawnable | true даёт мобу яйцо призыва и позволяет правилам появления размещать его в мире. |
is_summonable | true позволяет создать его командой /summon. |
runtime_identifier | Необязательно. Заимствует скрытое, зашитое в игру поведение ванильного моба, например minecraft:snowball. Большинству мобов это не нужно. |
properties | Необязательно. Значения, которые моб запоминает, о них ниже. |
У многих ванильных мобов есть ещё строка spawn_category, например "creature" или "monster". Твой моб работает и без неё.
Свойства: значения, которые моб запоминает
Свойства - это небольшие данные, которые хранятся у каждого моба. Их можно менять из событий, проверять фильтрами и читать в Molang через q.property('wiki:mood').
"properties": {
"wiki:mood": {
"type": "enum",
"values": ["calm", "angry"],
"default": "calm",
"client_sync": true
},
"wiki:rubies_eaten": {
"type": "int",
"range": [0, 5],
"default": 0
}
}| Тип | Что хранит | Дополнительное поле |
|---|---|---|
bool | true или false | нет |
int | Целое число | range: наименьшее и наибольшее допустимое значение |
float | Дробное число | range: наименьшее и наибольшее допустимое значение |
enum | Одно слово из списка | values: список допустимых слов |
default- начальное значение. Это может быть и выражение на Molang: так ванильные пчёлы вычисляют своё начальное состояние.client_syncотправляет значение в пакет ресурсов, чтобы его могли использовать анимации и контроллеры рендера. Включай его, только когда от значения зависит внешний вид.
Свойства или группы компонентов?
Используй группу компонентов, когда моб должен вести себя иначе. Используй свойство, когда нужно просто что-то запомнить или когда вместе с ним должны меняться модель или текстура.
Часть 2: components
components активны всегда, с момента появления моба. Клади сюда то, что никогда не меняется: семейство, хитбокс, физику и то, как он ходит.
"components": {
"minecraft:type_family": { "family": ["ruby_golem", "golem", "mob"] },
"minecraft:health": { "value": 40, "max": 40 },
"minecraft:collision_box": { "width": 1.2, "height": 2.4 },
"minecraft:physics": {},
"minecraft:movement": { "value": 0.25 },
"minecraft:movement.basic": {},
"minecraft:navigation.walk": { "avoid_water": true },
"minecraft:jump.static": {},
"minecraft:behavior.random_stroll": { "priority": 6, "speed_multiplier": 0.8 },
"minecraft:behavior.look_at_player": { "priority": 7, "look_distance": 8 }
}Каждый ключ - это один компонент, а его объект хранит настройки этого компонента. Пустой объект {} значит "используй значения по умолчанию". Компонентов сотни: смотри их все в разделе Компоненты сущностей.
Часть 3: группы компонентов
Группа компонентов - это именованный набор компонентов, который выключен, пока событие его не добавит. Так один и тот же моб может быть сначала детёнышем, а потом взрослым, или сначала спокойным, а потом злым.
"component_groups": {
"wiki:baby": {
"minecraft:is_baby": {},
"minecraft:scale": { "value": 0.5 },
"minecraft:ageable": {
"duration": 1200,
"grow_up": { "event": "wiki:grow_up", "target": "self" }
}
},
"wiki:angry": {
"minecraft:attack": { "damage": 6 },
"minecraft:behavior.melee_attack": { "priority": 3 },
"minecraft:movement": { "value": 0.32 }
}
}Несколько правил, которые стоит знать:
- Названия групп выбираешь ты. Если добавить своё пространство имён (
wiki:angry), не будет конфликтов и их легко заметить. - У моба может быть только одна копия каждого компонента. Когда добавляется группа с
minecraft:movement, используется её скорость вместо той, что была у моба раньше. - Если добавить уже активную группу, её компоненты запускаются заново. Например,
minecraft:timerснова начнёт отсчёт с нуля.
Часть 4: события
События - это переключатели. У каждого события есть название и список действий, чаще всего add и remove для групп компонентов.
"events": {
"wiki:grow_up": {
"remove": { "component_groups": ["wiki:baby"] }
},
"wiki:become_angry": {
"add": { "component_groups": ["wiki:angry"] },
"set_property": { "wiki:mood": "angry" }
}
}Что-то должно вызвать событие. В группе детёныша выше minecraft:ageable вызывает wiki:grow_up, когда время выходит. Другие компоненты, например minecraft:damage_sensor, minecraft:timer и minecraft:environment_sensor, тоже вызывают события. И команды тоже могут: /event entity @e[type=wiki:ruby_golem] wiki:become_angry.
События умеют гораздо больше: выбирать случайно, выполнять шаги по порядку и проверять условия. Всё это на следующей странице, События сущностей.
Рубиновый голем целиком
Вот всё вместе. Голем чаще всего появляется взрослым, иногда детёнышем. Он злится, когда игрок его бьёт, и успокаивается через 20 секунд.
{
"format_version": "1.26.50",
"minecraft:entity": {
"description": {
"identifier": "wiki:ruby_golem",
"is_spawnable": true,
"is_summonable": true,
"properties": {
"wiki:mood": {
"type": "enum",
"values": ["calm", "angry"],
"default": "calm",
"client_sync": true
}
}
},
"components": {
"minecraft:type_family": { "family": ["ruby_golem", "golem", "mob"] },
"minecraft:health": { "value": 40, "max": 40 },
"minecraft:collision_box": { "width": 1.2, "height": 2.4 },
"minecraft:physics": {},
"minecraft:movement": { "value": 0.25 },
"minecraft:movement.basic": {},
"minecraft:navigation.walk": { "avoid_water": true },
"minecraft:jump.static": {},
"minecraft:behavior.hurt_by_target": { "priority": 2 },
"minecraft:behavior.random_stroll": { "priority": 6, "speed_multiplier": 0.8 },
"minecraft:behavior.look_at_player": { "priority": 7, "look_distance": 8 },
"minecraft:damage_sensor": {
"triggers": [
{
"on_damage": {
"filters": { "test": "is_family", "subject": "other", "value": "player" },
"event": "wiki:become_angry"
}
}
]
}
},
"component_groups": {
"wiki:baby": {
"minecraft:is_baby": {},
"minecraft:scale": { "value": 0.5 },
"minecraft:ageable": {
"duration": 1200,
"grow_up": { "event": "wiki:grow_up", "target": "self" }
}
},
"wiki:angry": {
"minecraft:attack": { "damage": 6 },
"minecraft:behavior.melee_attack": { "priority": 3 },
"minecraft:movement": { "value": 0.32 },
"minecraft:timer": {
"time": 20,
"looping": false,
"time_down_event": { "event": "wiki:calm_down" }
}
}
},
"events": {
"minecraft:entity_spawned": {
"randomize": [
{ "weight": 80 },
{ "weight": 20, "add": { "component_groups": ["wiki:baby"] } }
]
},
"wiki:grow_up": {
"remove": { "component_groups": ["wiki:baby"] }
},
"wiki:become_angry": {
"add": { "component_groups": ["wiki:angry"] },
"set_property": { "wiki:mood": "angry" }
},
"wiki:calm_down": {
"remove": { "component_groups": ["wiki:angry"] },
"set_property": { "wiki:mood": "calm" }
}
}
}
}Как всё происходит:
- Голем появляется. Игра сама вызывает
minecraft:entity_spawned, аrandomizeдаёт шанс 1 к 5 добавитьwiki:baby. - Игрок бьёт голема. Датчик урона проверяет фильтр (атакующий - игрок?) и вызывает
wiki:become_angry. - Это событие добавляет группу злости: теперь у голема есть атака, поведение ближнего боя и скорость побольше.
hurt_by_targetк этому моменту уже сделал игрока его целью. - Таймер в группе злости отсчитывает 20 секунд, а потом вызывает
wiki:calm_down, который снова убирает группу.
Советы
- В
componentsклади только то, что не меняется. Если компонент есть и вcomponents, и в группе, сложно понять, какой из них активен. То, что меняется, держи только в группах. - Одна задача на группу. Маленькие группы вроде
wiki:angryиwiki:babyпроще комбинировать, чем одну огромную группу на каждое состояние. - Подсматривай в ваниль. Файлы коровы, волка и пчелы в разделе Ванильные сущности показывают много настоящих приёмов.
Если что-то не работает
| Что ты видишь | Скорее всего, причина |
|---|---|
Моба не существует (/summon не срабатывает) | Ошибка в JSON или опечатка в identifier. Проверь журнал контента. |
| Нет яйца призыва | is_spawnable равен false, или в пакете ресурсов нет spawn_egg |
| Событие ничего не делает | Название группы в add не совпадает с названием в component_groups |
| Ошибка свойства в журнале | Свойство не объявлено в description.properties, или значение выходит за range или values |
| Моб никогда не возвращается обратно | Ничто не вызывает событие, которое убирает группу |
Больше помощи в гайде Когда что-то сломалось. Дальше: События сущностей.