Подтвердить что ты не робот

Проектирование таблиц для хранения различных требований и характеристик для многопользовательской игры

Оригинальный вопрос:

Здравствуйте,

Я создаю очень простой проект для хобби - многопользовательскую игру на основе браузера. Я застрял в разработке таблиц для хранения информации о требованиях к квесту/навыкам.

В настоящее время я разработал таблицы следующим образом:

  • таблица пользователь (основная информация о пользователях)
  • таблица stat (множество характеристик)
  • таблица user_stats (подключение каждого пользователя со статистикой)

Другой пример:

  • таблица монстры (основная информация о врагах npc)
  • table monster_stats (соединение монстров с статистикой, используя ту же таблицу статистики сверху)

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

Аналогичным образом - что является эффективным способом хранения информации о требованиях к навыкам? (определенный класс символов, минимальный уровень и т.д.).

Я был бы признателен за любую помощь или информацию о создании игр, управляемых базой данных.

Изменить:

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

Я хотел бы получать ссылки на статьи/фрагменты кода/все, что связано с передовыми методами проектирования баз данных для хранения игровых данных (хорошим примером такого рода информации является buildingbrowsergames.com).

Буду благодарен за любую помощь.

4b9b3361

Ответ 1

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

Онлайн-игры подразумевают некоторую настойчивость, а это означает, что у вас есть два типа данных - один из них разработан вами, другой создается игроками в процессе игры. Скорее всего, вы собираетесь хранить их в своей базе данных. Удостоверьтесь, что у вас есть разные таблицы для них и перекрестно ссылаются на них с помощью обычных правил нормализации базы данных. (например, если ваш игрок создает большой меч, вы не создаете целую новую строку со всеми свойствами меча. Вы создаете новую строку в таблице player_items со свойствами каждого экземпляра и ссылаетесь на строку широкого слова в таблицу item_types, которая содержит свойства item для каждого элемента.) Если вы обнаружите, что в строке данных содержатся некоторые вещи, которые вы создали, и некоторые вещи, которые игрок меняет во время игры, вам необходимо нормализовать его на две таблицы.

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

Попробуйте найти согласованную терминологию для разделения данных экземпляра из данных типа - это облегчит жизнь позже, когда вы исправляете живую игру и стараетесь не мучить тяжелую работу ваших игроков, редактируя неправильные таблицы. Это также упрощает кэширование - вы можете, как правило, кэшировать данные своего класса/типа безнаказанно, потому что он только когда-либо изменяется, когда вы, разработчик, подталкиваете новые данные там. Вы можете запустить его через memcached или подумать о загрузке всего этого во время запуска, если в вашей игре есть непрерывный процесс (т.е. Нет PHP/ASP/CGI/etc) и т.д.

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

На действительную сторону обработки не может быть дан ответ, не зная, как вы хотите создать свою игру. Дизайн базы данных должен соответствовать дизайну игры. Но я пропущу тривиальную идею. Возможно, вам захочется создать базовый объект, а затем увеличить его рунами или кристаллами или что-то еще. Для этого вам просто нужно отношение "один ко многим" между экземпляром экземпляра экземпляра и экземпляром дополнения. (Помните, что у вас также могут быть типы типов и таблиц типов дополнений.) Каждое увеличение может указывать свойство элемента (например, долговечность, максимальный урон в бою, вес) и модификатор (как правило, как множитель, например, от 1.1 до добавьте 10% бонус). Вы можете увидеть мое объяснение, как реализовать эти модифицирующие эффекты здесь и здесь - те же принципы применяются для временных навыков и заклинаний, применяемых для постоянной модификации предмета.

