Загальний аналізатор правил для настільних ігор RPG - як це зробити?


19

Я хочу створити загальний аналізатор правил для систем RPG стилю пером та папером. Правило може включати зазвичай від 1 до N сутностей від 1 до N ролей кістки та обчислення значень на основі декількох атрибутів сутності.

Наприклад:

У гравця STR 18, його озброєна в даний час зброя дає йому бонус +1 STR, але зловживання DEX -1. Він атакує сутність монстра, і тепер логіка гри необхідна для виконання набору правил або дій:

Гравець котить кістки, якщо він отримує, наприклад, 8 або більше (значення базової атаки, яке йому потрібно передати, є одним з його базових атрибутів!), Його атака є успішною. Потім монстр перекочує кістки, щоб обчислити, чи буде атака через броню. Якщо так, шкода буде заподіяна, якщо не атака була заблокована.

Крім простих математичних правил, можуть бути такі обмеження, як застосування лише до певного класу користувача (наприклад, воїн проти майстра) або будь-якого іншого атрибута. Тож це не лише обмежується математичними операціями.

Якщо ви знайомі з такими RPG-системами, як Dungeon та Dragons, ви дізнаєтесь, що я роблю.

Моє питання полягає в тому, що я не маю поняття, як саме це будувати найкращим чином. Я хочу, щоб люди могли налаштувати будь-які правила, а пізніше просто виконати такі дії, як вибір гравця та монстра та виконати дію (набір правил, як атака).

Я прошу менше про допомогу в частині речей із базою даних, але більше про те, як створити структуру та аналізатор для неї, щоб мої правила були гнучкими. До речі, мовою вибору для цього є php.

Редагувати I:

Дозвольте уточнити свою мету: я хочу створити зручний інтерфейс (для якого не потрібно, щоб хтось вивчав мову програмування) для створення більш-менш складних ігрових правил. Проста причина: для особистого використання не потрібно пам’ятати всі правила весь час, ми просто не так часто граємо, і пробка їх шукає кожен раз. Також: Виглядає цікаве завдання робити і навчитися чомусь. :)

Що я намагався поки що: просто замислюватися над концепцією, а не витрачати час на створення неправильної архітектури. Поки я маю ідею дозволити користувачеві створити стільки атрибутів, скільки їм потрібно, а потім призначити стільки атрибутів, скільки їм хочеться, для будь-якого типу сутності. Суб'єкт може бути гравцем, монстром, предметом, будь-чим. Тепер, коли щось обчислює, дані стають доступними для аналізатора правил, щоб аналізатор правил мав змогу виконувати такі дії, як якщо Player.base_attack + кістки (1x6)> Monster.armor_check, то Monster.health - 1; Тут питання про те, як створити цей аналізатор.

Правка II:

Ось приклад досить базового значення, але для правильного його обчислення необхідно враховувати безліч різних речей і змінних:

Бонус за базову атаку (термін) Ваш базовий бонус за атаку (його спільнотою d20 називають BAB) - це бонус за атаку, отриманий з класу та рівня символів. Бонуси за базову атаку збільшуються різними темпами для різних класів персонажів. Персона отримує другу атаку за раунд, коли його бонус за базову атаку досягає +6, третю з бонусом за базову атаку +11 або вище, а четверту - за бонус за базову атаку +16 або вище. Бонуси за базові атаки, отримані з різних класів, наприклад, для багатокласового персонажа, стека. Бонус за базову атаку персонажа не надає більше атак після досягнення +16, не може бути менше +0 та не збільшується через рівень класу після того, як рівень персонажа досягне 20-го. Мінімальний бонусний напад на атаку необхідний для певних подвигів.

Ви можете прочитати його тут http://www.dandwiki.com/wiki/Base_Attack_Bonus_(Term), включаючи посилання на класи та подвиги, які знову мають свої правила для обчислення значень, необхідних для базової атаки.

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



