Как я могу обрабатывать изменения версий при сохранении ресурсов?

9

Я уже некоторое время работаю над RPG и использую два различных метода сериализации.

  • Враги, оружие, предметы сохраняются как XML.
  • Карты и события сохраняются как «контролируемые двоичные файлы» (каждый класс получает метод сохранения / загрузки, и они решают, что они хотят сохранить / загрузить).

Но я начал подвергать сомнению мой выбор для карт и событий. Мои опасения:

  • Я создал редактор карт, но мне все еще не хватает возможности изменить мелочи, просто открыв файл.
  • Изменения так запутались. Скажем, я хочу добавить переменную в класс, если я не загружаю / не сохраняю каждую карту снова, она ломается позже.

Первое беспокойство трудно обойти без изменения моей техники. Я думал о переходе на JSON, но это много работы. Я также думаю, что это выглядит довольно некрасиво с атрибутами [DataContract] и [DataMember] везде.

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

user1776562
источник

Ответы:

5

Есть много способов справиться с проблемой управления версиями; Вы можете сделать это, имея одну функцию загрузки для каждой версии, вы можете попытаться автоматизировать процесс, описав (через атрибуты обычно) преобразование структуры активов с течением времени, вы можете выполнить специфичные для версии проверки внутри функций загрузки / сохранения и т. д. ,

Мне нравится подход «описать изменения», но я считаю, что попытка сделать это с помощью атрибутов быстро становится неловкой . Я бы использовал функции вместо этого; реализовать функцию, которая преобразует данные в версии Nв данные в версии N + 1для всех ваших соответствующих версий. При загрузке сверяйте версию с последней и, если это не так, пропустите данные через все соответствующие функции управления версиями. Всегда сохраняйте последнюю версию.

Это работает лучше всего, если вы выполняете преобразование, когда данные все еще находятся в форме значения ключа времени выполнения. Это означает, что вы, вероятно, захотите реализовать представление для ваших данных, которое представляет собой подход «мешок свойств среды выполнения», потому что вы не можете использовать базовую форму значения ключа JSON или XML, если у вас есть собственный двоичный формат. Если вы этого не сделаете, вам также может понадобиться сохранить старые определения классов, что выглядит ужасно. Возможность иметь свои активы в этом плохом формате также очень полезна для разработки редактора игр.

Во время разработки, когда вы выполняете итерацию ваших данных, они естественно всплывают до последней версии, и вы можете в конечном итоге удалить старые функции контроля версий. Это более или менее тот же высокоуровневый подход, который мы использовали для создания версий художественных ресурсов (таких как карты) в Guild Wars 2.


Теперь, после всего сказанного, я думаю, что полезно поддерживать как текстовую, так и двоичную сериализацию для ресурсов. Во время разработки сохраняйте все свои данные в удобочитаемом формате на основе XML или JSON. Это может значительно увеличить вашу итерационную способность, потому что вам не нужно создавать такие сложные инструменты для редактирования данных. Вы можете вернуться к возможности делать простые быстрые настройки вручную.

Во-вторых, предполагая, что вам все еще нужен двоичный формат для доставки игры (который может улучшить размер файла или время ввода-вывода, так что это действительно допустимо), разработайте API-интерфейсы сериализации и десериализации для управления версиями. Versioning это еще полезно в контексте доставки, потому что , как какой - то момент вы можете обновления судов или исправления ошибок. Есть некоторые документы , описывающие возможности управления версиями .NET сериализации и сериализации Boost в том , что вы можете найти интересные. Если будут идти на поддержку как текст , так и бинарные форматы, убедитесь , что вы проверить их время от времени (или строят автоматизированные тесты , чтобы сделать это, даже лучше).


источник
Спасибо за комментарий, дал мне сом идеи, как продолжить.
user1776562
1

Используйте язык разметки с парами атрибут-значение, такими как XML или JSON.

Парсер может просто игнорировать любые атрибуты, которые он не понимает, или использовать значения по умолчанию для любых, которые он не находит, что делает обратную и прямую совместимость довольно легкой. Кроме того, формат удобен для чтения, поэтому вы можете легко редактировать его в текстовом редакторе.

Когда вы используете установленный язык, такой как XML или JSON, вы также заметите, что многие языки сценариев поддерживают его, поэтому, когда вам все еще нужно написать сценарий для редактирования большого количества файлов, вам будет гораздо проще это сделать.

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

Языки разметки часто не допускают произвольного доступа, если весь документ не будет считан с жесткого диска и проанализирован. Но на практике это не имеет большого значения, потому что жесткие диски быстрее всего с последовательным чтением. Произвольный поиск нескольких раз в разных частях одного и того же файла часто может быть намного медленнее, чем простое чтение файла за один раз, даже если это означает, что вы прочитали больше данных, чем нужно.

Philipp
источник
1

Вы можете использовать protobuf. https://code.google.com/p/protobuf/ Это дает вам преимущества json / xml, которые вы можете легко расширять при совместимости с предыдущими версиями, плюс преимущество того, что вы работаете в двоичном формате. Рабочий процесс заключается в том, что вы создаете описание формата данных на языке protobuf, а затем генерируете исходный код для сериализации и десериализации. Источник может быть создан для нескольких языков. Также большим преимуществом является то, что у вас есть четкая спецификация ваших сериализованных данных, в отличие от json, где спецификация выполняется неявно при чтении / записи.

Arne
источник
Выглядит круто, но я использую c #, это похоже на c ++, python и java.
user1776562
Есть версия на C #. Я не проверял это лично, но есть один.
Арне