Стоит ли реализовывать игровую механику / правила отдельно от основного кода?

25

Не уверен, подходит ли он для данного сообщества, или вместо этого следует перейти в Stackoverflow.

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

Я думал о том, возможно ли / возможно ли реализовать механику игры отдельно от основного кода утилиты? Я имею в виду, что для настольных игр у нас есть те книги правил, которые не содержат реальных алгоритмов всех действий, а скорее описывают некоторые протоколы и ограничения, ссылаясь на контекст каждого такого элемента. Можно ли сделать что-то подобное для компьютерной игры, например, описать все правила на каком-то очень высоком уровне, легко читаемом (и изменяемом) человеческим языком программирования, который затем «потребляется» и анализируется утилитарным кодом в рабочий экземпляр игровой механики?

Похоже, мне нужно написать свой собственный язык и компилятор для него)) Что я, конечно, не смогу сделать. Но может быть, есть более легкий подход к проблеме?

К вашему сведению: моим языком выбора для кода утилиты будет Python 3.x

тИС
источник
Поскольку вы неопытны и работаете как один разработчик, я предлагаю вам не пытаться реализовать все самостоятельно. Использование библиотек SDL2 может быть очень полезным для вас во многих областях, и они имеют привязки Python, поэтому вы можете работать на языке, который вам удобен. Чтобы достичь того, к чему вы стремитесь, дизайн вашей архитектуры должен быть выполнен очень, очень, тщательно, и я бы ожидал хотя бы одного полного переписывания даже для опытной команды. Кроме того, Python на самом деле не намного легче выучить, чем любой другой язык, и, по моему мнению, имеет серьезные недостатки на промежуточном уровне.
ttbek
Концепция, которую вы ищете, распространена за пределами игровой разработки. Существует набор программных инструментов, называемых механизмами бизнес-правил, которые должны делать именно это. В игре Dev, вы также можете использовать эти инструменты. Например, GameplayKit от Apple включал классы GKRuleSystem и GKRule для аналогичной цели. Расширение потребовало бы некоторых усилий, чтобы разрешить это внешнее редактирование, но могло бы быть структурировано таким образом, чтобы изменить поведение без перекомпиляции вашего кода.
Сэнди Чепмен

Ответы:

34

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

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

Наиболее близкие из известных мне вещей - это Vassal (который гораздо более программный, чем вы описали), или создание мода для Tabletop Simulator (который в основном зависит от взаимодействия человека с целью интерпретации и обеспечения соблюдения любых правил игры).

Pikalek
источник
Твердый совет. Я стараюсь сохранить свой код как можно более слабым, чтобы облегчить расширяемость, но у вас всегда будут случаи, когда намного проще что-то жестко закодировать / связать. Даже как профессиональный разработчик не легкая задача, и определенно не новичок дружелюбный.
angarg12
В настоящее время TTS поддерживает Lua, и принудительные правила теперь не полностью зависят от взаимодействия с человеком.
Аве
17

Я думал о том, возможно ли / возможно ли реализовать механику игры отдельно от основного кода утилиты?

Это абсолютно возможно. В играх часто используется сценарий Lua .

Из связанной статьи:

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

Многие игры используют Lua. (Я бы сделал ссылку, но репутация нового пользователя ограничивает количество ссылок.)

Скрипты Lua могут быть скомпилированы во время выполнения. Это означает, что они могут (например) быть текстовыми файлами, находящимися в папке «scripts» вашей игры, легко редактируемыми моддером. Ваша игра загружает их и запускает их.

Я видел, как скрипты Lua определяют свойства игровых юнитов. Вот случайный пример из TA Spring.

Но вы хотите «описать все правила». В теории это возможно, поскольку Lua - полноценный язык, но проблема в том, что вам нужно быть достаточно проницательным, чтобы основной код игры знал, что нужно искать скрипты для расширения его поведения.

Например, вы можете разработать карточную игру, которая умеет искать карты в каталоге «scripts / cards». Это отлично подходит для добавления новых карт или редактирования существующих. Но если вы позже захотите расширить свою игру, включив в нее миниатюры на сетке, вам придется редактировать основной код - никакие излишества Lua не приведут вас туда самостоятельно.

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

Nichevo
источник
7
Этот ответ подразумевает, что Lua - единственный язык сценариев, используемый таким образом. Есть много других скриптовых языков, которые могут быть встроены в игровые движки. Некоторые движки также идут своим путем и реализуют свой собственный предметно-ориентированный язык сценариев. Я обычно не рекомендую это (потому что создание языка - это тонна работы), но это следует упомянуть.
Филипп
3

Существует целый ряд подходов, и от того, что вы пытаетесь делать, будет зависеть, стоит ли какой-то конкретный из них того или иного. В частности, какой контроль вы хотите предложить твикеру?

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

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

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

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