2
Я насправді думав про саме такий тип проблеми сьогодні вранці (не пов’язаний з RPG, але керує правилами двигунів) і намагався думати про недержавні машинні підходи до обробки правил і про те, наскільки комбінаторні аналізатори настільки ефективні при виконанні завдання, яке зазвичай виконується державні машини. Я думаю, що існує багато можливостей, щоб монадійні комбінатори більш чітко підходили до більшості проблем з державними машинами. Це може здатися химерністю, але я думаю, що в цій ідеї є щось, лише мої 2 копійки. Системи RPG - це класична проблема веселої практики. Мені подобається кодування, можливо, я спробую цей підхід.
Джиммі Хоффа

1
@jk. ця стаття нагадує мені зразок, який мені сподобався для аналізу аргументів програм командного рядка, використовуючи словник Funcs, який ініціалізує стан програми на основі аргументів як ключі до словника. Здивований, я ніколи раніше не знаходив цього повідомлення від Йегге, дуже класно, дякую, що вказав на нього.
Джиммі Хоффа

4
Я не дуже впевнений, чому це було закрито як "не справжнє питання". Питання на "дошці" вищого рівня щодо питання архітектури програми, яка має специфічний набір вимог (система правил RPG). Я проголосував за його повторне відкриття, але для його повторного відкриття знадобиться ще 4 голоси.
Рейчел

1
Чесно кажучи, я подумав, що цей сайт підходить саме для подібних концептуальних питань, тоді як stackoverflow.com розглядають як проблеми з кодом / реалізацією.
бурзум

Відповіді:


9

Те, що ви просите, - це по суті доменна мова - невелика мова програмування для вузької мети, в цьому випадку визначає правила RPG P&P. Розробити мову в принципі не складно, але є значна кількість попередніх знань, які ви повинні отримати, щоб бути взагалі продуктивними. На жаль, для цієї речі немає центральної орієнтації - ви повинні зібрати її за допомогою проб, помилок та безлічі досліджень.

Спочатку знайдіть набір примітивних операцій, за допомогою яких можна реалізувати інші операції. Наприклад:

  • Отримайте або встановіть властивість гравця, NPC або монстра

  • Отримайте результат рулону штампу

  • Оцініть арифметичні вирази

  • Оцініть умовні вирази

  • Виконай умовне розгалуження

Створіть синтаксис, який виражає ваші примітиви. Як ви будете представляти числа? Як виглядає твердження? Чи закінчуються твердження крапкою з комою? Новий рядок припинено? Чи є структура блоку? Як ви це позначите: через символи чи відступи? Чи є змінні? Що являє собою юридичну назву змінної? Чи змінні змінні? Як ви отримаєте доступ до властивостей об’єктів? Чи предмети першокласні? Чи можете ви створити їх самостійно?

Напишіть аналізатор, який перетворює вашу програму на абстрактне синтаксичне дерево (AST). Дізнайтеся про розбір висловлювань з рекурсивним аналізатором зниження. Дізнайтеся, як розбір арифметичних виразів з рекурсивним пониженням дратує, і аналізатор пріоритетності операторів зверху вниз (Pratt parser) може полегшити ваше життя і коротший код.

Напишіть перекладача, який оцінює ваш AST. Він може просто читати кожен вузол на дереві і робити те, що воно говорить: a = bстає new Assignment("a", "b")стає vars["a"] = vars["b"];. Якщо це полегшує ваше життя, перетворіть AST у більш просту форму перед оцінкою.

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

ATK = D20
if ATK >= player.ATK
    DEF = D20
    if DEF < monster.DEF
        monster.HP -= ATK
        if monster.HP < 0
            monster.ALIVE = 0
        end
    end
end

Крім того, дізнайтеся, як вставити існуючу мову сценаріїв, наприклад, Python або Lua у свою програму, і скористайтеся нею. Недоліком використання мови загального призначення для завдання, що стосується конкретного домену, є те, що абстракція є герметичною: усі функції та можливості мови існують досі. Перевернути це те, що вам не доведеться це самостійно реалізовувати - і це суттєвий перелом. Розглянемо це.


