การออกแบบโดเมนขับเคลื่อนได้ดีสำหรับเกมหรือไม่?


10

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

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


2
ฉันสามารถพูดได้ว่าการออกแบบที่ได้รับความนิยมสำหรับเกมคือสถาปัตยกรรมชิ้น การออกแบบใหม่ที่มีการเล่นที่ขอบเลือดของเกมเอ็นจิ้นคือการออกแบบที่เน้นข้อมูล แต่ฉันไม่สามารถพูดคุยกับ Domain Driven Design ในวิดีโอเกมได้ดังนั้นเพียงแค่แสดงความคิดเห็น
James

เกมไม่ใช่แอปพลิเคชันทางธุรกิจ สถาปัตยกรรมเสียงในแอปพลิเคชันทางธุรกิจ (DDD / CQRS) นั้นไม่ได้มีเสียงที่แน่นอนในเกมและในทางกลับกัน ทำไมไม่วิจัยโมเดลมัณฑนากรหรือโมเดลส่วนประกอบ? สิ่งเหล่านี้ "ดี" สำหรับเกมและจะช่วยบรรเทาปัญหาซิงเกิลของคุณ - แม้จะบอกว่าซิงเกิลนั้นมักจะใช้ได้ดีในเกม โดยเฉพาะอย่างยิ่งถ้าคุณกำลังพัฒนาอินดี้ มีสมาธิในการทำบางสิ่งบางอย่างมิฉะนั้นคุณจะได้ที่ดินอย่างฉันด้วยสถาปัตยกรรมที่ยอดเยี่ยม แต่ไม่มีเกม
Jonathan Dickinson

ขอบคุณสำหรับคำแนะนำ ฉันจะอ่านเกี่ยวกับการออกแบบส่วนประกอบ ฉันจะจบเกมที่ฉันกำลังทำอยู่แม้ว่าการออกแบบจะไม่ดี ฉันมีกำหนดส่งพฤศจิกายนนี้ lol ฉันได้ลบแนวคิดของ Singleton และฉันฉีดโมดูลไปยังวัตถุที่ต้องการ ฉันเดาว่าตอนนี้จะเพียงพอแล้ว แต่ฉันต้องเรียนรู้เพิ่มเติม
Sylpheed

คำตอบ:


12

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

เช่นนี้คำตอบของฉันคือว่ามันไม่ "ดี" มันมักจะเป็นจุดเริ่มต้นที่สมเหตุสมผล แต่พิสูจน์ได้ว่าไม่เพียงพอเมื่อคุณไป คุณไม่ค่อยมีโดเมนเดียว แต่มีหลายโดเมนที่แตกต่างกันภายในซอฟต์แวร์ชิ้นเดียว - ตัวอย่างเช่นคุณอาจมีโดเมนของเกม (โลก, ตัวละคร, ไอเท็ม), โดเมนของ renderer (shaders, the meshes, วัสดุ), โดเมนของอินพุต (ระบบไฟล์, เครือข่าย, คีย์บอร์ดและเมาส์) และปัญหาเกิดขึ้นที่โดเมนซ้อนทับกันและมีอิทธิพลต่อกันและกัน บ่อยครั้งที่ในการเข้าร่วม 2 โดเมนด้วยกันคุณรู้ว่ามีการพึ่งพาที่นั่นซึ่งต้องมีการเปลี่ยนแปลงซึ่งหมายความว่าการเป็นตัวแทนของคุณกลายเป็นภาระมากกว่าความช่วยเหลือ

