# Свойства блоков ## Вид ### Текстура - *texture* Название текстуры блока (указывается только имя, без расширения или пути к файлу) Файл текстуры должен находиться в `res/textures/blocks/` и иметь формат **png** ### Текстурирование сторон - *texture-faces* >[!IMPORTANT] > Не может использоваться одновременно с *texture* Массив из 6 названий текстур, позволяющих указать их для каждой из сторон отдельно. Пример: ```json "texture-faces": [ "grass_side", "grass_side", "dirt", "grass_top", "grass_side", "grass_side" ] ``` ### Модель - *model* Модель блока из списка: - "block" - используется по-умолчанию для всех обычных блоков - "none" - невидимый блок (пример: воздух) - "X" - модель травы (крест из двух спрайтов) - "aabb" - модель, соответствующая хитбоксу блока (составной хитбокс будет объединен в один). Примеры: трубы, лампочки, панели. - "custom" - используется при указании собственной модели через *model-name* ### Имя модели - *model-name* Кроме встроенных типов моделей, можно использовать собственные, загружаемые из файлов. В свойстве указывается имя модели без `точка_входа:models/` и расширения. > [!WARNING] > Текстуры (материалы), использующиеся в модели, должны находиться в атласе `blocks` и указываться в соответствующем формате: > `blocks:имя_текстуры` ### Группа отрисовки - *draw-group* Целое число определяющее номер группы отрисовки данного блока. Актуально для полупрозрачных блоков - решает проблемы невидимых сторон блоков за этим блоком. ### Полупрозрачность - *translucent* Включает поддержку полупрозрачности в текстурах блока (примеры: вода, лёд). Следует использовать только при надобности, так как влияет на производительность. Не требуется для полной прозрачности (трава, цветы). ### Вращение - *rotation* Профиль вращения (набор положений, в которые можно установить блок) из списка: - "none" - вращение блока отключено (по-умолчанию) - "pipe" - профиль "труба". Примеры блоков: бревно, труба, лампочка - "pane" - профиль "панель". Примеры блоков: панель, дверь, табличка - "stairs" - профиль "ступеньки" ("pane" + перевернутые варианты) ### Испускаемые частицы - *particles* Частицы указываются в виде JSON объекта. Имена свойств можно найти [в разделе, посвященном частицам](particles.md). При приближении к блоку движок создаст эмиттер, который будет работать до разрушения блока или отдаления камеры на некоторое расстояние. ## Варианты Некоторые свойства могут варьироваться динамически, в зависимости от номера варианта, хранимого в пользовательских битах блока. Параметры вариативности указываются в блоке `state-based`: ```json { ... "state-based": { "offset": 0, "bits": 4, "variants": [ {...}, ... ] } } ``` - `offset` определяет битового смещения, с которого начинается индекс варианта. (По-умолчанию - 0) - `bits` определяет число бит, кодирующих индекс варианта. (По-умолчанию - 4). На данный момент максимальное число вариантов - 16, поэтому указание более 4 бит не имеет практического смысла. Доступные для вариативности свойства: - model - model-name - texture - texture-faces - model-primitives (устарело) Управление состоянием производится через `block.set_variant(x, y, z, index)`. ### Кастомные модели по вариантам (переключение геометрии) Для custom-моделей можно переключать геометрию по варианту. Укажите отдельный `model-name` в нужных вариантах — рендерер кэширует геометрию по паре (id блока, вариант). Базовая модель (из корня) становится вариантом 0. Массив variants соответствует индексам 1+. Пример (база + два кастомных варианта): ```json { "model": "custom", "model-name": "stairs_middle", "state-based": { "bits": 4, "variants": [ { "model": "custom", "model-name": "stairs_left" }, { "model": "custom", "model-name": "stairs_right" } ] } } ``` В этом примере: - Вариант 0 = `stairs_middle` (из корня) - Вариант 1 = `stairs_left` (из variants[0]) - Вариант 2 = `stairs_right` (из variants[1]) ## Освещение ### Излучение - *emission*: Массив из трех целых чисел - R, G, B освещения от 0 до 15. Примеры: - `[15, 15, 15]` - самый яркий белый свет - `[7, 0, 0]` - слабый красный свет - `[0, 0, 0]` - блок не излучает свет (по-умолчанию) ### Светопроводимость - *light-passing* При значении `true` блок проводит свет от излучающих блоков. ### Солнечная светопроводимость - *sky-light-passing* При значении `true` блок не препятствует прохождению вертикального луча солнечного света. ### Без освещения - *shadeless* Выключает освещение на модели блока. ### Вершинный Ambient-Occlusion - *ambient-occlusion* Определяет наличие эффекта вершинного AO. Включен по-умолчанию. ### Отсечение - *culling* Режим отсечения граней: - **default** - обычное отсечение граней - **optional** - отсечение граней среди блоков одной группы отрисовки можно отключить через настройку `graphics.dense-render` (Плотный рендер блоков). - **disabled** - отсечение граней среди блоков одной группы отрисовки отключено. В режиме `optional` при отключении `graphics.dense-render` будет использоваться `*_opaque` вариант текстуры (при наличии). ## Физика ### Препятствие - *obstacle* Значение false отключает хитбокс у блока (позволяет игроку проходить сквозь блок) ### Хитбокс - *hitbox* Массив из 6 чисел описывающих смещение и размер хитбокса блока. Числа указываются в диапазоне [0.0, 1.0] - т.е в пределах блока (в случае расширенного блока хитбокс может быть больше единицы, но не должен выходить за пределы size). Массив `[0.25, 0.0, 0.5, 0.75, 0.4, 0.3]` описывает хитбокс: - смещен на 0.25 м на запад - смещен на 0.0 м вверх - смещен на 0.5 м на север - шириной (с востока на запад) 0.75 м - высотой 0.4 м - длиной (с юга на север) 0.3 м Для составных хитбоксов используется свойство *hitboxes* - массив хитбоксов, например: ```json "hitboxes": [ [0, 0, 0, 1, 0.625, 1], [0, 0.6875, 0, 1, 0.3125, 1] ] ``` ### Приземленность - *grounded* Блок может быть установлен только на полный блок. Разрушается при разрушении блока под ним. ### Выделяемость - *selectable* При значении в `false` курсор будет игнорировать блок, выделяя тот, что находится за ним. ### Заменяемость - *replaceable* При значении в `true` на месте блока можно установить любой другой блок. Пример: вода, трава, цветок. ### Разрушаемость - *breakable* При значении в `false` блок нельзя сломать. ## Инвентарь ### Скрытый блок - *hidden* При значении в `true` блок не появляется в инвентаре и для него не генерируется предмет, поэтому c 0.17 требуется указать свойство *picking-item* ### Подбираемый предмет - *picking-item* Предмет, который будет выбран при нажатии средней кнопкой мыши на блок. Пример: блок `door:door_open` скрыт (hidden) поэтому указывается `picking-item: "door:door.item"` ### Имя макета UI - *ui-layout* Позволяет указать id XML-макета интерфейса блока. По-умолчанию используется строковый id блока. ### Размер инвентаря - *inventory-size* Число слотов инвентаря блока. По-умолчанию - 0 (инвентарь отсутствует) ## Расширенные блоки ### Размер блока - *size* Массив из трех целых чисел. Значение по-умолчанию - `[1, 1, 1]`. ## Поля блока Поля блоков позволяет записывать больше уникальных для конкретного блока данных, чем это позволяют пользовательские биты. Поля блока объявляются в следующем формате: ```json "fields": { "имя": {"type": "тип_данных"}, "имя_массива": {"type": "тип_данных", "length": "длина_массива"} } ``` Кроме `type` и `length` доступен параметр `convert-strategy` определяющий стратегию конвертации значения при сужении типа данных. Параметр принимает одно из двух значений: - `reset` - значение, не попадающее в новый диапазон, будет сброшено до 0 - `clamp` - значение будет сведено к ближайшему в новом диапазоне Пример: число 231 при изменении типа поля с int16 до int8: - в режиме `reset` превратится в 0 - в режиме `clamp` превратится в 127 Доступные типы данных: | Тип | Размер | Описание | | ------- | -------- | ----------------------------- | | int8 | 1 байт | целочисленный знаковый 8 бит | | int16 | 2 байта | целочисленный знаковый 16 бит | | int32 | 4 байта | целочисленный знаковый 32 бит | | int64 | 8 байт | целочисленный знаковый 64 бит | | float32 | 4 байта | вещественный 32 бит | | float64 | 8 байт | вещественный 64 бит | | char | 1 байт | символьный | - На данный момент общая сумма размеров полей не может превышать 240 байт. - Поле без указания длины массива эквивалентно массиву из 1 элемента. - Массив символьного типа может использоваться для хранения UTF-8 строк. ## Пользовательские свойства Доступ к пользовательским свойствам производится через таблицу `block.properties[id]["свойство"]` где id - числовой id (индекс) блока. Пользовательские свойства должны быть объявляены в файле `пак:config/user-props.toml`: ```toml "пак:имя_свойства" = {} ``` Пример: [пользовательские свойства пака **base**](../../res/content/base/config/user-props.toml). ## Свойства, вводимые паком `base` ### Прочность - *base:durability* Время разрушения блока без инструментов и эффектов в секундах. ### Лут - *base:loot* Список таблиц со свойствами: ```json { "item": "пак:предмет", "min": 1, "max": 3, "chance": 0.5 } ``` - count равен 1 по-умолчанию. Не нужно указывать если указаны `min` и `max`. - min, max - минимальное и максимальное количество предмета. - chance - вероятность выпадения предмета. По-умолчанию: 1.0. Следует учитывать, что в item указывается именно предмет. Т.е. чтобы указать предмет блока, нужно добавить `.item` после имени блока. Пример: `base:dirt.item`. Для генерации лута следует использовать функцию `block_loot(block_id: int)` в модуле `base:util`. ## Другое ### Имя скрипта - *script-name* Позволяет указать название скрипта блока. Свойство обеспечивает возможность использования одного скрипта для нескольких блоков. Название указывается без `пак:scripts/` и расширения. ### Интервал тактов - *tick-interval* Интервал в тактах мира (1/20 секуды). Значение 20 приводит к интервалу вызова on_block_tick равному одной секунде. ## Методы Методы используются для управлением перезаписью свойств при расширении блока другими паками. ### `имя_свойства@append` Добавляет элементы в конец списка, вместо его полной перезаписи. ## Теги - *tags* Теги позволяют обозначать обобщённые свойства блоков. Названия следует формировать как `префикс:имя_тега`. Префикс не является обязательным, но позволяет избегать нежелательных логических коллизий. Пример: ```json { "tags": [ "core:ore", "base_survival:food", ] } ``` Теги блокам можно добавлять и из других паков, с помощью файла `ваш_пак:tags.toml`. Пример ```toml "префикс:имя_тега" = [ "рандомный_пак:какой_то_блок", "ещё_один_пак:предмет", ] "другой_префикс:другое_имя_тега" = [ # ... ] ```