Kavramsal olarak, bir oyunda yeniden oynatma nasıl çalışır?


145

Tekrarın bir oyunda nasıl uygulanabileceğini merak ediyordum.

Başlangıçta, oyunda gerçekleştirilen her oyuncu / ai eyleminin yalnızca bir komut listesi olacağını düşündüm ve ardından oyunu 'yeniden oynar' ve motorun her zamanki gibi çalışmasını sağlar. Ancak, ben FPS replayler baktım / oyun RTS ve dikkatli incelenmesi üzerine parçacıklar ve grafiksel / sesli glitches gibi şeyler bile tutarlıdır (ve bu hataları genellikle içinde tutarlı).

Peki bu nasıl oluyor? Sabit kamera açılı oyunlarda, tüm sahnenin her karesini depolanan bir akışa yazıp ardından akışı tekrar oynatabileceğini düşündüm, ancak bu, kamerayı duraklatmanıza ve hareket ettirmenize izin veren oyunlar için yeterli görünmüyor. etrafında. Sahnedeki her şeyin konumlarını zamanın her noktasında saklamanız gerekir (Hayır?). Yani parçacıklar gibi şeyler için, bu, oyun sırasında oyunun performansına önemli bir çekiş gibi görünen, itilecek çok fazla veri.


11
Orijinal Star Craft Tekrarları aslında tutarlı DEĞİLDİR. Aynı oyunu iki kez izleyebilir ve oldukça farklı sonuçlar görebilirsiniz.
Andres

1
@Andres: İlginç, fark etmemiştim. Özellikle RTS türü için Company Of Heroes'u düşünüyordum.
Steven Evers

4
SnOrfus'un sorduğuna inandığım şeyi açıklığa kavuşturmak için: Bazı oyunlar (Uncharted 2, Halo 3, hatta Battlefield 2) bir oyunun tamamını kaydetmenize izin verir. Oyun bittikten sonra, belirli bir hızda oynayabilir ve eylem gerçekleşirken seviyeyi haritadaki herhangi bir konumdan görüntüleyerek uçabilirsiniz. Bu yüzden tüm oyuncuların / nesnelerin hareketlerini kaydetmekle ilgili olduğunu ve video arabelleğiyle ilgili bir şey olmadığını varsayıyorum.
Sean

1
@Sean O'Hollaren: Evet, bu doğru.
Steven Evers

1
Ardından, tekrarların neredeyse varsayılan olduğu araba yarışı oyunlarını da ekleyeceğim. Eminim modellerin yeri kaydedilmiştir ve sonra her şey motorda çalıştırılır.
d -_- b

Yanıtlar:


61

İlk düşüncenizin doğru olduğunu düşünüyorum. Bir tekrar oluşturmak için, kullanıcıdan alınan tüm girdileri (alındığı kare numarasıyla birlikte) herhangi bir rastgele sayı oluşturucunun ilk tohumlarıyla birlikte saklarsınız. Oyunu yeniden oynatmak için, kaydedilen tohumları kullanarak PRNG'lerinizi sıfırlar ve oyun motorunu aynı giriş sırasını (çerçeve numaralarına senkronize edilmiş) beslersiniz. Birçok oyun, kareler arasında geçen süreye göre oyun durumunu güncelleyeceğinden, her karenin uzunluğunu da kaydetmeniz gerekebilir.


Tekrar oynatma, canlı oyundan farklı bir kare hızında çalışabileceğinden, çerçeve numaraları iyi bir referans olmayabilir.
Ben S

6
@Ben: Çerçeve numaraları hala aynı olacağından, Framerate bir fark yaratmaz. Bu doğru cevap.
BlueRaja - Danny Pflughoeft

14
Grafik çerçeveler ve motor 'çerçeveleri' (veya yinelemeler) mutlaka aynı değildir. Birçok eski oyunda, motor tek bir ana döngüde grafiklerle aynı hızda güncellenir. Modern motorlarda, grafiklerin genellikle GPU'nun izin verdiği kadar hızlı güncellenmesine izin verilir; motor, oyun dinamiklerinin (genellikle bir fizik motoru) iyi ve tutarlı bir şekilde çözülmesi için gereken seviyede çalışır.
Dan Bryant