2
Не поганий підхід, але я послідовно скептично ставляться до DSL, вони дуже багато працюють над тим, щоб виправитись (особливо, якщо ви говорите про справжній DSL зі спеціальним синтаксисом і все, на відміну від просто деякого вільного API, який мають люди почав дзвонити в "DSL", тож краще будьте впевнені, що збираєтесь скористатись чортом з нього, якщо ви тоді це того варто. Часто мені здається, що люди хочуть спробувати DSL там, де вони збираються використовувати його лише для роботи з невеликими правилами. Ось моє правило: Якщо реалізація DSL + використання менше коду, ніж жоден DSL, продовжуйте її виконувати, я не думаю, що в цьому випадку це було б так.
Джиммі Хоффа

1
@JimmyHoffa: Досить справедливо. Мені просто подобається шукати мовні рішення, особливо для ігор. Я, мабуть, недооцінюю труднощі зробити щось маленьке та функціональне, тому що я це робив багато разів. І все-таки це здається відповідною рекомендацією в цьому випадку.
Джон Перді

Я думаю, що слід сказати, що це правильний підхід до подібної проблеми, але це визначається тим, що людина, яка виконує реалізацію, є людиною з достатньою кваліфікацією. Навчаючись, DSL відмінно підходять для юніорів, але для фактичного вивільненого продукту я ніколи не хотів би бачити, щоб хтось із старших класів писав DSL, а для молодших вирішувати проблему DSL слід по-іншому.
Джиммі Хоффа

Прочитавши це, я думаю, що я міг би просто оцінити сценарії луа для цього. Мінусом тут буде те, що користувач повинен вміти писати сценарії з луа. Моя особиста мета - написати інтерфейс, який можна використовувати без знань про програмування, як, наприклад, конструктор правил у магенто (додаток для електронної комерції). Тому що я хочу, щоб люди могли додати свої власні правила. Я не реалізую нічого комерційного, просто інструмент, який дозволяє мені та моїм друзям вводити правила системи RPG, яку ми граємо на нерегулярній основі, і повертаючись до правил, і застосовувати їх - це біль через деякий час ...
burzum

1
@burzum: А як із тим, щоб ваш інтерфейс генерував сценарії lua?
TMN

3

Я б почав з визначення різних "Фаз" кожної дії.

Наприклад, бойова фаза може включати:

GetPlayerCombatStats();
GetEnemyCombatStats();
GetDiceRoll();
CalculateDamage();

Кожен з цих методів мав би доступ до деяких досить загальних об'єктів, таких як " Playerта" Monster, і здійснював би досить загальні перевірки, які інші сутності можуть використовувати для зміни значень.

Наприклад, у вашому GetPlayerCombatStats()методі може бути щось таке, що виглядає так :

GetPlayerCombatStats()
{
    Stats tempStats = player.BaseStats;

    player.GetCombatStats(player, monster, tempStats);

    foreach(var item in Player.EquippedItems)
        item.GetCombatStats(player, monster, tempStats);
}

Це дозволяє легко додавати будь-яку організацію з певними правилами, наприклад класом гравця, монстром або обладнанням.

В якості іншого прикладу, припустимо, ви хотіли Меч вбивати все, крім кальмара , який дає вам +4 проти всього, якщо тільки ця річ не має щупальця, і в цьому випадку вам доведеться опустити меч і отримати -10 в бою.

Ваш клас обладнання для цього меча може мати такий GetCombatStatsвигляд:

GetCombatStats(Player player, Monster monster, Stats tmpStats)
{
    if (monster.Type == MonsterTypes.Tentacled)
    {
        player.Equipment.Drop(this);
        tmpStats.Attack -= 10;
    }
    else
    {
        tmpStats.Attack += 4;
    }
}

Це дозволяє легко змінювати бойові значення без необхідності знати про іншу логіку бою, а також дозволяє легко додавати нові додатки до програми, оскільки лише деталі та логіка реалізації Вашого обладнання (або будь-якої сутності). необхідно існувати в самому класі сутності.

Ключові речі, які слід з’ясувати, це в яких точках можуть змінюватися значення та які елементи впливають на ці значення. Як тільки у вас є такі, складання окремих компонентів повинно бути простим :)


Це шлях. У більшості ПП та паперових RPG є етапи розрахунків, що, як правило, записано в путівниках. Ви також можете розмістити впорядкованість етапу в упорядкованому списку, щоб зробити його більш загальним.
Хакан Деріал

