Этот туториал — часть серии Начало работы — День 4, Неделя 3.
Проблема: правильные данные, неправильная форма
На этой неделе вы работали у источника: коллекция Карты — это реальные данные дизайна, перечитанные таблицей, отфильтрованные и сохранённые в виды. Это правильное место для данных — и всё же ни один потребитель данных не хочет их в такой форме.
Ваш движок, какой бы он ни был, ждёт конкретную JSON-структуру — не весь объект карты в том виде, в котором он лежит на диске, а card.damage и card.owner, и только те поля, которые ему нужны. Ваша команда тем временем хочет просматривать баланс в электронной таблице — настоящие CSV-строки, которые можно открыть, переставить и прокомментировать в Excel или Google Sheets.
Никто не просит «дайте мне редактор». Оба просят проекцию данных: ту же правду, разложенную под их инструмент. Делать эту проекцию руками на каждом проходе баланса — значит вернуться к переписыванию: копировать числа из одной системы в другую, ровно тот дрейф, который эта серия существует, чтобы убрать.

Пользовательский формат экспорта — это сохранённый рецепт
IMS Creators экспортирует через пользовательские форматы экспорта — именованные рецепты, описывающие, как набор элементов становится файлами: какие элементы (опционально ограниченные типом), в каком формате, с какими полями и переписанные опциональным скриптом.
Формат определяете один раз; коллекция продолжает экспортировать через него вечно. Соберём те, что нужны нашим двум потребителям.
JSON для движка: выберите поля, оставьте один файл
Создайте формат для движка:
- Заголовок —
Карты для движка. - Тип — Игровая карта, чтобы этот формат экспортировал только карты.
- Формат — JSON.
JSON-экспорт предлагает три шаблона формы:
- Полный — все данные элемента, всё, что имеет имя и не является служебным.
- Только значения — структурированные значения, всё ещё сгруппированные по блокам.
- Выбранные поля — только поля, помеченные вами в списке полей, — ничего внутреннего, ничего лишнего.
Для движка подходит Выбранные поля: отдайте ровно Имя, Стоимость, Урон и Легендарная, ничего больше. Выберите поля, задайте каждому имя вывода в списке полей — движок называет Урон иначе, выведите его под этим именем — и эти имена станут ключами объектов в экспортированных файлах.

CSV для команды: электронная таблица, а не структура
Те же данные баланса становятся строками для ревью вторым форматом — CSV. Вы можете выбрать колонки, нужные электронной таблице, решить разделитель (запятая или точка с запятой — точка с запятой, если так ждёт местный Excel) и добавить строку заголовков. Каждая карта становится строкой.

Теперь рецепт для движка и рецепт для ревью сосуществуют, оба целятся в одну коллекцию Карты, оба питаются одними данными.
Постобработка: пересоберите каждый элемент скриптом
Шаблоны покрывают «отдай мне эти поля». Более глубокое несоответствие — движку данные нужны вложенными иначе, чем хранит редактор — закрывает скрипт постобработки, прикреплённый к формату.
Экспорт прогоняет каждый элемент через небольшую JavaScript-функцию. Ваш код получает подготовленный элемент как asset_data, и всё, что функция возвращает, записывается для этого элемента. Скрипт по умолчанию ничего не делает:
return asset_data;
Но допустим, движок грузит карты как словарь по коротким именам, со значениями, упрощёнными до плоскости, и флагами, переименованными. Скрипт может пересобирать каждый элемент и вычислять производные значения — движок получает готовые данные, которые ему иначе пришлось бы считать самому:
return {
name: asset_data.Name,
damage: asset_data.Damage,
cost: asset_data.Cost,
legendary: asset_data.IsLegendary,
power_budget: asset_data.Damage + asset_data.Cost,
overtuned: asset_data.Damage / asset_data.Cost > 1.5,
};
Ключи name, damage, cost и legendary приходят прямо из имён вывода, заданных в Выбранных полях, — подготовленный элемент несёт ровно эти выбранные поля под этими именами. Остальное — обычный JavaScript: power_budget складывает два поля, overtuned прогоняет те же значения через сравнение. Файл несёт производные данные — сумму, флаг — которые движок читает готовыми, не пересчитывая из сырых чисел. Любая обработка, выражаемая на JavaScript, выполняется на каждом элементе по текущим данным при каждом экспорте. Никакого слоя сопоставления в коде, никакого перечитывания таблиц руками.

