# Контент-паки

Для создания контент-пака сначала нужно придумать ему название (id) соответствующее следующим требованиям:
- название может состоять только из букв латиницы, цифр и символа подчёркивания '\_'
- название не может начинаться с цифры
- длина названия должна находиться в пределах от 2 до 24 включительно

Далее в *res/content* создаётся папка с выбранным названием контент-пака.

В созданной папке создаётся файл **package.json** с следующим содержимым:
```json
{
    "id": "выбранное_имя_пака",
    "title": "имя контент-пака для отображения в меню контента",
    "version": "версия контент-пака в формате major.minor",
    "creator": "создатель контент-пака",
    "description": "краткое описание",
    "dependencies": [
        "зависимости",
        "пакета"
    ]
}
```

Вместо `creator` можно указать массив `creators`

Уровни зависимостей указываются с помощью префиксов в имени:
- '!' - обязательная зависимость
- '?' - опциональная зависимость
- '~' - слабая зависимость
Отсутствие префикса интерпретируется как '!'.

Пример: '~randutil' - слабая зависимость 'randutil'.

Версии зависимостей указываются после '@' и имеют операторы для ограничения допустимых версий.
Отсутствие версии зависимости интерпретируется как '\*', т.е. любая версия.

Пример: 'randutil@>=1.0' - зависимость 'randutil' версии 1.0 и старше.

Пример:
```json
{
    "id": "doors",
    "title": "DOORS",
    "creator": "MihailRis",
    "version": "1.0",
    "description": "doors test"
}
```

Изображение контент-пака добавляется в виде файла *icon.png* в папку пака (не в textures). Рекомендованный размер изображения: 128x128

# Файловая система

Каждый загруженный пак монтируется к внутренней файловой системе как новая точка входа, имя которой совпадает с id пака.

Это значит, что для доступа к файлам пака не требуется использование дополнительных функций:

```lua
print(file.read("пак:package.json")) -- выведет содержимое package.json пака
```

Также это является одной из причин того, что некоторые id зарезервированы от использования.

Точки входа монтируются как read-only. Для получения доступа к записи существует функция pack.request_writeable.

Подробнее про библиотеку [file](scripting/builtins/libfile.md).

# Структура контент-пака

Пусть вас не пугает следующий текст, ведь минимальный пак содержит только package.json.

- Контент:
    - `block_materials/` - определения материалов блоков
    - `blocks/` - определения блоков
    - `items/` - определения предметов
    - `generators/` - генераторы мира
    - `entities/` - определения сущностей
    - `skeletons/` - определения скелетов сущностей
    - `presets/` - пресеты (может использоваться и паками в своих целях)
        - `text3d/` - 3D текст
        - `weather/` - погода
- Код:
    - `modules/` - скриптовые модули
    - `scripts/` - скрипты контента, мира
        - `components/` - компоненты сущностей
- Ассеты (ресурсы клиентской стороны):
    - `fonts/` - шрифты
    - `models/` - 3D модели
    - `textures/` - текстуры
    - `shaders/` - шейдеры
        - `effects/` - эффекты пост-обработки
    - `sounds/` - звуки и музыка
    - `texts/` - файлы локализации
- GUI:
    - `layouts/` - макеты UI
        - `pages/` - макеты страниц меню (элемент pagebox)
- Конфигурация:
    - `config/` - файлы конфигурации
        - `defaults.toml` - переопределения стандартных привязок к контенту, такие как сущность игрока, генератор по-умолчанию и т.д.
        - `bindings.toml` - привязки к клавишам / мыши
        - `user-props.toml` - пользовательские свойства определений контента
    - `devtools/` - вспомогательные файлы внутренних инструментов отладки
    - `content.json` - генерируемые автоматически списки контента, используемое для проверки корректности индексов в мире и конвертации при несовпадении
    - `icon.png` - иконка пака
    - `package.json` - файл опеределения пака
    - `preload.json` - списки предзагрузки ассетов, которые не загружаются автоматически, не следует указывать ассеты без надобности
    - `resources.json` - списки определений [ресурсов](resources.md) (не путать с ассетами)
    - `resource-aliases.json` - файлы объявления псевдонимов для [ресурсов](resources.md)

> [!WARNING]
> Ручное редактирование `content.json` противопоказано и скорее всего приведёт к необратимой поломке миров.

# Источники контента

Поиск контент-паков производится среди **источников контента**, являющихся путями в файловой системе движка.

Приоритет источника определяет порядок сканирования: если один и тот же пак найден в нескольких источниках, 
будет выбран тот, что принадлежит источнику с наивысшим приоритетом.

Источники контента в порядке убывания приоритета:
- `world:content` - контент папке с миром (`мир/content/`)
- `user:content` - контент в папке пользователя (`$HOME/.voxeng/content/`)
- `project:content` - контент в папке с проектом (`проект/content/`)
- `res:content` - встроенный контент, поставляемый вместе с ядром движка (`res/content/`)

Т.е. если в `world:content` и в `user:content` есть один и тот же пак, будет выбрана версия из `world:content`.

Версия пака, при этом, на данный момент, не учитывается.
