2026-09-06 05:22:12 +04:00
|
|
|
# VII. Работа над движком
|
|
|
|
|
|
|
|
|
|
FParkan развивается небольшими законченными изменениями. Для нового поведения
|
|
|
|
|
сначала нужен пример из оригинала и Rust-тест, затем реализация и объяснение
|
|
|
|
|
в соответствующей главе. Если меняется видимый результат, проверка заканчивается
|
|
|
|
|
запуском приложения на настоящих игровых ресурсах.
|
|
|
|
|
|
|
|
|
|
## Где находится код
|
|
|
|
|
|
|
|
|
|
Библиотеки в `crates/` читают архивы и форматы, связывают ресурсы миссии,
|
|
|
|
|
вычисляют геометрию и хранят мир. Они не создают окно и не обращаются к GPU.
|
|
|
|
|
Окно находится в адаптере winit, графические ресурсы — в адаптере Vulkan.
|
|
|
|
|
`fparkan-game` связывает их в приложение.
|
|
|
|
|
|
|
|
|
|
У файла на диске и объекта в игре разные сроки жизни. Одна модель может быть
|
|
|
|
|
прочитана однажды и использоваться многими объектами, у каждого из которых
|
|
|
|
|
свои положение и время анимации. Материалы и текстуры тоже разделяются между
|
|
|
|
|
экземплярами. Владение этими данными видно из Rust-структур; отдельный сервис
|
|
|
|
|
или интерфейс добавляется, когда появляется реальная потребность.
|
|
|
|
|
|
|
|
|
|
## Один тест на правило
|
|
|
|
|
|
|
|
|
|
Для бинарного формата полезен короткий массив байтов: тест проверяет значения
|
|
|
|
|
полей и отказ при обрыве записи или неправильной ссылке. Для преобразования
|
|
|
|
|
координат удобны точки и повороты, результат которых легко посчитать вручную.
|
|
|
|
|
Тесты находятся рядом с соответствующим алгоритмом и запускаются через
|
|
|
|
|
`cargo test --workspace`.
|
|
|
|
|
|
|
|
|
|
Оригинальные ресурсы остаются в установленной игре. Локальные тесты с ними
|
|
|
|
|
помечены `#[ignore]`, чтобы обычная проверка работала без коммерческих файлов.
|
2026-10-11 13:12:50 +04:00
|
|
|
Сообщение об ошибке должно сразу назвать ресурс и причину: например, какой
|
|
|
|
|
материал сослался на отсутствующую текстуру. Поэтому диагностика остаётся
|
|
|
|
|
частью самого запуска и не зависит от отдельного отчёта.
|
2026-09-06 05:22:12 +04:00
|
|
|
|
|
|
|
|
## Числа и порядок вычислений
|
|
|
|
|
|
|
|
|
|
Порядок умножения матриц имеет значение: поворот объекта вокруг своей оси и
|
|
|
|
|
поворот его положения вокруг начала мира дают разные результаты. Единицы высоты
|
|
|
|
|
ландшафта могут отличаться от единиц размещённых объектов. Эти преобразования
|
|
|
|
|
выполняются в одном месте и проверяются конкретными точками.
|
|
|
|
|
|
|
|
|
|
Оригинальный x86-код использует x87. Промежуточное значение может иметь большую
|
|
|
|
|
точность, чем сохранённый `float32`. Особенно внимательно проверяются переходы
|
|
|
|
|
между кадрами анимации, округление и границы треугольников. Эмулировать x87 во
|
|
|
|
|
всём движке не требуется: существенные расхождения разбираются в конкретной
|
|
|
|
|
формуле.
|
|
|
|
|
|
|
|
|
|
Случайные числа и порядок обхода тоже влияют на поведение. Перестановка вызовов
|
|
|
|
|
генератора меняет время молнии или траекторию частицы даже при прежнем seed.
|
|
|
|
|
Для повторяемой проверки сохраняют начальное состояние и одинаковую
|
|
|
|
|
последовательность шагов. Дополнительные потоки и альтернативные алгоритмы
|
|
|
|
|
имеют смысл после измерения узкого места.
|
|
|
|
|
|
|
|
|
|
## Проверка изображения
|
|
|
|
|
|
|
|
|
|
Успешное создание Vulkan pipeline доказывает только корректность обращения
|
|
|
|
|
к API. Положение моделей, масштаб карты, текстуры, прозрачность и свет
|
|
|
|
|
проверяются в самом окне. Validation layer помогает находить ошибки владения
|
|
|
|
|
GPU-ресурсами, синхронизации и пересоздания swapchain.
|
|
|
|
|
|
|
|
|
|
Кадр для сравнения читается после завершения работы GPU. При изменении размера
|
|
|
|
|
окна старые framebuffer и изображения освобождаются лишь после окончания их
|
|
|
|
|
использования. При сворачивании окно может иметь нулевой размер; тогда новые
|
|
|
|
|
кадры не отправляются. Обычное закрытие завершает программу успешно.
|
|
|
|
|
|
|
|
|
|
Оптимизация начинается с измерения: время загрузки, число повторных декодирований,
|
|
|
|
|
объём текстур и время кадра. Повторное использование уже загруженного ресурса
|
|
|
|
|
обычно полезнее дополнительного слоя управления кэшем.
|