Скрипт пишется в приложении. Редактор показывает живой предпросмотр на реальном элементе с другой стороны — до экспорта хоть одного файла вы видите, как будет выглядеть первая карта после скрипта, а это убивает главную проблему экспорта: обнаружение, что форма неправильная, уже после записи файлов.
Скрипт выполняется на каждом элементе в фоне
Экспорт каждого элемента проходит через один и тот же скрипт независимо, поэтому форма гарантированно согласована по всей колоде — первая и тридцатая карта дают одну структуру. Именно пересобранные данные ложатся на диск.
Экспорт папки: один клик, настоящие файлы
Когда формат готов, экспортируйте набор: кликните правой кнопкой по коллекции Карты, выберите команду экспорта и формат, укажите папку назначения.
Что ложится туда, зависит от формата:
- CSV — один
<имя>.csvсо строкой на карту, готовый для электронной таблицы. - JSON, один файл — весь набор в одном файле, массив пересобранных элементов. Движок грузит его один раз при старте.
- JSON, файл на элемент — каждый элемент своим
<element-id>.json, повторяя знакомый вам по файлам самого проекта принцип один файл — один элемент.

Так как это обычные текстовые файлы, экспорт падает прямо в вашу git-историю — каждое изменение баланса в коллекции даёт чистое, читаемое диффом изменение в экспорте, просматриваемое как любой другой патч.
Суждение
Ваши редакторы и просмотрщики видят дизайн органично; движок видит его проекцию. Проекция одноразовая, проекция скриптованная, и проекция никогда не становится вторым источником истины — переэкспортируйте, и она пересоберётся из реальных данных. Это всё ещё «переписывание» в буквальном смысле — кроме того, что его выполняет приложение, каждый раз идеально одинаково, без опечаток и дрейфа.
Далее: автоэкспорт
Форматы означают, что экспорт — это один клик без раздумий. Но «помнить кликнуть после каждой правки» — ровно та дисциплина, что разваливается в день дедлайна. Завтра, финальный шаг цикла: автоэкспорт — коллекция пересоздаёт файлы при сохранении, и Godot подхватывает новый баланс, пока никто ничего не экспортирует.
Готовы придать форму своему экспорту? Скачайте IMS Creators, откройте ims.cr5.space/desktop, создайте JSON-формат для движка с Выбранными полями и CSV-формат для команды и просмотрите оба на реальной карте сегодня.
Готовы? Измените характеристику карты, и Godot перезагрузит её - следующий пост в этой серии.
FAQ
Что именно такое пользовательский формат экспорта?
Сохранённый рецепт создания файлов из набора элементов: опциональный тип элемента, формат (JSON или CSV), какие поля или шаблон использовать и опциональный скрипт постобработки. Создаёте один раз, экспортируете через него сколько угодно раз.
В чём разница между JSON-шаблонами?
Полный экспортирует все данные элемента — всё, что имеет имя и не является служебным. Только значения оставляет лишь структурированные значения, сгруппированные по блокам. Выбранные поля экспортирует только поля, указанные вами явно, — самая чистая проекция для движка, потому что в файл не протекает ничего внутреннего.
Что получает скрипт постобработки?
Каждый подготовленный элемент как asset_data. Скрипт запускается на каждом элементе, и файл пишется тем, что вернула функция. Стандартный return asset_data; пропускает элемент без изменений; скрипт нужен, чтобы пересобрать данные под точную структуру движка — и обработать их: вычислить суммы, отношения или флаги на лету, а не просто выбрать поля.
Зачем вообще CSV, если JSON чище?
Потому что огромная часть аудитории данных баланса — не код, а люди. CSV-строки открываются в Excel, Google Sheets и каждом инструменте для таблиц, что когда-либо написан. Команда просматривает и комментирует строки; движок грузит пересобранный JSON. Два формата, одна коллекция, ноль перепечатывания.
Что значит «Объединить в один файл» для JSON?
Это управляет раскладкой вывода. Сгруппировано — весь набор ложится в один файл как массив, идеально для движка, который грузит баланс один раз при старте. Без группировки каждый элемент — свой файл <element-id>.json, повторяя принцип, которым пользуется сам проект. Выбирайте под потребителя.
Как экспортировать после создания формата?
Кликните правой кнопкой по коллекции (или папке элементов), выберите команду экспорта, формат и папку назначения. Файлы пересобираются из текущих данных каждый раз — устаревшего снимка для освежения нет.
Можно ли коммитить экспортированные файлы в git?
Да — и нужно. Экспорт — обычный текст, так что каждое изменение баланса становится читаемым диффом. Коммит даёт вам просматриваемую историю того, что именно видел движок в каждый момент времени.