Deterministik bir fizik simülasyonunu nasıl yapabilirim?


43

Oyuncuların bir bulmacayı / haritayı çözmek için parçaları ve parçaları hareket ettirdiği sert cisimleri içeren bir fizik oyunu yaratıyorum. Oyunun oldukça önemli bir yönü, oyuncular bir simülasyon başlattığında , işletim sistemi, işlemci vb. Ne olursa olsun her yerde aynı şekilde çalışacak olmaları ...

Çok fazla karmaşıklığa yer var ve simülasyonlar uzun süre çalışabiliyor, bu nedenle fizik motorunun kayan nokta işlemleriyle ilgili olarak tamamen belirleyici olması önemli, aksi takdirde bir oyuncunun makinesinde "çözmek" için bir çözüm görünebilir ve başka bir "başarısız".

Bu determinizmi oyunumda nasıl başarabilirim? Javascript, C ++, Java, Python ve C # gibi çeşitli çerçeveler ve diller kullanmaya istekliyim.

Box2D (C ++) ve diğer dillerdeki eşdeğerlerinin yanı sıra, ihtiyaçlarımı karşıladığı görülüyor, ancak özellikle trigonometrik fonksiyonlarda kayan nokta determinizminden yoksun kaldım.

Şimdiye kadar gördüğüm en iyi seçenek Box2D'nin Java eşdeğeri (JBox2D). Birçok operasyon için kullanmak StrictMathyerine kayan nokta determinizminde bir girişimde bulunuyor gibi görünüyor Math, ancak bu motorun oyunu henüz yapmadığım için ihtiyacım olan her şeyi garanti edip etmeyeceği belli değil.

İhtiyaçlarımı karşılamak için mevcut bir motoru kullanmak veya değiştirmek mümkün mü? Yoksa kendi başıma bir motor mu yapmam gerekecek?

EDIT: Birinin neden böyle bir hassasiyete ihtiyacı olacağı umrunda değilse, bu yazının geri kalanını atlayın. Yorumlarda ve cevaplarda bulunan bireyler, yapmamam gereken bir şeyi aradığıma inanıyor gibi görünüyor ve bu yüzden oyunun nasıl çalışması gerektiğini daha da açıklayacağım.

Oyuncuya engeller ve hedef içeren bir bulmaca veya seviye verilir. Başlangıçta, bir simülasyon çalışmıyor. Daha sonra, bir makine oluşturmak için kendilerine sağlanan parçaları veya araçları kullanabilirler. Başlattıktan sonra simülasyon başlar ve makinelerini düzenleyemezler. Makine haritayı çözerse, oyuncu seviye attı. Aksi takdirde, durdurma düğmesine basmaları, makinelerini değiştirmeleri ve tekrar denemeleri gerekecektir.

Her şeyin deterministik olmasının nedeni, her makinenin konumunu, boyutunu ve rotasyonunu kaydederek her makineyi (bir seviye çözmeyi deneyen bir takım parça ve araçlar) eşleştirecek bir kod üretmeyi planlamamdır. Daha sonra oyuncuların çözmeleri (bu dosyalar tarafından temsil edilen) çözmeleri paylaşmaları ve çözmeleri doğrulayabilmeleri, birbirlerinden öğrenebilecekleri, yarışmalara katılabilecekleri, ortak çalışabilecekleri vb. Mümkün olacaktır. olanlar, determinizm eksikliğinden etkilenmeyecekler. Ancak gerçekten zor seviyeleri çözen yavaş veya karmaşık tasarımlar olabilir ve bunlar muhtemelen en ilginç ve paylaşmaya değer olacak olanlardır.


Yorumlar genişletilmiş tartışmalar için değildir; bu konuşma sohbete taşındı . Soruna bir çözümünüz olduğunu düşünüyorsanız, lütfen bunu bir yorum yerine bir cevap olarak yayınlamayı düşünün; bu, düzenlemeyi, kabul edilen oylama / işaretleme yoluyla değerlendirmeyi veya geri bildirim için doğrudan geri bildirim için doğrudan yorum yapmayı kolaylaştırır dokuma daha uzun bir konuşma dizisine cevap verir.
DMGregory

Yanıtlar:


45

Kayan nokta sayılarının deterministik bir şekilde ele alınması hakkında

Kayan nokta deterministiktir. Olmalı. Karmaşık bir durum.

Kayan nokta sayılarıyla ilgili çok sayıda literatür var:

Ve nasıl sorunlu olduklarını:

