พื้นหลัง
Roblox ให้ชุดของ API เพื่อใช้งานกับโคลัสเตอร์ข้อมูลผ่าน DataStoreService ส่วนใหญ่การใช้งานกับเหตุการณ์ข้อมูลที่เกี่ยวข้องกับผู้เล่น เช่น การบันทึก การโหลด แ
ประสบการณ์ส่วนใหญ่บน Roblox ใช้ API เหล่านี้เพื่อให้บางรูปแบบของข้อมูลผู้เล่น การใช้งานเหล่านี้แตกต่างกันในการนำเสนอ แต่ทั้งหมดนี้มุ่งเน้นที่จะแก้ปัญหาเดียวกัน
ปัญหาทั่วไป
ด้านล่างเป็นบางส่วนของปัญหาที่พบบ่อยที่สุดที่ระบบจะพยายามแก้ปัญหา:
ในการเข้าถึงหน่วยความจำ: DataStoreService ร้องขอการดำเนินการเว็บที่ทำงานได้อย่างเชิญชวนและอยู่ภายใต้ขีดจำกัดอัตรา
- อ่านครั้งแรกในตอนเริ่มต้นเซสชัน
- เขียนในตอนท้ายของเซสชัน
- ระยะเวลาเขียนที่ระยะเวลาที่กำหนดเพื่อให้มีประสิทธิภาพในการมิติเหตุการณ์ที่เขียนล้มเหลว
- เขียนเพื่อให้แน่ใจว่าข้อมูลจะถูกบันทึกไว้ในขณะที่ประมวลผลการซื้อ
การจัดเก็บที่มีประสิทธิภาพ: การเก็บข้อมูลทั้งหมดของเซสชันของผู้เล่นในตารางเดียวช่วยให้คุณอัปเดตมูลค่าหลายอะตัมและจัดการข้อมูลเดียวกันในคำขอน้อยลง นอกจากนี้ยังล
ผู้พัฒนาบางรายยังใช้การเรียงลำดับอัตโนมัติเพื่อแก้ไขโครงสร้างข้อมูลขนาดใหญ่ (โดยปกติเพื่อบันทึกในเกมเนื้อหาที่สร้างโดยผู้ใช้)
การเลียนแบบ: ลูกค้าต้องการการเข้าถึงที่สม่ำเสมอของข้อมูลผู้เล่น (เช่นเพื่อปรับปรุง UI) ประมาณการเลียนแบบข้อมูลผู้เล่นไปยังลูกค้าทั่วไปจะช่วย
การจัดการข้อผิดพลาด: เมื่อไม่สามารถเข้าถึง DataStores ได้ โซลูชันส่วนใหญ่จะใช้วิธีการที่พยายามอีกครั้งและการกู้คืนสู่ 'ข้อมูลเริ่มต้น' โดยมีความระมัดระวังเป็นพิเศษเ
การทดลองใหม่: เมื่อสโตร์ข้อมูลไม่สามารถใช้งานได้ หลายวิธีการใช้งานจะนำมาซึ่งการทดลองใหม่ และการรีไม่สามารถเปลี่ยนข้อมูล "เรียล" ได้ และสื่อสารสถานการณ์ให้กับผู้ใช้
ล็อคเซสชัน: หากข้อมูลของผู้เล่นคนเดียวถูกโหลดและอยู่ในหน่วยความจำบนหลายเซิร์ฟเวอร์ สามารถเกิดปัญหาในเซิร์ฟเวอร์ที่เก็บข้อมูลเก่าไว้ได้
การจัดการการซื้ออะตอม: ตรวจสอบ, รางวัล, และบันทึกการซื้ออะตอมเพื่อป้องกันไม่ให้สูญหายหรือได้รับการรางวัลหลายครั้ง
รหัสตัวอย่าง
Roblox มีรหัสอ้างอิงเพื่อช่วยให้คุณออกแบบและสร้างระบบข้อมูลผู้เล่น ส่วนที่เหลือของหน้านี้ตรวจสอบรายละเอียดพื้นหลังการใช้งาน รายละเอียดการใช้งาน และข้อควรระวังทั่วไป
หลังจากนำโมเดลเข้าสู่ Studio คุณควรเห็นโครงสร้างไดเรกทอรี่ต่อไปนี้:
สถาปัตยกรรม
ระดับกราฟิกระดับสูงนี้แสดงระบบสําคัญในตัวอย่างและวิธีที่พวกเขาใช้งานกับโค้ดในส่วนที่เหลือของประสบการณ์
ลองอีกครั้ง
คลาส: DataStoreWrapper >
พื้นหลัง
เมื่อ DataStoreService ทำการร้องขอเว็บภายใต้หลังคา ร้องขอของมันไม่ได้รับประกันว่าจะประสบความสำเร็จ เมื่อสิ่งนี้เกิดขึ้น วิธีการ DataStore จะแสดงข้อผิดพลาด เพื่อให้คุณ
ข้อผิดพลาด "otay" ที่พบบ่อยสามารถเกิดขึ้นได้หากคุณพยายามจัดการกับความล้มเหลวของระบบเก็บข้อมูลเช่นนี้:
local function retrySetAsync(dataStore, key, value)
for _ = 1, MAX_ATTEMPTS do
local success, result = pcall(dataStore.SetAsync, dataStore, key, value)
if success then
break
end
task.wait(TIME_BETWEEN_ATTEMPTS)
end
end
ขณะที่นี่เป็นเครื่องมือที่สมบูรณ์ปลอดภัยสำหรับฟังก์ชันทั่วไป แต่ไม่เหมาะสำหรับคำขอ DataStoreService เพราะมันไม่รับประกันความสัมพันธ์ในการสร้างคำขอ การร
- Request A ทำให้ค่าของ key K เป็น 1
- คำขอล้มเหลวดังนั้นจึงได้กำหนดให้ทำซ้ำใน 2 วินาที
- ก่อนที่จะเกิดขึ้นซ้ำ ร้องขอ B ตั้งค่าของ K ให้ 2 แต่การทดลองรีไซเคิลของรีไซล์ขอ A ทันทีจะเขียนค่านี้และตั้งค่า K เป็น 1
แม้ว่า UpdateAsync คีย์UpdateAsync คำขอยังคงต้องประมวลผลเพื่อหลีกเลี่ยงสถานะที่แปรปร
ระบบข้อมูลผู้เล่นของเราใช้คลาสใหม่, DataStoreWrapper คีย์
ใกล้ชิด
DataStoreWrapper ให้วิธีการที่ตรงกับวิธีการ DataStore วิธี: DataStore:GetAsync() ,
วิธีเหล่านี้จะถูกเรียกเมื่อ:
เพิ่มคำขอให้เป็นคิว แต่ละคีย์มีคิวของตัวเองซึ่งจะประมวลผลคำขอในลำดับและในลำดับ ธรรมดาของคำขอจะปรากฏให้เห็นจนกว่าคำขอจะสำเร็จ
คุณสมบัตินี้เขียนขึ้นบนคลาส ThreadQueue ซึ่งเป็นตัวจัดกำหนดเวลาและจำกัดระดับการกำหนดเวลาของไธรรมาภิญโญณา แทนที่จะกลับมาให้คำสัญญา ThreadQueue จะนำเสนอไธร
หากคำขอล้มเหลว มันจะทำงานใหม่ด้วยค่าเท่าทวีที่กำหนดได้ รูปแบบนี้เป็นส่วนหนึ่งของการโทรกลับที่ส่งไปที่ ThreadQueue ดังนั้นพวกเขาจึงมีการรับประกันว่าจะสำเร็จก่อนคำขอต่อไปในคิวสำ
เมื่อรายการคำขอสำเร็จแล้ว วิธีรายการคำขอจะกลับมาพร้อมกับลาย success, result
DataStoreWrapper ยังเปิดเผยวิธีการรับความยาวของคิวสำหรับกุญแจที่กำหนดและล้างออกสิ่งที่เก่าออก ตัวเลือกนี้มีประโยชน์อย่างมากในสถานการณ์เมื่อเซิร์ฟเวอร์กำลังปิดลงและไม่มีเวลาใน
อุปสรรค
DataStoreWrapper ปฏิบัติตามหลักการที่ว่า, นอกเหนือจากสถานการณ์ที่ краีดาวน์โหมดที่ผิดพลาดทุกคำขอของเก็บข้อมูลจะต้องสำเร็จ (ส
มันยากที่จะตัดสินใจเกี่ยวกับชุดของกฎที่ชัดเจนสำหรับเมื่อคำขอปลอดภัยจากคิว พิจารณาคำขอต่อไปนี้:
Value=0, SetAsync(1), GetAsync(), SetAsync(2)
พฤติกรรมที่คาดหวังคือว่า GetAsync() จะกลับมา 1 หากเราลบคำขอ SetAsync() จากคิวเนื่องจากการเปลี่ยนแปลงล่า
การเคลื่อนไหวที่เหมาะสมคือเมื่อมีคำขอเขียนใหม่ถูกเพิ่มเข้ามา จะเฉพาะการเรียกร้องเก่าที่สุดเท่า ๆ กับคำขออ่านครั้งล่าสุดเท่านั้น โดยปกติแล้
DataStoreWrapper อาจต้องการให้คุณระบุว่าคำขอ UpdateAsync() นี้อนุญาตให้อ่านและ/หรือเขียนหรือไม่ แต่จะไม่มีผลกับระบบข้อมูลผู้เล่นของเรา ซึ่งไม่สา
เมื่อถูกนำออกจากคิว, มันยากที่จะตัดสินใจเกี่ยวกับกฎที่เป็นธรรมชาติสำหรับ วิธี นี้ควรจะจัดการ เมื่อค
ในที่สุด, มุมมองของเราคือว่าการประมวลผลที่เรียบง่าย (ประมวลผลทุกคำขอ) เป็นที่นิยมที่นี่และสร้างสภา
ล็อคอินเซส
คลาส: SessionLockedDataStoreWrapper >
พื้นหลัง
ข้อมูลผู้เล่นจะถูกเก็บไว้ในหน่วยความจำบนเซิร์ฟเวอร์และอ่านเขียนเฉพาะในห้องเก็บข้อมูลพื้นฐานเมื่อจำเป็น คุณสามารถอ่านและปรับปรุงข้อมูลผู้เล่นในหน่วยความจำได้ทันทีโดยไม่ต้อง
เพื่อให้รุ่นนี้ทำงานได้ตามที่ตั้งใจไว้ จึงเป็นเรื่องสำคัญว่าไม่มีเซิร์ฟเวอร์มากกว่าหนึ่งเซิร์ฟเวอร์สามารถโหลดข้อมูลผู้เล่นไปยังหน่วยความจำจาก DataStore ในเวลาเดียวกัน
เช่นเดียวกับตัวอย่างด้านล่าง หากเซิร์ฟเวอร์ A โหลดข้อมูลของผู้เล่น เซิร์ฟเวอร์ B ไม่สามารถโหลดข้อมูลนั้นได้จนกว่าเซิร์ฟเวอร์ A จ
แม้ว่า Roblox จะอนุญาตให้ลูกค้าเชื่อมต่อกับเซิร์ฟเวอร์เดียวในแต่ละครั้ง แต่คุณไม่สามารถรับประกันได้ว่าข้อมูลจากเซสชันหนึ่งจะถูกบันทึกไว้ก่อนเริ่มเซสชันต่อไปได้ พิจารณาสถานการณ์ต่อไปนี
- เซิร์ฟเวอร์ A ทำการโอนย้ายข้อมูล DataStore เพื่อบันทึกข้อมูลของพวกเขา แต่คำขอล้มเหลวและต้องใช้การลองอีกครั้งหลายครั้งเพื่อสำเร็จ ในระหว่างระยะเวลาการลองอีกครั้งผู้เล่นเข้าร่ว
- เซิร์ฟเวอร์ A ทำการเรียก UpdateAsync() มากเกินไปไปยังคีย์เดียวกันและได้รับการจำกัดความเร็ว คำขอการบันทึกสุดท้ายจะถูกวางในคิว ในขณะที่คำขออยู่ในคิวผู้เล่นจะเข้าร่วม
- ในเซิร์ฟเวอร์ A บางรหัสที่เชื่อมต่อกับกิจกรรม PlayerRemoving จะปรากฏก่อนที่ข้อมูลของผู้เล่นจะถูกบันทึก ก่อนที่การดำเนินการนี้จะสำเร็จผู้เล่นจะเข้าร่วมเซิร์ฟเวอร์ B
- ประสิทธิภาพของเซิร์ฟเวอร์ A ลดลงจนกว่าจะมีการบันทึกครั้งสุดท้ายส่งล่าช้าจนกว่าผู้เล่นจะเข้าร่วมเซิร์ฟเวอร์ B
สถานการณ์เหล่านี้ควรจะเป็นสถานการณ์ที่หายาก แต่พวกเขาก็เกิดขึ้น โดยเฉพาะอย่างยิ่งในสถานการณ์ที่ผู้เล่นออกจากเซิร์ฟเวอร์หนึ่งและเชื่อมต่อกับอีกเซิร
การล็อคเซสชั่นสโนว์เวอร์ได้รับความเสี่ยงนี้โดยการรับประกันว่าเมื่อผู้เล่นกุญแจ DataStore ของเขาถูกอ่านโดยเซิร์ฟเวอร์ก่อน
ใกล้ชิด
SessionLockedDataStoreWrapper เป็น meta-Wraper รอบ DataStoreWrapper คลาส DataStoreWrapper ให้การจัดการคิวและลองทำให้ใหม่ ซึ่ง 0> SessionLockedDataStore0> เสริมด้วยการล็อคเซสชัน
SessionLockedDataStoreWrapper ผ่านทุ
หน้าเฉพาะการเปลี่ยนแปลงจะดำเนินการด้วย UpdateAsync สำหรับแต่ละคำขอที่ดำเนินการต่อไปนี้:
ตรวจสอบว่ากุญแจปลอดภัยในการเข้าถึง และทำลายการดำเนินงานหากไม่ใช่กรณีนั้น "ปลอดภัยในการเข้าถึง" หมายถึง:
ตัวแสดงผลของสําคัญไม่รวมค่าที่ไม่รู้จัก LockId ที่ปรับปรุงล่าสุดน้อยกว่าเวลาหมดอายุล็อค
หากเซิร์ฟเวอร์นี้ได้วางค่า LockId ของตัวเองในช่อง LockId เมื่อเร็ว ๆ นี้แล้ว ค่านี้ยังคงอยู่ในช่อง ก
UpdateAsync ประมวลผลการดำเนินงาน DataStore ที่ผู้ใช้ขอร้องขอ โดยเฉพาะ Class.GlobalDataStore:GetAsync()|GetAsync() จะแปลเป็น 0> function
ขึ้นอยู่กับพารามิเตอร์ที่ผ่านเข้ามาในคำขอ UpdateAsync จะล็อคหรือปลดล็อคกุญแจ:
หากรหัสถูกล็อกไว้ UpdateAsync ตั้ง LockId ในเมทริกของรหัสให้เป็น GUID หรือไม่สามารถเก็บได้ในหน่
หากต้องการปลดล็อกกุญแจ UpdateAsync จะลบ LockId คีย์
ตัวปรับปรุงการลองใหม่เป็นค่าในตัว DataStoreWrapper เพื่อให้การดำเนินการนี้ดำเนินการใหม่หากมีการหยุดที่ขั้นตอนที่ 1 เนื่องจากการเชื่อมต่อถูกล็อก
ข้อความผิดพลาดที่กำหนดเองนี้ยังถูกส่งไปยังผู้บริโภค เพื่อให้ระบบข้อมูลผู้เล่นสามารถรายงานข้อผิดพลาดทางเลือกในกรณีของการล็อคเซสชันไปยังลูกค้า
อุปสรรค
การล็อคเซสชันใช้งานระบบจะขึ้นอยู่บนเซิร์ฟเวอร์ที่เคยปล่อยล็อคของมันเมื่อมันเสร็จสิ้นกับมัน นี่ควรเกิดขึ้นผ่านคำสั่งเพื่อปลดล็อคกุญแจเป็นส่วนหนึ
อย่างไรก็ตาม การปลดล็อกอาจล้มเหลวในบางสถานการณ์ เช่น:
- เซิร์ฟเวอร์พังหรือ DataStoreService คีย์ๆ เพื่อเข้าถึงกุญแจ
- เนื่องจากความผิดพลาดในโลจิกหรือข้อผิดพลาดที่คล้ายคลึงกันไม่สามารถให้คำแนะนำเพื่อปลดล็อกกุญแจได้
คีย์นี่จะทำโดยปกติเป็นส่วนหนึ่งของวงจรการบันทึกอัตโนมัติที่ทำงานในหลังบาทของร
หากหมดเวลาล็อคโดยไม่ต้องปรับปรุงล็อค แสดงว่าเซิร์ฟเวอร์ใด ๆ สามารถรับมาซึ่งล็อคได้ หากเซิร์ฟเวอร์ที่แตกต่างกันรับมาซึ่งล็อค การพยายามโดยเซิร์ฟเวอร์ปัจจุบันที่จะอ่านหรือเขีย
การประมวลผลผลิตภัณฑ์ของผู้พัฒนา
Singleton: ReceiptHandler >
พื้นหลัง
คันบาท ProcessReceipt ทำงานในบทบาทสำคัญในการกำหนดเมื่อใดจะจบการซื้อ ProcessReceipt เรียกในสถานการณ์ที่เฉพาะเจาะจงมาก สำหรับชุดรับประกันของมันดูที่ Class.MarketplaceService.Process
แม้ว่าคำอธิบายของ "การจัดการ" การซื้ออาจแตกต่างกันระหว่างประสบการณ์ เราใช้เกณฑ์ต่อไปนี้
การซื้อไม่ได้รับการจัดการมาก่อน
การซื้อนี้สะท้อนในเซสชันปัจจุบัน
นี่ต้องใช้การดำเนินการต่อไปนี้ก่อนที่จะกลับมา PurchaseGranted :
- ตรวจสอบว่า PurchaseId ยังไม่ได้บันทึกเป็นระเบียบเรียนแล้ว
- รางวัลการซื้อในข้อมูลผู้เล่นในหน่วยความจำ
- บันทึก PurchaseId ในข้อมูลผู้เล่นในหน่วยความจำของผู้เล่น
- เขียนข้อมูลผู้เล่นในหน่วยความจำของผู้เล่นไปยัง DataStore
การล็อคเซสชันทำให้กระบวนการนี้เรียบง่าย เนื่องจากคุณไม่จำเป็นต้องกังวลเกี่ยวกับสถานการณ์ต่อไปนี้:
- ข้อมูลผู้เล่นในหน่วยความจำในเซิร์ฟเวอร์ปัจจุบันอาจไม่ได้รับการปรับปรุง และคุณอาจต้องดึงข้อมูลล่าสุดจาก DataStore ก่อนที่จะตรวจสอบประวัติการซื้อ PurchaseId ของคุณ
- คันเรียกสำหรับการซื้อเดียวกันที่ดำเนินการในเซิร์ฟเวอร์อื่น ๆ ที่คุณต้องอ่านและเขียนประวัติของ PurchaseId และบันทึกข้อมูลผู้เล่นที่ปรับแต่งด้วยการซื้อสะท้อนอะตอมเพื่อป้องกันสภาพแห่ง
การล็อคเซสชันรับประกันว่าหากการเขียนโค้ดไปยังผู้เล่นของ DataStore สำเร็จไม่มีเซิร์ฟเวอร์อื่นที่อ่านหรือเขียน
ใกล้ชิด
ความคิดเห็นใน ReceiptProcessor ระบุวิธีการ:
ตรวจสอบว่าข้อมูลผู้เล่นถูกโหลดบนเซิร์ฟเวอร์นี้และไม่มีข้อผิดพลาดใด ๆ
เนื่องจากระบบนี้ใช้การล็อคเซสชัน การตรวจสอบนี้ยังยืนยันว่าข้อมูลในหน่วยความจำเป็นสมบูรณ์ที่สุด
หากข้อมูลผู้เล่นยังไม่โหลด (ซึ่งคาดว่าจะเกิดขึ้นเมื่อผู้เล่นเข้าร่วมเกม) รอให้ข้อมูลผู้เล่นโหลดเสร็จ ระบบยังรับฟังผู้เล่นที่ออกจากเกมก่อนที่ข้อมูลของพวกเขา
ตรวจสอบว่า PurchaseId ไม่ได้ถูกบันทึกไว้ในข้อมูลผู้เล่นแล้ว
เนื่องจากการล็อคเซสชัน รายการ PurchaseIds ในหน่วยความจำของระบบจะเป็
อัปเดตข้อมูลผู้เล่นในเซิร์ฟเวอร์นี้เพื่อ "รางวัล" การซื้อ
ReceiptProcessor ใช้วิธีการเรียกคืนทั่วไปและกำหนดเรียกคืนที่แตกต่างกันสำหรับแต่ละ DeveloperProductId
อัปเดตข้อมูลผู้เล่นในเซิร์ฟเวอร์นี้เพื่อเก็บไว้ใน PurchaseId
ส่งคำขอเพื่อบันทึกข้อมูลในหน่วยความจำไปยัง DataStore โดยการส่งคำขอนี้จะส่งคืน PurchaseGranted หากคำขอนี้สำเร็จ หากไม่สำเร็จ NotProcessedYet กลับ
หากคำขอบันทึกนี้ไม่สำเร็จ คำขอบันทึกผู้เล่นในหน่วยความจำอาจยังคงสำเร็จได้ ในระหว่างการโทรกลับ ProcessReceipt ครั้งต่อไป สเต็ป 2 จัดการสถานการณ์นี้และกลับมาให้ PurchaseG
ข้อมูลผู้เล่น
Singletons: PlayerData.Server PlayerData.Client>
พื้นหลัง
โมดูลที่ให้ระบบสำหรับการอ่านและเขียนข้อมูลเซสชันของผู้เล่นโดยสามารถใช้ได้ใน Roblox ประสบการณ์ ส่วนนี้ให้ครอบคลุม PlayerData.Server และ PlayerData.Client
ใกล้ชิด
PlayerData.Server และ PlayerData.Client กำลังติดตาม:
- กําลังโหลดข้อมูลของผู้เล่นลงในหน่วยความจํา รวมถึงการจัดการกรณีที่ผิดพลาดในการโหลด
- ให้ระบบอินเทอร์เฟซเพื่อให้ผู้เล่นสามารถเรียกใช้และเปลี่ยนแปลงข้อมูลผู้เล่นได้
- การเลียนแบบการเปลี่ยนแปลงในข้อมูลของผู้เล่นไปยังคลายเอ็นเพื่อให้สามารถเข้าถึงได้
- การเรียกร้องให้โหลดและ/หรือบันทึกข้อผิดพลาดให้กับลูกค้าเพื่อให้สามารถแสดงกระบวนการแสดงข้อผิดพลาด
- การบันทึกข้อมูลของผู้เล่นอย่างต่อเนื่องเมื่อผู้เล่นออกไปและเมื่อเซิร์ฟเวอร์ปิด
กำลังโหลดข้อมูลผู้เล่น
SessionLockedDataStoreWrapper ทำให้มีการโทร getAsync ร้านค้า
หากคำขอนี้ล้มเหลว ข้อมูลปกติจะถูกใช้และโปรไฟล์ถูกติดป้ายว่า "ผิดพลาด" เพื่อให้แน่ใจว่าไม่เขียนในหน้าเก็บข้อมูลในภายหลัง
ตัวเลือกอื่นคือการเตะผู้เล่น แต่เราแนะนำให้ผู้เล่นเล่นด้วยข้อมูลเริ่มต้นและล้างข้อความเป็นสิ่งที่เกิดขึ้นแทนที่จะลบพวกเขาออกจากประสบการณ์
การโหลดข้อมูลครั้งแรกจะถูกส่งไปยัง PlayerDataClient ที่ประกอบด้วยข้อมูลที่โหลดและสถานะข้อผิดพลาด (ถ้ามี)
กระทู้ใด ๆ ที่ผลิตโดยใช้ waitForDataLoadAsync สำหรับผู้เล่นจะถูกดำเนินการต่อ
การให้ระเบียบาดาลของเซิร์ฟเวอร์
- PlayerDataServer เป็นตัวแปรที่สามารถต้องการและเข้าถึงได้โดยใด ๆ โค้ดเซิร์ฟเวอร์ที่ดำเนินการในสภาพแวดล้อมเดียวกัน
- ข้อมูลผู้เล่นจัดเป็นพจนานับสําคัญและมีค่า คุณสามารถดําเนินการเหล่านี้บนเซิร์ฟเวอร์โดยใช้วิธี setValue ، getValue และ updateValue และวิธี 1> RemoveValue1>
- วิธีการ hasLoaded และ waitForDataLoadAsync สามารถใช้ได้เพื่อให้แน่ใจว่าข้อมูลจะโหลดก่อนที่คุณจะเข้าถึงมัน เราแนะนำให้ทำเช่นนี้ในหน้าจอโหลดก่อนที่จะเริ่มระบบอื่น ๆ เ
- วิธี hasErrored สามารถขอได้หากผู้เล่นไม่สามารถโหลดได้เริ่มต้น สาเหตุการณ์นี้ทำให้พวกเขาใช้ข้อมูลเริ่มต้น ตรวจสอบวิธีนี้ก่อนอนุญาตให้ผู้เล่นทำการซื้อใด ๆ เนื่องจากการซื้อ
- สัญญาณ playerDataUpdated ปลายสายด้วย player และ key และ 1> value1> เมื่อข้อมูลผู้เล่นเปลี่ยนแปลง ระบบชุดสามารถสมัครรับสิ่งนี้ได้
การเลียนแบบการเปลี่ยนแปลงไปยังลูกค้า
- การเปลี่ยนแปลงใด ๆ ของข้อมูลผู้เล่นใน PlayerDataServer จะถูกเลียนแบบไปยัง PlayerDataClient ยกเว้นกุญแจนั้นถูกกำหนดให้เป็นส่วนตัวโดยใช้ setValueAsPrivate
- setValueAsPrivate ใช้เพื่อระบุคีย์ที่ไม่ควรส่งไปยังลูกค้า
- PlayerDataClient รวมถึงวิธีการรับค่าของกุญแจ (รับ) และสัญญาณที่เปิดเมื่อมันได้รับการปรับปรุง (อัปเดต) วิธีการ hasLoaded และวิธีการ loaded สัญญาณยังรวมอย
- PlayerDataClient เป็นตัวเดียวที่สามารถต้องการและเข้าถึงได้โดยใดๆ รหัสลูกค้าที่ทำงานในสภาพแวดล้อมเดียวกัน
การเรียกร้องข้อผิดพลาดไปยังลูกค้า
- สถานะข้อผิดพลาดที่พบเมื่อบันทึกหรือโหลดข้อมูลผู้เล่นถูกเลียนแบบไปยัง PlayerDataClient
- เข้าถึงข้อมูลนี้ด้วยวิธี getLoadError และ getSaveError รวมถึงสัญญาณ loaded และ 1> Saved1>
- มีสองประเภทของข้อผิดพลาด: DataStoreError (คำขอ DataStoreService ล้มเหลว) และ SessionLocked (ดู 1> การล็อคเซสชัน1>)
- ใช้เหตุการณ์เหล่านี้เพื่อปิดการซื้อของลูกค้าและใช้การแจ้งเตือนบนกระดาษสัญญาณ. รูปภาพนี้แสดงตัวอย่างกระทู้:
การบันทึกข้อมูลผู้เล่น
เมื่อผู้เล่นออกจากเกม ระบบจะดำเนินการต่อไปตามขั้นตอนต่อไปนี้:
- ตรวจสอบว่าปลอดภัยในการเขียนข้อมูลผู้เล่นไปยังห้องเก็บข้อมูลหรือไม่ สถานการณ์ที่เกิดขึ้นโดยไม่ปลอดภัยรวมถึงข้อมูลผู้เล่นไม่สามารถโหลดหรือยังคงอยู่ในการโหลด
- สร้างคำขอผ่าน SessionLockedDataStoreWrapper เพื่อเขียนค่าข้อมูลในหน่วยความจำปัจจุบันไปยังหน่วยความจำและลบล็อกเซสชันเมื่อเสร็จสิ้น
- ล้างข้อมูลผู้เล่น (และแปรตัวอื่น ๆ เช่นเมทาดาตาและสถานะข้อผิดพลาด) ออกจากหน่วยความจำของเซิร์ฟเวอร์
ในห่วงโซ่ที่มีประจำ เซิร์ฟเวอร์เขียนข้อมูลของผู้เล่นแต่ละรายไปยังห้องเก็บข้อมูล (ข้อมูลนี้จะปลอดภัยในการบันทึก) นี่คือการลดข้อเสียหายในกรณีที่เกิดความล้มเหลวของเซิร์ฟเวอร์และจำเป็นต
เมื่อได้รับคำขอให้ปิดเซิร์ฟเวอร์ สิ่งต่อไปนี้จะเกิดขึ้นใน BindToClose คอลแล็ค:
- มีคำขอเพื่อบันทึกข้อมูลของผู้เล่นในเซิร์ฟเวอร์ตามปกติที่ผู้เล่นออกจากเซิร์ฟเวอร์ คำขอเหล่านี้ทำซ้ำกันโดยปกติเมื่อผู้เล่นออกจากเซิร์ฟเวอร์ คำขอเหล่านี้ไม่มีเวลาใน
- เพื่อเร่งการบันทึก คำขออื่น ๆ ในแถวของแต่ละกุญแจจะถูกล้างออกจาก DataStoreWrapper ใต้พื้น (ดู การทดลองใหม่)
- คอลแล็กทูนไม่สามารถกลับไปยังผู้ที่ทำคำขอได้จนกว่าคำขอทั้งหมดจะเสร็จสิ้น