Как моделируются игры (например, Oblivion)?

Я только что начал играть Elder Scrolls IV: Oblivion несколько дней назад, и одна вещь, о которой я не могу не задуматься, - это то, как система квеста обрабатывается программно?

В частности, в игре много десятков (сотни?) квестов и даже подзапросов, все из которых отражены в игровой среде множеством способов: от сценариев событий, которые происходят в игре в определенное время/места между конкретными людьми (при условии, что они все еще живы), к связанным предметам квеста (некоторые из которых связаны с конкретными NPC и состояниями квеста), к разному диалогу с различными NPC (опять же, с сложным деревом, которое может быть изменено диалог с другими NPC и общее состояние квеста).

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

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

Есть ли у кого-нибудь опыт такого рода вещей, который может объяснить (в общем), что входит в эти системы?

Ответы

Ответ 1

Я просто догадываюсь. Не делал такого программирования, но я много думал о том, как они это делают, играя в RuneScape.

Вероятно, существует множество флагов и переменных, связанных с вашей учетной записью, и по мере продвижения по квесту их значения меняются. Сначала символ X отмечен как живой, а в местоположении Y. Позже она обозначена как в месте Z. Затем она умерла. Итак, когда вы входите в местоположение Y, он проверяет переменную, чтобы увидеть, есть ли она там и помещает туда свой объект или нет. Между тем, другой игрок, который не начал квест, может находиться в одной и той же области и видеть что-то еще полностью.

Ответ 2

Я не разработчик игр, но я могу видеть что-то, что может быть здесь здесь...

Объектно-ориентированное программирование допускает такую ​​сложность и динамичность, аккуратно инкапсулируя данные и логику во многие объекты. Эти объекты могут взаимодействовать "в устной форме", используя обмен сообщениями между объектами для делегирования задач друг другу. Отправитель сообщения не должен знать, как получатель будет интерпретировать сообщение, оставив метод действия полностью до получателя. Точно так же, как в реальном мире, делегирование позволяет вещам работать более плавно.

Например, когда вы заказываете грибовидное ризотто из Del Posto в Нью-Йорке, заказываете ли вы его, возвращаясь на кухню и разговаривая с шеф-поваром напрямую? Вы надеваете фартук и сами готовите ризотто? Вы едете в ближайшую грибную ферму и выбираете свои грибы? Нет, нет. Вы просто делегируете эти задачи официанту, команде шеф-поваров и поставщику продукции, соответственно. Чтобы получить грибовидное ризотто, все, что вам нужно сделать, это сказать официанту, что вы этого хотите. Остальное делается автоматически через цепочку делегирования. Такая же группа, вероятно, существует в вашей игре.

Теперь вернемся к объектам. Некоторые объекты наследуют данные и логику от родительских объектов, и таким образом могут иметь большое количество общих данных/логики; назовем этих братьев и сестер. В примере игрового квеста каждый квест, вероятно, является его собственным "объектом квеста", с базовыми данными и логикой, унаследованными от родительского "родителя квеста". Квест-братья могут отличаться друг от друга, применяя дополнительные данные/логику, относящиеся к конкретным квестам.

В зависимости от ваших действий в игре (и ваших выборов в меню игры, возможно) игровой объект может поменять один активный объект квеста для одного из его братьев и сестер. Часто это можно сделать с помощью действительно простой команды (в псевдокоде, не моделированном после какого-либо конкретного языка программирования):

gameObject.activeQuest -> getCurrentObject(); 
//returns the object containing all of the data/logic of the current active quest:
Gibbons_GoldenArtifacts
//Let say the quest description is "Scour the Catacombs of Gibbon for a 
mysterious treasure"

gameObject.activeQuest -> setCurrentObject(Gibbon_DefeatGhost)
//sets the activeQuest object (note that QUEST OBJECT contains baseline data/logic)
//assuming, say, Gibbon_DefeatGhost is an object like so:

Gibbon_DefeatGhost={QUEST OBJECT};
Gibbon_DefeatGhost.extend(
    description="Defeat Gibbon ghost to retrieve his golden artifacts";
    objective="Defeat Gibbon ghost";
    questNPC="Gibbon ghost";
    questLocation="Gibbon Inner Sanctum"
    questTriggers[1]="When PLAYER enters Gibbon Inner Sanction: Release Gibbon ghost"; 
    questTriggers[2]="When Gibbon is slain: Drop Gibbon golden artifacts"
)

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

Надеюсь, что я не полностью моюсь клоуном на этом...

Ответ 3

Конечный автомат (FSM) или автомат с конечным состоянием (множественное число: автоматы) или просто конечный автомат - это поведенческая модель, используемая для проектирования компьютерные программы. Он состоит из конечного числа состояний, связанных с переходами. Переход - это набор действий, который начинается с одного состояния и заканчивается другим (или тем же) состоянием. Переход запускается триггером, а триггер может быть событием или условием.