Özet için. En azından, tek bir iş parçacığında, aynı sırayla gerçekleşen aynı verilerle aynı işlemler belirleyici olmalıdır. Böylece girdiler hakkında endişelenerek ve yeniden sırayla başlayabiliriz.


Sorun yaratan böyle bir girdi zamandır.

Her şeyden önce, her zaman aynı zamanlamayı hesaplamanız gerekir. Zamanı ölçmemeyi söylemiyorum, fizik simülasyonuna zaman geçirmeyeceğinizi söylüyorum, çünkü zamandaki değişimler simülasyondaki bir gürültü kaynağı.

Fizik simülasyonuna geçmiyorsanız neden zaman ölçüyorsunuz? Bir simülasyon adımının ne zaman aranması gerektiğini bilmek için geçen süreyi ölçmek ve - ne zaman uyuduğunuzu varsayarak - ne kadar uyuyacağınızı ölçmek istersiniz.

Böylece:

  • Ölçüm süresi: evet
  • Simülasyonda kullanım süresi: Hayır

Şimdi, talimat yeniden sipariş ediliyor.

Derleyici bununla f * a + baynı olduğuna karar verebilir b + f * a, ancak bunun farklı bir sonucu olabilir. Ayrıca fmadd'i derleyebilir ya da bunun gibi birden fazla satırın birlikte olması ve SIMD ile yazmaları ya da şu anda düşünemeyeceğim başka bir optimizasyona karar vermeleri gerekebilir . Ve aynı işlemlerin aynı sırayla yapılmasını istediğimizi unutmayın, hangi işlemlerin gerçekleştiğini kontrol etmek istiyoruz.

Ve hayır, çift kullanmanız sizi kurtarmaz.

Özellikle ağdaki kayan nokta sayılarını senkronize etmek için derleyici ve yapılandırması hakkında endişelenmeniz gerekir. Yapıları aynı şeyi yapmayı kabul etmeleri gerekir.

Muhtemelen, yazı derleme ideal olacaktır. Bu şekilde hangi işlemin yapılacağına karar verirsiniz. Ancak, bu çoklu platformları desteklemek için bir problem olabilir.

Böylece:


Sabit nokta sayıları için durum

Yüzenlerin bellekte temsil edilmesinden dolayı, büyük değerler hassasiyetini kaybedecek. Değerlerinizi küçük tutmanın (kelepçeyi) problemi azaltmasının nedeni budur. Böylece, devasa hızlar ve geniş odalar yok. Bu da ayrı fizik kullanabileceğiniz anlamına gelir çünkü tünel açma riskiniz daha düşüktür.

Öte yandan, küçük hatalar birikir. Yani, kısalt. Yani, tamsayı tipine ölçek ve döküm. Bu şekilde hiçbir şey bilmediğini biliyorsun. Tamsayı tipinde kalarak yapabileceğiniz işlemler olacaktır. Kayan noktaya geri dönmeniz gerektiğinde, ölçeklendirme işlemini gerçekleştirir ve geri alırsınız.

Not Ölçeği söylüyorum. Buradaki fikir, 1 birimin aslında ikisinin gücü olarak temsil edileceğidir (örneğin 16384). Her ne ise, sabit yap ve kullan. Temel olarak sabit nokta numarası olarak kullanıyorsunuz. Aslında, bazı güvenilir kütüphanelerden uygun sabit nokta sayıları kullanabiliyorsanız, çok daha iyi.

Kısaltmak diyorum. Yuvarlama sorunu hakkında, oyuncu kadrosundan sonra elde ettiğiniz değerin son kısmına güvenemeyeceğiniz anlamına gelir. Bu yüzden, alçı ölçeğinden önce gerekenden biraz daha fazlasını elde etmek ve sonra kesmek için.

Böylece:

  • Değerleri küçük tutun: Evet
  • Dikkatli yuvarlama: Evet
  • Mümkün olduğunda sabit nokta numaraları: Evet

Bekle, neden kayan noktaya ihtiyacın var? Yalnızca bir tamsayı türü ile çalışamaz mıydınız? Ah, doğru. Trigonometri ve radikalleşme. Trigonometri ve radikasyon için tabloları hesaplayabilir ve kaynağınızda pişirilmesini sağlayabilirsiniz. Veya bunların yerine sabit nokta sayıları kullanmak dışında bunları kayan nokta sayıları ile hesaplamak için kullanılan algoritmaları uygulayabilirsiniz. Evet, hafızayı, performansı ve hassasiyeti dengelemeniz gerekir. Yine de, kayan nokta sayıları dışında kalabilir ve deterministik kalabilirsiniz.

Orijinal PlayStation için böyle şeyler yaptıklarını biliyor muydunuz? Lütfen Köpeğimle Tanış Yamalar .

