ฟังก์ชั่นการเขียนโปรแกรมและสถานะของเกมล้วนๆ


12

มีเทคนิคทั่วไปในการจัดการสถานะ (โดยทั่วไป) ในภาษาโปรแกรมการทำงานหรือไม่? มีคำตอบในทุกภาษา (ฟังก์ชั่น) การเขียนโปรแกรมเพื่อจัดการสถานะโกลบอล แต่ฉันต้องการหลีกเลี่ยงสิ่งนี้เท่าที่จะทำได้

สถานะทั้งหมดในลักษณะการทำงานบริสุทธิ์เป็นพารามิเตอร์ฟังก์ชั่น ดังนั้นฉันจึงจำเป็นต้องกำหนดสถานะของเกมทั้งหมด (แฮชแมปขนาดมหึมากับโลกผู้เล่นตำแหน่งคะแนนสินทรัพย์ศัตรู ... )) เป็นพารามิเตอร์สำหรับทุกฟังก์ชั่นที่ต้องการจัดการโลกบนอินพุตหรือทริกเกอร์ที่กำหนด . ฟังก์ชั่นของตัวเองเลือกข้อมูลที่เกี่ยวข้องจาก bloest gamestate ทำอะไรกับมันจัดการกับ gamestate และคืน gamestate แต่นี่ดูเหมือนจะเป็นทางออกที่ไม่ดีสำหรับผู้ชาย ถ้าฉันใส่เกมมิ่งทั้งหมดลงในฟังก์ชั่นทั้งหมดมันจะไม่มีประโยชน์สำหรับฉันในทางตรงกันข้ามกับตัวแปรทั่วโลกหรือวิธีการที่จำเป็น

ฉันสามารถใส่ข้อมูลที่เกี่ยวข้องลงในฟังก์ชั่นและคืนการกระทำที่จะนำไปใช้สำหรับอินพุตที่กำหนด และหนึ่งฟังก์ชั่นเดียวใช้การกระทำทั้งหมดกับนักเล่นเกม แต่ฟังก์ชั่นส่วนใหญ่ต้องการข้อมูล"ที่เกี่ยวข้อง" จำนวนมาก move()ต้องการตำแหน่งวัตถุ, ความเร็ว, แผนที่สำหรับการชน, ตำแหน่งของศัตรูทั้งหมด, สุขภาพในปัจจุบัน, ... ดังนั้นวิธีนี้ดูเหมือนจะไม่ทำงานเช่นกัน

ดังนั้นคำถามของฉันคือฉันจะจัดการกับรัฐจำนวนมากในภาษาโปรแกรมที่ใช้งานได้โดยเฉพาะอย่างยิ่งสำหรับการพัฒนาเกมได้อย่างไร

แก้ไข:มีกรอบเกมบางอย่างสำหรับการสร้างเกมใน Clojure มีวิธีการแก้ปัญหานี้บางส่วนคือการเธรดวัตถุทั้งหมดในเกมเป็น "เอนทิตี" และวางไว้ในกระเป๋าใบใหญ่ หน้าที่หลัก Gigantถือหน้าจอและหน่วยงานและกิจกรรมจับ ( :on-key-down, :on-init, ... ) สำหรับองค์กรนี้และเรียกห่วงจอแสดงผลหลัก แต่นี่ไม่ใช่ทางออกที่สะอาดที่ฉันค้นหา


ฉันคิดเกี่ยวกับสิ่งนี้มาพักหนึ่งแล้ว สำหรับฉันมันไม่ใช่อินพุตที่เป็นปัญหาเฉพาะเนื่องจากคุณยังต้องป้อนองค์ประกอบ (เหมือนกัน) ให้กับฟังก์ชั่นในการเขียนโปรแกรมที่ไม่ทำงาน ไม่มันเป็นเอาท์พุท (และการปรับปรุงที่เกี่ยวข้องที่ตามมา) ซึ่งเป็นปัญหา พารามิเตอร์การป้อนข้อมูลบางส่วนของคุณควรรวมกัน สำหรับmove()คุณน่าจะผ่านวัตถุ 'ปัจจุบัน' (หรือตัวระบุสำหรับมัน) รวมทั้งโลกที่มันเคลื่อนที่ผ่านและเพิ่งได้รับตำแหน่งและความเร็วปัจจุบัน ... เอาท์พุทเป็นโลกฟิสิกส์ทั้งหมดหรืออย่างน้อย รายการของวัตถุที่เปลี่ยนแปลง
Clockwork-Muse

ข้อได้เปรียบของฟังก์ชั่นบริสุทธิ์คือฟังก์ชั่นต้นแบบแสดงการพึ่งพาทั้งหมดที่โปรแกรมของคุณมี
tp1