3
@iamgopal: sözde rasgele sayı üretecinin durumunu biliyorsanız, bu sorun zaten çözülmüştür. Başka bir yöntem, rastgele sayıları başka bir girdi biçimi olarak ele almak ve bunları tuşlara basma ve benzerlerinin yanında kaydetmek olabilir.
Kylotan

1
Bu yaklaşımın, oyun motorunuzun belirleyici olmasını ve sabit bir zaman adımıyla çalıştığını belirtmek isterim. Blizzard'ın tüm RTS oyunlarının bu şekilde yapıldığına inanıyorum. Belirleyici olmayan oyunlar, uzun vadede tutarlılığı sağlamak için ek senkronizasyon verilerini içerecektir.
John Leidegren

28

Starcraft ve Starcraft: Brood War'un bir tekrar özelliği vardı. Bir maç tamamlandıktan sonra, daha sonra görüntülemek üzere tekrarı kaydetmeyi seçebilirsiniz. Tekrar oynatırken, haritada gezinebilir ve birimlere ve binalara tıklayabilir, ancak davranışlarını değiştiremezsiniz.

Bir keresinde orijinal oyunda oynanmış bir maçın tekrarını izlediğimi hatırlıyorum, ancak tekrar Brood War'da izleniyordu. Tanıdık olmayanlar için Brood War, tüm orijinal birimleri ve binaları ve çeşitli yenileri içerir. Orijinal oyunda oyuncu, bilgisayarın kolay kolay karşı koyamayacağı birimler oluşturarak bilgisayarı mağlup etmişti. Tekrarı Brood War'da oynadığımda, bilgisayarın oluşturduğu ve oyuncuyu yenmek için kullandığı farklı birimlere erişimi vardı. Dolayısıyla, aynı tekrar dosyası, dosyayı hangi Starcraft sürümünün oynattığına bağlı olarak farklı bir kazanan ile sonuçlandı.

Konsepti her zaman büyüleyici buldum. Görünüşe göre tekrar oynatma özelliği, oynatıcının tüm girdilerini kaydederek çalışıyordu ve bilgisayarın bu uyaranlara her seferinde tam olarak aynı şekilde yanıt vereceğini varsayıyordu. Oyuncu girdileri orijinal Starcraft tekrar oyuncusuna beslendiğinde, oyun tam olarak orijinal maçta olduğu gibi oynandı. Brood War tekrar oynatıcısına aynı kesin girdi beslendiğinde, bilgisayar farklı tepki verdi, daha güçlü birimler oluşturdu ve oyunu kazandı.

Bir tekrar motoru yazıyorsanız akılda tutulması gereken bir şey.


6
+1: Çok ilginç. Bunu hiç duymamıştım. Nasıl geliştirdiklerine dair iyi bir fikir verir.
Steven Evers

18

İki ana yöntem vardır:

  1. Olayları (oynatıcı / ai eylemleri gibi) kaydetme - aynen söylediğiniz gibi.
  2. Saklama durumu (tam oyun durumu, ardışık anlarda nesnelerin konumu).

Bu ne yapmak istediğinize bağlıdır. Bazen olayları depolamak daha iyidir, çünkü bu genellikle çok daha az hafıza gerektirir. Diğer taraftan, farklı hızlarda ve farklı başlangıç ​​noktalarından oynatılabilen tekrarlar sağlamak istiyorsanız, durumları saklamak daha iyidir. Durumları depolarken, bunları her olaydan sonra mı yoksa saniyede yalnızca 12 veya 25 kez mi depolayacağınıza da karar verebilirsiniz - bu, tekrarınızın boyutunu azaltabilir ve geri / ileri sarmayı kolaylaştırabilir.

"Durum" un grafik durum anlamına gelmediğini unutmayın. Daha çok birim pozisyonları, kaynakların durumu vb. Grafikler, parçacık sistemleri ve benzeri şeyler genellikle belirleyicidir ve "animasyon X, zaman Y: Z" olarak depolanabilir.

