'Zoning' พื้นที่บนแผนที่ขนาดใหญ่เช่นเดียวกับดันเจี้ยน


10

เกมของฉันมีแผนที่เหมือนของ Minecraft ในลักษณะที่เป็น pseudoinfinite และสร้างแบบสุ่ม และใหญ่ สมมติว่าผู้ใช้สำรวจโซน 1000x1000 (2D ที่นี่) นั่นคือ 1,000,000 แผ่น

เห็นได้ชัดว่าฉันจะไม่สามารถเก็บมันไว้ในความทรงจำได้ และฉันไม่ต้องการเพิกเฉยทุกอย่างออกจากไพ่ 10 ใบหรือรัศมีใด ๆ - ทั้งคู่จะไม่มีอะไรอัปเดต (NPC ทั้งหมดอาจเป็นกระเบื้องปฏิกิริยา) และฉันจะต้องทำงานกับตำแหน่งที่น่าอึดอัดใจเช่น 1382,12918

ดังนั้นถ้าฉันจะแบ่งมันออกเป็นชิ้น ๆ หรือโซนหรืออะไรก็ตามที่บอกว่าเป็น 64x64 แผ่นฉันจะต้องเก็บแต่ละตำแหน่งของวัตถุและวัตถุเช่น:

ก้อน a, b ตำแหน่ง x, y

แต่ถ้าฉันต้องการดันเจี้ยนและสิ่งที่คล้ายในแผนที่ของฉัน กระเบื้องเดี่ยวที่อาจนำไปสู่ดันเจี้ยน 40 ชั้นแต่ละอันมีพื้นที่ 40x40 ฉันไม่สามารถเก็บพวกมันไว้ในแผนที่เดียวกันได้

และมีด้านความจำ ฉันสามารถเก็บหน่วยความจำในเวลาเดียวกันได้มากเท่าไหร่ ฉันสามารถเรียงต่อกันตาม ID ได้อย่างง่ายดายและมีอาร์เรย์ 2D ปกติอยู่ที่นั่น หรืออีกครั้งมีวิธีแก้ปัญหาที่มีประสิทธิภาพมากกว่าการมีไฟล์ข้อมูลประเภทไทล์หรือไม่ ดังนั้นสำหรับ 64x64 .. นั่นจะเท่ากับ 20K หรืออะไรก็ตาม ฉันต้องการโหลดให้มากที่สุดเท่าที่จะทำได้เพื่อการอัปเดตที่สมจริงที่สุด แต่ฉันไม่รู้ว่าขีด จำกัด แบบไหนที่ฉันสามารถตีได้

คำตอบ:


9

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

สิ่งที่คุณคิดเกี่ยวกับที่นี่คือชุดข้อมูลที่กระจัดกระจาย: สิ่งที่ดัชนีที่มีศักยภาพมีขนาดใหญ่ (หรือไม่ จำกัด ) แต่ใช้สัดส่วนเพียงเล็กน้อยเท่านั้น จุดสำคัญคือคุณไม่ทราบว่าจะใช้สัดส่วนใด

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

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

คุณสามารถเพิ่มประสิทธิภาพการจัดเก็บได้มากยิ่งขึ้น สมมติว่าคุณจัดเรียงไทล์ของคุณเป็นชิ้น ๆ และก้อนมีความละเอียด 64x64x64 รับกระเบื้องที่ 125, 1, 132 คุณรู้ว่ามันอยู่ในกลุ่ม (1,0,2) ดังนั้นคุณจึงมีโลกซึ่งประกอบด้วยอาร์เรย์อันเล็กกะทัดรัดและเมทริกซ์ของดัชนีอัน (-1 ถ้าไม่มีก้อน) เนื้อหาของแต่ละก้อน (ถ้ามี) คือเมทริกซ์ของดัชนีไทล์ 64x64x64 (-1 หากกระเบื้องยังไม่มีอยู่) และอาร์เรย์ที่ย่อขนาดของกระเบื้องที่ใช้แล้ว ด้วยวิธีนี้คุณจะไม่เผาดัชนีกระเบื้องจำนวนมากสำหรับชิ้นส่วนที่ไม่เคยใช้ ด้วยการทำตามวิธีการนี้และเลือกตัวเลขที่เหมาะสมสำหรับกลุ่มข้อมูลย่อยคุณสามารถขยายจักรวาลของคุณอย่างหนาแน่นและควบคุมการใช้หน่วยความจำของคุณ ที่จริงแล้วถ้าคุณทำชิ้นส่วนของคุณ 32x32x32

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