Для характеристик символов в игре, управляемой базой данных, я бы обычно советовал придерживаться наивного подхода к одному столбцу (целое или плавающее) для статистики. Добавление столбцов позже не является сложной операцией, и поскольку вы собираетесь много читать эти значения, вы, возможно, не захотите постоянно выполнять объединения с ними. Однако, если вам действительно нужна гибкость, тогда ваш метод в порядке. Это сильно напоминает таблицу уровня навыков, которую я предлагаю ниже: множество игровых данных можно смоделировать таким образом - сопоставить класс или экземпляр одной вещи с классом или экземпляром других вещей, часто с некоторыми дополнительными данными для описания отображения (в этот случай, значение статистики).

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

Другие хорошие методы работы с базами данных применимы, конечно, - используйте транзакции, когда вам нужно обеспечить, чтобы несколько действий происходили атомарно (например, торговля), добавляли индексы в наиболее часто встречающиеся поля, использовали VACUUM/OPTIMIZE TABLE/независимо от того, сохранить производительность и т.д.

(Исходный ответ ниже этой точки.)

Если честно, я бы не хранил информацию о запросах квеста в реляционной базе данных, а в каком-то script. В конечном счете, ваша идея "требования" принимает несколько различных форм, которые могут использоваться для разных видов данных (например, уровня, класса, предыдущих квестов, владения предметами) и операторов (уровень может быть минимальным или максимальным, некоторые квесты может потребовать элемент, тогда как другие могут потребовать его отсутствия и т.д.), не говоря уже о сочетании союзов и дизъюнкций (для некоторых квестов требуются все требования, тогда как другие могут требовать только одного из нескольких). Такого рода вещи гораздо легче указать на императивном языке. Это не значит, что у вас нет таблицы квестов в БД, просто вы не пытаетесь кодировать иногда произвольные требования в схему. У меня должен быть столбец require_script_id для ссылки на внешний script. Полагаю, вы могли бы поместить фактический script в БД в текстовое поле, если оно тоже подходит.

Требования к навыкам подходят для БД, хотя и довольно тривиальны, учитывая типичную игровую систему навыков обучения по мере продвижения по уровням в определенном классе:

table skill_levels
{
    int skill_id FOREIGN KEY;
    int class_id FOREIGN KEY;
    int min_level;
}

myPotentialSkillList = SELECT * FROM skill_levels INNER JOIN
    skill ON skill_levels.skill_id = skill.id
    WHERE class_id = my_skill
    ORDER BY skill_levels.min_level ASC;

Нужно ли дерево навыков? Добавьте столбец prerequisite_skill_id. И так далее.

Ответ 2

Update:

Судя по комментариям, похоже, что у многих людей есть проблема с XML. Я знаю, что это круто для bash сейчас, и у него есть свои проблемы, но в этом случае я думаю, что это работает. Одна из других причин, по которой я его выбрал, состоит в том, что для ее синтаксического анализа имеется тонна библиотек, что облегчит жизнь.

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

Оригинальное сообщение:

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

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

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

Сводка: вы можете придумать свою собственную схему, создать свой XML файл и затем загрузить его во время выполнения (или даже сохранить XML в базе данных).

Пример XML:

<quests>
    <quest name="Return Ring to Mordor">
        <characterReqs>
            <level>60</level>
            <finishedQuests>
                <quest name="Get Double Cheeseburger" />
                <quest name="Go to Vegas for the Weekend" />
            </finishedQuests>
            <skills>
                <skill name="nunchuks" />
                <skill name="plundering" />
            </skills>
            <items>
                <item name="genie lamp" />
                <item name="noise cancelling headphones for robin williams' voice />
            </items>
        </characterReqs>
        <steps>
            <step number="1">Get to Mordor</step>
            <step number="2">Throw Ring into Lava</step>
            <step number="3">...</step>
            <step number="4">Profit</step>
        </steps>
    </quest>
</quests>

Ответ 3

Похоже, вы готовы к общим принципам объектно-ориентированного дизайна (OOD). Я намеренно игнорирую контекст (игры, MMO и т.д.), Потому что на самом деле не имеет значения, как вы выполняете процесс проектирования. И мне, давая вам ссылки, менее полезно, чем объяснять, какие условия будут наиболее полезными для поиска себя, ИМО; Я поставлю их жирным шрифтом.