3
IMO ภาษาที่ใช้งานได้ไม่เหมาะสมสำหรับการเขียนเกม นี่เป็นหนึ่งในปัญหามากมายที่คุณจะต้องแก้ไข เกมต้องการการควบคุมประสิทธิภาพที่แม่นยำมากและไม่ค่อยมีการทำงานพร้อมกันที่ดีเนื่องจากเหตุการณ์ที่เกิดขึ้นโดยวิธีที่ไม่อาจคาดเดาได้ (บริสุทธิ์) ภาษาที่ใช้งานได้นั้นมีความโดดเด่นในเรื่องการปรับให้เป็นแบบขนานและยากที่จะปรับให้เหมาะสม เกมเขียนยากและฉันขอแนะนำให้ทำในภาษาทั่วไปก่อนที่จะทำอะไรที่ซับซ้อน (การเขียนโปรแกรมการทำงาน)
Casey Kuball

คำตอบ:


7

ผลข้างเคียงและสถานะในภาษาโปรแกรมการทำงานเป็นปัญหาที่กว้างขึ้นในวิทยาการคอมพิวเตอร์ ในกรณีที่คุณไม่ได้พบพวกเขาก่อนที่อาจจะดูที่monads ได้รับการเตือนว่า: พวกเขาเป็นแนวคิดขั้นสูงและคนส่วนใหญ่ที่ฉันรู้ (ฉันรวม) ต่อสู้เพื่อเข้าใจพวกเขา มีหลายมีหลายบทเรียนออนไลน์ด้วยวิธีการที่แตกต่างกันและความต้องการความรู้ โดยส่วนตัวแล้วฉันชอบที่สุดของ Eric Lippert

ฉันเป็นโปรแกรมเมอร์ C # ที่ไม่มีพื้นหลัง "การเขียนโปรแกรมการทำงาน" แต่อย่างใด สิ่งนี้คือ "monad" ที่ฉันคอยฟังและสิ่งที่ใช้กับฉันคืออะไร?

Eric Lippert เกี่ยวกับ Monads

บางสิ่งที่ควรพิจารณา:

  • คุณยืนยันในการใช้ภาษาที่ใช้งานได้จริงหรือไม่? หากคุณมีทักษะในการเขียนโปรแกรมเชิงฟังก์ชั่นและการพัฒนาเกมบางทีคุณอาจจะดึงมันออกมา (แม้ว่าฉันต้องการทราบว่าผลประโยชน์คุ้มค่ากับความพยายามหรือไม่)
  • จะดีกว่าไหมถ้าใช้วิธีการทำงานเฉพาะเมื่อจำเป็นเท่านั้น หากคุณกำลังใช้ภาษาเชิงวัตถุ (หรือเป็นไปได้มากกว่าที่เป็นกระบวนทัศน์หลายกระบวน) ไม่มีอะไรหยุดคุณจากการใช้สไตล์การใช้งานเพื่อนำไปใช้ในส่วนที่ได้ประโยชน์จากมัน (ชอบ MapReduce หรือเปล่า?)

ความคิดสุดท้าย:

  • Parallelism: ในขณะที่เกมจะใช้มันอย่างหนัก AFAIK มากที่สุดของมันแล้วที่เกิดขึ้นใน GPU ต่อไป
  • การไร้สัญชาติ: การกลายพันธุ์ของรัฐเป็นส่วนสำคัญของเกม การพยายามกำจัดพวกมันอาจทำให้เรื่องยุ่งยากโดยไม่จำเป็น
  • อาจดูว่าภาษาฟังก์ชัน # F เล่นกับระบบเชิงวัตถุของ. NET ได้อย่างไรหากคุณสนใจ

สรุปแล้วฉันคิดว่าแม้ว่ามันจะเป็นเรื่องที่น่าสนใจในเชิงวิชาการ แต่ฉันสงสัยว่าวิธีการนี้ใช้ได้จริงและคุ้มค่ากับความพยายาม


ทำไมโพสต์ความคิดเห็นเกี่ยวกับเรื่องที่คุณไม่มีประสบการณ์? ความคิดเห็นที่มาจากผู้คนที่ติดอยู่ในกรอบความคิดเดียว
Anthony Raimondo

4

ฉันได้เขียนเกมสองสามเกมโดยใช้ F # (กระบวนทัศน์หลายภาษาไม่บริสุทธิ์ภาษาที่ใช้งานได้เป็นอันดับแรก) ด้วยวิธีการที่หลากหลายตั้งแต่ OOP ถึงFRPไฟเบอร์กลาสนี่เป็นคำถามที่กว้างขวาง แต่ฉันจะทำให้ดีที่สุด

มีเทคนิคทั่วไปในการจัดการสถานะ (โดยทั่วไป) ในภาษาโปรแกรมการทำงานหรือไม่?