Це звучить для мене досить статично і не дозволяє користувачеві просто вводити / будувати потрібні правила в інтерфейсі? Те, що ви описуєте, звучить більше як жорсткі правила. Це також можна зробити, якщо ви маєте список вкладених правил. Я не хочу жорстко кодувати жодні правила. Якби я міг зробити все в коді, мені не потрібно було б ставити це питання, це було б просто. :)
бурзум

@burzum Так, це означає, що правила визначалися б кодом, однак це робить його дуже розширюваним з коду. Наприклад, якщо ви хотіли додати новий тип класу, або нову частину обладнання, або новий тип монстра, вам просто потрібно створити об’єкти класу для цієї сутності та заповнити відповідними методами у своєму класі своєю логікою.
Рейчел

@burzum Я просто прочитав правки на ваше запитання. Якщо ви хочете , двигун правил тільки для використання призначеного для користувача інтерфейсу, я хотів би розглянути можливість зробити пул сутностей ( Player, Monster, Dice, і т.д.), а також створення що - то , що дозволяє користувачам штук сутностей перетягнути / падіння в «рівняння» області, заповнення параметрів суб'єкта (наприклад, заповнення player.base_attack) та вкажіть прості оператори щодо того, як шматки поєднуються разом. На моєму блозі у мене фактично розміщено щось, що аналізує математичне рівняння, яке ви можете використовувати.
Рейчел

@Rachel, що ви описуєте, це мертвий легкий OOP, у природі навіть багато прикладів, які використовують RPG, як речі, як приклади для навчання OOP. Маючи ці об’єкти і працювати з ними - це легка частина, я міг би будувати їх на льоту на основі даних із бази даних. Проблема у вашому підході - жорсткі правила, такі як GetEnemyCombatStats (), незалежно від того, що робитиме цей метод, потрібно десь визначити через інтерфейс користувача та зберігати у db. Здається, що ваша стаття схожа на ту, що github.com/bobthecow/Ruler або цю github.com/Trismegiste/PhpRules .
бурзум

0

Я б поглянув на maptool, зокрема рамки 4-го видання Rumble . Це найкраща система, яку я бачив для налаштування того, про що ти говориш. На жаль, найкраще все ще жахливо жорстоке. Їх «макро» система ... скажімо ... розвивалася з часом.

Щодо "аналізатора правил", я б просто дотримувався будь-якої мови програмування, якою вам подобається, навіть якщо це PHP. Там не буде жодного хорошого способу кодування всіх правил вашої системи.

Тепер, якщо ви хочете, щоб ваші користувачі могли писати набір правил їх, тоді ви дивитесь на реалізацію власної мови сценаріїв. Користувачі скриптують власні дії на високому рівні, ваш php інтерпретує це в щось, що насправді впливає на значення бази даних, а потім він кидає купу помилок, тому що це жахливо крихка система, яка була впроваджена протягом багатьох років. Дійсно, відповідь Джона Перді прямо на бал.


0

Я думаю, що вам потрібно вміти абстрактно думати про те, що буде у вашому проблемному просторі, придумати якусь модель і потім базувати свою DSL на цьому.

Наприклад, у вас можуть бути сутності, дії та події на найвищому рівні. Валки рулонів - це події, що відбуваються в результаті дій. Дії матимуть умови, які визначають, чи є вони доступні в тій чи іншій ситуації та "сценарій" речей, які виникають під час дії. Більш складними речами буде можливість визначення послідовності фаз, де можуть відбуватися різні дії.

Після того, як у вас з’явиться якась концептуальна модель (і я пропоную вам записати її та / або намалювати схеми для її представлення), ви можете почати розглядати різні способи її реалізації.

Один шлях полягає у визначенні того, що називається зовнішнім DSL, де ви визначаєте свій синтаксис і використовуєте такий інструмент, як antlr, щоб проаналізувати його та викликати свою логіку. Інший маршрут - використовувати засоби, наявні в мові програмування, для визначення вашого DSL. Такі мови, як Groovy та Ruby, особливо добре в цьому просторі.

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.