В OOD база данных схема поступает непосредственно из вашей системы дизайн, а не наоборот. Ваш дизайн расскажет вам, что ваши классы базовых объектов и какие свойства могут жить в одной и той же таблице (те, что в 1:1 отношение с объектом), в отличие от того, чтобы создавать таблицы сопоставления (что-либо с 1: n или n: m - для exmaple, один пользователь имеет несколько характеристик, поэтому он 1: n). Фактически, если вы правильно выполняете OOD, у вас будет нулевое решение относительно окончательной компоновки БД.

"Правильный" способ делать любое сопоставление OO изучается как многоэтапный процесс, называемый "Нормализация базы данных" . Основы которого так же описаны: найдите "arity" объектных отношений (1:1, 1: n,...) и сделайте таблицы отображения для 1: n и n: m. Для 1: n вы получаете две таблицы: "базовая" таблица и таблица "base_subobjects" (например, ваши "пользователи" и "user_stats" - хороший пример) с "внешним ключом" (идентификатор базового объекта) в качестве столбца в таблице сопоставления подобъектов. Для n: m вы получаете три таблицы: "base", "subobjects" и "base_subobjects_map", где карта имеет один столбец для базового идентификатора и один для подобъекта Id. Это может потребоваться в вашем примере для N квестов, каждый из которых может иметь M-требования (поэтому условия требования могут быть разделены между квестами).

Это 85% того, что вам нужно знать. Остальное - как обрабатывать наследование, о котором я советую вам просто пропустить, если вы не мазохист. Теперь просто подумайте, как вы хотите, чтобы он работал, прежде чем начинать кодирование, а остальное - торт.

Ответ 4

Нить в @Shea Daniel answer находится на правильном пути: спецификация квеста нереляционная, а также включает логика, а также данные.

Использование XML или Lua - примеры, но более общая идея заключается в разработке собственного Доменного языка для кодирования квестов. Вот несколько статей об этой концепции, связанных с дизайном игры:

Вы можете сохранить блок кода для заданного квеста в поле TEXT в своей базе данных, но у вас не будет большой гибкости при использовании SQL для запроса определенных его частей. Например, учитывая навыки, которыми обладает персонаж, квесты которого открыты для него? Это будет непросто запросить в SQL, если требования к поисковому запросу закодированы в вашей DSL в поле TEXT.

Вы можете попытаться закодировать отдельные предпосылки реляционным образом, но он быстро выходит из-под контроля. Реляционные и объектно-ориентированные просто не сочетаются друг с другом. Вы можете попытаться смоделировать его следующим образом:

Chars <--- CharAttributes --> AllAttributes <-- QuestPrereqs --> Quests

И затем выполните LEFT JOIN поиск любых квестов, для которых в атрибутах символов отсутствуют предварительные условия. Здесь псевдокод:

SELECT quest_id
FROM QuestPrereqs
 JOIN AllAttributes
 LEFT JOIN CharAttributes
GROUP BY quest_id
HAVING COUNT(AllAttributes) = COUNT(CharAttributes);

Но проблема заключается в том, что теперь вам нужно смоделировать каждый аспект вашего персонажа, который может быть предварительным условием (статистика, навыки, уровень, владения, завершенные квесты) в качестве абстрактного "атрибута", который вписывается в эту структуру,

Это решает эту проблему отслеживания предварительных требований к поиску, но это оставляет вам другую проблему: персонаж моделируется не реляционным способом, по существу, архитектурой Entity-Attribute-Value, которая разбивает кучу реляционных правил и создает другие типы запросов невероятно сложно.

Ответ 5

Не имеет прямого отношения к дизайну вашей базы данных, но аналогичный вопрос был задан несколько недель назад о примерах диаграмм классов для RPG

Я уверен, что вы можете найти там что-то полезное:)

Ответ 6

