Выбери свое собственное приключение - стек выбора

8

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

Часть меня задается вопросом, должен ли каждый вариант иметь «счет», и затем я использую его (возможно, с порогом), чтобы определить, каким должно быть следующее действие, и каждое действие добавляется к результату.

Я в основном делаю это в swift / SpriteKit, но я думаю, что это больше о концепции, чем код на данном этапе.

В ответ на комментарий Джоша ниже:

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

Грубое предположение в формате:

  { "text":"You arrive in the dungeon and there are 2 doors",
   "options":[
    1: "Go left",
    2: "Go Right"
    ],
   "score" : 0 // first page
  }
  {"text" "You went left and meet a dragon",
  "options":[
    0: "Game over, you were eaten" // something to handle game over
    ],
   "score" : 1 
  }
  {"text" "You meet a mushroom who tells you the princess is in another castle",
  "options":[
    4: "Give up, game over", // something to handle game over
    8: "Jump down the pipe"
    ],
   "score" : 2 
  }

Спасибо

TommyBs
источник
Как вы в настоящее время представляете каждую «страницу» своего приключения? Являются ли они просто жестко закодированными функциями в Swift? Вы читаете текст / изображения и варианты выбора, доступные для каждой страницы из файла данных? Если да, то как выглядит файл?
@JoshPetrie обновил немного информации
TommyBs
Основная проблема заключается в том, что просто не существует элегантного способа представления нелинейного повествования с помощью линейного носителя, такого как исходный код. Идеальным методом IMO было бы иметь UML-подобный визуальный редактор, в котором сюжетные точки представлены в виде блоков, а возможные повествовательные потоки - в виде стрелок. Но для большинства небольших проектов, скорее всего, было бы больше работы по внедрению такого редактора, чем просто писать кучу спагетти-кода, заполненного ifсимволами else«s», switch«s» и case«надеется», что вы закончите, прежде чем потеряете здравомыслие.
Филипп
@Philipp Разве UML-диаграмма не является точной диаграммой объектов? Возможно, вы могли бы изучить подходы сериализации графа объектов, чтобы найти хорошие способы представления графа объектов в линеаризованном виде.
Uliwitness
@uliwitness Существуют различные виды диаграмм UML. Наиболее близким к дереву диалога является диаграмма действий . Я экспериментировал с различными инструментами для генерации кода из диаграмм UML один раз и был весьма разочарован. Обычно вы получаете довольно грязный код, который еще не функционален и требует ручного заполнения методов-заглушек.
Филипп

Ответы:

12

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

Использование флагов

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

{"text" "You meet a mushroom who tells you the princess is in another castle",
"options":[
  4: "Give up, game over", // something to handle game over
  8: [64:"Jump down the pipe", "Exit stage left"]
  ],
 "score" : 2
 "setflag" : 32
}

Где 2-й вариант появляется только если flags & 64установлен. Вы также можете реализовать эту setflagопцию, если появляется сцена или был сделан определенный выбор.

Использование предметов

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

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

  • Элементы имеют свойства, которые работают как флаг. Например, в «Ведьмаке 3» игрок получает объект, способный рассеять иллюзорные стены. Сам этот элемент может быть «флагом», но также может быть и то, что у объекта есть свойство can_dispel_illusions. Преимущество в том, что вы можете реализовать несколько объектов, которые можно использовать в одном и том же сценарии. Таким образом, сцена / диалог / дверь может проверить, есть ли у игрока «что-то» в инвентаре, у которого есть свойство can_dispel_illusions.

Это дает вам возможность дать игроку иллюзию выбора; если игрок не встретил ведьму в первой сцене, пропустив, таким образом, «жезл рассеивания», то позже игрок может получить «кольцо рассеивания» от какого-то сомнительного торговца, что предотвратит состояние игры, в котором невозможно выиграть.

Если вы не планируете давать игроку «настоящий» инвентарь, квестовые предметы могут попасть в список, скрытый от игрока.

пример:

{"items":[
  "Wand of Dispel": { "properties": ["can_dispel_illusions","illumination"]}
]}

а также:

{"text" "The corridor ends in a dead end. The wall feels cold when you touch it.",
"options":[
  4: "Turn back", 
  8: {"can_dispel_illusions": "Check if the wall is real."} 
  ],
 "score" : 2 
}

{"text" "The witch hands you an object. She observes what you're going to do next.",
"options":[
  14: "Leave the witch's house", 
  22: "Look at the object."} 
  ],
 "giveitem" : "Wand of Dispel" 
}
Felsir
источник
2

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

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

Вообще, я видел, как этот подход использовался в симуляторах интерактивного жанра. Вы можете услышать, как Дэн Фабулич из Choice Of Games обсуждает это решение в этом эпизоде круглого стола Game Design.

Преимущества этого подхода:

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

Некоторые недостатки:

  • если решения зависят от отдельных атрибутов, они могут быть поверхностными и формальными
  • и наоборот, если решения слишком сложны, сбалансировать игру / историю становится сложнее
Pikalek
источник
1

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

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

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

Как бы вы смоделировали это в программе?

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

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

uliwitness
источник
0

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

Как работают диалоговые деревья?

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

Джесси Уильямс
источник
0

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

JBiggs
источник