İşlevsel bir dille oyun yazmanın zorlukları ve faydaları nelerdir?


81

İşlevsel dillerin oyun yazımı için en yaygın kullanılan olmadığını bilmeme rağmen, herhangi bir programlama bağlamında ilginç görünecek gibi görünen birçok fayda var. Özellikle paralelleştirme kolaylığı, odak gittikçe daha fazla işlemciye doğru ilerledikçe çok faydalı olabileceğini düşünüyorum.

Ayrıca, .NET ailesinin yeni bir üyesi olarak F # ile doğrudan XNA ile kullanılabilir, örneğin LISP, Haskell, Erlang, vb.

Herhangi biri işlevsel kodla oyun yazma tecrübesine sahipse, pozitif ve negatif olan ne oldu? Ne için uygun, ne değil?

Düzenleme: Bunun için tek bir iyi cevap olduğuna karar vermek zor, bu yüzden topluluk wiki yazısı olarak daha uygun olabilir.


3
en sevdiğim oyunlardan biri (Rogue) LISP'de yazılmışken, bu soru (ve cevap potansiyeli) benim için çok ilginç.
Justin L.

Rogue'in LISP'de yazıldığını bilmiyordum, ama bunu ilginç buldum. Klasik oyun :)
McMuttons

2
Neden bahsettiğinden emin değilim. Rogue C. roguebasin.roguelikedevelopment.org/index.php?title=Rogue
Mason Wheeler,

2
Orijinal Rogue'nin C'de olması konusunda haklı olduğunuza eminim, çünkü Unix'te yazılmış, ancak Lisp'ta kesinlikle birkaç Rogue klonu var : cl-user.net/asp/root-dir (doğrudan Oyun bağlantısı değil) , çok özel karaktere sahipti, bağlantı kopmuş gibi görünüyor).
Cyclops

Yanıtlar:


57

Şu anda Haskell'de bir oyun üzerinde çalışıyorum. Genel olarak işlevsel programlama için konuşamam, ancak özellikle Haskell için:

İyi

Bunlar Haskell'i gerçekten öne çıkaran harika şeyler.

  • Saflık, kodunuzla ilgili akıl yürütmenin çok daha kolay olduğu anlamına gelir. Bir değişkenin "geçerli" değeri veya belirli bir işlevi kullanmanın bir şekilde küresel durumunuzla çakışıp çakışmadığı konusunda endişelenmenize gerek yoktur. Ayrıca, paralellik ve eşzamanlılığın çalışmak için çok daha kolay olduğu (ve çoğu durumda önemsiz) olduğu anlamına gelir. Bu şeyler oyun geliştiricileri için bir nimettir olabilir.
  • Haskell, kendi yaratıcılığınızın soyutlarını kullanarak çok yüksek bir seviyede yazmayı çok kolaylaştırır. Haskell'deki çok genel koddan çok genel kod yazmak genellikle daha kolaydır ve bunun yararları daha az geliştirme süresi ve daha kolay kod anlama ile kendini gösterir. Haskell'de, bir arayüz kullanmanın tamamen yeni bir dil kullanmak gibi bir şey olduğunu bildiğim diğer dillerden daha doğru (hala Haskell ekosisteminin geri kalanının faydalarını koruyor). Dillerin çoğu dilde ne diyor, Haskell bir kütüphane diyor ve zorlama hissetmiyor. Eğer psuedocode'da oyununuz hakkında akıl yürüten bir sebep bulursanız, muhtemelen basit bir arayüz yazıp gerçek bir kod oluşturabilirsiniz ve genellikle buna değecektir.
  • Bu, diğer cevaplarla çelişebilir, ancak Haskell, zorunlu kodu kullanma konusunda bildiğim diğer dillerden daha iyidir. Saflığın kısıtları, Haskell'in "değerlendirme" (ifadeleri azaltma) ve "yürütme" (yan etkiler yapma) kavramları arasında bir ayrım olduğu anlamına gelir. Ne zaman ve nasıl yan etkilerin sözde "zorunlu" diller tarafından benzersiz bir şekilde gerçekleştirildiğini kontrol edebilirsiniz. Daha önce saflık hakkında söylediklerime rağmen, bazı C bağları hala çok zorunluluktur (OpenGL, sana bakıyorum), bu yüzden zorunlu kod üzerindeki bu hassas kontrol çok açıktır. En terbiyeli C programcılarının bile alıştıktan sonra takdir etmeleri olasıdır.
  • GHC oldukça hızlı ikili dosyalar üretir. Ortak C derleyicilerinden oluşturulan ikili dosyalar kadar hızlı değillerdir, ancak bir büyüklük sırasına göredir ve yorumlanmış bir dille elde edeceğinizden çok daha hızlıdırlar. Oyununuzu Python gibi diğer yüksek seviyeli dillerde yazamıyor olsanız bile, çok yavaş olacaktır, Haskell'de yapabilmeniz için iyi bir şans var.
  • Haskell'de oyunla ilgili pek çok kitaplık bulunmamasına rağmen, aşağıdaki "Kötü" başlığı altında belirtildiği gibi, Haskell dış işlev arayüzü, şimdiye dek kullandığım en kolayıdı. Haskell'da neredeyse sadece yazarak C'ye bağlayabilirsiniz.