Bazen tekrarlar, anticheating şeması olarak kullanılır. O halde olayları saklamak muhtemelen burada en iyisidir.


10

Teknik olarak, motorunuzu deterministik olarak yazmalısınız, bu rasgelelik değildir. Oyunda bir karakterin rakibin kolunu hedef aldığını ve bir silah ateşlediğini varsayarsak, her durumda rakibe aynı miktarda hasar verilmelidir.

X konumunda bir bombanın patladığını varsayarsak, bu patlamanın ürettiği parçacıkların her zaman aynı görsel sonucu vermesi gerekir. Rastgeleliğe ihtiyacınız varsa, bir dizi rastgele sayı oluşturun, oyun oynanırken bir çekirdek değeri seçin ve bu çekirdek değerini tekrar oynamaya kaydedin.

Genelde bir oyunda rastgelelik olması kötü bir fikirdir. Çok oyunculu gibi şeyler için bile, oyuncularınızın yarısının bir patlamanın etrafını görmesini sağlayamazsınız, diğerleri ise sadece doğru rastgele değeri alamadıkları için göremez.

Her şeyi deterministik yapın ve iyi olmalısınız.


1
Ya AI? AI rastgele değil mi?
Jesse Jashinsky

18
Bu gerçekten gerekli değil. Tüm rastgele olaylar için tohumlanmış sözde rastgele sayılar kullanın ve tohumu yeniden oynatma dosyasına kaydedin. Bu şekilde, tekrar oynatma sırasında aynı "rastgele" sayılar üretilecektir.
Ben S

13
-1 bilgisayarlarda "rastgeleliğin" nasıl çalıştığına dair net bir yanlış anlama için
BlueRaja - Danny Pflughoeft

10
um .... hayır .... "Gerçek" rastgelelik diye bir şey olmadığının tamamen farkındayım. Ancak çoğu insan rastgele tohumlarını sistem zamanı gibi bir şeye ayarlayarak bunu aşmaya çalışır. Ancak böyle bir şeyin yapılmaması gerektiğini söylüyorum. Sistem API'sini veya önceden tanımlanmış rastgele sayılar tablosunu kullanması umurumda değil. Başlangıçta söylediğim şey doğruydu. Motorundaki her fonksiyon, girdilerine göre aynı sonucu üretmelidir. Zaman asla bir faktör olmamalıdır.
Timothy Baldridge

2
Parçacıkların oyun mekaniği ile anlamlı bir şekilde etkileşimi yoksa, RNG'lerin onlar için farklı olması gerçekten önemli değil. Bu, ağ ile senkronize edilmiş bir simülasyon durumunda yardımcı olacaktır (çoğu RTS oyununda ve diğer birçok oyun türünde olduğu gibi), çünkü simülasyonun her kareyi senkronize etmesi biraz daha azdır (parçacık efektleri ayrı ayrı güncellenir).
RCIX

10

Başlangıç ​​durumu ve zaman damgalı bir dizi eylem göz önüne alındığında, kaydedilen eylemlerin gerçekleşmesi beklendiğinden sırayı gözden geçirin.

Rastgele olayların tamamen aynı şekilde yeniden meydana gelmesini sağlamak için, tohumlanmış sözde rastgele sayılar kullanın ve tohumu yeniden oynatma dosyasına kaydedin .

Çekirdekten rastgele sayılar oluşturmak için aynı algoritmayı kullandığınız sürece, tüm olayları oyun durumunun tam anlık görüntülerine gerek kalmadan canlı oyunda olduğu gibi yeniden oluşturabilirsiniz.

Bu, tekrarların sırayla izlenmesini gerektirecektir , ancak bu, oyun tekrarları için oldukça normaldir (bkz. Starcraft 2). Zaman çizelgesine rastgele erişime izin vermek istiyorsanız, tam durum anlık görüntülerini belirli aralıklarla (örneğin her dakika) zaman çizelgesinde belirli bir ayrıntı düzeyinde atlayabilirsiniz.


