शुद्ध कार्यात्मक प्रोग्रामिंग और खेल राज्य


12

एक कार्यात्मक प्रोग्रामिंग भाषा में राज्य (सामान्य रूप से) को संभालने के लिए एक सामान्य तकनीक है? वैश्विक स्थिति को संभालने के लिए हर (कार्यात्मक) प्रोग्रामिंग भाषा में समाधान हैं, लेकिन मैं जहां तक ​​संभव हो, इससे बचना चाहता हूं।

एक शुद्ध कार्यात्मक तरीके से सभी राज्य फ़ंक्शन पैरामीटर हैं। इसलिए मुझे पूरे खेल राज्य (दुनिया, खिलाड़ियों, पदों, स्कोर, संपत्ति, दुश्मन, ...) के साथ एक विशाल हैशमप को सभी कार्यों के लिए एक पैरामीटर के रूप में रखना चाहिए जो किसी दिए गए इनपुट या ट्रिगर पर दुनिया को हेरफेर करना चाहता है। । फ़ंक्शन स्वयं गेमस्टैट ब्लॉब से प्रासंगिक जानकारी चुनता है, इसके साथ कुछ करें, गेमस्टेट में हेरफेर करें और गेमेट को वापस लौटाएं। लेकिन यह समस्या के लिए एक गरीब आदमी समाधान की तरह दिखता है। यदि मैं पूरे गेमस्टैट को सभी कार्यों में लगाता हूं, तो वैश्विक चर या अनिवार्य दृष्टिकोण के विपरीत मेरे लिए कोई लाभ नहीं है।

मैं केवल संबंधित जानकारी को कार्यों में डाल सकता हूं और उन कार्यों को वापस कर सकता हूं जो दिए गए इनपुट के लिए लिए जाएंगे। और एक एकल फ़ंक्शन गेमस्टेट के सभी कार्यों को लागू करता है। लेकिन अधिकांश कार्यों के लिए "प्रासंगिक" जानकारी की बहुत आवश्यकता होती है। move()ऑब्जेक्ट पोज़िशन, वेलोसिटी, टक्कर के लिए मैप, सभी एनीमीज़ की पोज़िशन, करेंट हेल्थ ... की ज़रूरत है, इसलिए यह तरीका काम भी नहीं करता।

तो मेरा सवाल यह है कि मैं एक कार्यात्मक प्रोग्रामिंग भाषा में राज्य की भारी मात्रा को कैसे संभालूं - विशेष रूप से खेल के विकास के लिए?

EDIT: क्लोजर में गेम बनाने के लिए कुछ गेम फ्रेमवर्क हैं। इस समस्या को हल करने के लिए दृष्टिकोण आंशिक रूप से खेल में सभी वस्तुओं को "संस्थाओं" के रूप में पिरो कर एक विशाल बैग में रखना है। एक विशाल मुख्य कार्य स्क्रीन रखा है और संस्थाओं और संभाल घटनाओं ( :on-key-down, :on-init, ...) इस संस्थाओं के लिए और मुख्य प्रदर्शन पाश चलाते हैं। लेकिन यह वह स्वच्छ समाधान नहीं है जिसे मैं खोज रहा हूं।


मैं कुछ समय से इस तरह की बात सोच रहा था; मेरे लिए, यह नहीं है इनपुट कि अद्वितीय समस्या है, तब भी आप फ़ीड (मोटे तौर पर) गैर कार्यात्मक प्रोग्रामिंग में कार्य करने के लिए एक ही तत्व के लिए है के रूप में। नहीं, यह आउटपुट (और बाद में संबंधित अपडेट) यही समस्या है। आपके कुछ इनपुट मापदंडों को संयोजित किया जाना चाहिए; के लियेmove() , आपको संभवतः 'करंट' ऑब्जेक्ट (या इसके लिए एक पहचानकर्ता) में पास होना चाहिए, साथ ही वह दुनिया जिसके माध्यम से आगे बढ़ रहा है, और बस वर्तमान स्थिति और वेग प्राप्त करें ... आउटपुट तब संपूर्ण भौतिकी दुनिया है, या कम से कम बदली हुई वस्तुओं की सूची।
क्लॉकवर्क-म्यूज़ियम

शुद्ध कार्यात्मक का लाभ यह है कि फ़ंक्शन प्रोटोटाइप आपके कार्यक्रम की सभी निर्भरता दिखाता है।
tp1

3
आईएमओ, कार्यात्मक भाषाएं खेल लिखने के लिए खराब रूप से अनुकूल हैं। यह कई समस्याओं में से एक है जिसे आपको हल करने की आवश्यकता होगी। खेलों को प्रदर्शन के बहुत सटीक नियंत्रण की आवश्यकता होती है, और अप्रत्याशित तरीके से स्वाभाविक रूप से होने वाली घटनाओं के कारण शायद ही कभी अच्छी संगति होती है। (शुद्ध) कार्यात्मक भाषाएं तुच्छ रूप से समानांतर होने के लिए उल्लेखनीय हैं, और अनुकूलन के लिए कठिन हैं। एक खेल लिखने के लिए कठोर है, और मैं इसे जटिल (कार्यात्मक प्रोग्रामिंग) के रूप में कुछ लेने से पहले सिर्फ एक विशिष्ट भाषा में करने की सलाह देता हूं।
केसी कुबल