Ryan1729
источник
Сделать это с открытым исходным кодом - моя цель, на самом деле. Проблема в том, как реализовать эту расширяемость наиболее простым способом, чтобы другие игроки в игре (например, MP game, btw) могли создавать свои собственные расширения базового набора правил и делиться ими с каждым из них. другое, как-то избегая конфликтов одновременно. Итак, если один пользователь разрабатывает какое-либо расширение, переопределяющее определенные правила, а другой разрабатывает другое расширение, как обеспечить, чтобы у третьего пользователя, который хочет использовать оба из них в своих играх, не возникало проблем с совместимостью? Помимо принуждения к тесному сотрудничеству.
тис
... и реализовать его таким образом, чтобы не потребовалось изменение какого-либо служебного кода и, следовательно, слишком много знаний о программировании.
тис
1
Я не думаю, что был бы способ предотвратить проблемы с совместимостью (даже установка цвета чего-либо может вызвать это!) Я думаю, что лучше всего было бы иметь способ обнаруживать возможные проблемы совместимости и иметь хороший способ для пользователей ответить. В зависимости от дизайна интерфейса кода утилиты и рассматриваемых расширений может существовать способ заказа обратных вызовов и т. Д., Который дает желаемый результат. Опять же, не может быть. Оповещение пользователя о том, что могут быть проблемы, и почему кажется, что пользовательский опыт лучше, чем вещи, которые ломаются без объяснения причин.
Ryan1729
2

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

Стоит ли это того, зависит от сложности системы. Как будто я не стал бы беспокоиться о Pac-Man, но я не мог представить, как написать Dwarf Fortress каким-либо другим способом.

Robyn
источник
Спасибо, @Robyn. Любой совет по чтению для тех, кто не знает, как правильно подходить к этой конструкции? Существуют ли какие-то устоявшиеся шаблоны проектирования для таких приложений? Какие-нибудь книги, которые охватывают предмет?
тис
Нет книг, извините. Но основная идея простого движка правил: создать класс Rule, у которого есть свойство для каждой части информации, которая необходима для описания правила. Если некоторые из этих свойств содержат лямбда-функции, вы можете назначить им сложные варианты поведения. Создайте класс, который создает список правил, чтобы все ваши правила были в одном месте. Создайте другой класс, у которого есть метод, который принимает список правил в качестве входных данных и применяет их к системе.
Robyn
2

Это определенно возможно. Если оно того стоит, зависит от ваших целей.

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

Если вы хотите, чтобы ваша игра была легко расширяемой, возможно, это хорошая идея.

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

Одной из игр, которая делает это, является Rimworld (у меня нет аффилированности), и вы, возможно, сможете увидеть и поучиться из того, как они это сделали, в основном поместив много игровых данных и механики в XML-файлы, которые находятся в папках игры, чтобы каждый мог их увидеть и изменить. Ядро / движок игры было сделано с использованием Unity.

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

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

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

user985366
источник
Хотя я вижу, как игровые данные могут быть определены с помощью xml, я не представляю, как вы можете использовать их для определения игровой механики / правил. Не могли бы вы привести пример / статью по теме?
тис
Правила @tis - это просто другой тип данных. Если в моем движке есть «Если A до B», я могу загрузить A и B из XML-файла, теперь пользователи могут устанавливать довольно произвольные правила, один дополнительный бит, который может помочь, - это предоставление списка всех возможных As и B, которые вы поддерживаете сами по себе. Например, «Если статус статического типа затем перемещает скорость 100», «Если статус статуса и время> x, то статус статуса» Так что в своем проекте подумайте, какие типы правил вы хотите разрешить для каких типов объектов (статус, время, скорость движения) и с какими видами композиций разрешить (и / или, и т.д ...). Если статус подводный и время> 5 здоровья -10.
ttbek
1

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

Об этом написаны толстые книги, которые могут быть страшными, когда вы новичок, но основные принципы довольно просты.

Главное, что вы определяете, с какими объектами вы работаете. Вы не говорите, о какой игре вы думаете, но такие вещи, как игрок, монстр, предмет, снаряжение, оружие, броня и т. Д. Являются типичными объектами.

Если вам нужны разные типы игр, вам, вероятно, понадобится объект Game, который заботится о состоянии победы и тому подобное. Возможно, объект Map тоже?

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

Подклассы: и оружие, и доспехи являются снаряжением. Оборудование - это предметы. Есть, вероятно, другие типы предметов. Возможно, вам будет полезно определить класс Combatant, в котором оба игрока и монстры являются подклассами.

Идея состоит в том, что, например, у Оружия будет много общего со всеми другими типами Предметов, они имеют вес, размер и другие подобные свойства.

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

Подклассы также позволяют вашим создателям модов сказать: «Мой новый тип оружия похож на стандартное оружие, за исключением того, что ...»

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

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