Что касается вашей базовой структуры, вы можете (в зависимости от характера вашей игры) хотеть рассмотреть стремление к конвергенции представления между персонажем игрока и персонажами, не являющимися игроками, так что код, который, естественно, будет работать одинаково на любом из них, приходится беспокоиться о различии. Это предполагает, что вместо таблиц user и monster, имеющих таблицу character, которая представляет все ПК и NPC, имеет общую таблицу, а затем таблицу user для информации, уникальную для ПК и/или учетных записей пользователей. Таблица user имела бы внешний ключ character_id, и вы могли бы указать строку символа игрока тем, что существует строка user, соответствующая ей.

Для представления квестов в модели, подобной вашей, способ, которым я бы это сделал, будет выглядеть так:

quest_model
===============
id
name ['Quest for the Holy Grail', 'You Killed My Father', etc.]
etc.

quest_model_req_type
===============
id
name ['Minimum Level', 'Skill', 'Equipment', etc.]
etc.

quest_model_req
===============
id
quest_id
quest_model_req_type_id
value [10 (for Minimum Level), 'Horseback Riding' (for Skill), etc.]

quest
===============
id
quest_model_id
user_id
status
etc.

Итак, quest_model - это основное определение структуры квеста; каждый quest_model может содержать 0..n связанных строк quest_model_req, которые являются требованиями, характерными для этой модели квеста. Каждый quest_model_req связан с quest_model_req_type, который определяет общий тип требования: достижение минимального уровня, наличие навыка, обладание единиц оборудования и т.д. quest_model_req также имеет value, который настраивает требование для этого конкретного квеста; например, требование типа минимального уровня может иметь value из 20, то есть вы должны быть как минимум на уровне 20.

Таким образом, таблица quest - это отдельные экземпляры квестов, которые игроки предпринимают или предпринимают. quest связан с quest_model и a user (или, возможно, character, если вы когда-либо захотите, чтобы NPC могли выполнять квесты!) И имеет status, указывающий, где прогресс квеста стенды, и любое другое отслеживание оказывается полезным.

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

О, и, поскольку кто-то еще бросил свои верительные грамоты, я утверждаю, что я был разработчиком игр для хобби в живом, публичном проекте в течение 16 лет.

Ответ 7

Я бы очень осторожно относился к тому, что вы на самом деле храните в БД, особенно для MMORPG. Имейте в виду, что эти вещи предназначены для того, чтобы быть МАССИВНЫМИ с тысячами пользователей, а игровой код должен выполняться чрезмерно быстро и отправлять множество данных по сети не только игрокам на своих домашних подключениях, но и между серверами на back-end. В конце концов, вам также придется масштабировать, а базы данных и масштабирование - это не две вещи, которые я чувствую, особенно хорошо, особенно когда вы начинаете окутываться в разные регионы, а затем добавляете серверы экземпляров в свои осколки и т.д. Вы получаете множество серверов, которые разговаривают с базами данных и передают много данных, некоторые из которых даже не имеют отношения к игре (текст SQL, идущий на SQL-сервер, является бесполезным сетевым трафиком, который вы должны сократить).

Вот предложение: Ограничьте базу данных SQL для хранения только тех вещей, которые будут меняться, когда игроки будут играть в игру. Монстры и статистика монстров не изменятся. Статистика предметов и предметов не изменится. Цели квеста не изменятся. Не храните эти вещи в базе данных SQL, а вместо этого храните их в коде.

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

