Як обробити кілька сюжетних сюжетів в грі RPG?


26

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

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

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

ОНОВЛЕННЯ 1:

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

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


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

Так, саме це я спочатку хотів, однак мені потрібно, щоб це було незалежним від коду. Це означає, що історією можна повністю керувати із зовнішнього файлу. Отже, я повинен знайти спосіб узагальнити сказане, що ви сказали, і зробити це таким чином, щоб я не втрачав контроль над проектом (рішень досить багато). Буде оновлено питання. Спасибі!
Валентин Раду

Отож, щоб бути більш конкретним, я не можу перевірити if (isTree)чи зберегти isTreeглобальний вар, оскільки історія може мати, а може і не мати цього вибору. Знаєте, що я маю на увазі? Це більше схоже на механізм вибору, який обслуговуватиме декілька історій.
Валентин Раду

Також у цього є ще одна проблема, скажімо, що якщо користувач вирішив посадити дерево, яке ми встановили, isTree=trueпроте пізніше він робить щось інше, наприклад, бореться зі шкільним товаришем, який у відповідь йде і рубає своє дерево, поки дерево ще молоде тому що він отримав удару попкою. Тепер у нас є дві змінні, які впливають на існування дерева isTree==true' and didFightBrat == false '. Знаєте, що я маю на увазі? І ланцюг може тривати назавжди, на існування дерева може впливати невідома кількість факторів. Знаєте, що я маю на увазі?
Валентин Раду

Потім збережіть ці дані у файлі на диску. Вам потрібно буде створити дві підпрограми для завантаження та збереження інформації, а потім використовувати ці підпрограми з кожної частини коду за необхідності.
Рандольф Річардсон

Відповіді:


18

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

Кожен вузол знаходиться в "активному" або "неактивному" стані, і він може бути активним лише тоді, коли всі його батьки вже активні. Структура графіка (які вузли там і як вони пов’язані) є частиною даних гри, але активний / неактивний стан є частиною збережених даних гравця.

Таким чином, ви можете моделювати такі речі: коли ви садите дерево, ви позначаєте завдання "посаджене дерево" як активне; потім, пізніше в грі, ще одне завдання "treeGrown" називає батьками як "посаджене дерево", так і якийсь інший вузол (частина історії). Тоді "treeGrown" стає активним лише тоді, коли гравець потрапить до цього моменту в історії, а також активовано "посаджене дерево".

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


Дуже гарна відповідь, дякую. Він фактично вирішує і інші проблеми, які у мене теж є, як збереження прогресу користувача. Це те, що мені потрібно.
Валентин Раду

@NathanReed Чому це не могло бути циклічним? Бути ациклічним, як правило, не є особливістю, а побічним продуктом дизайну графіків. Я б не створив це з таким наміром. Наприклад, уявіть, якби ви хотіли, щоб ваше дерево визнало пори року. Вони за своєю природою циклічні, і дуга вашої історії може бути однаковою залежно від варіантів, доступних протягом одного сезону.

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

@NathanReed Ах, вибачте, я пропустив рекурсивну частину.

3

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

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

Ще декілька у Вікіпедії .

З підзаголовка " Коли використовувати рухові двигуни" (наголос - мій):

  • Проблема просто надто складна для традиційного коду.
  • Проблема може бути не складною, але ви не бачите надійного способу її побудови.
  • Проблема виходить за рамки будь-якого очевидного алгоритму.
  • Це складна проблема, яку потрібно вирішити. Очевидних традиційних рішень немає, або проблема до кінця не вивчена.
  • Логіка часто змінюється
  • Сама логіка може бути простою, але правила змінюються досить часто. У багатьох організаціях випуски програм є рідкісними, і правила можуть допомогти забезпечити "спритність", яка потрібна і очікується досить безпечним способом.
  • Експерти з домену та бізнес-аналітики легко доступні, але не є технічними.
  • Експерти з домену часто володіють великими знаннями про бізнес-правила та процеси. Зазвичай вони нетехнічні, але можуть бути дуже логічними. Правила можуть дозволити їм висловити логіку власними термінами. Звичайно, їм все одно доводиться критично мислити і бути здатними до логічного мислення. Багато людей на нетехнічних посадах не навчаються формальній логіці, тому будьте уважні та працюйте з ними. Кодифікуючи ділові знання в правилах, ви часто виявляєте дірки в тому, як ділові правила та процеси в даний час розуміються.

Слід зазначити, що періодично механізм правил найкраще реалізовувати, використовуючи спрощену доменну "мову" або щось на зразок YAML. Я б не запропонував XML.


1

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

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

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

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

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

Вся ця інфраструктура служить для того, щоб імітувати поведінку людського майстра-підземелля: він, як правило, бере ментальний запис про поточну ситуацію (HMS ["зовнішня"]) через рішення гравців та умови навколишнього середовища; коли щось додається, він може приймати рішення, використовуючи свій ментальний запис, і записувати певний статус внутрішньої стратегії (HSM ["внутрішній"]), щоб уникнути подібного реагування, якщо, наприклад, деяка ситуація.

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