Kötü

Bunlar iyi değildir ama olmadan çalışılan şeylerdir çok fazla çaba.

  • İşlevsel olmayan dillerle çalışmaya alışkınsanız Haskell'i öğrenmek için gereken zaman ve çaba oldukça yüksek olabilir. Dilin kendisi çok zor değil, ancak ortak dil uzantılarını ve çok sayıda kütüphaneyi hesaba kattığınızda (unutmayın, diğer dillerdeki dil özelliklerini düşünebileceğiniz birçok şey Haskell'deki kütüphanelerdir), çok daha fazla hüzünlü görünmektedir. Benim düşünceme göre, buna değer, ancak diğerleri aynı fikirde olmayabilir.
  • Bazı insanlar tembellikten çok şikayet eder. Ne yaptığınızı biliyorsanız, izlemesi zor olan uzay sızıntılarına neden olmayacaksınız (birkaç yıldan beri bir alan sızıntısı yaratmadım), ancak yeni başlayanlar bununla daha fazla sorun yaşıyor. Bu insanları vurmak ve bunun bir sorun olmadığını iddia etmek aptallık olur, ancak bunun kolayca deneyimle çözülebilecek bir sorun olduğunu iddia edeceğim.
  • Haskell'de oyun yapmak için pek çok büyük kütüphane yok ve pek çok Haskellers de oyun yazmıyor, bu yüzden kaynakları bulmak ve bu konuda yardım etmek zor.

Çirkin

Bunlar, üstesinden gelmek için büyük çaba harcayacak şeylerdir.

  • Kaynak yoğun bir oyun yazıyorsanız, GHC'nin çöp toplayıcısı sizi çok zorlayabilir. Bu bir nesiller, dünyayı durdurma GC'sidir, bu yüzden arada bir, birkaç kare düşürebilirsiniz. Bazı oyunlar için bu sorun değil, ama diğerleri için büyük bir problem. Ben ve Haskell kullanan diğer bazı oyun geliştiricileri, GHC için uygulanan yumuşak gerçek zamanlı bir GC görmek istiyoruz, ancak bu konuda henüz hiçbir çaba gösterilmiyor. Şu anda, bu konuda çalışmaktan endişe duymuyorum (ve bundan henüz hiç çerçeve atmadığını görmedim), ancak en az bir başka takım ana oluşturma döngüsünü C'ye koymaya çalıştı.

2
FRP hakkında ne düşünüyorsun?
Wei Hu,