Сделайте то же самое для статистики монстров и статистики предметов. Эти вещи не меняются во время игры, поэтому нет необходимости держать их в БД вообще, и поэтому эта информация НИКОГДА не должна путешествовать по сети. Единственное, что вы храните, это идентификатор предметов или убийств монстров или что-то вроде того, что не является детерминированным (т.е. Оно может меняться во время игры так, как вы не можете предсказать). У вас могут быть выделенные серверы элементов или серверы статистики монстров или что-то в этом роде, и вы можете добавить их к своим осколкам, если у вас будет огромное количество этих вещей, которые занимают слишком много памяти, а затем просто передают данные, необходимые для конкретного квеста или на сервер экземпляра, который обрабатывает эту вещь, чтобы сократить пространство в пространстве, но имейте в виду, что это увеличит объем данных, необходимых для передачи сети, чтобы развернуть новый сервер экземпляров, чтобы это было компромиссным. Пока вы осознаете последствия этого компромисса, вы можете использовать здравый смысл и решить, что вы хотите сделать. Другая возможность заключается в том, чтобы ограничить серверы экземпляров конкретным квером/регионом/событием/всем и только оснастить его достаточной информацией для того, на что он несет ответственность, но это более сложно и потенциально ограничивает масштабирование, поскольку распределение ресурсов станет статичным, а не динамический (если у вас 50 серверов каждого квеста, и внезапно все идут по одному квесту, у вас будет 49 бездействующих серверов и один действительно затопленный сервер). Опять же, это компромисс, поэтому убедитесь, что вы его понимаете и делаете правильный выбор для своего приложения.

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

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

Теперь для представления квестов в коде я бы рассмотрел шаблон спецификации (http://en.wikipedia.org/wiki/Specification_pattern). Это позволит вам легко создавать цели квеста с точки зрения того, какие события необходимы для обеспечения выполнения спецификации для выполнения этого квеста. Затем вы можете использовать LUA (или что-то еще), чтобы определить свои квесты, когда вы строите игру, чтобы вам не приходилось делать массовые изменения кода и переделывать всю проклятую вещь, чтобы сделать так, что вам нужно убить 11 монстров вместо 10 чтобы получить Меч 1000 истин в конкретном квете. Как на самом деле делать что-то подобное, я думаю, выходит за рамки этого ответа и начинает поражать мои знания в программировании игр, поэтому, возможно, кто-то еще здесь поможет вам, если вы решите пойти по этому маршруту.

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

Изменить: не заметил вашего добавления о пригодных к использованию предметах. Я собираюсь предположить, что это вещи, которые игрок может создать специально в игре, например, пользовательские элементы. Если игрок может постоянно изменять эти элементы, вы можете просто комбинировать атрибуты того, что они создаются, как во время выполнения, но вам нужно будет хранить идентификатор каждого атрибута в БД где-нибудь. Если вы делаете конечное число вещей, которые вы можете добавить (например, драгоценные камни в Diablo II), вы можете исключить объединение, просто добавив это число столбцов в таблицу. Если есть конечное количество элементов, которые можно создать, и конечное число способов, с помощью которых вещи differnet могут быть объединены в новые элементы, тогда, когда определенные элементы объединены, вам не нужно сохранять комбинированные атрибуты; он просто становится новым элементом, который уже определен вами в какой-то момент. Тогда они просто имеют этот элемент вместо своих компонентов. Если вы уточните поведение вашей игры, я могу добавить дополнительные предложения, если это будет полезно.

Ответ 8

Я бы приблизился к этому с объектно-ориентированной точки зрения, а не с точки зрения данных. Похоже, что у вас может быть довольно много (возможно сложных) объектов - я бы рекомендовал сначала их смоделировать (со своими отношениями) и полагаться на ORM для сохранения.

Ответ 9

Когда у вас есть проблема с данными, база данных - ваш друг. То, что вы сделали до сих пор, кажется совершенно правильным.

С другой стороны, другие проблемы, о которых вы говорите, по-видимому, ориентированы на поведение. В этом случае объектно-ориентированный анализ и решение будут работать лучше.

Например: Создайте класс квеста с дочерними классами specificQuest. Каждый ребенок должен реализовать метод bool HasRequirements(Player player).

Ответ 10

Другой вариант - это какой-то механизм правил (Drools, например, если вы используете Java).

Ответ 11

Если я создавал базу данных для такой ситуации, я мог бы сделать что-то вроде этого:

Quest
    [quest properties like name and description]
    reqItemsID
    reqSkillsID
    reqPlayerTypesID
RequiredItems
    ID
    item
RequiredSkills
    ID
    skill
RequiredPlayerTypes
    ID
    type

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

Еще одна вещь, которую нужно иметь в виду - нормализация. Там длинная статья здесь, но я сконцентрировал первые три уровня на следующих более или менее:

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

[Отказ от ответственности: у меня очень мало опыта работы с базами данных SQL, и я новичок в этом поле. Я просто надеюсь, что помогу.]

Ответ 12

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

Ex: список убийств, уровень, посещаемые регионы и т.д.

Две вещи, которые это делает для вашего процесса dev:

1) Каждый раз, когда у вас есть событие в игре, вам нужно иметь большой старый блок переключателей, который проверяет все эти типы атрибутов, чтобы увидеть, нужно ли что-то обновлять

