aboutsummaryrefslogtreecommitdiff
path: root/docs/specs/fxid.md
diff options
context:
space:
mode:
authorValentin Popov <valentin@popov.link>2026-06-22 00:58:51 +0300
committerValentin Popov <valentin@popov.link>2026-06-22 00:58:51 +0300
commit78fc5f1debf1395d5df0bab7cc0dde54351205cb (patch)
treeef8f7c72a183723fcbea0b2d1fefd7c28ca7bc18 /docs/specs/fxid.md
parent50c2cf4686b53ebd2b76318223096660e92305a4 (diff)
downloadfparkan-78fc5f1debf1395d5df0bab7cc0dde54351205cb.tar.xz
fparkan-78fc5f1debf1395d5df0bab7cc0dde54351205cb.zip
docs: rewrite MkDocs documentation
Diffstat (limited to 'docs/specs/fxid.md')
-rw-r--r--docs/specs/fxid.md202
1 files changed, 0 insertions, 202 deletions
diff --git a/docs/specs/fxid.md b/docs/specs/fxid.md
deleted file mode 100644
index e3a583d..0000000
--- a/docs/specs/fxid.md
+++ /dev/null
@@ -1,202 +0,0 @@
-# FXID
-
-`FXID` — бинарный формат эффекта в движке Parkan: Iron Strategy.
-Эта страница задаёт контракт формата и исполнения на уровне, достаточном для 1:1 порта рендера/симуляции эффектов и для lossless-инструментов.
-
-Связанные контейнеры: [NRes](nres.md), [RsLi](rsli.md).
-
-## 1. Контейнер
-
-- Тип ресурса в `NRes`: `0x44495846` (`FXID`).
-- Значения `attr1/attr2/attr3` в типовых игровых данных стабильны, но при редактуре их нужно сохранять как есть.
-
-## 2. Бинарный формат
-
-Все значения little-endian.
-
-### 2.1. Заголовок (60 байт)
-
-```c
-struct FxHeader60 {
- uint32_t cmd_count; // 0x00
- uint32_t time_mode; // 0x04
- float duration_sec; // 0x08
- float phase_jitter; // 0x0C
- uint32_t flags; // 0x10
- uint32_t settings_id; // 0x14
- float rand_shift_x; // 0x18
- float rand_shift_y; // 0x1C
- float rand_shift_z; // 0x20
- float pivot_x; // 0x24
- float pivot_y; // 0x28
- float pivot_z; // 0x2C
- float scale_x; // 0x30
- float scale_y; // 0x34
- float scale_z; // 0x38
-};
-```
-
-Поток команд начинается строго с `offset = 0x3C`.
-
-### 2.2. Команда
-
-Каждая команда:
-
-1. `uint32 cmd_word`
-2. body фиксированного размера, зависящего от `opcode`
-
-Поля `cmd_word`:
-
-- `opcode = cmd_word & 0xFF`
-- `enabled = (cmd_word >> 8) & 1`
-- `bits 9..31` нужно сохранять 1:1
-
-Выравнивания между командами нет.
-
-### 2.3. Размеры команд
-
-| Opcode | Размер |
-|---:|---:|
-| 1 | 224 |
-| 2 | 148 |
-| 3 | 200 |
-| 4 | 204 |
-| 5 | 112 |
-| 6 | 4 |
-| 7 | 208 |
-| 8 | 248 |
-| 9 | 208 |
-| 10 | 208 |
-
-## 3. Смысл заголовка
-
-- `cmd_count`: число команд в потоке.
-- `time_mode`: способ вычисления текущего коэффициента эффекта.
-- `duration_sec`: длительность (в рантайме переводится в миллисекунды).
-- `phase_jitter`: амплитуда случайного фазового сдвига.
-- `flags`: флаги поведения (видимость, альфа-модификаторы, режимы гейтинга).
-- `settings_id`: индекс профиля/настроек эффекта.
-- `rand_shift_*`: случайный пространственный сдвиг.
-- `pivot_*`: локальная опора.
-- `scale_*`: базовый масштаб инстанса эффекта.
-
-## 4. Флаги заголовка
-
-Практически важные биты:
-
-- `0x0001`: случайный сдвиг фазы
-- `0x0008`: случайный пространственный сдвиг (`rand_shift_*`)
-- `0x0010`: ветки видимости/окклюзии
-- `0x0020`: треугольный ремап альфы
-- `0x0040`: инверсия исходного active-state
-- `0x0080`, `0x0100`: фильтрация по времени суток
-- `0x0200`: умножение альфы на нормализованное время жизни
-- `0x0400`, `0x1000`: дополнительные биты состояния менеджера эффекта
-- `0x0800`: дополнительный гейтинг
-
-Неизвестные биты должны сохраняться без изменений.
-
-## 5. `time_mode` (0..17)
-
-База:
-
-- `tn = (now - start) / (end - start)`
-- `prev = предыдущая вычисленная альфа`
-
-Поддерживаемые семейства режимов:
-
-- константный режим;
-- линейный (`tn`), обратный (`1-tn`), циклический (`fract(tn)`);
-- режимы от внешних параметров мира/очереди;
-- режимы на основе норм векторов состояния;
-- режимы с ограничением вниз/вверх относительно `prev`.
-
-После вычисления:
-
-- при `flags & 0x0200` применяется `alpha *= tn`;
-- при `flags & 0x0020` применяется triangular remap.
-
-## 6. Resource-ссылки внутри команд
-
-Для opcode `2/3/4/5/7/8/9/10` используется ссылка:
-
-```c
-struct ResourceRef64 {
- char archive[32];
- char name[32];
-};
-```
-
-Контракт:
-
-- строки ASCII, нуль-терминированные;
-- сравнение имён регистронезависимое;
-- обычно:
- - `opcode 2`: `sounds.lib` + `*.wav`
- - остальные: `material.lib` + имя материала/эффекта.
-
-## 7. Runtime-контракт исполнения
-
-На создании инстанса:
-
-1. Заголовок копируется в runtime-состояние.
-2. Вычисляется `end_time`.
-3. Для каждой команды создаётся runtime-объект по `opcode`.
-4. В объект копируется `enabled`.
-5. Объект инициализируется контекстом эффекта.
-
-На каждом кадре:
-
-1. Вычисляется текущий коэффициент/альфа по `time_mode` и `flags`.
-2. Выполняется update каждой команды.
-3. Выполняется emit/render часть активных команд.
-4. Применяются события Start/Stop/Restart.
-
-## 8. Строгий парсер (рекомендуемый)
-
-1. Проверить `len(payload) >= 60`.
-2. Прочитать `cmd_count`.
-3. Идти от `ptr = 0x3C`.
-4. Для каждой команды:
- - проверить `ptr + 4 <= len`;
- - прочитать `opcode`;
- - проверить, что `opcode` поддержан;
- - проверить `ptr + size(opcode) <= len`;
- - сдвинуть `ptr += size(opcode)`.
-5. Проверить `ptr == len(payload)`.
-
-## 9. Writer и редактор
-
-Для lossless-совместимости:
-
-- сохранять все неизвестные поля/биты;
-- не менять фиксированные размеры команд;
-- не добавлять padding;
-- пересчитывать только `cmd_count` и размеры контейнера;
-- сохранять порядок команд.
-
-## 10. Что требуется для 1:1 переноса
-
-1. Полная поддержка opcode `1..10`.
-2. Точный контракт вычисления `time_mode` и `flags`.
-3. Точное поведение `ResourceRef64`.
-4. Повторяемый RNG и одинаковая политика плавающей точки.
-
-## 11. Статус валидации
-
-- Формальные инварианты FXID зафиксированы в спецификациях проекта и проверены legacy-валидаторами.
-- На полном retail-корпусе `testdata/Parkan - Iron Strategy` проверено `923/923` FXID payload без ошибок.
-
-## 12. Статус покрытия и что осталось до 100%
-
-Закрыто:
-
-1. Контейнер FXID, fixed-size командный поток, opcode-покрытие `1..10`.
-2. Базовый runtime-контур исполнения эффекта.
-3. Корпусная валидация формата на retail-данных.
-
-Осталось:
-
-1. Полная field-level семантика payload каждого opcode для авторинга новых эффектов «с нуля».
-2. Формальная спецификация всех `time_mode` веток на уровне точных числовых формул и edge-case поведения.
-3. Полный набор пиксельных parity-тестов FX (оригинал vs новый рендер) на фиксированных сценах.