Stateวิธีที่ต้องการของฉันคือการมีประเภทไม่เปลี่ยนรูปที่แสดงถึงทั้งเกม ฉันมีการอ้างอิงที่ไม่แน่นอนกับกระแสStateที่อัพเดทแต่ละเห็บ นี่ไม่บริสุทธิ์อย่างเคร่งครัดแต่มันจำกัดความไม่แน่นอนไว้ที่เดียว

ถ้าฉันใส่เกมมิ่งทั้งหมดลงในฟังก์ชั่นทั้งหมดมันจะไม่มีประโยชน์สำหรับฉันในทางตรงกันข้ามกับตัวแปรทั่วโลกหรือวิธีการที่จำเป็น

ไม่จริง. เนื่องจากStateชนิดไม่เปลี่ยนรูปคุณจึงไม่สามารถมีองค์ประกอบเก่า ๆ ที่กลายพันธุ์ในโลกในรูปแบบที่ไม่เหมาะสม วิธีนี้ช่วยแก้ไขปัญหาที่ใหญ่ที่สุดด้วยGameObjectวิธีการ (เป็นที่นิยมโดย Unity): มันยากที่จะควบคุมลำดับของการUpdateโทร

และแตกต่างจากการใช้ globals มันเป็นหน่วยทดสอบและขนานได้อย่างง่ายดาย

คุณควรเขียนฟังก์ชันตัวช่วยที่ได้รับคุณสมบัติย่อยของสถานะเพื่อแยกแยะปัญหา

ตัวอย่างเช่น:

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

ดังนั้นคำถามของฉันคือฉันจะจัดการกับรัฐจำนวนมากในภาษาโปรแกรมที่ใช้งานได้โดยเฉพาะอย่างยิ่งสำหรับการพัฒนาเกมได้อย่างไร

สำหรับเกมง่ายๆคุณสามารถใช้วิธีการด้านบน (ฟังก์ชันผู้ช่วย) สำหรับสิ่งที่ซับซ้อนกว่านี้คุณอาจต้องการลอง " เลนส์ "

ตรงข้ามกับความคิดเห็นบางส่วนที่นี่ฉันขอแนะนำอย่างยิ่งให้เขียนเกมในภาษาการเขียนโปรแกรม (ไม่บริสุทธิ์) หรืออย่างน้อยก็ลองดู! ฉันพบว่ามันทำให้การวนซ้ำเร็วขึ้นรหัสฐานเล็กลงและมีข้อบกพร่องน้อยลง

ฉันไม่คิดว่าคุณต้องเรียนรู้พระเพื่อเขียนเกมด้วยภาษา FP (ไม่บริสุทธิ์) นี่เป็นเพราะรหัสของคุณมีแนวโน้มที่จะถูกบล็อกและเธรดเดี่ยว

นี่เป็นเรื่องจริงโดยเฉพาะถ้าคุณกำลังเขียนเกมแบบผู้เล่นหลายคน จากนั้นสิ่งต่าง ๆ จะกลายเป็นเรื่องง่ายขึ้นด้วยวิธีการนี้เนื่องจากจะช่วยให้คุณสามารถทำให้สถานะเกมเป็นลำดับและส่งผ่านเครือข่าย

ทำไมถึงมีเกมอื่น ๆ ที่ไม่ได้เขียนด้วยวิธีนี้ ... ฉันไม่สามารถพูดได้ อย่างไรก็ตามนี่เป็นความจริงในโดเมนการเขียนโปรแกรมทั้งหมด (ยกเว้นการเงิน) ดังนั้นฉันจะไม่ใช้สิ่งนี้เป็นข้อโต้แย้งว่าภาษาที่ใช้งานได้เหมาะสมกับการเขียนโปรแกรมเกม

นอกจากนี้ยังดีคุ้มค่าการอ่านเป็นRetrogames หน้าที่หมดจด


1

สิ่งที่คุณต้องการคือการพัฒนาเกม FRP

วิดีโอแนะนำบางส่วน:

มันเป็นไปได้ 100% และเป็นที่นิยมในการสร้างตรรกะของเกมหลักในรูปแบบที่ใช้งานได้จริงอุตสาหกรรมโดยรวมอยู่เบื้องหลังติดอยู่ในกรอบความคิดเดียว

เป็นไปได้ที่จะทำมันในความสามัคคีเช่นกัน

เพื่อตอบคำถามสถานะเกมใหม่จะได้รับการอัปเดต / สร้างทุกครั้งที่มีการเคลื่อนไหวบางอย่างดังที่ carmack กล่าวในการพูดคุยของเขานั่นไม่ใช่ปัญหา การลดลงอย่างมากของค่าโสหุ้ยในการรับรู้ซึ่งมาจากสถาปัตยกรรมที่มีความสามารถในการบำรุงรักษาสูงและยืดหยุ่นได้ซึ่งมีความยืดหยุ่นสูง

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.