Bu arada, grafikler için kayan nokta kullanmadığını söylemiyorum. Sadece fizik için. Tabii ki, pozisyonlar fiziğe bağlı olacak. Ancak, bir çarpıştırıcının bildiğiniz gibi bir modelle eşleşmesi gerekmez. Modellerin kesilmesinin sonuçlarını görmek istemiyoruz.

Böylece: SABİT NOKTA NUMARALARI KULLANIN.


Açıkçası, kayan noktaların nasıl çalıştığını belirtmenize izin veren bir derleyici kullanabilirsiniz ve bu sizin için yeterliyse, bunu yapabilirsiniz. Bu her zaman bir seçenek değildir. Ayrıca bunu determinizm için yapıyoruz. Sabit nokta sayıları, hiçbir hata olmadığı anlamına gelmez, hepsinden sonra sınırlı hassasiyetleri vardır.

"Sabit nokta numarasının zor" olduğunu kullanmamak için iyi bir neden olduğunu sanmıyorum. Ve bunları kullanmak için iyi bir neden istiyorsanız, bu determinizm, özellikle de platformlar arasındaki determinizmdir.


Ayrıca bakınız:


Zeyilname : Dünyanın boyutunu küçük tutmayı öneriyorum. Bununla birlikte, hem OP hem de Jibb Smart, orijinal şamandıralardan uzaklaşmanın daha az hassas olduğu noktasını ortaya koymaktadır. Bu, dünyanın sınırından çok daha erken görülen fizik üzerinde bir etkiye sahip olacak. Sabit nokta sayıları, kesin olarak kesindirler, her yerde eşit derecede iyi (ya da istersen kötü) olacaklardır. Determinizm istiyorsak bu iyi. Ayrıca, genellikle fiziği yapma şeklimizin küçük farklılıkları yükseltme özelliğine sahip olduğunu da belirtmek isterim. The Incredible Machine ve Contraption Maker'da Kelebek Etkisi - Deterministik Fiziği görün .


Fizik yapmanın başka bir yolu

Düşündüm, kayan nokta sayısındaki küçük hassasiyetin artmasının nedeni, bu sayılar üzerinde yinelemeler yapmak olduğumuzdur. Her simülasyon aşaması, son simülasyon aşamasının sonuçlarını alır ve üzerlerinde bir şeyler yaparız. Hataların üzerine biriken hatalar. Bu senin kelebek efektin.

Aynı makinede tek bir iplik kullanarak tek bir yapı göreceğimizi sanmıyorum, aynı girdi tarafından farklı çıktılar veriyor. Ancak, başka bir makinede olabilir veya farklı bir yapı olabilir.

Orada test etmek için bir argüman var. İşlerin tam olarak nasıl çalışması gerektiğine karar verirsek ve hedef donanım üzerinde test yapabilirsek, farklı davranışa sahip yapılar ortaya koymamalıyız.


Ancak, çok fazla hata biriktiren uzakta çalışmamak için bir argüman var. Belki de bu, fiziği farklı bir şekilde yapmak için bir fırsattır.

Bildiğiniz gibi, sürekli ve ayrık bir fizik var, her ikisi de zaman aşımındaki her bir nesnenin ne kadar ilerleyeceği üzerinde çalışıyor. Bununla birlikte, sürekli fiziğin, bir çarpışmanın olup olmadığını görmek için farklı muhtemel instantları araştırmak yerine çarpışma anında çözülmesine imkan veren bir aracı vardır.

Bu nedenle, aşağıdakileri öneriyorum: her bir nesnenin bir sonraki çarpışmasının ne zaman olacağını, tek bir simülasyon adımından birinin çok daha büyük, büyük bir zaman adımıyla ne olacağını anlamak için sürekli fizik tekniklerini kullanın. Sonra en yakın çarpışma anını alırsınız ve her şeyin o anda nerede olacağını anlarsınız.

Evet, bu tek bir simülasyon adımının çok çalışmasıdır. Bu, simülasyonun hemen başlamayacağı anlamına gelir ...

... Ancak, her seferinde çarpışmayı kontrol etmeden sonraki birkaç simülasyon adımını simüle edebilirsiniz, çünkü bir sonraki çarpışmanın ne zaman olacağını zaten biliyorsunuzdur (veya büyük zaman diliminde çarpışma gerçekleşmez). Ayrıca, bu simülasyonda biriken hataların önemi yoktur, çünkü simülasyon büyük zaman adımına ulaştığında, önceden hesapladığımız konumları yerleştiririz.