जवाबों:


7

कार्यात्मक प्रोग्रामिंग भाषाओं में साइड-इफेक्ट्स और राज्य कंप्यूटर विज्ञान में एक व्यापक समस्या है। यदि आपने पहले उनका सामना नहीं किया है, तो शायद मोनाड्स पर एक नज़र डालें । हालांकि, उन्हें चेतावनी दी जाती है: वे एक काफी उन्नत अवधारणा हैं और ज्यादातर लोग मुझे (मुझे शामिल) जानते हैं कि उन्हें समझ लेना चाहिए। विभिन्न दृष्टिकोण और ज्ञान आवश्यकताओं के साथ कई, कई ट्यूटोरियल ऑनलाइन हैं। व्यक्तिगत रूप से, मुझे एरिक लिपर्ट सबसे अच्छा लगा।

मैं कोई भी "कार्यात्मक प्रोग्रामिंग" पृष्ठभूमि के साथ एक सी # प्रोग्रामर हूं। यह "मोनाड" चीज क्या है जिसके बारे में मैं सुनता रहता हूं, और यह मेरे लिए क्या उपयोग है?

मोनाड्स पर एरिक लिपर्ट

कुछ बातों पर विचार करना है, हालांकि:

  • क्या आप विशुद्ध रूप से कार्यात्मक भाषा का उपयोग करने पर जोर देते हैं? यदि आप कार्यात्मक प्रोग्रामिंग और गेम डेवलपमेंट दोनों में कुशल हैं, तो शायद आप इसे खींच सकते हैं। (हालांकि मैं यह जानना चाहूंगा कि क्या लाभ प्रयास के लायक हैं।)
  • केवल जहां आवश्यक हो, कार्यात्मक दृष्टिकोण का उपयोग करना बेहतर नहीं होगा? यदि आप एक ऑब्जेक्ट-ओरिएंटेड (या, अधिक संभावना है, एक बहु-प्रतिमान) भाषा का उपयोग कर रहे हैं, तो कुछ भी आपको कार्यात्मक शैली का उपयोग करने से रोकता नहीं है जो कि उन वर्गों को लागू करते हैं जो इससे लाभ उठाते हैं। (Kinda जैसे MapReduce, शायद?)

कुछ अंतिम विचार:

  • समानांतरवाद: जबकि खेल इसे भारी रूप से उपयोग करते हैं, AFAIK अधिकांश यह पहले से ही वैसे भी GPU पर होता है।
  • स्टेटलेसनेस: स्टेट ऑफ म्यूटेशन खेल का एक अभिन्न हिस्सा है। इनसे छुटकारा पाने की कोशिश करना बस बेकार के मामलों को उलझा सकता है।
  • हो सकता है कि यदि आप रुचि रखते हैं, तो कार्यात्मक भाषा एफ # ऑब्जेक्ट-ओरिएंटेड पारिस्थितिकी तंत्र के साथ कैसे खेलती है।

कुल मिलाकर, मुझे लगता है कि भले ही यह अकादमिक रूप से दिलचस्प हो, मुझे संदेह है कि यह दृष्टिकोण व्यावहारिक है और प्रयास के लायक है।


किसी ऐसे विषय के बारे में टिप्पणी क्यों दें जिसका आपको कोई अनुभव नहीं है? सोच के एक प्रतिमान में फंसे लोगों से एक राय।
एंथोनी रायमोंडो

4

मैंने F # (बहु-प्रतिमान, अशुद्ध, कार्यात्मक-प्रथम भाषा) का उपयोग करते हुए कुछ गेम लिखे हैं, जिसमें OOP से लेकर FRP तक के दृष्टिकोण हैं । यह एक व्यापक प्रश्न है, लेकिन मैं अपना सर्वश्रेष्ठ प्रयास करूंगा।

एक कार्यात्मक प्रोग्रामिंग भाषा में राज्य (सामान्य रूप से) को संभालने के लिए एक सामान्य तकनीक है?

मेरा पसंदीदा तरीका एक अपरिवर्तनीय प्रकार है जो पूरे खेल का प्रतिनिधित्व करता है State। मेरे पास वर्तमान का एक परस्पर संदर्भ है जो Stateप्रत्येक टिक को अपडेट किया गया है। यह कड़ाई से शुद्ध नहीं है , लेकिन यह एक स्थान पर परिवर्तनशीलता को सीमित रखता है।

यदि मैं पूरे गेमस्टैट को सभी कार्यों में लगाता हूं, तो वैश्विक चर या अनिवार्य दृष्टिकोण के विपरीत मेरे लिए कोई लाभ नहीं है।

