У меня есть онлайн-игра, в которой игроки каким-то образом формируют мир, например. Жилье Ultima Online, где вы можете строить свои дома непосредственно на определенных участках карты мира. Это изменения, которые должны сохраниться со временем как часть постоянного мира.
В то же время команда разработчиков добавляет новый контент и вносит поправки в старый контент, чтобы улучшить и расширить игру для новых игроков. Они будут делать это на сервере разработки сначала во время тестирования, а затем должны объединить свою работу с «работой» игроков на живом сервере.
Предполагая, что мы исправляем проблемы с дизайном игры - например. игроки могут строить только в определенных областях, поэтому они никогда не конфликтуют географически с изменениями дизайнера - каковы хорошие способы обработки данных или организации структур данных, чтобы избежать конфликтов, когда новые данные дизайнера объединяются с данными нового игрока?
Пример 1: игрок создает предмет нового типа, и игра назначает ему идентификатор 123456. Все экземпляры этого элемента относятся к 123456. Теперь представьте, что разработчики игр имеют похожую систему, и дизайнер создает новый элемент, также пронумерованный 123456. Как этого можно избежать?
Пример 2: кто-то делает популярный мод, который дает всем вашим драконам французский акцент. Он включает в себя скрипт с новым объектом под названием, assignFrenchAccent
который они используют для назначения новых голосовых ресурсов каждому объекту дракона. Но вы собираетесь развернуть свой DLC «Наполеон против Смауга», у которого есть одноименный объект - как вы можете сделать это без особых проблем с обслуживанием клиентов?
Я подумал о следующих стратегиях:
- Вы можете использовать 2 отдельных файла / каталога / базы данных, но тогда ваши операции чтения значительно усложняются. «Показать все элементы» должен выполнить одно чтение в БД дизайнера и одно чтение в БД плеера (и все равно должен как-то различать 2).
- Вы можете использовать 2 разных пространства имен в одном магазине, например. использование строк в качестве первичного ключа и добавление к ним префикса «DESIGN:» или «PLAYER:», но создание этих пространств имен может быть нетривиальным, а зависимости неясными. (Например. В СУБД вы не сможете эффективно использовать строки в качестве первичных ключей. Вы можете использовать целые числа и распределить все первичные ключи ниже определенного числа, например, 1 миллион, для данных конструктора, а все, что выше этой точки, будет данные игрока. Но эта информация невидима для СУБД, и ссылки на внешние ключи будут пересекать «разрыв», что означает, что все инструменты и сценарии должны явно обходить ее.)
- Вы всегда можете работать с одной и той же общей базой данных в режиме реального времени, но производительность может быть низкой и риск повреждения данных игрока может быть повышен. Это также не распространяется на игры, которые работают на более чем 1 сервере с различными мировыми данными.
- ... есть другие идеи?
Мне приходит в голову, что, хотя это в первую очередь проблема для онлайн-игр, концепции могут применяться и к моддингу, когда сообщество создает моды в то же самое время, когда разработчики исправляют свою игру. Используются ли здесь какие-либо стратегии, чтобы уменьшить вероятность взлома мода при выходе новых патчей?
Я также пометил это как «контроль версий», потому что на одном уровне это то, что это - две ветви разработки данных, которые необходимо объединить. Возможно, некоторые идеи могут прийти с этого направления.
РЕДАКТИРОВАТЬ - некоторые примеры, добавленные выше, чтобы помочь прояснить проблему. Я начинаю думать, что проблема в действительности связана с пространством имен, которое может быть реализовано в магазине с помощью составных ключей. Это упрощает стратегию слияния, по крайней мере. Но могут быть альтернативы, которых я не вижу.
источник
Ответы:
Я думаю, что ответы, предлагающие решения БД, переходят к конкретной реализации без понимания проблемы. Базы данных не облегчают слияния, они просто дают вам основу для хранения ваших данных. Конфликт все еще конфликт, даже если он находится в БД. И проверка - решение проблемы для бедного человека - это будет работать, но с огромными затратами для вашего удобства.
То, что вы здесь говорите, относится к распределенной модели развития проблемы. Я считаю, что первый шаг - не думать об игроках и дизайнерах как об отдельных типах создателей контента. Это устраняет искусственное измерение вашей проблемы, которое не влияет на решение.
По сути, у вас есть основная линия - каноническая версия, утвержденная разработчиком. У вас (возможно) могут быть и другие ветки - живые серверы, на которых люди активно разрабатывают моды и делятся ими. Контент может быть добавлен в любую ветку. Важно отметить, что ваши дизайнеры здесь не являются чем-то особенным - они просто создатели контента, которые живут внутри дома (и вы можете найти их и ударить, когда они облажаются).
Тогда принятие пользовательского контента является стандартной проблемой слияния. Вы должны либо вытянуть их изменения обратно в основную линию, объединить, затем вытолкнуть снова, либо перенести изменения основной линии в их ветвь и объединить (оставив основную линию «чистой» от созданного пользователем материала). Как обычно, тянуть к своей ветке и исправлять это более дружелюбно, чем просить других людей вытащить ваши изменения и затем пытаться исправить это удаленно с их стороны.
Как только вы работаете с моделью такого типа, применяются все обычные процессы предотвращения конфликтов слияния. Некоторые из наиболее очевидных:
источник
Храните все как атрибут (или декоратор) - с точками монтирования. Давайте возьмем дом, который игрок спроектировал в качестве примера:
Таким образом, каждая сущность может иметь одну или несколько точек монтирования - каждая точка монтирования может принимать ноль или более других компонентов. Эти данные будут храниться вместе с версией, в которой они были сохранены, а также с любыми соответствующими свойствами (например, смещением и т. Д. В моем примере). Скорее всего, NoSQL здесь подойдет (Key = Entity ID, Value = Serialized Binary) Данные).
Каждый компонент должен был бы иметь возможность «обновить» старые данные из предыдущей версии (никогда не удалять поля из сериализованных данных - просто «обнулить» их) - это обновление происходит в ту минуту, когда оно загружено (затем оно сразу же сохраняется в доступна последняя версия). Скажем, в нашем доме изменились размеры. Код обновления относительно определит расстояние между северной и южной стенами и пропорционально изменит смещения всех содержащихся объектов. В качестве другого примера у нашей мясной миски может быть удалено поле «Еда», и вместо этого можно получить «Сорт» (мясо) и «Рецепт» (шарики). Сценарий обновления превратит «мясные шарики» в «мясные», «шарики». Каждый компонент должен также знать, что делать с изменениями в точках монтирования - например,
Все это оставляет ровно одну открытую проблему: что произойдет, если два объекта конфликтуют друг с другом (не их контейнер - точки монтирования защищают вас от этого)? После обновления вы должны проверить наличие коллизий и попытаться разрешить их (разводя вещи, как SAT). Если вы не можете понять, как разрешить столкновение, удалите один из объектов и поместите его в тайник - где они могут купить эти удаленные предметы (бесплатно) или продать их (по полной цене); и, очевидно, уведомить игрока, что обновление сломало некоторые из их макета - возможно, с функцией «увеличения», чтобы они могли увидеть проблему.
В конечном итоге вы должны оставить сложные изменения в руках игроков (быстро потерпеть неудачу), так как никакой алгоритм не может объяснить эстетику - вы должны просто иметь возможность дать игроку контекст относительно того, где был элемент (чтобы он мог запомнить, а не просто приземлиться со всеми этими предметами в своем тайнике и не знать, где они были).
источник
Я пытаюсь связать это с чем-то, что я понимаю, поэтому я думаю сейчас о Minecraft. Я представляю живой сервер, где игроки вносят изменения в режиме реального времени, в то время как разработчики работают на тестовом сервере, исправляя / создавая новый контент.
Ваш вопрос почти как 2 уникальных вопроса:
Я бы попробовал решить # 1 через временную систему ссылок. Например, когда кто-то создает новый объект, он может быть помечен как изменчивый или временный. Я полагаю, что весь новый контент, созданный на тестовом сервере, будет помечен как энергозависимый (хотя он также может ссылаться на энергонезависимый контент).
Когда вы будете готовы перенести новый контент на действующий сервер, ваш процесс импорта найдет изменчивые объекты и назначит им идентификаторы объектов живого сервера, которые установлены в камне. Это отличается от прямого импорта / слияния, потому что вы должны иметь возможность ссылаться на существующие энергонезависимые объекты, если вам нужно исправить или обновить их.
Для # 2 кажется, что вам действительно нужен некоторый уровень промежуточной трансмутации скрипта, который может хешировать имя функции в уникальном пространстве имен. т.е.
становится
источник
Если файлы данных являются текстовыми, а не двоичными, и дизайнеры и проигрыватели модифицируют различные области, вы можете попробовать объединить SVN.
источник
Я думаю, что база данных / файловая система, реплицируемая в средах с процедурой «извлечения», была бы лучше
Таким образом, всякий раз, когда дизайнер хочет внести какие-либо изменения в мир, он извлекает / блокирует все активы, которые он хочет создать / изменить, на всех копиях базы данных (разработка и производство), поэтому никакой другой игрок или дизайнер не может изменить его. , Затем он будет работать с базой данных разработки до тех пор, пока не будет завершен новый проект, и тогда изменения будут объединены с производственной базой данных, и эти активы будут зарегистрированы / разблокированы во всех средах.
Редактирование проигрывателя будет работать почти таким же образом, за исключением того, что роли базы данных / файловой системы будут поменяны местами - они работают с производственной базой данных, и все обновления загружаются в dev после завершения.
Блокировка актива может быть ограничена свойствами, в которых вы хотите гарантировать отсутствие конфликтов: в Примере 1 вы заблокируете,
ID 123456
как только игрок начнет его создавать, поэтому разработчикам не будет назначен этот ID. В Примере 2 ваши разработчики заблокировали имя сценарияassignFrenchAccent
во время разработки, поэтому игрок должен был бы выбрать другое имя при разработке своей модификации (эта небольшая неприятность может быть уменьшена пространством имен, но это само по себе не позволит избежать конфликтов, если вы не дадите пользователь / разработчик конкретного пространства имен, и тогда у вас возникнет та же проблема с управлением пространствами имен). Это означает, что вся разработка должна считываться из одной онлайновой базы данных, но все, что вам требуется от этой базы данных в этих примерах, это имена объектов, поэтому производительность не должна быть проблемой.С точки зрения реализации, достаточно иметь единую таблицу со всеми ключами и состоянием активов (доступно, заблокировано из dev, заблокировано из prod), синхронизировано / доступно в реальном времени в разных средах. Более сложное решение будет реализовывать полную систему контроля версий - вы можете использовать существующую систему, такую как CVS или SVN, если все ваши ресурсы находятся в файловой системе.
источник
Я думаю, что дело здесь в том, чтобы четко принять вашу ответственность. 1) Сервер сообщает, что в настоящее время приемлемо, и API для доступа. База данных изменяется в соответствии с определенными правилами. 2) Создателям разрешено создавать контент, но он должен воспроизводиться после обновлений. Это исключительно ваша ответственность: любое обновление должно быть в состоянии анализировать старые структуры данных, желательно как можно более чистыми и простыми.
Идея «Маунт-Пойнт» имеет свои преимущества, если вы заинтересованы в отслеживании уникальных предметов и позиций внутри гибкой структуры, особенно если мы признаем, что вся «домашняя» структура игрока претерпит кардинальные изменения, и вы хотите сохранить это немного деко в своих шкафчиках.
Это очень сложный вопрос, удачи! Там, вероятно, не существует ни одного ответа.
источник
Я не думаю, что это большая проблема, как вы делаете это.
Я бы просто переписал созданные пользователем моды, предупредив, что «Mod X может работать некорректно с этой версией», оставив создателям модов изменить свою работу. Я не думаю, что это нереалистичное ожидание, что обновления могут отключить определенные моды.
То же самое для контента, созданного пользователем, просто сделайте резервную копию и перезаписать.
У меня нет реального опыта в этом, просто вносить предложения.
источник