Концептуально, як перетворення працює в грі?


145

Мені було цікаво, як повтор може бути реалізований у грі.

Спочатку я думав, що буде лише командний список кожного гравця / ай дії, який було зроблено в грі, і він потім «переграє» гру та дозволить двигунові відображати як завжди. Тим НЕ менше, я подивився на повторах в FPS / RTS гри, і після ретельного огляду навіть такі речі , як частинки і графічні / звукові глюки послідовні (і ці глюки , як правило , в послідовній).

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


10
Оригінальні повтори ремесел зірок насправді НЕ відповідали. Ви можете переглянути одну і ту ж гру двічі і побачити деякі досить різні результати.
Андрес

1
@Andres: Цікаво, я не помічав. Зокрема, для жанру RTS я думав про Company Of Heroes.
Стівен Еверс

4
Щоб уточнити, що я вважаю, просить SnOrfus: Деякі ігри (Uncharted 2, Halo 3, навіть Battlefield 2) дозволяють вам записати гру в повному обсязі. Після закінчення гри ви можете відтворити її з визначеною швидкістю та пролетіти через рівень, коли відбувається дія, переглядаючи її з будь-якої позиції на карті. Тож я припускаю, що мова йде про запис ходу всіх плеєрів / об’єктів, а не про щось, що стосується буфера відео.
Шон

1
@Sean O'Hollaren: Так, це правильно.
Стівен Еверс

1
Тоді я також додам для гоночних ігор на автомобілях, де повтори майже за замовчуванням. Я впевнений, що місце розташування моделей записується, і тоді все просто запускається через двигун.
d -_- b

Відповіді:


61

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


Номери кадрів можуть бути не корисними орієнтирами, оскільки повтор може працювати в іншому кадрі, ніж гра в реальному часі.
Бен С

5
@Ben: Framerate не має значення, оскільки номери кадрів все одно будуть однаковими. Це правильна відповідь.
BlueRaja - Danny Pflughoeft

14
Графічні кадри та "кадри" двигуна (або ітерації) необов'язково однакові. У багатьох старих іграх двигун оновлювався з тією ж швидкістю, що і графіка, в одному головному циклі. У сучасних двигунах часто дозволяється оновлювати графіку так швидко, як дозволяє GPU, при цьому двигун тикає на рівні, необхідному для хорошого, послідовного вирішення динаміки гри (часто це фізичний двигун).
Дан Брайант

3
@iamgopal: якщо ви знаєте стан генератора псевдовипадкових чисел, то ця проблема вже вирішена. Іншим методом може бути трактування випадкових чисел як іншої форми введення та збереження цих поруч із натисканням клавіш тощо.
Кілотан

1
Я хотів би сказати, що цей підхід вимагає, щоб ваш ігровий движок був детермінованим і що він працює з фіксованим кроком часу. Я вірю, що всі ігри RTS Blizzard створені таким чином. Недетерміновані ігри включатимуть додаткові дані синхронізації для забезпечення послідовності в довгостроковій перспективі.
Джон Лейдегрен

28

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

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

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

Щось потрібно пам’ятати, якщо ви пишете двигун для повторного відтворення.


6
+1: Дуже цікаво. Я ніколи про це не чув. Забезпечує хороше розуміння того, як вони його розвивали.
Стівен Еверс

18

Є два основні методи:

  1. Зберігання подій (наприклад, дії гравця / ай) - так само, як ви говорите.
  2. Зберігання стану (повний стан гри, місце розташування предметів, в наступні моменти).

Це залежить від того, що ви хочете зробити. Іноді краще зберігати події, оскільки це займає зазвичай набагато менше пам’яті. З іншого боку, якщо ви хочете забезпечити повтори, які можна відтворювати з різною швидкістю та з різних стартових точок, краще зберігати стани. Під час зберігання станів ви також можете вирішити, чи зберігати їх після кожної події чи канату лише 12 або 25 разів на секунду - це може зменшити розмір відтворення та полегшити їх перемотування назад / перемотування вперед.

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