Şimdi, bulduğumuz bir sonraki çarpışmayı hesaplamak için her simülasyon adımındaki çarpışmaları kontrol etmek için kullanacağımız zaman bütçesini kullanabiliriz. Bu, büyük zaman adımını kullanarak ileriye dönük bir simülasyon yapabiliriz. Kapsamı sınırlı bir dünya varsayalım (bu büyük oyunlar için işe yaramayacak), simülasyon için gelecekteki durumların bir sırası olmalı ve sonra sadece son durumdan diğerine enterpolasyona girdiğiniz her bir çerçeve olmalıdır.


İnterpolasyon için tartışırdım. Ancak, ivme olduğu göz önüne alındığında, her şeyi aynı şekilde enterpolasyon yapamayız. Bunun yerine her nesnenin ivmesini hesaba katarak enterpolasyon yapmamız gerekiyor. Bu nedenle, büyük zaman aşımı için yaptığımız gibi aynı pozisyonu güncelleyebiliriz (bu aynı zamanda daha az hata eğilimli olduğu anlamına gelir, çünkü aynı hareket için iki farklı uygulama kullanmayacağız).


Not : Bu kayan nokta sayılarını yapıyorsak, bu yaklaşım nesnelerin kökenlerinden daha farklı davranma sorununu çözmez. Ancak, kesinliğin orijinden uzaklaştıkça kaybolduğu doğru olsa da, yine de belirleyicidir. Aslında, bu yüzden başlangıçta bunu bile gündeme getirmedi.


ek

OP'deki yorumdan :

Buradaki fikir, oyuncuların makinelerini bir biçimde (xml veya json gibi) kaydedebilecekleri, böylece her bir parçanın konumu ve dönüşü kaydedilecek. Bu xml veya json dosyası daha sonra makineyi başka bir oyuncunun bilgisayarında çoğaltmak için kullanılacaktır.

Yani, ikili format yok, değil mi? Bunun anlamı, geri kazanılan kayan noktaların orijinaliyle uyuşup uyuşmadığı ile ilgili endişelenmemiz gerektiğidir. Bakınız: Şamandıra Hassasiyeti Tekrar Ziyaret Edildi: Dokuz Haneli Şamandıralı Taşınabilirlik


Yorumlar genişletilmiş tartışmalar için değildir; bu konuşma sohbete taşındı .
Vaillancourt

2
Mükemmel cevap! Sabit nokta lehine 2 puan daha: 1. Kayan nokta, kökene daha yakın veya daha uzak davranacaktır (eğer aynı bulmacayı farklı bir yerde kullanıyorsanız), ancak sabit nokta olmaz; 2. sabit nokta aslında serisinin çoğu için kayan noktadan daha fazla hassasiyete sahiptir - sabit noktaları iyi kullanarak hassaslık kazanabilirsiniz
Jibb Smart

İkili verileri, hem XML hem de JSON'da, base64elemanları kullanarak kodlamak mümkündür . Bu tür büyük miktarda veriyi temsil etmenin etkili bir yolu değil, ancak ikili gösterimlerin kullanımını engellediklerini ima etmek yanlıştır.
Pikalek

1
@Pikalek farkındayım, OP bana yorumlar hakkında sorular sordu, base64'ü bir seçenek olarak bahsettim, diğerleri de dahil, hex de dahil olmak üzere, int olarak yeniden yorumla ve protobuf formatını kullanmak, çünkü hiç kimse bu dosyaları anlayamayacak, onlar değil (eğitimsiz) ) insan tarafından okunabilir. Sonra - farz ediyorum - bir mod yorumları kaldırdı (hayır, yukarıda belirtilen sohbette yok). Bu tekrar olacak mı? Bunu cevaptan çıkarmalı mıyım? Daha uzun yapmalı mıyım?
Theraot

@Theraot Ah, silinen yorumlar bağlamında bunu nasıl farklı yorumladığımı görebilirim. (FWIW, hem bu cevapta hem de sorudaki sohbetleri okudum). Verileri kodlamanın yerel ve etkili bir yolu olsa bile, bunun platformlar arasında aynı anlama geldiğinden emin olmak için hala daha büyük bir mesele var. Bu karmaşayı göz önüne alındığında, belki sadece olduğu gibi bırakmak en iyisidir. Aydınlattığın için teşekkürler!
Pikalek

6

Belirli bir iyi bilinen gerçek zamanlı strateji oyununu yapan bir şirket için çalışıyorum ve size kayan nokta determinizminin mümkün olduğunu söyleyebilirim.