ตัวอย่างที่คลุมเครืออาจเป็นห้องสมุดคณิตศาสตร์บนคอนโซลและตัวละครในเกมของคุณ ห้องสมุดคณิตศาสตร์ของคุณต้องการมีรายการข้อมูลจำนวนมากและจากนั้น 1 คำสั่งเพื่อดำเนินการในรายการนั้นเพื่อให้ทำงานได้อย่างมีประสิทธิภาพ ตัวละครในเกมของคุณแต่ละคนจะมีชุดข้อมูลจุดสุดยอดของตัวเองสำหรับการเรนเดอร์และแอนิเมชั่นเป็นต้นตอนนี้คุณจะได้รับข้อมูลจุดสุดยอดทั้งหมดของข้อมูลจุดสุดยอดจากตัวละครแต่ละตัวของคุณได้อย่างไร? คุณสามารถทำการคัดลอกช้าหรือคุณสามารถ refactor ตัวละครของคุณเพื่อให้ข้อมูลของพวกเขาคล้อยตามการประมวลผลโดยห้องสมุดคณิตศาสตร์ - แต่แล้วหนึ่งในโดเมนของคุณกำลังพังทลายลงเพื่อให้อีกอันหนึ่ง

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

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

รูปแบบการออกแบบปัจจุบันของฉันอยู่ในรูปแบบซิงเกิลและฉันต้องการทำการบันทึกใหม่เพื่อกำจัดสิ่งนี้

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


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

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

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

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

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

6

ตัวอย่าง

เมื่อถึงเวลาที่เขียนคำตอบนี้คำตอบที่โพสต์อื่น ๆ ทั้งหมดนี้ผิด

แทนที่จะถามว่า Domain-Driven Design นั้นดีสำหรับเกมหรือไม่ คุณควรถามว่า "การสร้างแบบจำลองโดเมน" นั้นดีสำหรับเกมหรือไม่

การสร้างแบบจำลองโดเมนดีสำหรับเกมหรือไม่

คำตอบคือ: บางครั้งมันก็สุดยอดจริงๆ อย่างไรก็ตามหากคุณกำลังสร้างเกมเรียลไทม์เช่น platformer หรือ FPS หรืออะไรก็ตาม (เกมหลายประเภท) ไม่ต้องทำ มันไม่เหมาะอย่างยิ่งสำหรับระบบเหล่านั้น อย่างไรก็ตามอาจมีระบบที่เกมเหล่านั้นที่ใช้รูปแบบโดเมนมีประสิทธิภาพ

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

ซอฟต์แวร์ทั้งหมดไม่ใช่ซอฟต์แวร์ที่คุณกำลังเขียน บางคนค่อนข้างแตกต่างจากคนอื่น ๆ

ตัวอย่างของโดเมนที่การสร้างแบบจำลองโดเมนทำงานได้ดีคือเกมไพ่เกมกระดานและระบบประเภทอื่น ๆ ที่ขับเคลื่อนด้วยเหตุการณ์

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

อย่างไรก็ตามเมื่อทุกอย่างซับซ้อนขึ้นคุณจะเริ่มเห็นนักพัฒนาใช้โมเดลโดเมนภายในเอนทิตีของพวกเขาเพื่อจัดการกับพฤติกรรมและการคำนวณบางประเภท

รูปแบบโดเมนในสถาปัตยกรรมเกม

เอ็นจิ้นเกมของคุณ (เช่น Unity3D) มักจะเป็นส่วนประกอบของเอนทิตี ใน platformer คุณอาจมีเอนทิตีสำหรับตัวละครของคุณและสถานะของมันจะกลายพันธุ์อยู่ตลอดเวลาเพื่ออัพเดทตำแหน่งเป็นต้น

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

UI แสดงสถานะเกมให้กับผู้ใช้ ผู้ใช้โต้ตอบกับ UI เรียกคำสั่งในชั้นบริการ บริการเลเยอร์โต้ตอบกับวัตถุโดเมน วัตถุโดเมนยกเหตุการณ์โดเมน ผู้ฟังเหตุการณ์จะได้ยินเหตุการณ์และทำให้เกิดการเปลี่ยนแปลงใน UI

UI> เลเยอร์บริการ> โมเดลโดเมน

