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

Немного поиска с помощью Google, кажется, указывает, что зомби mspdbsrv.exe являются известной проблемой в VS2005. Мы имели подобные (неустойчивые) проблемы, но там, казалось, не были решением.

Да, это сосет.

22
задан Yuval Adam 21 August 2009 в 18:44
поделиться

13 ответов

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

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

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

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

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

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

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

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

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 . И так далее.

24
ответ дан 29 November 2019 в 03:50
поделиться

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

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

3
ответ дан 29 November 2019 в 03:50
поделиться

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

2
ответ дан 29 November 2019 в 03:50
поделиться

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

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

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

1
ответ дан 29 November 2019 в 03:50
поделиться

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

1
ответ дан 29 November 2019 в 03:50
поделиться

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

Использование 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);

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

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

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

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

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

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

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

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

4
ответ дан 29 November 2019 в 03:50
поделиться

Regarding your basic structure, you may (depending on the nature of your game) want to consider driving toward convergence of representation between player character and non-player characters, so that code that would naturally operate the same on either doesn't have to worry about the distinction. This would suggest, instead of having user and monster tables, having a character table that represents everything PCs and NPCs have in common, and then a user table for information unique to PCs and/or user accounts. The user table would have a character_id foreign key, and you could tell a player character row by the fact that a user row exists corresponding to it.

For representing quests in a model like yours, the way I would do it would look like:

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.

So a quest_model is the core definition of the quest structure; each quest_model can have 0..n associated quest_model_req rows, which are requirements specific to that quest model. Every quest_model_req is associated with a quest_model_req_type, which defines the general type of requirement: achieving a Minimum Level, having a Skill, possessing a piece of Equipment, and so on. The quest_model_req also has a value, which configures the requirement for this specific quest; for example, a Minimum Level type requirement might have a value of 20, meaning you must be at least level 20.

The quest table, then, is individual instances of quests that players are undertaking or have undertaken. The quest is associated with a quest_model and a user (or perhaps character, if you ever want NPCs to be able to do quests!), and has a status indicating where the progress of the quest stands, and whatever other tracking turns out useful.

This is a bare-bones structure that would, of course, have to be built out to accomodate the needs of particular games, but it should illustrate the direction I'd recommend.

Oh, and since someone else threw around their credentials, mine are that I've been a hobbyist game developer on live, public-facing projects for 16 years now.

3
ответ дан 29 November 2019 в 03:50
поделиться

Обновление:

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

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

Исходное сообщение:

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

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

Так что, если бы я был на вашем месте, я мог бы подумать о сохранении информации о моих квестах в 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's 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>
12
ответ дан 29 November 2019 в 03:50
поделиться

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

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

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

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

(идентификатор базового объекта) в качестве столбца в таблице сопоставления подобъектов. Для n: m вы получите три таблицы: «base», «subobjects» и «base_subobjects_map», где карта имеет один столбец для базового идентификатора и один для идентификатора подобъекта. Это может быть необходимо в вашем примере для N квестов, каждый из которых может иметь M требований (так что условия требований могут быть разделены между квестами).

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

(идентификатор базового объекта) в качестве столбца в таблице сопоставления подобъектов. Для n: m вы получите три таблицы: «base», «subobjects» и «base_subobjects_map», где карта имеет один столбец для базового идентификатора и один для идентификатора подобъекта. Это может быть необходимо в вашем примере для N квестов, каждый из которых может иметь M требований (так что условия требований могут быть разделены между квестами).

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

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

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

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

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

5
ответ дан 29 November 2019 в 03:50
поделиться

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

3
ответ дан 29 November 2019 в 03:50
поделиться

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

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

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

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

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

1
ответ дан 29 November 2019 в 03:50
поделиться

I've done something sort of similar and my general solution was to use a lot of meta data. I'm using the term loosely to mean that any time I needed new data to make a given decision(allow a quest, allow using an item etc.) I would create a new attribute. This was basically just a table with an arbitrary number of values and descriptions. Then each character would have a list of these types of attributes.

Ex: List of Kills, Level, Regions visited, etc.

The two things this does to your dev process are:

1) Every time there's an event in the game you need to have a big old switch block that checks all these attribute types to see if something needs updating

2) Everytime you need some data, check all your attribute tables BEFORE you add a new one.

I found this to be a good rapid development strategy for a game that grows organically(not completely planned out on paper ahead of time) - but it's one big limitation is that your past/current content(levels/events etc) will not be compatible with future attributes - i.e. that map won't give you a region badge because there were no region badges when you coded it. This of course requires you to update past content when new attributes are added to the system.

1
ответ дан 29 November 2019 в 03:50
поделиться

только некоторые мелочи на ваше рассмотрение:

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

Часть 1 может можно выполнить, «пытаясь выполнить квесты в иерархическом порядке»:
пример:

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

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

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

2) Незначительное решение вашей проблемы с крафтингом, создание рецептов крафта, Предметы, которые содержат хранящиеся в них требования к крафтингу. .. поэтому, когда игрок пытается создать предмет ... он должен сначала купить рецепт ... а затем попробовать создать ... простой пример такого элемента Desc:
ItemName: «Легендарный меч мертвых»
Craftevel req. : 75
Требуемые элементы:
Предмет_1: Клинок мертвецов
Предмет_2: Проклятая печать
item_3: Святой драгоценный камень мертвых
и т.д ...

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

так что ваша база данных будет иметь только 1 поле (или 2, если вы хотите добавить требование уровня крафта, хотя оно уже будет включено в рецепт.

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

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

1
ответ дан 29 November 2019 в 03:50
поделиться
Другие вопросы по тегам:

Похожие вопросы: