การเข้ารหัสที่ขับเคลื่อนด้วยข้อมูล
ทุกสิ่งที่คุณพูดถึงคือสิ่งที่สามารถระบุได้ในข้อมูล ทำไมคุณโหลดaspecificmap
? เนื่องจากการกำหนดค่าเกมบอกว่าเป็นระดับแรกเมื่อผู้เล่นเริ่มเกมใหม่หรือเพราะเป็นชื่อของจุดบันทึกปัจจุบันในไฟล์บันทึกของผู้เล่นที่พวกเขาเพิ่งโหลดเป็นต้น
คุณหาได้aspecificmap
อย่างไร เพราะมันอยู่ในไฟล์ข้อมูลที่แสดงรหัสแผนที่และทรัพยากรบนดิสก์
จำเป็นต้องมีทรัพยากร "แกนหลัก" จำนวนน้อยซึ่งเป็นเรื่องยากหรือเป็นไปไม่ได้ที่จะหลีกเลี่ยงการเข้ารหัส ด้วยการทำงานเล็กน้อยสิ่งนี้สามารถ จำกัด ได้เพียงชื่อสินทรัพย์เริ่มต้นที่กำหนดค่าตายตัวเดียวmain.wad
หรือคล้ายกัน ไฟล์นี้สามารถที่อาจจะมีการเปลี่ยนแปลงที่ runtime game.exe -wad mymain.wad
โดยผ่านอาร์กิวเมนต์บรรทัดคำสั่งที่จะเล่นเกมอาคา
การเขียนรหัสที่ขับเคลื่อนด้วยข้อมูลนั้นอาศัยหลักการอื่นสองสามข้อ ตัวอย่างเช่นสามารถหลีกเลี่ยงการมีระบบหรือโมดูลขอทรัพยากรโดยเฉพาะและแทนที่จะกลับพึ่งพาเหล่านั้น นั่นคือไม่ควรDebugDrawer
โหลดdebug.font
ในโค้ดเริ่มต้น มีDebugDrawer
การจัดการทรัพยากรในรหัสเริ่มต้นแทน หมายเลขอ้างอิงนั้นอาจถูกโหลดจากไฟล์กำหนดค่าเกมหลัก
เป็นตัวอย่างที่เป็นรูปธรรมจาก codebase ของเราเรามีวัตถุ "ข้อมูลทั่วโลก" ที่โหลดจากฐานข้อมูลทรัพยากร (ซึ่งตัวมันเองเป็นค่าเริ่มต้น./resources
โฟลเดอร์ แต่สามารถโหลดมากเกินไปด้วยอาร์กิวเมนต์บรรทัดคำสั่ง) ID ข้อมูลฐานข้อมูลของข้อมูลส่วนกลางนี้เป็นชื่อทรัพยากรที่เข้ารหัสยากใน codebase เท่านั้น (เรามีชื่ออื่นเพราะบางครั้งโปรแกรมเมอร์ก็ขี้เกียจ แต่โดยทั่วไปแล้วเราจะแก้ไข / ลบข้อมูลเหล่านั้นในที่สุด) ออบเจ็กต์ข้อมูลส่วนกลางนี้เต็มไปด้วยส่วนประกอบที่มีจุดประสงค์เพื่อจัดเตรียมข้อมูลการกำหนดค่า หนึ่งในองค์ประกอบคือองค์ประกอบ UI Global Data ซึ่งมีการจัดการทรัพยากรไปยังทรัพยากร UI หลักทั้งหมด (แบบอักษร, ไฟล์ Flash, ไอคอน, ข้อมูลการแปล ฯลฯ ) ท่ามกลางจำนวนรายการการกำหนดค่าอื่น ๆ เมื่อนักพัฒนา UI ตัดสินใจเปลี่ยนชื่อเนื้อหา UI หลักจาก/ui/mainmenu.swf
เป็น/ui/lobby.swf
พวกเขาเพียงแค่อัปเดตการอ้างอิงข้อมูลทั่วโลก ไม่ต้องเปลี่ยนรหัสเครื่องยนต์เลย
เราใช้ข้อมูลส่วนกลางนี้สำหรับทุกสิ่ง ตัวละครที่เล่นได้ทั้งหมดทุกระดับ UI เสียงสินทรัพย์หลักการกำหนดค่าเครือข่ายทุกอย่าง (ดีไม่ใช่ทุกอย่างแต่สิ่งอื่น ๆ เหล่านั้นเป็นข้อบกพร่องที่จะแก้ไข)
วิธีนี้มีข้อดีอื่น ๆ มากมาย สำหรับหนึ่งมันทำให้การบรรจุทรัพยากรและการรวมเป็นหนึ่งในกระบวนการทั้งหมด เส้นทางที่เข้ารหัสยากในเอ็นจิ้นก็มีแนวโน้มที่จะหมายความว่าเส้นทางเดียวกันเหล่านั้นจะต้องถูกกำหนดค่าตายตัวในสิ่งที่สคริปต์หรือเครื่องมือที่ทำขึ้นสินทรัพย์เกมและเส้นทางเหล่านั้นสามารถซิงค์ได้หมด เราสามารถสร้างบันเดิลสินทรัพย์โดยใช้คำสั่งเดียวที่คล้ายกันbundle.exe -root config.data -out main.wad
และรู้ว่ามันจะรวมสินทรัพย์ทั้งหมดที่เราต้องการ นอกจากนี้เนื่องจาก Bundler จะติดตามการอ้างอิงทรัพยากรเรารู้ว่าจะรวมเฉพาะสินทรัพย์ที่เราต้องการและข้ามปุยซ้ายที่เหลืออยู่ตลอดชีวิตของโครงการอย่างหลีกเลี่ยงไม่ได้ (รวมทั้งเราสามารถสร้างรายการโดยอัตโนมัติได้ ปุยเพื่อการตัดแต่งกิ่ง)
กรณีมุมที่ยุ่งยากของสิ่งทั้งหมดนี้อยู่ในสคริปต์ การทำให้เครื่องยนต์ขับเคลื่อนข้อมูลนั้นเป็นแนวคิดง่าย ๆ แต่ฉันได้เห็นโครงการมากมาย (งานอดิเรกไปยัง AAA) ซึ่งสคริปต์ถูกพิจารณาว่าเป็นข้อมูลและ "อนุญาต" เพื่อใช้เส้นทางทรัพยากรอย่างไม่เจาะจง อย่าทำอย่างนั้น หากไฟล์ Lua ต้องการทรัพยากรและเพียงเรียกใช้ฟังก์ชันเช่นtextures.lua("/path/to/texture.png")
นั้นไปป์ไลน์ของสินทรัพย์จะมีปัญหามากมายที่รู้ว่าสคริปต์ต้องการ/path/to/texture.png
ทำงานอย่างถูกต้องและอาจพิจารณาว่าพื้นผิวนั้นไม่ได้ใช้งานและไม่จำเป็น สคริปต์ควรได้รับการปฏิบัติเหมือนรหัสอื่น ๆ : ข้อมูลใด ๆ ที่พวกเขาต้องการรวมถึงทรัพยากรหรือตารางควรระบุไว้ในรายการการกำหนดค่าที่เอ็นจิ้นและไพพ์ไลน์ของทรัพยากรสามารถตรวจสอบการพึ่งพาได้ ข้อมูลที่ระบุว่า "สคริปต์โหลดfoo.lua
" ควรพูดว่า "foo.lua
และให้พารามิเตอร์เหล่านี้ "ซึ่งพารามิเตอร์รวมถึงทรัพยากรใด ๆ ที่จำเป็นหากสคริปต์สุ่มวางไข่ศัตรูเช่นส่งรายการศัตรูที่เป็นไปได้ลงในสคริปต์จากไฟล์กำหนดค่านั้นจากนั้นเครื่องยนต์สามารถโหลดศัตรูที่มีระดับล่วงหน้าได้ ( เนื่องจากมันรู้รายการที่สมบูรณ์ของการวางไข่ที่เป็นไปได้) และไพพ์ไลน์ของทรัพยากรรู้ที่จะรวมศัตรูทั้งหมดเข้ากับเกม (เนื่องจากพวกมันถูกอ้างอิงอย่างชัดเจนจากข้อมูลการกำหนดค่า) หากสคริปต์สร้างสตริงชื่อพา ธ และเรียกใช้load
ฟังก์ชัน เอ็นจิ้นหรือไพพ์ไลน์ของทรัพยากรมีวิธีการที่จะรู้ว่าสินทรัพย์ใดที่สคริปต์อาจพยายามโหลด