Іноді повтори використовуються як схема протигрівання. Тоді зберігання подій, мабуть, найкраще тут.


10

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

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

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

Зробіть все детермінованим, і вам слід добре.


1
Що з ШІ? Чи AI не випадковий?
Джессі Яшинський

18
Це справді не потрібно. Використовуйте насінні псевдовипадкові числа для всіх випадкових подій та збережіть насіння у файлі повтору. Таким чином, однакові "випадкові" числа будуть генеруватися під час відтворення.
Бен С

13
-1 для явного нерозуміння того, як працює "випадковість" у комп’ютерах
BlueRaja - Danny Pflughoeft

10
гм .... ні .... я прекрасно усвідомлюю, що немає такого поняття, як "справжня" випадковість. Однак більшість людей намагаються обійти це, встановивши своє випадкове насіння на щось на зразок системного часу. Однак я говорю, що такого робити не слід. Мені все одно, чи він використовує системний API або заздалегідь задану таблицю випадкових чисел. Те, що я спочатку сказав, було правильним. Кожна функція його двигуна повинна давати однаковий результат на основі його входів. Час ніколи не повинен бути фактором.
Тимофі Болдрідж

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

10

З огляду на початковий стан та серію дій із часовими позначками , просто пройдіть послідовність, оскільки, як передбачається, відбудеться повторне повторення.

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

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

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


Якщо ви повторно закладаєте кожні певні кількості секунд (скажімо, 5 чи 10), це буде досить легко записати у ваш потік повторів, а також дозволить стрибати вперед або назад (по суті, до PRNG "ключових кадрів").
Клин

7

NVidia PhysX (двигун симуляції фізики, який часто використовується в іграх) здатний записувати повний стан фізичної сцени з часом. Це включає в себе будь-які рушійні дані від ігрового двигуна, а це означає, що вам не потрібно відстежувати насіння випадкових чисел, як пропонували інші. Якщо взяти цей дамп сцени, ви можете відтворити його у зовнішньому інструменті (надається NVidia), що дуже зручно для відстеження проблем з вашими фізичними моделями. Однак ви також можете використовувати той самий потік фізики для керування графічним двигуном, що дозволить вам нормально керувати камерою, оскільки фіксується лише фізика, що керує графікою. У багатьох іграх сюди входять ефекти частинок (PhysX включає деякі дуже складні системи частинок.) Що стосується звуку, я здогадуюсь, що це записано дослівно (як звуковий потік), але я '


4

Ваша оригінальна ідея є правильною, і про дійсно складні ефекти вони не згадуються виключно. Наприклад, система повторної роботи Warcraft 3 не зберігає стан анімації або ефектів частинок у разі випадкових ефектів тощо. Крім того, МОСТЬ речей можна обчислити з початкової точки детермінованим способом, так що для більшості систем які використовують випадкові змінні (наприклад, вибух частинок, який дає випадкове зміщення), все, що вам знадобиться, - це час ефекту та випадкове насіння. Потім ви могли б знову генерувати ефект, не знаючи, як він у кінцевому підсумку виглядатиме .. знаючи, що він проходить детермінований шлях коду.

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


3

Закинь мої два пенси.

Залежить від того, що ви хочете, повтор може бути здійснено через

  1. Запис відео буфера та відтворення пізніше,
  2. Захоплення стану об'єкта кожного кадру та відтворення пізніше,

Здебільшого люди хочуть інтерактивного відтворення, тому 2. це шлях. Тоді, залежно від ваших обмежень, існує кілька способів оптимізації цього процесу

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

Це справді захоплююча тема. Я пам’ятаю, що одна назва запуску оригінального Xbox Wreckless мала хорошу функцію відтворення. На жаль, неодноразово повтор перетворюється;)

о так, як міг хтось забути підмітальник часу Blinx ! чудове інтерактивне відтворення, яке було включено до фактичної механіки гри!


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


2

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

Хоча цікаве питання. Мені було б цікаво, як це робиться в професійних іграх.


2

Ден Брайант

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