Her belirli saniyede bir yeniden tohumlama yaparsanız (5 veya 10 diyelim), tekrar akışınızda kayıt yapmak ve ayrıca ileri veya geri atlamaya (esasen PRNG "anahtar karelere") izin vermek yeterince kolay olacaktır.
Kama

7

NVidia PhysX (oyunlarda sıklıkla kullanılan bir fizik simülasyon motoru), fiziksel sahnenin zaman içindeki tüm durumunu kaydedebilir. Bu, oyun motorundan gelen tüm sürüş girdilerini içerir; bu, diğerlerinin önerdiği gibi rastgele sayı tohumlarını izlemenize gerek olmadığı anlamına gelir. Bu sahne dökümünü alırsanız, fiziksel modellerinizle ilgili sorunları takip etmek için çok kullanışlı olan harici bir araçta (NVidia tarafından sağlanır) yeniden oynatabilirsiniz. Bununla birlikte, grafik motorunuzu çalıştırmak için aynı fizik akışını da kullanabilirsiniz, bu da normal kamera kontrolüne sahip olmanıza izin verir, çünkü yalnızca grafikleri süren fizik kaydedilmiştir. Pek çok oyunda bu, parçacık efektlerini içerir (PhysX, bazı çok karmaşık parçacık sistemlerini içerir.) Sese gelince, sanırım bunun kelimesi kelimesine kaydedildi (ses akışı olarak), ama ben '


4

Orijinal fikriniz doğru ve gerçekten karmaşık efektler için yalnızca hatırlanmıyorlar. Örneğin, Warcraft 3 yeniden oynatma sistemi, animasyonların durumunu veya rastgele efektler vb. Durumlarda parçacık efektlerini saklamaz. Ayrıca, MOST şeyler bir başlangıç ​​noktasından belirleyici bir şekilde hesaplamalı olarak hesaplanabilir, bu nedenle çoğu sistem için rasgele değişkenler kullanan (örneğin, rasgele bir uzaklık veren bir parçacık patlaması), ihtiyacınız olan tek şey efektin zamanı ve rastgele tohumdur. Daha sonra neye benzeyeceğini gerçekten bilmeden etkiyi yeniden üretebilirsiniz .. deterministik bir kod yolundan geçtiğini bilerek.

Tamamen kavramsal olarak düşündüğünüzde, olayların zaman çizelgesini yeniden oynatmak için ihtiyacınız olan tek şey kullanıcı eylemleridir. Program, rastgele değişkenler haricinde tam olarak aynı şekilde tepki verecektir. Bu senaryoda, rastgeleliği görmezden gelebilirsiniz (efektlerin TAMAMEN aynı görünmesi GERÇEKTEN fark eder mi, yoksa rastgele yeniden oluşturulmuş olabilir mi) veya çekirdek değerini depolayıp rastgeleliği taklit edebilirsiniz.


3

İki pensimi içeri at.

Ne istediğinize bağlı olarak, yeniden oynatma şu yolla gerçekleştirilebilir:

  1. Video arabelleğini kaydetme ve daha sonra tekrar oynatma,
  2. Nesne durumunu her karede yakalamak ve daha sonra tekrar oynatmak,

Çoğu zaman, insanlar etkileşimli bir tekrar oynatmak isterler, bu nedenle 2. yol budur. Ardından, kısıtlamalarınıza bağlı olarak bu süreci optimize etmenin birkaç yolu vardır.

  • Sistemin deterministik bir simülasyon * olmasını sağlayın, böylece her girdi tutarlı ve beklenen bir çıktı üretir
  • rastgelelik gerekliyse, rastgele sayıların tam olarak daha sonra yeniden üretilebileceğinden emin olun [Sözde Rastgele Sayı Üreteçleri PRNG ile tohumlamaya bakın veya hazır rastgele kümeler kullanın]
  • oyun öğelerini "mekanik" ve "estetik" öğelere ayırın. mekanik öğeler sonucu etkiler [örn. kolon düşmesi ve yolu tıkar], estetik öğeler gösterme amaçlıdır ve sistemdeki herhangi bir karar verme sürecini etkilemez [örn. kıvılcım gibi görsel parçacık efektleri].

