Концептуально, как работает воспроизведение в игре?

Мне было любопытно, как можно воспроизвести игру в игре.

Вначале я думал, что будет только командный список каждого действия игрока /ai, который был взят в игре, и затем он "воспроизводит" игру и позволяет движку отображать как обычно. Тем не менее, я просмотрел повторы в играх FPS/RTS, и при тщательной проверке даже такие вещи, как частицы и графические/звуковые сбои, согласованы (и эти глюки обычно в).

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

Ответ 1

Я думаю, что твоя первоначальная мысль была правильной. Чтобы создать повтор, вы сохраняете весь вход, полученный от пользователя (вместе с номером кадра, на котором он был получен) вместе с начальными семенами генераторов случайных чисел. Чтобы воспроизвести игру, вы reset ваши PRNG, используя сохраненные семплы, и загрузите игровой движок той же последовательности ввода (синхронизированной с номерами кадров). Поскольку многие игры будут обновлять состояние игры на основе количества времени, которое проходит между кадрами, вам также может потребоваться сохранить длину каждого кадра.

Ответ 2

Starcraft и Starcraft: у Brood War была функция повтора. После того, как матч будет завершен, вы можете выбрать сохранение повтора для просмотра позже. Во время воспроизведения вы можете прокручивать карту и нажимать на единицы и здания, но не изменять их поведение.

Я помню, как однажды наблюдал повтор матча, который был сыгран в оригинальной игре, но повтор просматривался в Brood War. Для незнакомых, Brood War содержит все оригинальные единицы и здания, а также множество новых. В оригинальной игре игрок победил компьютер, создав единицы, которые компьютер не мог легко сбить. Когда я играл в игру Brood War, компьютер имел доступ к разным подразделениям, которые он создал и использовал для победы над игроком. Таким образом, тот же самый файл повтора привел к другому победителю в зависимости от того, какая версия Starcraft воспроизводила файл.

Я всегда считал концепцию увлекательной. Казалось бы, функция воспроизведения работает, записывая все входы проигрывателя и предполагая, что компьютер будет реагировать на эти стимулы точно так же каждый раз. Когда входные данные игрока были загружены в оригинальный повторитель Starcraft, игра играла точно так же, как в исходном матче. Когда один и тот же точный ввод был подан в проигрыватель Brood War, компьютер реагировал по-разному, создал более сильные юниты и выиграл игру.

Что-то нужно иметь в виду, если вы пишете механизм воспроизведения.

Ответ 3

Существует два основных метода:

  • Сохранение событий (например, действий игрока /ai ) - так же, как вы говорите.
  • Состояние хранения (полное состояние игры, например, местоположение объектов, в последовательные моменты).

Это зависит от того, что вы хотите сделать. Иногда хранение событий лучше, потому что это занимает значительно меньше памяти. С другой стороны, если вы хотите предоставить повторы, которые могут воспроизводиться с разной скоростью и с разных начальных точек, лучше хранить состояния. При сохранении состояний вы также можете решить, хранить ли их после каждого события или f.e. всего 12 или 25 раз в секунду - это может уменьшить размер вашего воспроизведения и упростить перемотку/ускоренную перемотку вперед.

Обратите внимание, что "состояние" не означает графическое состояние. Больше что-то вроде позиций подразделения, состояния ресурсов и т.д. Такие вещи, как графика, системы частиц и т.д., Обычно детерминированы и могут храниться как "анимация X, время Y: Z".

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

Ответ 4

Технически вы должны написать свой движок детерминированным, это не случайность. Предполагая, что персонаж в игре нацелился на руку противника и стреляет оружием, тогда во всех случаях противнику должно быть нанесено одинаковое количество урона.

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

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

Сделайте все детерминированным, и вы должны быть в порядке.

Ответ 5

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

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

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

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

Ответ 6

NVidia PhysX (механизм моделирования физики, который часто используется в играх) способен записывать полное состояние физической сцены с течением времени. Это включает в себя любые входные данные от игрового движка, что означает, что вам не нужно отслеживать количество случайных чисел, как это предлагали другие. Если вы берете этот дамп сцены, вы можете воспроизвести его внешним инструментом (предоставляемым NVidia), что очень удобно для отслеживания проблем с вашими физическими моделями. Тем не менее, вы также можете использовать один и тот же поток физики для управления графическим движком, который затем позволит вам иметь нормальное управление камерой, поскольку только физика, управляющая графикой, была записана. Во многих играх это включает эффекты частиц (PhysX включает в себя некоторые очень сложные системы частиц.) Что касается звука, я предполагаю, что записанный дословно (как звуковой поток), но я не уверен.

Ответ 7