4
@Wei Hu: FRP fikrinin büyük bir hayranıyım ve birkaç farklı anlambilim oluşturmak ve birkaç uygulama yazmak da dahil olmak üzere oldukça kapsamlı bir şekilde araştırdım. En iyi uygulamalar hala ciddi anlamsal ve / veya uygulama hatalarına sahiptir. Oyunun gelişimi için uygun olduklarını söyleyebilirim, ancak geleneksel yaklaşımlara göre (henüz) pek çok avantajı yok.
Jake McArthur,

1
Anonim bir kullanıcı "çirkin" bölümünü silerek bu cevabı düzenlemeye çalıştı. "Haskell'deki çöp toplayıcısı şimdi 2011 itibariyle eşzamanlı, paralel ve nesillerdir ( ghc.haskell.org/trac/ghc/blog/new-gc-preview )"
Jari Komppa

1
Ne yazık ki, bu aslında doğru değil. Eşzamanlı GC'nin küçük genel gelişmeyi haklı çıkarmak için çok karmaşık olduğu bulundu ve bir araya gelmedi.
Jake McArthur

1
@ Hi-Angel C üreten eski bir GHC arka ucu var, ancak yerel kod oluşturucudan veya LLVM arka ucundan farklı değil. Hala GHC çalışma zamanını gerektirir. Ayrıca, bir C toplayıcısı hakkında, çöp toplayıcılardan kaçınmayı kolaylaştıracak özel bir şey yoktur. GC'yi elimine etmek bu kadar kolay ve ucuz olsaydı, diğer arka uçlar da muhtemelen yapardı.
Jake McArthur

19

Geçen yılı Haskell'de ticari bir oyun motoru geliştirmek için harcadım ve bizim için deneyim son derece olumluydu. Oyun dünyamız karmaşık ve Haskell editör formatından oyun motoru formatına dönüşüm sürecini modellemeyi kolaylaştırdı. Bu kodun zorunlu bir dilde nasıl görüneceğini düşünmekten nefret ediyorum.

Uzay sızıntıları bazı durumlarda ortaya çıkmış ve biraz sıkıntıya neden olmuş olsa da, genel şemada küçük bir miktar olmuştur (örneğin, benzer boyuttaki bir Java projesinde çıkmazlar bulmakla karşılaştırıldığında) ve bir kez düzeltildiler. , sabit kaldılar.

Yampa'ya benzer bir FRP kullanıyoruz ve bununla ilgili bir öğrenme eğrisi var, ancak bir kez bittiğinde, deneyim çok olumlu. Kütüphaneler bizim için sorun olmadı - ihtiyacımız olan her şey mevcuttu. Çöp toplama gecikmeleri, gömülü bir platform için özel bir sorundur. Animasyonu yönetmek için bazı C ++ kullandık. Performans da bunun gömülü bir platform olmasıyla ilgili bir sorun olmuştur (= yavaş işlemci). Bazı C'ler yaptık ve ayrıca hızlandırmak gibi yeni çıkan Haskell teknolojilerine bakıyoruz. C ++ animatörü erken bir tasarım kararıydı ve kodun çok yavaş olduğu yerler sadece çok küçük alanlar. Uzun vadede, tüm C'lerimizi Haskell'e çevirmek istiyoruz.

Haskell zor bir işi kolaylaştırmıştır ve az önce bahsettiğim tüm zorluklar, ürettiğimiz, temiz, bakılabilir ve kırılmaz olan karmaşık kod miktarına kıyasla küçüktü. Paralelcilik çok yakında oyun gelişiminde bir sorun olacak ve bununla başa çıkabilmemiz için son derece iyiyiz. Söylediklerimin bir kısmı küçük projeler için geçerli olmayabilir, çünkü uzun zamandır bu işteyiz, bu nedenle öğrenme eğrileri, kütüphane desteği, vb. Gibi başlangıç ​​maliyetleri daha az sorun yaratıyor.


