Я разработал RPG-игру, в которой есть несколько сюжетных потоков. Это означает, что, в зависимости от выбора пользователя, некоторые вещи могут или не могут произойти, вы можете достичь одной и той же цели несколькими способами, окончание может быть различным и так далее.
Я реализовал простой механизм принятия решений, который прекрасно работает, но имеет один огромный недостаток: в момент, когда вы принимаете решение, на историю сразу влияет ваше решение, а это значит, что вы не можете принять решение, которое повлияет на вас в далеком будущем. , Это потому, что история разворачивается как ветвь в древовидной структуре, и ей всегда нужно знать, какой узел следующий. Под капотом решения реализуются с использованием очереди: каждый узел знает о предыдущем узле и следующем узле (или, если это узел принятия решения, он ожидает ввода данных пользователем для установки следующего узла)
Я видел много игр со сложными механизмами принятия решений, и мне интересно, как они сделаны? Есть ли специальный дизайн, который делает вещи действительно легкими? Кто-нибудь делал что-то подобное и может подсказать, как с этим бороться?
ОБНОВЛЕНИЕ 1:
Важный аспект заключается в том, чтобы каким-то образом сохранить независимый код истории, чтобы им можно было манипулировать из внешнего файла. Я планирую использовать это как движок, поэтому даже возможные варианты должны исходить из внешнего файла. Код должен быть полностью абстрактным.
Кроме того, меня интересует дизайнерское решение, хороший способ сделать это, как это делают другие.
источник
if (isTree)
или сохранитьisTree
глобальную переменную, потому что история может иметь или не иметь такой выбор. Знаешь что я имею ввиду? Это больше похоже на двигатель выбора, который будет обслуживать несколько историй.isTree=true
однако позже он делает что-то еще, например, борется со школьным товарищем, который в свою очередь идет и рубит свое дерево, пока дерево еще молодо потому что он получил свою задницу. Теперь у нас есть 2 переменные, которые влияют на существование дереваisTree==true' and
didFightBrat == false`. Знаешь что я имею ввиду? И цепочка может продолжаться вечно, на существование дерева может влиять неизвестное количество факторов. Знаешь что я имею ввиду?Ответы:
Вы также можете обобщить очередь в ориентированный ациклический граф (DAG). Вы можете прочитать об этом в Википедии. По сути, каждый узел может иметь один или несколько родительских узлов, от которых он «зависит». Циклы не допускаются, т. Е. Если A зависит от B, B не может зависеть от A (напрямую или через любую косвенную цепочку других узлов).
Каждый узел находится в «активном» или «неактивном» состоянии, и ему разрешается становиться активным, только если все его родители уже активны. Структура графика (какие есть узлы и как они связаны) является частью данных игры, но активное / неактивное состояние является частью данных сохранения игрока.
Таким образом, вы можете моделировать такие вещи, как: когда вы сажаете дерево, вы помечаете задачу «plantedTree» как активную; затем, позже в игре, другая задача «treeGrown» называет «PlantedTree» и некоторый другой узел (часть истории) своими родителями. Затем «treeGrown» становится активным, только когда игрок достигает этой точки в истории, а также «PlantedTree» активен.
Вы можете включить другие функции, такие как узлы, которые активируются, если активируется какой-либо из их родителей, или узлы, которые активируются одним родителем и деактивируются другим, и так далее. Это довольно общая структура для создания историй с несколькими взаимозависимыми потоками.
источник
Из того, что я понимаю, вы хотите не просто механизм принятия решений, но и механизм правил. Для каждого решения вы выполняете подмножество правил, определенных этим решением. Выполнение этих правил часто зависит от состояния определенных объектов, таких как пример вашего дерева.
По сути, когда ваш игрок принимает решение, вы ищете это решение, выполняете правила и затем предоставляете следующий набор доступных решений, как обычно. Однако ваши правила динамичны в том смысле, что некоторые из них будут выполняться только на основе других правил, которые уже были выполнены.
Еще немного в Википедии .
Из их подзаголовка « Когда использовать правила» (акцент мой):
Стоит отметить, что иногда механизм правил лучше всего реализовывать с использованием упрощенного предметно-ориентированного «языка» или чего-то вроде YAML. Я бы не предложил XML.
источник
Вы должны учитывать, что событие не основано исключительно на решении пользователя. Как вы заметили, какое-то событие должно добавляться, если при принятии ряда последовательностей решений и затем добавлено что-то еще (например, через два дня).
Я думаю, что вам нужен способ моделирования событий и способ его запуска. В то время как первый более ограничен вашим конкретным случаем, последний может моделироваться с помощью иерархического конечного автомата (HSM), который прямо или косвенно инициирует ваши события.
Имейте в виду, что конечный автомат страдает проклятием размерности, которое смягчается только иерархической структурой. Вскоре вы поймете, что вам нужно смоделировать сложное значение статуса с помощью HMS, а также предоставить способ его запроса.
В этом сценарии у вас есть основные события (пользовательские решения, время, изменение погоды и т. Д.), Которые обрабатываются как HSM, так и базовыми обратными вызовами событий. HSM предоставляет модель для «памяти», а обратные вызовы предоставляют способ описать, как эта память должна использоваться для вычисления последствий последовательности решений / внешних событий.
Вы также можете в конечном итоге использовать диктонар (или некоторую другую структуру коллекции) HMS, по одному для каждого «аспекта» статуса, который вы должны вычислить. Примером может быть использование связанного с событием HMS и одного для решений, которые обратные вызовы принимают для запуска событий.
Вся эта инфраструктура служит для того, чтобы имитировать поведение человека, ведущего Мастера подземелий: он обычно запоминает текущую ситуацию (HMS ["external"]) из-за решений игрока и условий окружающей среды; когда что-то добавляется, оно может принимать решения с использованием своей ментальной записи и также записывать некоторый статус внутренней стратегии (HSM ["internal"]), чтобы избежать аналогичной реакции, если, например, добавляется некоторая ситуация.
источник