Farklı derleyicileri veya farklı ayarları olan aynı derleyiciyi veya hatta aynı derleyicinin farklı sürümlerini kullanmak, determinizmi bozabilir.

Eğer platformlar veya oyun versiyonları arasında çapraz oyuna ihtiyacınız varsa, o zaman sabit noktaya gitmeniz gerekeceğini düşünüyorum - kayan nokta ile bildiğim tek çapraz ekran PC ve XBox1 arasında, ama bu çok çılgınca.

Ya tamamen deterministik bir fizik motoru bulmanız ya da açık kaynaklı bir motor kullanmanız ve onu deterministik hale getirmeniz ya da kendi motorunuzu yuvarlamanız gerekir. Kafamın tepesinde, her şeyin birliğinin belirleyici bir fizik motoru eklediğini hissediyorum, ancak aynı makinede sadece deterministik mi yoksa tüm makinelerde deterministik mi olduğundan emin değilim.

Kendi eşyalarını yuvarlamaya çalışacaksan, yardımcı olabilecek birkaç şey:

  • Çok meyveli bir şey yapmıyorsanız, IEE754 yüzdeleri deterministtir (neyin kapsanıp kaplanmadığına dair daha fazla bilgi için "IEE754 determinizmi" google)
  • Her müşterinin kendi yuvarlama modunu ve hassasiyetini aynı şekilde ayarladığından emin olmanız gerekir (ayarlamak için controlfp kullanın)
  • yuvarlama modu ve kesinlik bazı matematik kütüphaneleri tarafından değiştirilebilir, bu nedenle kapalı kütüphaneleri kullanıyorsanız, arama yaptıktan sonra bunları kontrol etmek isteyebilirsiniz (tekrar kontrol etmek için controlfp kullanarak)
  • Bazı SIMD komutları deterministiktir, çoğu değil, dikkatli olun
  • yukarıda da belirtildiği gibi, determinizmi sağlamak için aynı platforma, aynı derleyicinin aynı versiyonuna, aynı konfigürasyonu, aynı derleyici ayarlarına ihtiyacınız var
  • durum desyncs'lerini tespit etmek için bazı araçlar oluşturun ve bunları teşhis etmeye yardım edin - örneğin, bir desync'in ne zaman gerçekleştiğini algılamak için her kareyi CRC oyun durumu, daha sonra oyun durumundaki değişikliklerin zahmetle dosyaya kaydedildiğini etkinleştirebileceğiniz ayrıntılı bir günlük kaydı moduna geçin, daha sonra birbirinden uzaklaşan simülasyonlardan 2 dosya al ve nerede yanlış gittiğini görmek için diff aracını karşılaştır
  • Tüm değişkenlerinizi oyun durumundaki başlangıç ​​desyncs kaynağı
  • Tüm oyun simülasyonunun, zaman zaman sahtekarlıkları önlemek için her seferinde aynı sırayla gerçekleşmesi gerekiyor, bu yanlışlığı yapmak inanılmaz derecede kolay, oyun simülasyonunuzu bunu en aza indirecek şekilde yapılandırmanız tavsiye edilir. Ben gerçekten bir yazılım tasarım deseni adam değilim, ama bu durumda muhtemelen iyi bir fikir - oyun simülasyonu güvenli bir kutu gibi bir model olduğunu düşünebilirsiniz ve oyun durumunu değiştirmenin tek yolu eklemek "mesajlar" veya "komutlar", yalnızca oyun durumunun dışındaki herhangi bir şeye erişimi sağlar (ör. oluşturma, ağ oluşturma, vb.). Bu yüzden, çok oyunculu bir oyun için simülasyonu ağ üzerinden bağlamak, bu komutları ağ üzerinden göndermek veya aynı simülasyonu tekrar oynatmak, komut akışını ilk defa kaydetme durumudur.

1
Birlik, aslında, Veri Odaklı Teknoloji Yığınları için yeni Unity Physics sistemi ile platformlar arası bir determinizm hedefi için çalışıyor, ancak anladığım kadarıyla, halen devam eden bir çalışma ve henüz raftan tam kullanıma hazır değil.
DMGregory

Deterministik olmayan bir SIMD talimatının bir örneği nedir? Gibi yaklaşık olanları mı düşünüyorsunuz rsqrtps?
Ruslan

@DMGregory, zaten kullanabildiğiniz gibi önizlemede olmalıdır - ama söylediğiniz gibi henüz bitmemiş olabilir.
Joe

@Ruslan evet rsqrtps / rcpps sonuçları uygulamaya bağlıdır
Joe

5