Це саме те, що я думав спочатку, коли намагався зрозуміти, як вони це зробили, щоб гра повторювалась завжди однаково. З Думом я подумав, як випадково пройшли пагони: D. Зберігайте будь-яке випадкове число, що звикло, я дізнався, що це може бути рішенням. Це було до того, як я натрапив на PDF-документ про технологію Crysis. Деякі текстури шуму там, а також трави чи дерева, як здається, використовують псевдорандомізацію з фіксованим оборотним насінням, щоб зробити це так, щоб ви не бачили зміненого розміщення шуму, дерев та трави в будь-який час, коли дивитесь!

Уникаючи при цьому, зберігати мільйони дерев і положень трави. Мабуть, псевдо випадкова послідовність може відтворювати ту саму, коли і фіксована логіка, просто робити підроблену статистично випадкову послідовність чисел.


Якщо ви хочете звернути на це увагу Дена, додайте коментар до його внеску - інакше він, ймовірно, не побачить його.
півзахисник

Може це бути причиною того, що я просто гість, але я не міг побачити жодної функції "додати коментар" у батьківському дописі, відповів Дан, не кажучи вже про відповідь Дана. Я бачив, що є функція вдосконалення редагування, навіть для публікацій, яких немає, моє, але як це працює?
Антонімічний

Ах, гарне запитання! Тут здається, що вам потрібно 50 балів повторень, щоб коментувати питання чи відповіді, крім ваших власних - мої вибачення. 50, однак отримати дуже просто - зазвичай це досягає лише пара корисних внесків. Так, ви можете редагувати питання та відповіді інших людей, хоча ваші зміни будуть переглянуті іншими людьми до 2000 року. Дивіться свою таблицю привілеїв тут .
півзахисник

1

Проблема послідовного відтворення така ж (ну, простіша), як і послідовна багатокористувацька гра.

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

Запис усіх вхідних даних, а не лише здогадка - є бібліотека для читання Warcraft3 повторів із виявленням цього.

Вхід включає часові позначки для цієї відповіді.


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

-1

Я б вважав, що з певними кроками гра зробить короткий огляд стану всього (ВСЕ). Тоді, коли відбувається повторне просте використання лінійної інтерполяції, можна використовувати для заповнення "дірок". Принаймні, так я думаю, що це буде зроблено.

Ви вірні, що запис входів був би ненадійним / не гарантував би однаковий вихід. У грі безумовно слід відстежувати стан усіх об'єктів (або принаймні важливих)


2
Ні, подача одних і тих же входів призведе до абсолютно такого ж результату, як і в перший раз. Вам просто потрібно переконатися, що ви правильно встановили таймінги, подаючи вхід між тими ж кадрами, де він був отриманий спочатку. Періодично збереження всього стану гри може зажадати колосальної пам’яті та створити непослідовні результати.
Пітер Рудерман

@ Петер, "подача одних і тих же входів призведе до абсолютно однакового результату": ні. У багатьох іграх є випадковий елемент, який може бути різним при кожному відтворенні. Потрібно відстежувати більше, ніж входи.
houbysoft

Це правда. Вам також потрібно зберігати насіння ваших PRNG (див. Мою відповідь на це питання).
Пітер Рудерман

1
Я знаю, що це продуктивність і забирає пам'ять, але якщо ви пропустите одну дрібницю, що стосується входу або випадкових генераторів ... або насправді що-небудь, повтор відключиться на жахливу дотичну!
Боб Фінхаймер

@BlueRaja, ідея зйомки пам’яті Боба не обов'язково є надуманою, хоча хороший двигун може записувати «дельти» стану, а не кодувати всю пам'ять для кожної ітерації. Це, мабуть, простіше підтримати на рівні двигуна. Крім того, запис випадкових насінин не був би достатнім для підтримки перемотування назад, оскільки випадкове прогресування не є оборотною процедурою без спеціальної підтримки за всією логікою, що спирається на випадковість. Більш гнучко записувати результати випадкових операцій як частини потоку подій.
Дан Брайант
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.