सच नहीं। क्योंकि Stateप्रकार अपरिवर्तनीय है, आपके पास कोई भी पुराना घटक नहीं हो सकता है जो दुनिया को गैर-परिभाषित तरीकों से बदल सकता है। यह GameObjectदृष्टिकोण के साथ सबसे बड़ी समस्या को ठीक करता है (एकता द्वारा लोकप्रिय): Updateकॉल के क्रम को नियंत्रित करना कठिन है ।

और ग्लोबल्स का उपयोग करने के विपरीत, यह आसानी से इकाई-परीक्षण योग्य और समांतर है,

आपको सहायक कार्यों को भी लिखना चाहिए जो समस्या को तोड़ने के लिए राज्य के उप-गुण प्राप्त करते हैं।

उदाहरण के लिए:

let updateSpaceShip ship = 
  {
    ship with 
      Position = ship.Position + ship.Velocity
  }

let update state = 
  { 
    state with 
      SpaceShips = state.SpaceShips |> map updateSpaceShip 
  }

यहाँ updateपूरे राज्य में updateSpaceShipकार्य किया जाता है , लेकिन केवल एक व्यक्ति SpaceShipके अलगाव में कार्य करता है ।

मैं केवल संबंधित जानकारी को कार्यों में डाल सकता हूं और उन कार्यों को वापस कर सकता हूं जो दिए गए इनपुट के लिए लिए जाएंगे।

मेरा सुझाव एक Inputप्रकार बनाना होगा जो कीबोर्ड, माउस, गेम-पैड, आदि राज्यों को रखता है। फिर आप एक फ़ंक्शन लिख सकते हैं जो एक Stateऔर Inputअगले रिटर्निंग लेता है State:

let applyInput input state = 
  // Something

आपको यह पता लगाने के लिए कि यह एक साथ कैसे फिट बैठता है, समग्र खेल कुछ इस तरह दिख सकता है:

let mutable state = initialState ()

// Game loop
while true do
  // Apply user input to the world
  let input = collectInput ()

  state <- applyInput input state

  // Game logic
  let dt = computeDeltaTime ()

  state <- update dt state

  // Draw
  render state

तो मेरा सवाल यह है कि मैं एक कार्यात्मक प्रोग्रामिंग भाषा में राज्य की भारी मात्रा को कैसे संभालूं - विशेष रूप से खेल के विकास के लिए?

सरल गेम के लिए आप ऊपर दिए गए दृष्टिकोण (सहायक कार्यों) का उपयोग कर सकते हैं। कुछ अधिक जटिल के लिए, आप " लेंस " आज़माना चाह सकते हैं " ।

यहां कुछ टिप्पणियों के विपरीत, मैं दृढ़ता से (अशुद्ध) कार्यात्मक प्रोग्रामिंग भाषा में गेम लिखने का सुझाव दूंगा, या कम से कम इसे एक कोशिश दे रहा हूं! मैंने पाया है कि यह पुनरावृत्ति को तेज, कोड-बेस को छोटा और बग को कम सामान्य बनाता है।

मैं भी नहीं लगता कि आपको एफपी भाषा में (अशुद्ध) गेम लिखने के लिए मोनाड्स सीखने की जरूरत है। ऐसा इसलिए है क्योंकि आपका कोड सबसे अधिक अवरुद्ध और एकल थ्रेडेड होने की संभावना है।

यह विशेष रूप से सच है यदि आप एक मल्टीप्लेयर गेम लिख रहे हैं। तब चीजें इस दृष्टिकोण के साथ बहुत आसान हो जाएंगी क्योंकि यह आपको खेल राज्य को तुच्छ रूप से क्रमबद्ध करने और नेटवर्क पर भेजने की अनुमति देता है।

अधिक खेल इस तरह क्यों नहीं लिखे गए हैं ... मैं नहीं कह सकता। हालाँकि, यह सभी प्रोग्रामिंग डोमेन (शायद वित्त को छोड़कर) में सच है, इसलिए मैं इसे एक तर्क के रूप में उपयोग नहीं करूंगा कि कार्यात्मक भाषाएं खेल प्रोग्रामिंग के लिए बीमार हैं।

इसके अलावा अच्छी तरह से लायक एक विशुद्ध रूप से कार्यात्मक रेट्रो है


1

आपकी तलाश क्या है एफआरपी खेल विकास।

कुछ वीडियो परिचय:

विशुद्ध रूप से कार्यात्मक तरीके से कोर गेम लॉजिक बनाने के लिए यह 100% संभव और बेहतर है, एक पूरे के रूप में उद्योग सोच के एक प्रतिमान में फंस गया है।

यह एकता में भी करने के लिए संभव है।

सवाल का जवाब देने के लिए एक नई गेम स्थिति को अपडेट किया जाएगा / हर बार कुछ चालें बनाई जाएंगी, जैसा कि कारमैक अपनी बात में कहता है, यह कोई समस्या नहीं है। संज्ञानात्मक ओवरहेड में भारी कमी जो विशुद्ध रूप से कार्यात्मक, उच्च बनाए रखने योग्य, लचीली वास्तुकला से आती है जो प्रदर्शन को हिट करती है, अगर यह बिल्कुल भी मौजूद है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.