Aradığınız türden bir cevap olup olmadığından emin değilim, ancak hesaplamaları merkezi bir sunucuda çalıştırmak için alternatif olabilir . İstemcilerin yapılandırmayı sunucunuza göndermesini sağlayın, simülasyonu gerçekleştirmesine izin verin (veya önbelleğe alınmış bir tane almasını sağlayın) ve sonuçları daha sonra istemci tarafından yorumlanıp grafiklere işlenmesini sağlayın.

Elbette bu, istemciyi çevrimdışı modda çalıştırmak zorunda kalabileceğiniz planları kapatır ve simülasyonların ne kadar yoğun hesaplama gerektirdiğine bağlı olarak, çok güçlü bir sunucuya ihtiyacınız olabilir. Ya da birden çokları, ancak en azından aynı donanım ve yazılım konfigürasyonlarına sahip olmalarını sağlama seçeneğiniz var. Gerçek zamanlı bir simülasyon zor olabilir ama imkansız olmayabilir (canlı video akışlarını düşünün - çalışırlar, ancak biraz gecikmeli).


1
Tamamen katılıyorum. Bu, tüm kullanıcılarla paylaşılan bir deneyimi garanti etmektir. gamedev.stackexchange.com/questions/6645/… benzer bir konuyu tartışıyor, müşteri tarafı ile sunucu tarafı fiziği arasındaki farkı karşılaştırıyor.
Tim Holt 23

1

% 100 güvenilir olmasa da, çoğu zaman iyi çalışması gerektiği ve uygulanması çok kolay olan bir karşı sezgisel öneri vereceğim.

Hassasiyeti azaltın.

Önceden belirlenmiş bir sabit zaman adımı boyutu kullanın, fiziği standart çift duyarlıklı şamandırada her zaman adımı boyunca uygulayın, ancak daha sonra her değişkenden sonra tüm değişkenlerin çözünürlüğünü tek duyarlığa (veya daha da kötü bir şeye) azaltın . Daha sonra, kayan nokta yeniden sıralamanın muhtemel sapmalarının çoğu (aynı programın bir referans çalıştırmasıyla karşılaştırıldığında) muhtemelen ortaya çıkarılabilir, çünkü bu sapmalar, azaltılmış hassasiyette olmayan basamaklarda meydana gelir. Bu yüzden, sapma, sonunda kayda değer bir Lyapunov birikmesi (Kelebek Etkisi) şansını yakalamaz.

Elbette, simülasyon (gerçek fiziğe kıyasla) olabileceğinden biraz daha az doğru olacaktır, ancak programınızın tamamı aynı şekilde yanlış olduğu sürece bu gerçekten kayda değer değildir .

Şimdi, teknik olarak konuşursak, elbette, bir yeniden düzenlemenin daha yüksek önem derecesine ulaşan bir sapmaya neden olabileceği muhtemeldir, ancak sapmalar gerçekten sadece yüzmeye bağlıysa ve değerleriniz sürekli fiziksel büyüklükleri gösteriyorsa, bu son derece düşüktür. doubleİkisi arasında yarım milyar değer bulunduğunu unutmayın single, bu nedenle çoğu simülasyondaki zaman adımlarının büyük çoğunluğunun simülasyon çalışmaları arasında tamamen aynı olması beklenebilir. Bir sapmanın nicelleştirme yoluyla yaptığı birkaç durum umarım çok uzun sürmeyen simülasyonlarda olacaktır (en azından kaotik dinamiklerle değil).


Ayrıca sormak istediklerinizin tam karşıt yaklaşımını düşünmenizi tavsiye ederim: belirsizliği benimseyin ! Eğer davranış biraz özgün değilse, o zaman bu aslında gerçek fizik deneylerine daha yakındır. Öyleyse, neden her simülasyon çalışması için başlangıç ​​parametrelerini kasıtlı olarak rastgele seçmiyorsunuz ve simülasyonun sürekli olarak birden fazla deneme üzerinde başarılı bir şekilde gerçekleşmesini gerekli kılıyorsunuz? Bu, fizik hakkında ve makinelerin sadece bir simülasyonda gerçekçi olan süper kırılgan olanlardan ziyade yeterince sağlam / doğrusal olacak şekilde nasıl tasarlanacağını öğretecektir.


Yuvarlama işlemi bir işe yaramaz çünkü yüksek hassasiyetli sonuç deterministik değilse, sonuçta bir sistemde bir diğerine ve diğer sistemde bir sonuç elde edilir. Örneğin, her zaman en yakın tamsayıya yuvarlayabilirsiniz, ancak daha sonra bir sistem bilgisayarı 1.0 ve diğeri 0.999999999999999999999999999999999999999999 'i hesaplar ve farklı yuvarlar.
yoyo