2) Каждый раз, когда вам нужны данные, проверьте все таблицы атрибутов перед добавлением нового.

Я нашел, что это хорошая стратегия быстрого развития для игры, которая органично развивается (не полностью запланированная на бумаге раньше времени), но одно большое ограничение заключается в том, что ваше прошлое/текущее содержание (уровни/события и т.д.) будет не совместимы с будущими атрибутами, т.е. эта карта не даст вам значок региона, потому что не было никаких региональных значков, когда вы его закодировали. Это, конечно, требует обновления прошлого содержимого при добавлении новых атрибутов в систему.

Ответ 13

просто несколько соображений для вашего рассмотрения:

1) Всегда старайтесь, чтобы ваши требования "получить квест" были простыми.. и сложности "Готово квест" были сложными..

Часть 1 может быть выполнена с помощью "попытки сделать ваши квесты в иерархическом порядке":
Пример:

QuestA: (Убейте ворона демона) (quest req: Lvl1)
 QuestA.1: сохраните "unkown" в лесу, чтобы получить некоторую информацию.. (quest req: QuestA)
 QuestA.2: Создайте меч Кристалла... и т.д. (Quest req: QuestA.1 == Done)
 QuestA.3:... и т.д. (Quest req: QuestA.2 == Done)
 QuestA.4:... и т.д. (Quest req: QuestA.3 == Done)
и т.д.
 QuestB (Найдите потерянную гробницу) (quest req: (QuestA.statues == Done))
 QuestC (Go To the demons Hypermarket) (Quest req: (QuestA.statues == Done & player.level == 10)
и т.д....

Это позволит вам сэкономить много полей данных/суставов таблиц.

ДОПОЛНИТЕЛЬНЫЕ МЫСЛИ:
если вы используете указанную выше систему, вы можете добавить дополнительное поле вознаграждения в таблицу квейских квестов под названием "enableQuests" и добавить имя квестов, которые необходимо включить..
Логично.. у вас будет поле "включено", назначенное каждому квесту.

2) Небольшое решение для вашей проблемы с обработкой, создайте рецепты рецептов, элементы, которые содержат в себе необходимые навыки создания предметов. поэтому, когда игрок пытается создать предмет... ему нужно купить рецепт 1-го... затем попробуйте крафтинг.. простым примером такого деталя Desc было бы:
ItemName: "Легендарный меч мертвых"
Craftevel req.: 75
Необходимые предметы:
Item_1: Лезвие мертвых
Item_2: проклятая печать
item_3: Святой драгоценный камень мертвых
и т.д...

и когда он нажимает действие "craft", вы можете разобрать его и сравнить с его инвентарем/ящиком...

поэтому у вашей Crafting DB будет только 1 поле (или 2, если вы хотите добавить обработчик LvL req., хотя он уже будет включен в рецепт.

ДОПОЛНИТЕЛЬНЫЕ МЫСЛИ:
Такие элементы могут быть сохранены в формате xml в таблице. Это упростит анализ...

3) Подобная система XML может быть применена к вашей системе квестов.. для выполнения требований к завершению квеста.