Сборщики данных для веб-инструментов Space Stories Marine Corps. Репозиторий
читает прототипы игры, локализацию и RSI-ресурсы, преобразует их в стабильные
JSON-контракты и сохраняет готовые данные в data/.
Сгенерированные файлы не редактируются вручную. Источниками истины являются код сборщиков, конфигурация и конкретный commit игрового репозитория.
Полное руководство по совместной разработке data и app находится в
ssmc-wiki-app/docs/CONTRIBUTOR_GUIDE.md.
flowchart LR
Game["space-stories-cm14<br/>YAML · Fluent · XML · RSI"]
Config["config/"]
Common["scripts/common/"]
Catalog["scripts/catalog/"]
Chemistry["scripts/chemistry/"]
Mobs["scripts/mobs/"]
CatalogData["data/catalog/"]
ChemistryData["data/chemistry/"]
MobsData["data/mobs/"]
App["ssmc-wiki-app"]
Game --> Catalog
Game --> Chemistry
Game --> Mobs
Config --> Catalog
Common --> Catalog
Common --> Mobs
Catalog --> CatalogData --> App
Chemistry --> ChemistryData --> App
Mobs --> MobsData --> App
Каждый предметный модуль изолирован в scripts/<module>/ и пишет только в
data/<module>/. Общие чтение прототипов и Fluent-локализация находятся в
scripts/common/. Модуль химии использует собственный YAML loader, потому что
его промежуточный формат отличается от Entity-прототипов каталога и мобов.
config/ редактируемая конфигурация каталога
scripts/
common/ общий resolver прототипов и локализация
catalog/ каталог предметов
chemistry/ реагенты, реакции и guidebook
mobs/ параметры людей и каст ксеноморфов
data/
catalog/ публичный каталог, диагностика и PNG
chemistry/ публичный каталог и промежуточные индексы
mobs/ публичный каталог мобов
.github/workflows/ сборка, публикация и PR-проверки
Новый независимый сборщик добавляется по той же схеме:
scripts/<module>/, data/<module>/, тесты, валидатор и отдельный workflow.
Связывать его напрямую с другим предметным модулем не следует; повторяемую
инфраструктуру нужно вынести в scripts/common/.
config/catalog-sources.ymlперечисляет разрешённые автоматы и компьютеры карго. Автоматического поиска по префиксу нет: новый источник не попадёт в каталог без явного добавления.- Сборщик читает торговые предложения и заказы карго.
- От каждого найденного предмета выполняется обход графа: содержимое ящиков и наборов, слоты, магазины, патроны, снаряды, установленные обвесы, гарнитурные ключи и другие технические зависимости.
- Для каждой достигнутой сущности создаётся отдельная карточка. Заполненный и пустой варианты не склеиваются автоматически.
- Из компонентов извлекаются нормализованные блоки характеристик: оружие и урон, броня, обвесы, хранение, растворы, связь, навыки и совместимость.
- Автоклассификатор назначает один раздел по механическим признакам и контексту источника.
config/catalog-overrides.jsonприменяется последним. Если редактор выбрал категорию, отличную от автоматической, карточка получаетedited: true.- Сборщик пишет JSON и рендерит PNG; валидатор проверяет связи, цены, категории, overrides и отсутствие устаревших спрайтов.
Разделы: Оружие, Боезапас, Обвесы, Броня, Экипировка, Медицина,
Снаряжение, Другое, Скрытые.
Скрытые — полноценный раздел, а не boolean-флаг. Автоклассификатор его не
назначает: предмет может попасть туда только через override. Приложение скрывает
такие карточки из обычной выдачи, но может открывать их по связям других предметов.
config/catalog-sources.yml использует schemaVersion: 3:
vendors— Entity ID автоматов сCMAutomatedVendor;cargoCatalogs— Entity ID компьютеров сRequisitionsComputer;classification.excludePrototypeIds— техническое исключение из публикации;classification.categoryOverrides— редкая настройка автоматической классификации в кодовой конфигурации, не админская правка.
Админские решения хранятся только в config/catalog-overrides.json:
{
"schemaVersion": 2,
"items": {
"PrototypeId": { "category": "Скрытые" }
}
}Отсутствующий файл, пустой файл и {} означают «overrides отключены». Любой
непустой документ обязан соответствовать схеме; неизвестный ID или категория
останавливают сборку вместо тихого повреждения данных.
Веб-приложение должно читать data/catalog/catalog.json (schemaVersion: 4):
items— карточки и нормализованные характеристики;publicCatalog.itemIdsиpublicCatalog.categories— публикация и разделы;sources— автоматы и карго-каталоги;availability— способы получения предмета;relationshipsиcontainsItemIds— нормализованные связи;overridesиreview— результат редакторского слоя и диагностика.
Цена карго относится ко всему заказу. У корневого ящика/предмета находятся
cost и, при наличии дополнений, includedItemIds. Дополнительная сущность не
получает ложную отдельную цену: у неё записывается includedWithItemId.
data/catalog/index.json (schemaVersion: 3) — технический отчёт сборщика:
полные торговые записи, сырой граф связей, source-файлы и счётчики обхода. Это не
контракт интерфейса; app не должен зависеть от его внутренней структуры.
Спрайт карточки задаётся полем sprite.file и лежит в
data/catalog/sprites/. Каталог и папка PNG валидируются как единое целое.
build.py— CLI и порядок всех этапов сборки.catalog.py— чтение торговых источников, обход графа и сборка документов.classification.py— извлечение признаков и правила категорий.config.py— строгая проверка sources/overrides и применение правок.core.py— категории, слоты, типы связей и публикуемые компоненты.prototypes.py— специфичные для каталога парсеры размеров и реагентов.relations.py— содержимое, боеприпасы, обвесы и совместимость.statistics.py— нормализованные блоки характеристик.sprites.py— чтение RSI, композиция состояний и запись PNG.reporting.py— JSON, review и сравнение с предыдущей сборкой.validate.py— проверка публичного контракта и его соответствия index/config.test_*.py— модульные и регрессионные тесты.
scripts/chemistry/guides.py читает XML guidebook, index.py индексирует YAML
реагентов и реакций, build.py разрешает наследование и локализацию, а
validate.py проверяет итог. Публичный файл — data/chemistry/catalog.json;
index.json и guides.json являются промежуточными диагностическими данными.
Время запуска намеренно не записывается: при одинаковом игровом commit и коде JSON должен быть байт-в-байт одинаковым.
scripts/mobs/build.py собирает пороги здоровья и броню базового человека и
игровых каст ксеноморфов. validate.py проверяет схему, диапазоны, обязательные
поля и разумное минимальное количество каст. Публичный файл —
data/mobs/catalog.json.
Требуется Python 3.11+ и локальный checkout
MetalSage/space-stories-cm14. Из корня этого репозитория:
python -m pip install -r requirements.txt
python -m pip install pytest ruff
python -m pytest
python -m ruff check scriptsПолучить commit игры:
git -C /path/to/space-stories-cm14 rev-parse HEADСобрать и проверить каталог:
python -m scripts.catalog.build \
--game-source /path/to/space-stories-cm14 \
--config config/catalog-sources.yml \
--index-output data/catalog/index.json \
--output data/catalog/catalog.json \
--sprites-output data/catalog/sprites \
--commit GAME_COMMIT \
--locale ru-RU
python -m scripts.catalog.validate \
--catalog data/catalog/catalog.json \
--index data/catalog/index.json \
--config config/catalog-sources.yml \
--sprites data/catalog/spritesСобрать и проверить химию:
python -m scripts.chemistry.guides \
--game-source /path/to/space-stories-cm14 \
--output data/chemistry/guides.json \
--commit GAME_COMMIT
python -m scripts.chemistry.index \
--game-source /path/to/space-stories-cm14 \
--output data/chemistry/index.json \
--commit GAME_COMMIT
python -m scripts.chemistry.build \
--index data/chemistry/index.json \
--guides data/chemistry/guides.json \
--game-source /path/to/space-stories-cm14 \
--output data/chemistry/catalog.json \
--locale ru-RU
python -m scripts.chemistry.validate \
--catalog data/chemistry/catalog.jsonСобрать и проверить мобов:
python -m scripts.mobs.build \
--game-source /path/to/space-stories-cm14 \
--output data/mobs/catalog.json \
--commit GAME_COMMIT \
--locale ru-RU
python -m scripts.mobs.validate \
--catalog data/mobs/catalog.jsonpr-checks.ymlзапускает Ruff, все тесты и валидаторы текущих данных.build-catalog.ymlавтоматически пересобирает каталог при изменении его кода или конфигурации; также поддерживает ручной запуск.build-chemistry-catalog.ymlиbuild-mobs.ymlзапускаются вручную.- Все публикующие workflow используют одну concurrency-группу, чтобы боты не
перезаписали параллельные изменения в
data/.
Перед pull request:
- Меняйте источник истины, а не только сгенерированный JSON.
- Добавляйте регрессионный тест для исправленной ошибки или нового правила.
- Пересобирайте затронутый модуль из конкретного commit игры.
- Запускайте тесты, Ruff и валидатор модуля.
- Проверяйте diff: изменение кода без изменения источника не должно неожиданно добавлять/удалять предметы или менять категории.
Версии библиотек сборки зафиксированы в requirements.txt. Это важно для
воспроизводимости JSON и бинарного представления PNG между локальной машиной и
GitHub Actions.