Evet, cevapta dediğim gibi bu mümkün. Ancak oyun fiziğinde diğer aksaklıklar gibi, nadiren de olur . Yani yuvarlama yapar yardım. ( Olsa da aşağıya
inmezdim; önyargıdan

0

Numaraları saklamak için kendi sınıfını oluştur!

Hesaplamaların tam olarak nasıl gerçekleştirileceğini biliyorsanız, deterministik bir davranışı zorlayabilirsiniz. Örneğin, uğraştığınız tek işlem çarpma, bölme, toplama ve çıkarma ise, tüm sayıları sadece rasyonel bir sayı olarak göstermeniz yeterli olacaktır. Bunu yapmak için, basit bir Rasyonel sınıfı iyi yapacaktır.

Ancak daha karmaşık hesaplamalar yapmak istiyorsanız (örneğin, örneğin trigonometrik fonksiyonlar), o zaman bu fonksiyonları kendiniz yazmak zorunda kalacaksınız. Bir sayının sinüsünü almak istiyorsanız, sadece yukarıda belirtilen işlemleri kullanırken sayının sinüsüne yaklaşan bir fonksiyon yazmanız gerekir. Bunların hepsi yapılabilir, ve bence diğer cevaplardaki kıllı detayların çoğunu çevreledi. Tradeoff, bunun yerine biraz matematikle uğraşmak zorunda kalacaksınız.


3
Rasyonel aritmetik, her türlü sayısal entegrasyon için tamamen pratik değildir. Her zaman aşaması ancak * / + -o zaman bile olsa , paydalar zaman içinde daha da büyüyecek ve büyüyecek.
leftaroundabout

Bütünleşmeyi düşünmeden bile, bunun iyi bir çözüm olmayacağını umardım, çünkü sadece birkaç çarpma veya bölme yaptıktan sonra, payınızı ve paydaşınızı temsil eden sayıların 64-bit bir tamsayıdan taşması beklenir.
jvn91173

0

Burada terminolojinin bir karışıklığı var. Fiziksel bir sistem tamamen deterministik olabilir, ancak faydalı bir süre için modellemesi imkansız olabilir, çünkü davranışı başlangıç ​​koşullarına karşı son derece hassastır ve başlangıç ​​koşullarında sonsuz küçük bir değişiklik tamamen farklı davranışlar üretecektir.

İşte davranıştır gerçek cihazın bir video kasıtlı bir istatistiksel anlamda hariç öngörülemeyen:

https://www.youtube.com/watch?v=EvHiee7gs9Y

N adımdan sonraki sonucun, başlangıç ​​koşullarının N. Ondalık basamağına bağlı olduğu basit matematiksel sistemleri (sadece toplama ve çarpma kullanarak) inşa etmek kolaydır. Böyle bir sistemi tutarlı bir şekilde modellemek için yazılım yazmak, kullanıcının sahip olabileceği herhangi bir bilgisayar donanımı ve yazılımı üzerinde, mümkün olmayan bir bütçeniz olsa bile , her olası donanım ve yazılım kombinasyonunda uygulamayı test edin.

Bunu düzeltmenin en iyi yolu, soruna kaynağında saldırmaktır: Oyunun fiziğini tekrarlanabilir sonuçlar almak için olması gerektiği kadar belirleyici yapmak.

Alternatif olan, bir şeyi modellemek için bilgisayar yazılımını değiştirerek onu deterministik hale getirmeye çalışmaktır. fiziğin belirttiği gibi olmayan bir şeyi . Sorun, fiziği açıkça değiştirmeye kıyasla, sisteme daha fazla karmaşıklık katmanı eklemiş olmanızdır.

Spesifik bir örnek olarak, oyununuzun katı cisimlerin çarpışmalarını içerdiğini varsayalım. Eğer sürtünmeyi görmezden bile, kesin hareket halindeyken dönebilecek rastgele şekilli nesneler arasındaki çarpışmaların modellenmesi pratikte imkansızdır. Ancak durumu değiştirirseniz, yalnızca nesneler dönmeyen dikdörtgen tuğla olur, hayat çok daha basitleşir. Oyununuzdaki nesneler tuğla gibi görünmüyorsa, bu gerçeği bazı "fiziksel olmayan" grafiklerle gizleyin; örneğin, kelimenin tam anlamıyla bazı dumanların veya alevlerin arkasındaki çarpışma anını veya bir çizgi film-metin balonu "Ouch" u gizleyin ya da her neyse.

Oyuncu, oyunu oynayarak oyun fiziğini keşfetmelidir . Öz tutarlı olduğu ve akla yatkın olması için sağduyulu deneyime benzer olduğu sürece "tamamen gerçekçi" olmaması önemli değildir.

Fiziğin kararlı bir şekilde davranmasını sağlarsanız, bunun bir bilgisayar modeli de en azından yuvarlama hatalarının alakasız olacağı anlamında kararlı sonuçlar üretebilir.


1
Terminolojide herhangi bir karışıklık görmüyorum. OP, potansiyel olarak kaotik bir sistemden deterministik davranış istiyor. Bu tamamen yapılabilir.
Mark

Daha basit şekiller kullanmak (daireler ve dikdörtgenler gibi) sorunu hiç değiştirmez. Hala çok fazla trigonometrik fonksiyon, sqrt, vs ... ihtiyacınız var ...
jvn91173

-1

Tek kayan nokta kesinliği yerine çift ​​kayan nokta kesinliği kullanın . Mükemmel olmasa da, fizik'inizde deterministik sayılacak kadar kesin. Ay'a çift kayan nokta hassasiyetli bir roket gönderebilirsiniz, ancak tek kayan nokta hassasiyetli değil.

Gerçekten mükemmel bir determinizme ihtiyacınız varsa, sabit nokta matematik kullanın . Bu size daha az hassasiyet verecektir (aynı sayıda bit kullandığınız varsayılarak), ancak deterministik sonuçlar. Sabit nokta matematik kullanan hiçbir fizik motorunun farkında değilim, bu nedenle bu rotaya gitmek istiyorsanız kendiniz yazmanız gerekebilir. (Size karşı tavsiye edeceğim bir şey.)


11
Çift duyarlıklı yaklaşım , kelebek etkisinden kaynaklanıyor . Dinamik bir sistemde (bir fizik sim gibi), başlangıç ​​koşullarındaki küçük bir sapma bile geri bildirim yoluyla çoğalabilir, kartopu fark edilebilir bir hataya kadar yükselebilir. Fazladan kalan tüm rakamlar bunu biraz daha geciktiriyor; kartopunun sorun yaratacak kadar büyürken biraz daha yuvarlanmasına neden oluyor.
DMGregory

2
Aynı anda iki hata: 1) Çift kayan noktalar aynı problemlere maruz kalır ve genellikle problemi sadece geleceği hata ayıklamak için zorlaştırır. 2) Sabit noktanın kayan noktadan daha az kesin olması gerektiğini bildiren hiçbir kural yoktur. Eldeki ölçeğe ve probleme veya sabit nokta numarası için kullanmaya hazır olduğunuz belleğe bağlı olarak, daha az hassas, eşit derecede hassas veya daha hassas olabilirler. "Daha az kesin olduklarını" söylemek mantıklı değil.
phresnel