Например:

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

Оба бойца могут иметь такие навыки, как критический удар и уклонение.

Теперь, какой объект за что отвечает?

Существует не один правильный ответ на это. Многое зависит от того, какую настройку вы хотите разрешить.

Если вы никогда не вызываете объект (например, карту), этот объект никак не может изменить атаку.

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

Удачи!

Стиг Хеммер
источник
Ваш вклад действительно ценится, и вы приложили немало усилий, так что он определенно стоит +1, но я случайно знаю об ООП в целом (хотя и не обладаю достаточным опытом). Мои текущие проблемы связаны с наиболее общим подходом к проектированию, который я должен использовать. Моя игра не такая масштабная, как D & D, но тем не менее, она ОЧЕНЬ глубока в своей механике. Это означает много сложных, смешанных на разных уровнях правил. Что я хотел бы позволить пользователям значительно расширить, а не только немного подправить некоторые значения. Это может быть не простое решение, на самом деле ..
тис
@tis Ключом к этому является принятие правильного решения о том, что на самом деле являются объектами в вашей ОО-модели игры. «Очевидное» место для начала - использование «существительных», таких как оружие, доспехи и т. Д., Не единственный способ, и это может привести к запутанному беспорядку ненастраиваемого кода. Если правило гласит: «Вы только в полночь стреляете в монстра серебряными пулями на церковном дворе», где вы применяете это правило в кодексе? В классе Gun (или Bullet), в классе Monster, в классе Fighter пользователя, использующего оружие, в классе Churchyard или в классе Time? Лучшим ответом может быть «ничего из вышеперечисленного» ...
alephzero
... и переосмыслить весь дизайн с точки зрения класса Rules (который, вероятно, действительно является базой данных) и класса разрешения конфликтов. Теперь другие правила, такие как «если у вас нет пуль, вы все равно можете использовать свое оружие как дубину» и «если Алиса разыгрывает заклинание, которое частично (но не полностью) защищает Боба от пулевых ранений, пока Чарли пытается застрелить Боба, затем .... "есть единственное и" очевидное "место для реализации в коде. Вы можете обнаружить, что ваш оригинальный класс Gun сейчас очень мало делает, за исключением создания некоторых аудио-визуальных эффектов - и даже не это, если это текстовая игра!
Алефзеро
1

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

Например, вы упомянули настольные игры; если у вас была игра, основанная на D & D, у вас мог бы быть weapon_damageфайл, содержащий такие строки, как Battleaxe: 1d12. Ваш служебный код будет читать этот файл и всякий раз, когда Battleaxeваш код наносит ущерб, будет generate a number from 1-12, 1 time(s)добавлять их. Настроить строку для чтения Battleaxe: 4d6будет вместо этого generate a number from 1-6, 4 time(s)и добавить их. Точно так же у вас может быть папка, Creaturesа внутри у вас есть файл для каждого существа, включая строки вроде AC: 12; затем добавление новых файлов в эту папку создаст новых существ. Это может быть сделано даже для классов персонажей, типов местности, множества вещей.

Этот стиль настройки без кода все еще может быть очень мощным и охватывать многие части вашей игры. Однако это не позволяет пользователю вносить изменения, которые вы не указали явно. Например, вы можете разрешить Sneak Attack: [damage]давать любому существу или классу возможность добавлять [damage]к любой атаке, которая соответствует условиям для скрытой атаки. Вы могли бы даже предоставить способы изменить условия, такие как «всякий раз, когда вы атакуете из невидимости» или «когда вы фланкируете» или «когда у вас есть преимущество». Тем не менее, если пользователь решает, что он хочет скрытую атаку, то «Когда вы делаете бросок атаки, вы также можете бросать скрытность против восприятия цели. Если оба броска успешны, то добавьте урон Sneak Attack»

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

Камил Дракари
источник
Да, мне нужно разрешить им добавлять новую механику, просто изменить некоторые значения не получится. Я также подумал, что для этого может потребоваться отдельный язык, я просто подумал, что, возможно, уже есть тот, который я могу использовать в своем служебном коде Python.
тис
@tis Вы уже рассмотрели, что Википедия имеет по этой теме? en.wikipedia.org/wiki/Logic_programming
ttbek
0

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

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

И при разработке API мое любимое руководство - создавать язык, на котором вы хотите выразить свой код более высокого уровня (конечно, с учетом синтаксических ограничений вашего языка программирования).

Таким образом, хорошим подходом было бы написать некоторые гипотетические правила и механизмы именно так, как вы хотите, чтобы они были выражены (конечно, с использованием синтаксиса Python), таким образом выясняя, что вы хотите, чтобы основной API предоставил правилам и механике. слои.

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

Ральф Клеберхофф
источник