Игровая дата. Оркестр.

Рассмотрим игровой процесс. Аутсорсеры делают арт. Кто-то его принимает, аккуратно куда-то раскладывает. Кто-то его интегрирует в игру. Кто-то репортит о багах в арте, кто-то их фиксит. Есть девелоперские билды, релизные, с разными запакованными данными и хитрыми оптимизациями. Есть ночные реэкспорты всего и вся. Все это тегается, бранчится и живет под управлением системы контроля версий. Или не живет. Или летает – или ползает. Или цветет и пахнет – или покрылось плесенью.

Возникает стойкое ощущение, что этот процесс интереснее любых тонкостей организации NV40 или спаривания левых и правых команд на spu.

Рассмотрим asset management схему.  Сразу возникают вопросы. Ответов у меня на них нету, это как в известной сентенции про Русскую Литературу.  Она, как известно, ставит Великие Вопросы, но решать их отказывается.

1. ) Хранятся ли исходники арта под системой контроля версий? Это файловая система контроля версий или база данных, или что?

2. ) Одномоментен ли процесс интеграции арта в игру? Хранятся ли правила интеграции арта ( в виде make файлов, XNA правил сборки или еще в каком виде ). Если хранятся, то хранятся ли они вместе с артом, вместе с экспортируемым результатом или отдельно? Есть ли биективное соответствие между head trunk ревизией арта и head trunk игры? Если есть – то какие средства форсирования такого соответствия. Ночные реэкспорты, интеграции в системы контроля версий и DCC инструменты?

3. ) Структура пространства имен игровых данных. Синхронна ли она со структурой пространства имен арта? Плоская она или иерархическая? В ней допустимы абсолютные или относительные пути? Есть ли разница в идентификации ресурсов в девелоперском и релизном билде ( замена строк на id )? Есть ли пространства имен ( aka паки )? Если да, то есть ли перекрестные ссылки между паками? Сколько существует копий экспортированных данных для одного и того же ассета? Если копии есть - то как они возникают  ( для ускорения загрузки с DVD к примеру; или как побочный продукт наличия паков для игрового уровня ).