7
Bu cevabı gönderdiğinden beri 5 yıla yaklaşıyor; güncellemek için istekli misiniz Ticari oyun motoru nasıl çalıştı? Hangi parçaların değerli olduğu kanıtlandı? Umduğunuz gibi paralellikten yararlanabildiniz mi?
Levi Morrison,

17

Dave, bazı mükemmel noktalardan bahseder, ancak Haskell'in her iki sorunu da çözdüğünü belirtmek zorundayım. Vatansızlık, Devlet monad'ı kullanılarak atlanabilir (EDIT: pek değil - ayrıntılar için aşağıya bakınız) ve sıralama, IO monad'ı (EDIT: veya bu konuda başka herhangi bir monad ...) kullanılarak yapılabilir .

Karşılaşacağınız zorluklar (ve hem oyun programlamayı hem de Haskell'i öğrenmeye çalıştım), daha çok bu satırlar boyunca. (Bunların hepsi Haskell'e özgü, çünkü henüz başka bir FP diliyle henüz derinlemedim.)

  • FP Öğrenme eğrisi: FP, yinelemeli programlamadan eksiksiz bir zihniyet değişimi gerektirir. Döngü yerine haritalar ve kıvrımlar açısından düşünmeyi öğrenmek, alışkın değilseniz zihinsel bir antrenman gerektirir.
  • Mathy öğrenme eğrisi: Haskell, tasarımcılarının matematiksel karmaşıklığı ile hem kutsanmış hem de lanetlenmiştir, çünkü FP'nin temellerini öğrendikten sonra, monadlarla, morfizmlerle, oklarla ve zorlu olmamakla birlikte, diğer tüm düşüncelere ev sahipliği yapıyor kendi içinde ve çok soyut.
  • Monad'lar: Bu yavruları zihninizi etrafa sarmak özellikle zor değil, özellikle Eric Raymond'ın “fonksiyon kompozisyonunu fonksiyon çağrılarının sıralanmasını zorlama yoluna dönüştürmek için bir kesmek” olduğunu söylediklerini kabul ederseniz . Maalesef (bu Haskell'in popülerliği arttıkça daha da iyi bir hale gelse de), monadların birçok açıklaması ya programcıların çoğunun ("endofunctorlar kategorisindeki monoitler!") Ya da tamamen yararsız bir analoji üzerinden geliyor. Brent Yorgey'in üzücü derecede kesin bir örneği, "monadlar burritolar gibidir !" Şaka yapıyor mu sanıyorsun? Hiç kimsenin bir öğretici bu kadar aptalca bir benzetmeyle gelemeyeceğini mi? Tekrar düşün .)
  • Ekosistem: Yoldaki diğer tüm darbelerin ötesine geçmeyi başardıysanız, hala büyük ölçüde deneysel bir dille çalışmanın pratik günlük gerçekliğine karşı yanak ve zinde olursunuz. Buraya geldiğinde Tanrı sana yardım etsin. Ben Scala veya F #, ya da en azından orada başka bir dil için jonesing ciddiye başladı İşte burada bazı diğer kütüphanelerle çalışabilirlik garantisi. Bir zamanlar, Windows'taki OpenGL kütüphanelerini bağlayıp yükleyebilmek için Haskell'e ulaştım. Bu beni oldukça iyi hissettirdi. Sonra OpenGL ciltleri yeniden serbest bırakıldı ve yaptığım her şeyi kopardı. Haskell-diyarındaki hayat bu. Açıkçası, bu bir acı olabilir. Bullet motoru için bir sarıcı ister misin? Tehlikede - abandonware olarakgeçen yılın kasım ayından itibaren. Ogre3d sever misiniz? Hackage, sadece kütüphanenin bir alt kümesine bağlar . Alt satırda, oyun geliştirme için dayak yolu kapalı bir dile bağlı kalırsanız, temel sıhhi tesisat üzerinde çalışarak sürüyü takip edip C ++ ile sıkışmış olduğunuzdan çok daha fazla zaman geçireceksiniz.