ในระยะสั้นจบลงด้วย model-view-controller ด้วยการใช้งานเลเยอร์บริการ

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

ตกลงตอนนี้ DDD คืออะไร?

การออกแบบที่ขับเคลื่อนด้วยโดเมนโดยเฉพาะคือวัฒนธรรม / การเคลื่อนไหวของการเน้นรูปแบบการวิเคราะห์ที่ใช้ในการเรียนรู้เกี่ยวกับโดเมนเพื่อที่คุณจะได้สร้างสิ่งที่ถูกต้องและจากนั้นรูปแบบการใช้งานที่ช่วยให้คุณสามารถใช้ แนวคิดในรูปแบบโดเมนโดยใช้สำนวนภาษาของคุณ DDD มาจากชุมชนที่ทำงานกับโดเมนที่ซับซ้อนและมักจะมองหาวิธีการจัดการความซับซ้อนสูงในแอปพลิเคชันของพวกเขาโดยมุ่งเน้นที่การสร้างแบบจำลองโดเมน

DDD นั้นทำได้ไม่ดีนักหากเป้าหมายของคุณคือการเริ่มเขียนโค้ดเล่นกับระบบแล้วหาว่าคุณต้องการสร้างอะไรในภายหลัง ฯลฯ สมมติว่ามีโดเมนอยู่ไม่มากก็น้อย ดังนั้นถ้าคุณไม่รู้ว่าเกมของคุณจะเป็นอย่างไร .. จากนั้นมันจะไม่ทำงาน


1
ขอบคุณสำหรับความเข้าใจ ฉันได้คิดออกมาอาจจะ 3 หรือ 4 ปีที่ผ่านมา ฉันไร้เดียงสาตั้งแต่นั้นมา (5 ปีที่แล้ว) เนื่องจากฉันพยายามปรับให้พอดีกับ "รูปแบบการออกแบบ" กับปัญหาทั้งหมดของฉัน การเรียนรู้ "รูปแบบ" และสถาปัตยกรรมเหล่านี้ช่วยได้เพราะมันมีตัวเลือกเพิ่มเติมให้ฉัน ฉันมักจะยึดส่วนที่เป็นนามธรรมของรหัสของฉัน "เพียงพอ" เพื่อให้ง่ายสำหรับนักออกแบบ (สำคัญมาก) การทดสอบหน่วยและกลไกในอนาคต การใช้สถาปัตยกรรมมากเกินไปทำให้การทำงานหนักเกินไปและฉันเรียนรู้วิธีที่ยากลำบาก ตอนนี้ฉันได้ยกระดับสถาปัตยกรรมที่อิงส่วนประกอบเพื่อให้เหมาะกับสไตล์การเขียนโค้ดแล้ว SOLID ftw
Sylpheed

3

ไม่ฉันไม่คิดว่า DDD หรือสถาปัตยกรรม "buzzword" อื่น ๆ นั้นดีสำหรับเกม ด้วยข้อยกเว้นที่เป็นไปได้ของ "ระบบส่วนประกอบ" ซึ่งดูเหมือนจะได้รับความนิยมอย่างมากที่นี่

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


1
+1 สำหรับ "การออกแบบและเข้ารหัสแอปพลิเคชันของคุณจริง" รูปแบบเหล่านั้นเป็นแนวทางและคิดว่าฉันเป็นผู้กระตุ้นไม่มีอะไรเพิ่มเติม การเปลี่ยนปัญหาเพื่อให้เข้ากับวิธีแก้ปัญหาเป็นสิ่งที่ต้องทำ
Jonathan Dickinson

-1

ใช่ แต่คุณควรปรับตัว

เมื่อใช้ DDD คุณจะได้รับ modularity และความรับผิดชอบเดียวของแต่ละโดเมน แต่อะไรก็ได้ที่ทำให้ซับซ้อน

ดูคำตอบของฉันที่นี่


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