Вот такие вопросы. Я в курсе, что интернет полон ответами. Книги, лекции на конференциях, разное. 

 Мне интересны живые ответы. Если кто-то ответит конспективно – рад буду. 

  • http://www.vogster.com raskolnikov

    1) да, но в другой системе (Чужемозг(AB), code+content – p4)
    2) одномоментный – непонятно, правила имеются (в виде resource property), хранятся вместе с импорченным контентом (для реимпорта). Соответсвия нету (т.к. с одной стороны не удобно, с другой геморно + нестабильно)
    3) Синхронна, иерархическая, только абсолютные пути, разницы нет, есть пространства имен, перекрестные ссылки есть (но с ограничениями), 2 копии (локальная при импорте в движок + в импорченном ресурсе для изменения property), копии есть для ускорения и seek-free загрузки, все ненужно на этапе bake вырезается и выкидывается (оригиналы, нередактируемые проперти,…)

  • dDIMA

    1. Да. Как правило, лучше отделять арт базу данных. Так что она точно должна жить независимо, дальнейшее разделение (код движка, код игры, сборка) – это уже по желанию.
    2. Правила интеграции должны храниться. То есть процедуры коммитов между репозиториями арта и игры желательно иметь автоматическими и с максимумом проверок.
    3. У нас – плоско/иерархическая, так как можно устраивать вложенные пространства имен и все такое прочее. Разницы нет (всегда id). Перекрестные ссылки есть, хотя точнее сказать, что ссылки образуют орграф без циклов.

    А вообще сложно так конспективно ответить – ИМХО это лучше делать в живом общении. Поэтому предлагаю исправицца за пропуск Саймона в Мск и устроить новое (пока неанонсированное) пати в начале февраля ;).

  • Sergei_am

    О, да, тема довольно интересная и сложная. И презираемая большинством новичком из-за близостки к базам даннъх наверное…
    Как у нас:
    1. Хранятся, svn.
    2. Art можно заекспортить, после чего он доступен как минимум для дизайнеров и его можно располагать по картам в виде декоров. Для более его сложного использования нужно привлечь программера. Арт експортится по таблице, которая создается предварительно по согласии между дизайнерами, художниками и продюсером, т.е. известно количество анимаций, мешей и материаллов для данного обьекта. Арт хранится в Art/проект/Source, его заекспорченъй вариант в Art/проект/Exported, биекции нету. Зато екпортер не дает експортить не-HEAD ревизию. Есть реекспорт всего арта, последний же арт на совести его создателей.
    3. Структура експорченого арта не синхронна со структурой самого арта, что *ПЛОХО*. Но так сложилось. Она йерархическая, но риференсъ к ней плоские, т.е. папки игнорируются и конечно имена уникальнъ. Имена всегда стринги, в XML-ях с описаниями, таким образом билд процесс может в ети XML-и залезать, сравнивать текстуръ на одинаковость, менять их и т.д. Можно хоть все текстуръ заменить на “1.dds”, “2.dds”, .. или даже “0001″ (int32). Паков в виде пространства имен нет. Вообще ссълки между паками – дело странное, скорее возможность ссълатся на системнъе паки, которъе грузятся всегда и в начале. Копий нет.

    Как хочется:
    Я всегда думал, что на все ето можно посмотреть с такой точки зрения – ето просто load on demand для непреръвного некусочного мира. Можно мир/карту разбить на куски, где каждъй кусок – типа такой ‘мир’, сам по себе – в паке для куска картъ будут все уникальнъе меши. Отдельно пак для всего общего. И отдельно, паки для ‘катсцен’, т.е. локальнъе всплески арта, где анимации, меши, NPC, звук, диалог. Все ето нужно вътаскивать из скриптов, которъе ето управляют + делать prefetch етих паков, примерно как в God of war – условие, которое детектит наличие условия, необходимого для загрузки пака.
    При написании тех самъй сиквенсов/катсцен, дизайнер прописъвает скрипт, из котового вътаскиваются риференсъ к арту, делается дифф с зоной и все что в ней не встречается ложится в пак. Анимация, которая встречается в соседней катсцене, которая уже активна – ничего, загрузим опять…
    Примерно так.

  • http://www.vogster.com raskolnikov

    Sergei_am
    а не коматозно контент в svn?

  • Sergei_am

    Пока рога не показало. Завтра могу узнать, сколько там собралось творчества… один из последних юнитов, сорс арт – 2G.

  • http://assen.shtrak.com/ YE

    raskolnikov:

    We have 51 GB of data in the Subversion repository. This includes full history for all kinds of source branches (they, of course, are quite small in terms of size), all art assets (original Max and PSD files + exported data) for a released PC game, and all art assets for three games in development. Only one of the games in development is “next-gen” in terms of amount of content, and its content is maybe 33% ready; I expect the repository to exceed 150-200 GB before we ship it. I’ve heard quotes of 1 TB repositories per game in a large Californian studio making games everyone has heard of, if not played; but they are using Perforce. There are certainly other companies using Subversion at that scale; the one game I’ve heard about is Delta Force: Black Hawk Down.

    (I work with Sergei_am.)

  • http://assen.shtrak.com/ YE

    raskolnikov:

    A correction to Sergei_am’s 2 GB number: the folder is 2 GB, but Subversion duplicates all files in a working folder, so the data for the main character is actually 1 GB. This is a highly experimental model, and the artists have kept quite a lot of technically intermediate files (e.g. high-poly Max scenes resulting from a direct import from Mudbox); once the process is nailed down I expect such models to take more like 200-300 MB.

    A few more numbers:

    The “exported” version of the same character is around 55 MB, 48 of which are 3 2048×2048 uncompressed TGA files (we convert to DXTn in a later step, during the daily build procedure).

    The entire “HEAD” (latest current version) of the art folder is 20 GB (meaning you actually have 40 GB on disk, see Subversion).

  • http://assen.shtrak.com/ YE

    One more thing (why can’t I edit the comments??):

    When we first started storing art assets in Subversion, I measured three scenarios for the assets: XCOPY from our file server (where we used to keep them before), “svn checkout” (which gets the data and creates a working copy, from which you can commit), “svn export” (which just gets the data, i.e. has the same result as XCOPY). Even checkout was faster than XCOPY (even though it creates 3 files for each original), and export was much faster – my (unscientific) explanation was that XCOPY needs several network roundtrips *for each file* to negotiate a transfer, plus some overhead for browsing the remote folder tree; while with SVN operations all the folder enumeration happens at the server, which then pipes all the data in one huge uninterrupted file transfer.

  • IronPeter

    dDIMA, невопрос, надо исправиться.

    Sergei_am, маленькое уточненние. Допустим, есть файловая структура:

    /monsters/1.dds
    /building/1.dds

    И какой-то монстр референсит 1.dds. Это валидная ситуация? Текстура 1.dds уникальна в папке monsters.

    Судя по твоим словам – невалидная ситуация.

    По поводу SVN. У нас можно взять checkout части репозитория. И работать с ним, в частности проводить экспорт. По файлу находим путь в репозитории относительно корня и создаем экспорченный ресурс в game/data/ с таким же относительным путем. Так что художники могут брать апдейты на свою локальную часть данных. Живет в принципе.

  • Sergei_am

    IronPeter, имена текстур не уникальнъ. В материалах они, если локально находятся вместе с материалом – имеют локальнъй путь. Билд тул может их поменять, если где-то они повторяются и тогда их путь будет уже глобальнъй. Меши/анимации всегда локальнъ. А плоская структура – ето у обьектов.

  • ilya

    > Возникает стойкое ощущение, что этот процесс интереснее любых тонкостей организации NV40 или спаривания левых и правых команд на spu.
    Да и поважнее, с точки зрения production.
    Как у нас:
    /dDima, у нас все немного изменилось :) /
    1) Да, арт – в системе хранения версий. Файловая система.
    2) Зависимости м/ду тем, что лежит в art каталоге, и тем, что экспортится в игру, задается в scons файлах. Вообще, export pipeline – scons-based. (scons – система сборки, a-la make, только на питоне, http://www.scons.org). Пока какой-то art-ресурс не указан в соответсвующем scons-файле, в сборку он не попадет. Как только указан – сборка берет последню доступную версию.
    2.1) Никаких промежуточных форматов – нет. Все экспортится прямо из Maya/Max/Photoshop native. Все промежуточные шаги/преобразования форматов спрятаны в глубинах экспорта
    3) Во время экспорта, т.к. он scons-based, то идентификаторы – абсолютные имена файлов. Т.е. внутри системы сборки все зависимости – файловые. А для конкретного типа данных – зависит от. К примеру, есть соглашение (атавизм :) ), что имена текстур – уникальны в проекте. Так что можно экспортеру сказать getTexture(“Name”). И это уже его проблема – преобразовать в путь к файлу.

  • IronPeter

    Внятно, хорошая билд система – это плюс.

    ilya, я все же не понял – есть какая-то связь между именами до экспорта и после экспорта? Или это совершенно произвольное соответствие.

  • ilya

    IronPeter, нет, связи нет. В ран-тайме, так вообще, имен особенно нет. DWORD Id одни :)

  • IronPeter

    Хм, продолжу поспрашивать. Возникают вопросы.

    Какие действия надо произвести артисту, чтобы просмотреть его ресурс в игре. Какие усилия на первоначальную интеграцию? Надо сгенерить scons script. Надо сгенерировать уникальное имя, чтобы на диске появился файлик экспорченного ресурса. Надо закоммитить результат.

    Есть ли глобальный репозитарий, где хранится соответствие “имя до экспорта -> имя после экспорта”?

    Где хранятся scons скрипты – вместе с артом? Как можно убедиться, что для данного ресурса еще нет build скрипта? build скрипт – это один plain файл или иерархическая россыпь скриптиков? Если один – то часты ли конфликты при работе с системой контроля версий.

    Можно ли интегрировать целиком 3D сцену с текстурами, анимациями “в один щелчок мышкой”. Чтобы были иерархически созданы build правила для всех зависимых объектов.

    И пожалуйста поподробее про DWORD id. Эти самые id соответствуют именам файлов после экспорта ( scons как-никак file based )? Или же есть служба соответствия?

  • Sergei_am

    У нас експорт прямо в билд возможен, только там будут tga текстуръ. Зато все перезагружается на лету. Т.е. отличие билдового арта от только что заекспорченного, ето процесснутъй материал.

  • ilya

    2 IronPeter
    Общая мысль: жизнь художников надо облегчать :).

    Вводная: у нас игру можно собрать на _любом_ комрьютере проекта. Запускаешь одну команду – и она собирается. Вне зависимости, это машина программиста, тестировщика, гейм-дизайнера или художника. Это нисколько не исключает билд-машину, просто надо отделать теплое от мягкого.

    Теперь конкретно по вопросу: смотреть ресурсы можно отдельно от игры, а можно – в игре.

    Для отдельного просмотра – в неком специальном самописном приложении выбираем модельку/текстуру/flash… (из дерева каталогов) щелкаем на нем мышкой и говорим – preview. Автоматически генерятся все необходимые файлы для (dummy)экспорта, ресурс экспортится (под выбранную платформу) и запускается в игровом движке (опять же, на нужной платформе). Процесс, в зависимости от сложности ресурса, занимает 1-3 минуты.

    Теперь к просмотру в игре. Возможности, опять, две. Ресурс уже был, его поменяли, и ресурса не было. В первом случае – никакие скрипты менять не надо. Художник запускает батник “export_and_view.cmd” – на _своей_ машине, который экспортит уровни/уровень с новым ресурсом и автоматически запускает игру – опять же, все это под нужную платформу.
    Если же ресурса не было, то все сложнее. Но тут – опять две возможности :)). Если ресурс неинтерактивный, к примеру – новая текстура на геометрии, или новая елка в уровне или новый шейдер – то все, как в пердудущем пункте. Сложности, собственно, именно с интерактивными ресурсами. К примеру, сделали новое оружие. Тут, к сожалению, без скрипторов/программистов не обойтись. Ну, т.е. просмотреть его можно – см. самый первый пункт, но чтобы оно появился в игре, его действительно надо добывить в скрипты и, м. б., запрограммировать специальное поведение (к примеру, если то сих пор в игре было только милишное оружие, с тут сделали плазмаган, то программировать придется :) ).

    Так, далее по вопросам. Scons скрипты хранятся отдельно и от кода и от арта, но ближе, все-таки, к коду. Т.е., содержимое art католога не оказывает никакого влияния на игру, пока в сконсе не пропишут зависимости. Сконс-скрипты представляют из себя иерархическую структуру (дерево, на самом деле). Все ресурся подразделены по типам (уровни/персонажи/оружие/интерфейс/…), для каждого из них существует головной Sconscript, в котором перечислены все ресурсы, котрые экспортятся

    Касательно интеграции сцены целиком. Это – смотря что понимать под сценой цельком. Вернее – под ее стафом (stuff). Суровая реальность такова, что многие зависимости – неавные для системы сборки. К примеру, ma сцена сама, безо всякого сконса, ссылается на текстуры, референсную геометрию, шейдеры. Эти зависимости не прописываются явно в сконс-скриптах, а сканируются системой сборки. (Типа как #include сканируются при копмиляции cpp файла). Поэтому, чтобы все то, что есть в сцене, попало в сборку, достаточно подключить одну сцену. И не забыть все эти внешние референсы, как и саму сцену, добавить под систему хранения версий.
    Интерактивный стафф в Maya в уровни не расставляется у нас. Т.е., к примеру, NPC в уровни расставляются прямо в игре, в специальной моде.
    На самом деле, все еще несколько хуже. Из-за этих неявных зависимостей. И ряда наших внетренних рудиментов.

    По поводу понятия “после экспорта”. Для меня, “после эспорта” – это уже в игре, в real-time. В нем не очень хорошо использовать имена (из-за strcmp() ). dDima не раз рассказывал про memory-mapped файлы, в которых у нас хранатся игровые данные. Грубо говоря, каждый ресурс лежит в отдельной “секции” _внутри одного большого файла_, а идентификатором каждой секции является DWORD Id.

    Вот :)

  • IronPeter

    >Суровая реальность такова, что многие зависимости – неавные для системы сборки

    Это как раз очень хорошо. Что художник может тыкнуть по своему ma файлу, и он будет интегрирован со всеми зависимыми объектами.

    Про ваш билд я понял. Бинарные паки перестраиваются целиком – и это мне не очень нравится. Медленно для большого объема данных.

  • ilya

    > Бинарные паки перестраиваются целиком – и это мне не очень нравится. Медленно для большого объема данных.
    Отнюдь :)
    Вся прелесть scons’a в том и состоит, что он – декларативный. Т.о., в отличие от сборки с помощью командных файлов, которые пересобирают всегда и все, scons _проверяет зависимости_. И если пересобирать какой-то кусок не надо, то пересобираться он и не будет. Более того, процесс экспорта весьма непростой – много разных _маленьких_ экспортеров. На чем крутость сконса и проявляется. А укладывание готовых секций в бинарный pack – дело как раз весьма быстрое.

  • IronPeter

    хм… а мне сказывали – что у вас из .dae геометрия в пак складывается. Каждый билд. Безотносительно сконса.

  • Sergei_am
  • ilya

    2 IronPeter:
    Складыввется. Только не каждый билд. А только, если поменялась. Рассмотрим этот пример подробнее :)
    Есть исходная ma сцена. Содержащая, для простоты, текстуры и геометрию. Какие же у нас есть билдеры: билдер, превращающий ma в dae, Билдер, конвертящий геометрию из dae в platform-specific, Билдер, конвертящий текстуры из dae в platform-specific. И линкер, укладывающий бинарный пак.

    Если поменялась исходная ma сцена: То произойдет экспорт ma->dae. Поменялась гелметрия – произойдет экспорт dae->geom. Поменялись текстуры – то dae->tex. Потом линкер. (С геометрией немного не так – сложно понять, изменилась ли она, поэтому экспортится всегда, _если поменялась исходная сцена_. Если сцена не менялась – то нет)

    Если поменялся алгоритм укладки platform scpecific геометрии: ma->dae не запустится. dae->tex – не запустится. Запустится только dae->geom. И линкер.

    В реальных уровнях наполнение значительно сложнее, поэтому и билдеров значительно больше. И те из них, которые не нужны, не запускаются.
    На самом деле, мы еще не достигли нужной степени дискретизации билдеров :) Надо еще бить и бить на составные части. Но движемся в ту сторону.

  • IronPeter

    Значит, когда мне рассказывали, смешали конвертер dae->platform и линкер. Утверждали, что при пересборке пака происходит переконвертация всех геометрий, в него входящих. Впрочем, очевидно, что действительно можно кешировать почти все.

    Также понятно, что хочется упрощать рантайм. И задачу линковщика не перекладывать на рантайм, даже в простейшем виде ( поднимать файлики россыпью с диска ). Впрочем, не такая уж это большая нагрузка на рантайм. Перегрузку отдельных ресурсов все равно хочется делать. Без изменения пака целиком.

  • http://nesnausk.org ReJ

    На работе система идеалогически похожая на ты что и у Ilji.
    1) Код и арт контент -> P4, лежат раздельно в разных бранчах.
    2) Правила экспорта/тансформации/сборки, а также доп. проперти задаются XML файлами. XML хранятся рядом с артом. Для каждого арт ассета создают XML файл при помощи эдитора (есть скрипты для DCC или пресеты чтоб автоматизировать сложности там всякие), более етого XML файла реальный filename арт ассета никто не знает – все референсы между арт ассетами только на уровне XML файлов (далее работа в эдиторе только с ними).
    2.1) За весь процессинг арта отвечает кустомный тулзец (с оригинальным именем pipeline) читающий те XML дескрипторы. Для каждого типа арт ассета процесс разбит на множество шагов, а промежтучные результаты сохраняются (типа кэш) и могут быть использованны при обработке другого ассета. В финале – дата для конкретной платформы. Результаты также аплоадятся в ремоут кэш (этакая база данных) – для “других”. Этот процесс каждый запускает для себя (плюс автобилды), а финальная игровая дата в P4 не хранится.
    2.2) Тул может быть запущен в специальном режиме – тогда подхватывает новоизменённые арт файлы, упдайтит что надо и оповещает рантайм для перезагрузки.
    3) Синхронна, хиерархическая, пути абсолютные. Паки есть, но они не влияют на пространство имен – просто метод групировки данных для загрузки. Рантайм, кроме самого слоя загрузки, о паках вообщем незнает. Копии только для ускорения загрузки.

  • http://nesnausk.org ReJ

    Невнятно написал: “Правила экспорта/тансформации/сборки, а также доп. проперти задаются XML файлами” – XML сам правил конечно никаких неописывает, он просто дескриптор арт ассета (тип, зависимости от других ассетов, параметры на выходе) – а что делать с каким ассетом это уже в коде пайплайна прописано.