Bunun ters tarafı, işlerin hızla geliştiğidir. Ve gerçekten hepsi deneyimden ne istediğine bağlı. Bir oyun inşa etmek ve şöhret ve servet aramak için web sitenize koymak ister misiniz? C ++ veya Python ile yapıştırın. Ancak, süreçlerinizi geliştirmenizi gerektirecek yeni bir şey öğrenmek istiyorsanız, işlevsel bir dil deneyin. Öğrenirken sadece kendinize çok sabrınız.

Antti Salonen'in, Haskell oyun programlamasıyla tekrar tekrar açtıklarını anlatan ilginç bir blogu var . Okumaya değer.

Düzenleme (bir yıl sonra): Artık Devlet monadını daha fazla çalıştığımdan, devletin belirli bir işlevin dışında kalması amaçlanan için iyi bir çözüm olmadığını fark ettim. Vatansızlık için gerçek çözümler IOVar, ST, MVar (iplik güvenliği için) Haskell'de veya yine de geliştiriciden gizlenmiş olan iç durumu yönetmek için Oklar ve FRP kullanan Yampa gibi bir şey aracılığıyla bulunur. (Bu liste zorluk sırasına göre sıralanmıştır, ancak ilk üçü monadları anladığınızda özellikle zor değildir.)


1
Orada bazı iyi düşünceler, oldukça Haskell'e özgü olsa bile, bunların çoğu saçak diline uygulanan düşünceler olduğunu düşünüyorum. Kısaca bahsettiğiniz gibi, burası F # gibi dillerin parlama potansiyeline sahip olduğunu düşünüyorum. Örneğin, C # ile eyalet / UI Taşıma ve ardından vb potansiyel yol bulma, AI gibi algoritmalar için F # mantık modüllerine sahip
McMuttons

5

Amaç Caml!

İşlevsel dilleri kullanmak çoğu yazılım geliştirme türünde büyük bir avantaj olabilir, çünkü çoğunlukla geliştirme süresini önemli ölçüde kısaltırlar. Bir sunucuya arka uç bir oyuna ya da istemcideki AI ve mantık katmanlarını işlevsel bir dilde yazmak için büyük bir potansiyel görebiliyorum. Ve herkesin bildiği gibi, LISP NPC komut dosyası için kullanılmıştır.

Bir oyunun ön yüzünü işlevsel bir dilde yazmaya çalışacak olsaydım, kesinlikle melez bir dil olan Objektif Caml'a giderdim . Bu bir ML soyundan ve yinelemeli ve işlevsel stillerin karışmasına izin veriyor, durumsal nesnelerle nesnel bir sistemi var. (Caml, F # 'nin modellendiği dildir.)

OpenGL ciltlemeleri kusursuz çalışıyor gibi görünüyor ve insanlar OCaml'da uzun süredir oyunlar yapıyorlar. Dil derlenebilir ve potansiyel olarak çok hızlıdır (çok uzun zaman önce bazı ölçütlerde C'yi kazanmıştır, işlerin nasıl yürüdüğünü değil).

Ayrıca tonlarca kütüphane var. Bilgisayar bilimlerinden ciltlemeye, her türlü kütüphaneye kadar her şey.



3