Ваша оригинальная идея правильная, и для действительно сложных эффектов они не запоминаются исключительно. Например, система воспроизведения Warcraft 3 не сохраняет состояние анимации или эффекты частиц в случае случайных эффектов и т.д. Кроме того, вещи MOST могут вычисляться вычислительно с начальной точки детерминированным способом, поэтому для большинства систем которые используют случайные величины (например, взрыв частиц, который дает случайное смещение), все, что вам понадобится, это время действия и случайное семя. Затем вы могли бы повторно генерировать эффект, не зная, на что это будет похоже... зная, что он проходит путь детерминированного кода.

Думая об этом чисто концептуально, чтобы воспроизвести временную шкалу событий, все, что вам нужно, это действия пользователя. Программа будет реагировать точно так же, за исключением случайных величин. В этом случае вы можете либо игнорировать случайность (действительно ли имеет значение, если эффекты выглядят ТОЧНО одинаковыми или могут быть случайно сгенерированы), или сохранить начальное значение и подделать случайность.

Ответ 8

Бросьте мои два пенса.

В зависимости от того, что вы хотите, повтор можно выполнить с помощью

  • Запись буфера видео и воспроизведение позже,
  • Захват состояния объекта для каждого кадра и последующего воспроизведения,

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

  • обеспечить, что система является детерминированным симулятором *, так что каждый вход генерирует согласованный и ожидаемый выход
  • Если требуется случайность, убедитесь, что случайные числа могут быть воспроизведены ровно в более позднее время [посмотрите на посев с помощью генераторов псевдослучайных чисел PRNG или используйте произвольные случайные множества]
  • делить элементы игры на "механические" и "эстетические" элементы. механические элементы влияют на результат [например, падение столбца и путь блокировки], эстетические элементы проявляются и не влияют на процесс принятия решений в системе (например, эффекты визуальных частиц, такие как искры).

Это действительно увлекательная тема. Я помню, что у одного запуска для оригинального Xbox Wreckless была хорошая функция воспроизведения. К сожалению, неоднократно повторение проиграло;)

О, да, как мог кто-нибудь забыть Blinx Время Sweeper! отличный интерактивный реплей, который был включен в настоящий игровой механик!


* = Кажется, есть некоторые комментарии относительно временного шага. Я использую "симуляцию" здесь, чтобы захватить эту функцию. в основе, ваш двигатель должен иметь возможность создавать дискретные кадры времени. даже если кадр повтора занимает больше времени или меньше, чем исходный, система должна понимать, что прошла одна и та же временная дельта. это означает запись временного шага кадра с каждым записанным входом и подачу этой дельта на часы вашего двигателя.

Ответ 9

Возможно, вы могли бы просто сохранить стоп команд, отправляемых каждым игроком. Поэтому вместо того, чтобы экономить то, что бомба взорвалась в определенный момент и время или что какой-то автомобиль был уничтожен, вы просто сохраняете нажатия клавиш, отправленные каждым игроком. Затем в повторном воспроизведении вы просто имитируете игру, как это было бы с этими прессами. Я чувствую, что у него есть потенциал, чтобы заняться меньшим пространством, но я никогда не работал в такой системе воспроизведения.

Интересный вопрос. Мне было бы интересно, как это делается в профессиональных играх.

Ответ 10

Дэн Брайант

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

То, что я думал сначала, когда я пытался понять, как они это сделали, чтобы игра повторялась всегда одинаково каждый раз. С Doom я подумал о том, насколько случайны стрелы: D. Храните любое случайное число, которое было использовано, я узнал, что это может быть решение. Это было до того, как я наткнулся на pdf-документ о технологии Crysis. Некоторые шумы текстур и трава или древовидная структура, казалось, использовали псевдорандомизацию с фиксированным обратимым семенем, чтобы вы не видели измененного расположения шума, деревьев и травы в любое время!

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

Ответ 11

Проблема наличия последовательного воспроизведения одинакова (ну, проще), например, иметь последовательную многопользовательскую игру.

Как упоминалось ранее, повторы в играх RTS сохраняются путем записи всего входа (что имеет эффект. Прокрутка не влияет). Мультиплеер передает все входные данные, также

Запись всех входных данных не просто догадка - есть библиотека для чтения повторов Warcraft3 с раскрытием этого.

Ввод

содержит временные метки для этого ответа.

Ответ 12

Я бы поверила, что при определенных приращениях в игре будет снимок состояния всего (ВСЕ). Затем, когда происходит повторное воспроизведение, простое использование линейной интерполяции может использоваться для заполнения "дыр". По крайней мере, так я думаю, что это будет сделано.

Вы правы, что запись входов будет ненадежной/не гарантирует тот же выход. Игра определенно должна отслеживать состояние всех объектов (или, по крайней мере, важных)