Gerçekten büyüleyici bir konu. Orijinal Xbox Wreckless için bir lansman oyununun iyi bir oynatma özelliğine sahip olduğunu hatırlıyorum . Maalesef, birden fazla durumda tekrar başarısız olur;)

oh evet, nasıl biri Blinx Time Sweeper'ı unutabilir ! gerçek oyun mekaniğine dahil edilmiş harika interaktif tekrar !


* = zaman adımlamaya ilişkin bazı yorumlar var gibi görünüyor Bu özelliği yakalamak için burada "simülasyon" kullanıyorum. özünde, motorunuzun farklı zaman çerçeveleri üretebilmesi gerekir. Bir yeniden oynatma çerçevesinin işlenmesi orijinalinden daha uzun veya daha kısa sürse bile, sistemin aynı deltanın geçtiğini algılamalıdır . bu, kaydedilen her girişle çerçeve zaman adımını kaydetmek ve bu deltayı motor saatinize sağlamak anlamına gelir.


2

Belki de her oyuncu tarafından gönderilen bir komut yığını kaydedebilirsiniz. Dolayısıyla, bir bombanın belirli bir noktada ve zamanda patladığını veya belirli bir arabanın imha edildiğini kaydetmek yerine, her oyuncunun gönderdiği tuşlara basmayı kaydedersiniz. Ardından, tekrarda, oyunu bu baskılarda olduğu gibi basitçe simüle edersiniz. Bunun daha az yer kaplama potansiyeline sahip olduğunu hissediyorum, ancak böyle bir tekrar sistemi üzerinde hiç çalışmadım.

Yine de ilginç bir soru. Profesyonel oyunlarda nasıl yapıldığıyla ilgilenirim.


2

Dan Bryant

Ayrıca, rastgele tohumların kaydedilmesi geri sarma desteği için yeterli olmayacaktır, çünkü rastgele ilerleme, rastgeleliğe dayanan tüm mantıkta özel destek olmadan tersine çevrilebilir bir prosedür değildir. Olay akışının bir parçası olarak rastgele işlemlerin sonuçlarını kaydetmek daha esnektir.

Oyunun her seferinde aynı şekilde tekrar oynaması için nasıl başardıklarını anlamaya çalışırken ilk başta düşündüğüm şey buydu. Doom ile çekimlerin ne kadar rastgele gittiğini düşündüm: D. Kullanılan herhangi bir rastgele sayıyı saklayın, bunun bir çözüm olabileceğini öğrendim. Bu Crysis teknolojisi hakkında bir pdf belgesine rastlamamdan önceydi. Bazı dokular gürültü yapıyor ve çimen veya ağaç düzeni, bunu yapmak için sabit tersinir tohumla sahte rasgele oluşturma kullanıyor gibiydi, böylece her baktığınızda değişen gürültü, ağaç ve çimen eğilimi görmediniz!

Aynı anda kaçınarak, milyonlarca ağacı depolamak ve çim şaftlarını konumlandırmak. Görünüşe göre sözde rasgele dizi, mantık sabitlendiğinde, istatiksel olarak rastgele bir sayı dizisi oluşturmak için aynı şeyi her zaman yeniden oynatabilir.


Dan'in dikkatini buna çekmek istiyorsanız, katkısının altına bir yorum ekleyin - aksi takdirde muhtemelen görmeyecektir.
2013

Sadece bir misafir olmamın nedeni olabilir, ancak ebeveyn gönderisinde herhangi bir "yorum ekle" işlevini göremedim, diye yanıtladı Dan, Dan'in yanıtı bir yana, diye yanıtladı. Benim olmayan gönderiler için bile bir düzenleme-iyileştirme işlevi olduğunu gördüm, ama bu nasıl çalışıyor?
Antonymous

Ah, güzel soru! Burada görünüyor özürlerimle - Eğer soru ve cevapları sizinkinden başka yorumlamak 50 rep puanı gerektiğini. 50'yi elde etmek çok kolaydır - sadece birkaç yararlı katkı genellikle bunu başaracaktır. Evet, başkalarının sorularını ve yanıtlarını düzenleyebilirsiniz, ancak yaptığınız düzenlemeler 2000 yılına kadar başkaları tarafından incelenecektir. Ayrıcalık çizelgenizi burada görün .
2013

1

Tutarlı bir tekrar oynatma problemi, tutarlı bir çok oyunculu oyuna sahip olmak gibi aynıdır (daha kolay).

Daha önce de belirtildiği gibi, RTS oyunlarındaki tekrarlar, tüm girişlerin kaydedilmesiyle saklanır (bu bir etkisi vardır. Kaydırmanın etkisi yoktur.) Çok oyunculu, tüm girdileri de iletir.

Tüm girdilerin kaydedilmesi sadece bir tahmin değil - Warcraft3 tekrarlarını okumak için bir kütüphane var ve bunu ortaya koyuyor.

girdi, bu cevap için zaman damgaları içerir.


Hayır, tutarlı bir MP oyunuyla aynı (veya daha kolay) değil. MP oynarken, oyunlar genellikle herkesin oyunun aynı sürümüne sahip olmasını gerektirir; bu, depolanan oturumlar için geçerli değildir (çünkü oyunun daha eski bir sürümüyle kaydedilmiş olabilir). Oyunculardan biri AI rakibi ise bu özellikle kritiktir. Yeni bir sürümde, bir birimin kaydedildiği sürümden yalnızca bir saldırı noktasına sahip olduğu bir oyunu tekrar oynadığınızı hayal edin. Bu tamamen farklı bir sonuca yol açabilir.
drakon

-1

Oyunun belirli artışlarda her şeyin (HER ŞEY) durumunun anlık görüntüsünü alacağına inanıyorum. Daha sonra yeniden oynatma gerçekleştiğinde, doğrusal enterpolasyonun basit kullanımı "boşlukları" doldurmak için kullanılabilir. En azından ben böyle olacağını düşünüyorum.

Girişlerin kaydedilmesinin güvenilmez olacağı / aynı çıkışı garanti etmeyeceği konusunda haklısınız. Oyun kesinlikle tüm nesnelerin (veya en azından önemli olanların) durumunu takip etmelidir.


2
Hayır, aynı girdileri beslemek, ilk seferdeki ile tam olarak aynı sonucu verecektir. Sadece zamanlamayı doğru aldığınızdan emin olmalısınız, girişi başlangıçta alındığı aynı kareler arasında besleyin. Tüm oyun durumunu periyodik olarak kaydetmek, muazzam miktarda bellek gerektirebilir ve aynı zamanda tutarsız sonuçlar üretebilir.
Peter Ruderman

@Peter, "aynı girdileri beslemek tam olarak aynı sonuca neden olur": hayır. Birçok oyunda, tekrar her oynandığında farklı olabilen rastgele bir unsur vardır. Girişlerden daha fazlasını takip etmeniz gerekir.
houbysoft

Bu doğru. Ayrıca PRNG'lerinizin tohumlarını da saklamanız gerekir (bu soruya verdiğim cevaba bakın).
Peter Ruderman

1
Bunun performans ve hafıza tükettiğini biliyorum, ancak girdiye veya rastgele üreteçlere kadar 1 küçük şeyi kaçırırsanız ... veya gerçekten herhangi bir şey, tekrar korkunç bir teğete göre başlayacaktır!
Bob Fincheimer

@BlueRaja, Bob'un bellek anlık görüntüsü fikri o kadar uzak getirilmiş olmayabilir, ancak iyi bir motor her yineleme için tüm belleği kodlamak yerine durum 'deltalarını' kaydedebilir. Bunu motor seviyesinde desteklemek muhtemelen daha kolaydır. Dahası, rastgele tohumların kaydedilmesi geri sarma desteği için yeterli olmayacaktır, çünkü rastgele ilerleme, rastgeleliğe dayanan tüm mantıkta özel bir destek olmadan tersine çevrilebilir bir prosedür değildir. Olay akışının bir parçası olarak rastgele işlemlerin sonuçlarını kaydetmek daha esnektir.
Dan Bryant
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.