Avantajlar için, Temiz Oyun Kütüphanesini (http://cleangl.sourceforge.net/) kontrol edin ve platform oyununu kontrol edin. Kafanızı bir sözdizimine soktuğunuzda (denemenizi öneriyorum) yapıların saf şıklığını ve kaynağın ifade ettikleri kavramlarla ne kadar yakından eşleştiğini göreceksiniz. Ek bir bonus olarak, devletin soyutlanması ve açıkça devletin dışına çıkma zorunluluğu, kodunuzu çok daha çok çekirdekli dostu yapar.

Öte yandan, büyük bir paradigma kayması gerektirir. Bir anda bunu düşünmeden yapmaya alışkın olduğunuz şeylerin birçoğu artık yok ve basitçe yanlış kalıpları düşündüğünüz için nasıl çözeceğinizi şaşırtıyor olacaksınız.


2

Benim açımdan en büyük zorluklar şöyle olacaktır:

  • İşlevsel dillerin vatansızlığı : Oyunlardaki fikir, her bir varlığın bir durumu olduğu ve bu durumun kareden çerçeveye değiştirildiğidir. Bu davranışı bazı dillerde taklit etmek için mekanikler var (örneğin, plt şemasında "!" İle işlev görür) ancak bu doğal olmayan bir şeydir.
  • Yürütme sırası : Oyunlarda bazı kod bölümleri yürütmeden önce bitecek diğer kod bölümlerine bağlıdır. İşlevsel diller genellikle bir işlev bağımsız değişkenlerinin yürütme sırası hakkında hiçbir garanti vermez. Bu davranışı taklit etmenin yolları vardır (örneğin (begin..., plt şemasında " ").

Bu listeyi genişletmekte özgürsünüz (ve belki de bazı olumlu puanları eklemek için ^ ^).


1
Yürütme sırası Haskell gibi katı olmayan bir dilde değişebilir, ancak diğer kod bölümlerine bağlı kod bölümleri için sorunlara neden olmaz. Bunu talep üzerine bir değerlendirme olarak düşünebilirsiniz. Sonuç gerekli olana kadar bir hesaplama yapılmaz. Bence sizi üzecek tek yol performans açısından. Örneğin, bazı durumlarda iyi önbelleğe almayı zorlaştırabilir, çünkü hesaplamalar arasındaki bağımlılığı belirtmekten başka değerlendirme sırasını kontrol edemezsiniz.
Jason Dagit

1

Kodunuzu C / C ++ dilinde yazabilir ve komut dosyanız için Embedded Common Lisp gibi bir gömülü dil kullanabilirsiniz. Bunları farklı bir platformda derlemek için zor olsa da. Kendi kodlama dilinizi nasıl yazacağınızı öğrenmek için Lisp In Small Pieces'a bakabilirsiniz. Vaktiniz varsa, gerçekten o kadar zor değil.


0

LISP'de basit oyunlar yazdım ve eğlenceliydi ama önerebileceğim bir şey değildi. İşlevsel programlama tamamen sonuçtur. Bu nedenle, verileri işlemek ve kararlar almak için çok kullanışlıdır, ancak temel bir kontrol döngüsü gibi basit temiz kodlar yapmayı zorlaştırdım.

Ben F # öğrenmedim ama bu yüzden çalışmak için çok daha kolay olabilir.


İlk düşüncem, iskele ve durum yönetimini zorunlu bir dille yazmak ve ardından oyun mantığı ve işlevsel bitler yapmak olabilir. .NET ve C # / F # ile, örneğin, aynı kütüphaneleri kullandıkları ve bildiğim gerçek bir ceza olmadan birbirleriyle konuşabilecekleri için bu çok kolay olurdu.
McMuttons,

-1

olumlu olacağını performans ve taşınabilirlik ve olumsuz olacağını karmaşıklığı yönetmek , oyun bugün ciddi karmaşıktır ve bu tür fonksiyonel programlamada uygulamak zordur nesne yönelimli metodoloji veya genel programlama olarak karmaşıklığı daha iyi yönetebilir araçları veya programlama dili, gerek dil.


11
Benimle dalga mı geçiyorsun? FP, steroidlerin genel programlamasıdır. Veri türlerini hem genelleme yapabilme ve işlevlerini FP karmaşıklığı yönetmek için ciddi güç verir.
rtperson, 22.03.2010

FP'nin en güçlü yanlarından birinin genelleştirilmiş kod yapabilme kabiliyeti olduğuna katılıyorum.
McMuttons
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.