ฉันขอเตือนทุกคนที่เจอคำถามนี้ในอนาคต: แม้ว่าจะไม่มีสิ่งใดในโพสต์นี้ แต่มันก็น่ากลัวสำหรับเกมอย่าง Minecraft ซึ่งมีโลกที่ไม่กระจัดกระจาย (และ MrCranky กล่าวว่าเท่า.) โลกของคุณจะได้รับประโยชน์จากนี้ถ้ามี somethings น้อยและจำนวนมากnothingsไม่กี่ somethings และจำนวนมากของรถเปล่า

1
ฉันยอมรับอย่างเต็มที่ว่าค่าใช้จ่ายที่เกี่ยวข้องในการรักษาโซลูชันการจัดเก็บชุดข้อมูลที่เบาบางค่อนข้างสูงดังนั้นคุณจะไปเฉพาะเมื่อยอดคงเหลือเบ้อย่างชัดเจนไปทางเบาบาง ปัจจัยสำคัญ ได้แก่ : ต้นทุนของข้อมูล - รายการและความน่าจะเป็น - ข้อมูล - รายการ - ไม่ได้ใช้ Minecraft มีชุดข้อมูลที่มีศักยภาพและมีขนาดใหญ่มาก (แต่ละแผ่นมีจำนวนมากในแต่ละทิศทาง) สัดส่วนที่แท้จริงของโลกของเกมที่มีศักยภาพที่ใช้นั้นเล็กมาก แม้ว่าคุณจะอ้างว่าเป็นจำนวนมากในขณะที่คุณเดินทางไปทั่วโลก แต่ก็ยังเป็นส่วนเล็ก ๆ ของรายการข้อมูลที่มีศักยภาพ
MrCranky

1
สิ่งที่ทำให้ Minecraft แตกต่างกันคือราคาต่อหน่วยมีขนาดเล็ก - อาจเป็นพื้นที่เก็บข้อมูลไบต์เดียว ค่าหนึ่งระบุว่า 'ไม่มีสิ่งใด' ส่วนที่เหลือเป็นประเภทบล็อกและคุณสามารถใส่ลงในไบต์ได้อย่างง่ายดาย ดังนั้นคุณจะไม่ได้ดัชนีไปยังบล็อกเดียวนั่นเป็นเพียงแค่บ้าดัชนีมีขนาดใหญ่กว่าเพียงแค่การจัดเก็บค่าบล็อกจริง แต่กฎชุดข้อมูลที่กระจัดกระจายยังคงทำงานในระดับที่สูงขึ้น ก้อนแต่ละอัน (เช่น 64x64x64) มีราคาแพงในการจัดเก็บ (บล็อก 256K) ดังนั้นหากคุณสามารถใช้ค่าเล็ก ๆ น้อย ๆ เพื่อระบุว่าไม่มีตัวตนหรือที่อยู่ของมันถ้ามันมีอยู่คุณจะบันทึกที่เก็บข้อมูลขนาดใหญ่
MrCranky

6

ทำไมคุณไม่สามารถเก็บไทล์ได้หนึ่งล้านไทล์ แม้แต่โทรศัพท์ของฉันก็มี RAM 256MB; แผ่นเปล่าหนึ่งล้านแผ่นจะเป็นอย่างไร 4-32MB?


ดูเหมือนว่าจะมีการจัดเก็บจำนวนมาก นอกจากนี้ยังต้องใช้เวลานานในการอัปเดต
The Duck Communist

2
มันง่ายกว่ามากที่จะไม่สนใจชุดไพ่เรียงสำหรับการอัปเดตมากกว่าที่จะจัดการกับโซลูชั่นการจัดเพจดิสก์บางประเภท เพียง .. ไม่สนใจพวกเขา อย่าอัปเดตไทล์มากกว่าระยะทาง X จากนักแสดงที่รู้จักกันดี

2
@TheCommunistDuck สิ่งเดียวที่สำคัญคือจำนวนหน่วยความจำทั้งหมดที่ใช้ในการจัดเก็บแผ่นกระเบื้องไม่ใช่จำนวนแผ่น
Justin

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