# Material (`MAT0`) `MAT0` описывает материал и его фазовую анимацию. Связанные страницы: - [Wear table (`WEAR`)](wear.md) - [Texture (`Texm`)](texture.md) - [Render pipeline](render.md) ## 1. Контейнер - Тип ресурса: `0x3054414D` (`MAT0`). - Обычно хранится в `Material.lib`. - `attr1` используется как битовое поле runtime-флагов материала. - `attr2` задаёт версию заголовка payload. ## 2. Бинарный layout ```c struct Mat0Payload { uint16_t phaseCount; uint16_t animBlockCount; // должно быть < 20 // если attr2 >= 2 uint8_t metaA8; uint8_t metaB8; // если attr2 >= 3 uint32_t metaC32; // если attr2 >= 4 uint32_t metaD32; PhaseRecord34 phases[phaseCount]; AnimBlockRaw anim[animBlockCount]; }; ``` Если `attr2 < 2`, используются runtime-значения по умолчанию: - `metaA = 255` - `metaB = 255` - `metaC = 1.0f` - `metaD = 0` ## 3. Фазы материала ```c struct PhaseRecord34 { uint8_t params[18]; char textureName[16]; }; ``` В рантайме запись разворачивается в структуру ~76 байт: - набор коэффициентов цвета/освещения/прозрачности; - индекс слота текстуры; - дополнительные целочисленные поля. `textureName`: - пустая строка -> фаза без текстуры (`texSlot = -1`); - непустая строка -> загрузка текстуры по имени. ## 4. Анимационные блоки ```c struct AnimBlockRaw { uint32_t headerRaw; // mode = low 3 bits, interpMask = остальные uint16_t keyCount; KeyRaw keys[keyCount]; }; struct KeyRaw { uint16_t k0; uint16_t k1; uint16_t k2; // opaque, сохранять 1:1 }; ``` `k2` нельзя удалять или нормализовать: это часть бинарного контракта. ## 5. Выбор текущей фазы Материал выбирает фазу по времени и по режиму анимации блока: - loop; - ping-pong; - one-shot с clamp; - random-offset. При смешивании интерполируется только часть полей, остальные копируются из активной фазы. Для 1:1 совместимости важно сохранить эту выборочную интерполяцию. ## 6. Загрузка и fallback При запросе материала по имени: 1. Точный поиск по имени. 2. Если не найдено — fallback на `DEFAULT`. 3. Если `DEFAULT` отсутствует — используется запись с индексом `0`. ## 7. Атрибуты и флаги Практически важные биты `attr1`: - бит загрузки текстурной фазы с расширенными флагами; - флаги аппаратного профиля; - 4-битный режим (`nibbleMode`); - дополнительный флаг material-поведения. Неизвестные биты должны сохраняться без изменений. ## 8. Ограничения - `animBlockCount < 20` - `phaseCount` и фактический размер секции фаз должны совпадать - `textureName` должен быть NUL-terminated и укладываться в 16 байт ## 9. Правила writer/editor 1. Сохранять `attr1/attr2/attr3`. 2. Не менять `metaA/B/C/D` без явного запроса. 3. Сохранять opaque-поля анимации (включая `k2`) 1:1. 4. Проверять выход за границы payload при парсинге. ## 10. Статус валидации - Инварианты MAT0 зафиксированы в текущем toolchain проекта (`docs/specs` + `tools`). - В этом окружении нет полного игрового корпуса, поэтому статистика по всем материалам не пересчитывалась.