@phresnel, sabit nokta hassasiyetinin bir örneği olarak, IBM 1400 serisi isteğe bağlı olarak hassas sabit nokta ondalık matematik kullandı. Her numaraya 624 basamak ataysanız, çift duyarlıklı kayan nokta aralığını ve hassasiyetini aştınız .
Mark

@ phresnel (2) İyi nokta. Aynı sayıda bit kabul etmek için cevabımı güncelledim.
Evorlor

-2

Memento Pattern'i kullanın .

İlk çalıştırmanızda, her karedeki konumsal verileri veya ihtiyacınız olan ölçütleri kaydedin. Bu çok uygun değilse, sadece her karede yapın.

Sonra simülasyonu yeniden yarattığınızda, isteğe bağlı fiziği takip edin, ancak konum verilerini her karede güncelleyin.

Aşırı basitleştirilmiş sahte kod:

function Update():
    if(firstRun) then (SaveData(frame, position));
    else if(reproducedRun) then (this.position = GetData(frame));

9
Bunun OP'nin vakası için işe yaradığını sanmıyorum. Diyelim ki, ikimiz de oyunu farklı sistemlerde oynuyoruz. Her birimiz yapboz parçalarını aynı şekilde yerleştiririz - geliştirici tarafından önceden tahmin edilmeyen bir çözüm. "Başlat" ı tıkladığınızda, bilgisayarınız fiziği, çözümün başarılı olması için simüle eder. Aynısını yaptığımda, simülasyondaki bazı küçük farklar benim (özdeş) çözümümün başarılı olarak derecelendirilmemesine neden oluyor. Burada, başarılı koşunuzdaki memento ile görüşme fırsatım yok, çünkü makinenizde, o anda değil.
DMGregory

@DMGregory Bu doğru. Teşekkür ederim.
jvn91173
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.