56 lines
4.7 KiB
Markdown
56 lines
4.7 KiB
Markdown
# Система аватаров: основа
|
||
|
||
`avatar_base` реализует независимое состояние аватара: группы, именованные пресеты,
|
||
композицию целевых значений и JSON-состояние для сохранений. Зависимости от диалогов,
|
||
боевых персонажей и Live2D нет. Полный формат и контракт: [en.md](en.md).
|
||
|
||
## Управление
|
||
|
||
```csharp
|
||
IAvatar avatar = AvatarCatalog.Create("my_game/marao");
|
||
avatar.ApplyPresets(new Dictionary<string, string> {
|
||
["emotion"] = "angry",
|
||
["eyes_state"] = "opened"
|
||
});
|
||
AvatarFrame target = avatar.Resolve();
|
||
AvatarState saved = avatar.CaptureState();
|
||
```
|
||
|
||
Контентный мод зависит от `avatar_base>=1` и объявляет сущности `Kind: avatar`.
|
||
У определения есть `Id`, `Renderer`, `BaseValues` и `Groups`. У группы — `Default`,
|
||
`Priority`, `Presets`; у пресета — `Values`. Имена групп и пресетов произвольные,
|
||
регистрозависимые. Значения пресетов — целевые привязки для конкретного рендера,
|
||
а не универсальные числа от 0 до 1.
|
||
|
||
Каждая группа выбирает один пресет. Изменение группы сохраняет остальные группы.
|
||
Все изменения проверяются до применения: опечатка не оставляет частично изменённое
|
||
состояние. Неизвестные значения отклоняются, автоматических подмен нет.
|
||
|
||
Композиция начинается с `BaseValues`, затем применяет группы по возрастанию
|
||
`Priority`, при равенстве — по имени (ordinal). Более поздняя группа перекрывает
|
||
одноимённую привязку целиком. Порядок команд ничего не меняет. Например, эмоция
|
||
имеет приоритет 0, явное состояние глаз — 100. Пустой пресет `auto` не вносит
|
||
привязок и тем самым возвращает управление эмоции. Это обычное имя, не ключевое слово.
|
||
|
||
`Resolve()` возвращает полный неизменяемый снимок, без оставшихся значений прошлого
|
||
пресета. `CaptureState()` — отдельный DTO с ID аватара и выбором пресетов. При
|
||
восстановлении отсутствующие группы получают значения по умолчанию, неизвестные
|
||
группы/пресеты и чужой ID отклоняются. Изменения ресурсов не меняют уже созданный
|
||
экземпляр: владелец пересоздаёт его при перезагрузке.
|
||
|
||
## Граница реализации
|
||
|
||
`IAvatarRenderer` задаёт контракт визуального адаптера: корневой `Control`, применение
|
||
полного целевого состояния, время перехода и освобождение принадлежащих ему ресурсов.
|
||
Мод `avatar_layers` уже выбирает и отображает PNG-слои. Будущий адаптер Live2D будет
|
||
выбирать параметры модели. `AvatarRenderers.Create(avatar)` находит фабрику по `Renderer`
|
||
и применяет начальное состояние. После изменений владелец явно вызывает
|
||
`renderer.Apply(avatar.Resolve())`. Фабрики автоматически регистрируются и удаляются
|
||
вместе с модами через стандартный `ModTypeConsumer`.
|
||
|
||
В этой версии нет адаптера Live2D, сценарных команд, редактора,
|
||
проверки совместимости картинок и автоматической интеграции с сохранениями.
|
||
Существующие диалоговые аватарки работают как прежде. JSON-пример и правила владения
|
||
ресурсами приведены в английской документации. Тесты проверяют независимость
|
||
экземпляров, приоритеты, атомарность, сериализацию и загрузку настоящего ресурса.
|