Skip to content

Latest commit

 

History

History
147 lines (118 loc) · 12.3 KB

engine-decision.md

File metadata and controls

147 lines (118 loc) · 12.3 KB

Выбор стека клиента

Статус: принято 29.09.2026 владельцем проекта (issue #6). Основа — пять отчётов исследования в docs/research/.

Решение

PixiJS 8 + TypeScript + Vite для клиента и свой тонкий слой совместимости с cocos2d-x 2.x. Конвейер ассетов и данных пишем на Python в tools/, игровую логику — на чистом TypeScript отдельно от рендера. Запасной вариант — Phaser 4.

Платформа: сначала браузеры на компьютере — Chrome, Safari и Firefox на macOS, Windows и Linux. Телефоны — позже, отдельным этапом, если получится.

Почему:

  1. Модель сцены совпадает с оригиналом. Inferno построен на cocos2d-x 2.2.0. Узел cocos (anchorPoint × contentSize, координаты детей отсчитываются от левого нижнего угла родителя) ложится на Container.pivot в PixiJS. Поэтому перенос 145 макетов ccbi сводится к формуле преобразования и перевороту оси Y. У Phaser точка трансформации контейнера всегда (0,0), и каждый узел с anchor пришлось бы собирать из двух контейнеров.
  2. Главный технический риск — видеопамять, и PixiJS закрывает его штатно. В RGBA бой занимает в среднем 424 МиБ, в пике 648 МиБ. Стартовый набор с HD-интерфейсом — 1,05–1,36 ГБ. На компьютере достаточно выгружать текстуры по сценам. Для телефонов понадобятся сжатые текстуры KTX2/Basis (у PixiJS есть официальная поддержка, у Phaser Basis нет) и SD-набор.
  3. Обычный TS-проект (Vite, Vitest, Playwright) без редактора и своих форматов сцен. API стабилен в ветке 8.x: последняя версия 8.21.0 вышла 17.09.2026, лицензия MIT.
  4. Логика от движка не зависит. Бой (30 тиков в секунду, 362 скрипта поведения на своём мини-языке, навигация по зонам и A*), экономику и квесты придётся писать заново при любом выборе. Движок определяет только рендер и UI.

Почему не другие (взвешенная оценка из engines.md, из 100; у PixiJS 89,6):

Кандидат Оценка Главная причина
Phaser 4 82,2 у контейнера нет anchor, поэтому узлы двойные; нет Basis; v4 вышел только 10.04.2026
Phaser 3.90 78,6 ветка закончилась на 3.90 (23.05.2025)
Cocos Creator 3.8 72,0 по смыслу ближе всех, но сборка требует редактора с GUI, а ccbi без исходных .ccb не импортируются
Godot 4.7 65,8 нет TypeScript, C# в вебе не экспортируется, около 5 МБ движка, проблемы в Safari
cocos2d-html5 57,4 заброшен с 2018 года, есть ошибки на iOS; пригодится как образец ридера ccbi
Defold 56,2 Lua, GUI собирается в редакторе

Что выяснило исследование

Оригинал (native.md)

  • cocos2d-x 2.2.0, сборка GCC 4.9 (NDK r10) под armeabi. В динамической таблице 61 203 символа: почти все классы и методы игры с именами, поэтому реверс точечный и дешёвый.
  • Сервер встроен в клиент: namespace inferno::, локальный CRequestHandler, needServerAuth() возвращает false. Игра полностью офлайновая; сеть нужна только для покупок, соцсетей, облачных сохранений и скачивания событий.
  • Сохранения — открытый XML (profile.xml, mailbox.xml, last_waypoint.xml) плюс CCUserDefault.
  • Логика в основном в данных. Код упоминает только 144 из 13 192 id, способности целиком заданы данными, а поведения, эффекты и действия описаны XML-мини-языками.
  • Бой детерминирован: в боевом коде нет генератора случайных чисел. Сам боевой код — около 1 300 функций, у всех есть имена.

Сцены и графика (requirements.md, assets.md)

  • Четыре сцены: сплэш, колония, карта кампаний, бой. Поверх — меню, подготовка к бою, расстановка войск, магазины.
  • Изометрия с ромбом около 46×32 px. Земля карт — готовые картинки, нарезанные на тайлы. Навигация — зоны с порталами плюс A*.
  • 1 151 визуал, везде 15 fps. У юнитов 8 направлений: 5 нарисованы, остальные получаются отражением. У зданий до 12 слоёв.
  • Текстуры ETC1 хранят альфу в нижней половине — это подтверждено декодированием и шейдером в бинарнике. Цвет не премультиплицирован, поэтому при загрузке его нужно премультиплицировать. 1 340 кадров атласов повёрнуты на 90°, кадры упакованы без отступов.
  • Частиц, TMX и Spine нет. Восемь шейдеров постобработки (размытие, Splash, Focus и др.) переносятся почти без правок.

Интерфейс (ccbi.md)

  • 145 макетов (плюс 32 HD-копии) в формате CCBI v5, но в варианте Inferno: штатный ридер ломается на 253 файлах из 306. Прототип парсера читает все 306 без потерь, обратная сборка совпадает байт в байт.
  • 5 362 узла и 7 своих классов узлов (CCTextLayout, CCTextButton, CCScrollListView и др.). 9-slice, BMFont и вложенных ccbi нет, таймлайны простые — ключи есть только в 24 файлах.
  • Тексты в макетах — заглушки. Настоящие строки лежат в data/locale_*.json (после #29).

Ассеты и хостинг (assets.md)

  • Полный комплект для браузера в WebP q90 + Opus весит около 439 МБ (оригинал — около 560 МБ). На старте нужно 17–21 МБ, до первого боя ещё около 4 МБ.
  • Лимиты хостинга на 29.09.2026:
    • GitHub Pages — сайт до 1 ГБ, 100 ГБ трафика в месяц;
    • Cloudflare Pages — до 20 000 файлов по 25 МиБ, трафик статики без ограничений;
    • GitHub Releases отдаёт файлы без CORS, поэтому напрямую в браузер не подходит.
  • Публиковать ассеты разрешено. В git их не храним из-за объёма, собираем пакетами по сценам. Где размещать — GitHub Pages (ассеты попадают в сборку из Release-архива) или Cloudflare Pages — решаем на этапе 1, когда будет готов конвейер.

Архитектура клиента (эскиз)

tools/        Python, офлайн: текстуры → WebP/KTX2 + атласы JSON, ccbi → JSON,
              visuals → JSON, config и server.xml → data/
web/          TypeScript + Vite + PixiJS 8
  engine/     слой совместимости с cocos2d-x: узел с anchor и contentSize, actions, сцены,
              камера, ввод, звук, загрузка и выгрузка текстур по сценам
  ui/         загрузчик макетов из ccbi-JSON, ~10 виджетов, плеер таймлайнов, окна
  render/     изометрия и сортировка по глубине, покадровые анимации, постэффекты
  game/       модель и логика на чистом TS без PixiJS: шаг 30 Гц, интерпретатор скриптов
              поведения, навигация, экономика, квесты, сохранения; тесты на Vitest

Первый шаг: проверочный прототип (2–3 дня)

Прежде чем строить остальное, проверить на PixiJS:

  1. Три макета ccbi (yes_no_popup, construction_menu, CityScene): конвертер в JSON и загрузчик.
  2. Юнит в 8 направлениях с отражением: 200 штук на изометрической сцене с сортировкой по глубине, замер FPS.
  3. Текстуры WebP: расход видеопамяти и загрузка по сценам. Сравнение с KTX2/Basis отложено до этапа телефонов.
  4. Размытие под окном шейдером постобработки.
  5. Всё это — в Chrome и Safari на Mac.

Если слою совместимости для трёх макетов понадобится больше ~1,5 тыс. строк или в браузерах всплывут неустранимые проблемы, прототип повторяется на Phaser 4.

Риски

  • Видеопамять. На компьютере — выгрузка по сценам. Для телефонов (отдельный этап) ещё KTX2/Basis и SD-набор.
  • Свой каркас на PixiJS — 3–5 тыс. строк (сцены, actions, звук, камера). @pixi/sound и Howler обновляются редко.
  • Минорные релизы PixiJS иногда меняют поведение. Меры: фиксировать версию, держать скриншотные тесты (Playwright).
  • Нет эталонных скриншотов. Оригинал 32-битный и на Apple Silicon не запускается. Выход — реальное Android-устройство с поддержкой 32-битных приложений.

Оценка объёма (грубо)

  • UI-слой (загрузчик, виджеты, таймлайны): 22–33 человеко-дня. Логика окон: 65–160 человеко-дней, при любом движке.
  • Бой: около 1 300 функций оригинала. Реверс в Ghidra нужен точечно: выбор целей, движение, автомат состояний юнита, волны, пушки, экономика.

Попутно

  • Under Control. В его обосновании указан «Phaser 3.90+», но ветка 3.x закончилась на 3.90 (23.05.2025). Стабильный Phaser 4 вышел 10.04.2026.
  • Данные расходятся с кодом:
    • код ждёт секцию defense_boosts, а в данных она называется defense_technology_boosts;
    • секции credits и decorations код не читает;
    • config/server.xml (награды квестов) пока не разбирается — см. #30.