การใช้ข้อมูลผู้เล่นและระบบการซื้อ

*เนื้อหานี้แปลโดยใช้ AI (เวอร์ชัน Beta) และอาจมีข้อผิดพลาด หากต้องการดูหน้านี้เป็นภาษาอังกฤษ ให้คลิกที่นี่

พื้นหลัง

Roblox ให้ชุดของ API เพื่อใช้งานกับโคลัสเตอร์ข้อมูลผ่าน DataStoreService ส่วนใหญ่การใช้งานกับเหตุการณ์ข้อมูลที่เกี่ยวข้องกับผู้เล่น เช่น การบันทึก การโหลด แ

ประสบการณ์ส่วนใหญ่บน Roblox ใช้ API เหล่านี้เพื่อให้บางรูปแบบของข้อมูลผู้เล่น การใช้งานเหล่านี้แตกต่างกันในการนำเสนอ แต่ทั้งหมดนี้มุ่งเน้นที่จะแก้ปัญหาเดียวกัน

ปัญหาทั่วไป

ด้านล่างเป็นบางส่วนของปัญหาที่พบบ่อยที่สุดที่ระบบจะพยายามแก้ปัญหา:

  • ในการเข้าถึงหน่วยความจำ: DataStoreService ร้องขอการดำเนินการเว็บที่ทำงานได้อย่างเชิญชวนและอยู่ภายใต้ขีดจำกัดอัตรา

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

    ผู้พัฒนาบางรายยังใช้การเรียงลำดับอัตโนมัติเพื่อแก้ไขโครงสร้างข้อมูลขนาดใหญ่ (โดยปกติเพื่อบันทึกในเกมเนื้อหาที่สร้างโดยผู้ใช้)

  • การเลียนแบบ: ลูกค้าต้องการการเข้าถึงที่สม่ำเสมอของข้อมูลผู้เล่น (เช่นเพื่อปรับปรุง UI) ประมาณการเลียนแบบข้อมูลผู้เล่นไปยังลูกค้าทั่วไปจะช่วย

  • การจัดการข้อผิดพลาด: เมื่อไม่สามารถเข้าถึง DataStores ได้ โซลูชันส่วนใหญ่จะใช้วิธีการที่พยายามอีกครั้งและการกู้คืนสู่ 'ข้อมูลเริ่มต้น' โดยมีความระมัดระวังเป็นพิเศษเ

  • การทดลองใหม่: เมื่อสโตร์ข้อมูลไม่สามารถใช้งานได้ หลายวิธีการใช้งานจะนำมาซึ่งการทดลองใหม่ และการรีไม่สามารถเปลี่ยนข้อมูล "เรียล" ได้ และสื่อสารสถานการณ์ให้กับผู้ใช้

  • ล็อคเซสชัน: หากข้อมูลของผู้เล่นคนเดียวถูกโหลดและอยู่ในหน่วยความจำบนหลายเซิร์ฟเวอร์ สามารถเกิดปัญหาในเซิร์ฟเวอร์ที่เก็บข้อมูลเก่าไว้ได้

  • การจัดการการซื้ออะตอม: ตรวจสอบ, รางวัล, และบันทึกการซื้ออะตอมเพื่อป้องกันไม่ให้สูญหายหรือได้รับการรางวัลหลายครั้ง

รหัสตัวอย่าง

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


หลังจากนำโมเดลเข้าสู่ Studio คุณควรเห็นโครงสร้างไดเรกทอรี่ต่อไปนี้:

Explorer window showing the purchasing system model.

สถาปัตยกรรม

ระดับกราฟิกระดับสูงนี้แสดงระบบสําคัญในตัวอย่างและวิธีที่พวกเขาใช้งานกับโค้ดในส่วนที่เหลือของประสบการณ์

An architecture diagram for the code sample.

ลองอีกครั้ง

คลาส: 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 เพราะมันไม่รับประกันความสัมพันธ์ในการสร้างคำขอ การร

  1. Request A ทำให้ค่าของ key K เป็น 1
  2. คำขอล้มเหลวดังนั้นจึงได้กำหนดให้ทำซ้ำใน 2 วินาที
  3. ก่อนที่จะเกิดขึ้นซ้ำ ร้องขอ B ตั้งค่าของ K ให้ 2 แต่การทดลองรีไซเคิลของรีไซล์ขอ A ทันทีจะเขียนค่านี้และตั้งค่า K เป็น 1

แม้ว่า UpdateAsync คีย์UpdateAsync คำขอยังคงต้องประมวลผลเพื่อหลีกเลี่ยงสถานะที่แปรปร

ระบบข้อมูลผู้เล่นของเราใช้คลาสใหม่, DataStoreWrapper คีย์

ใกล้ชิด

An process diagram illustrating the retry system

DataStoreWrapper ให้วิธีการที่ตรงกับวิธีการ DataStore วิธี: DataStore:GetAsync() ,

วิธีเหล่านี้จะถูกเรียกเมื่อ:

  1. เพิ่มคำขอให้เป็นคิว แต่ละคีย์มีคิวของตัวเองซึ่งจะประมวลผลคำขอในลำดับและในลำดับ ธรรมดาของคำขอจะปรากฏให้เห็นจนกว่าคำขอจะสำเร็จ

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

  2. หากคำขอล้มเหลว มันจะทำงานใหม่ด้วยค่าเท่าทวีที่กำหนดได้ รูปแบบนี้เป็นส่วนหนึ่งของการโทรกลับที่ส่งไปที่ ThreadQueue ดังนั้นพวกเขาจึงมีการรับประกันว่าจะสำเร็จก่อนคำขอต่อไปในคิวสำ

  3. เมื่อรายการคำขอสำเร็จแล้ว วิธีรายการคำขอจะกลับมาพร้อมกับลาย success, result

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

อุปสรรค

DataStoreWrapper ปฏิบัติตามหลักการที่ว่า, นอกเหนือจากสถานการณ์ที่ краีดาวน์โหมดที่ผิดพลาดทุกคำขอของเก็บข้อมูลจะต้องสำเร็จ (ส

  1. มันยากที่จะตัดสินใจเกี่ยวกับชุดของกฎที่ชัดเจนสำหรับเมื่อคำขอปลอดภัยจากคิว พิจารณาคำขอต่อไปนี้:

    Value=0, SetAsync(1), GetAsync(), SetAsync(2)

    พฤติกรรมที่คาดหวังคือว่า GetAsync() จะกลับมา 1 หากเราลบคำขอ SetAsync() จากคิวเนื่องจากการเปลี่ยนแปลงล่า

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

    DataStoreWrapper อาจต้องการให้คุณระบุว่าคำขอ UpdateAsync() นี้อนุญาตให้อ่านและ/หรือเขียนหรือไม่ แต่จะไม่มีผลกับระบบข้อมูลผู้เล่นของเรา ซึ่งไม่สา

  2. เมื่อถูกนำออกจากคิว, มันยากที่จะตัดสินใจเกี่ยวกับกฎที่เป็นธรรมชาติสำหรับ วิธี นี้ควรจะจัดการ เมื่อค

ในที่สุด, มุมมองของเราคือว่าการประมวลผลที่เรียบง่าย (ประมวลผลทุกคำขอ) เป็นที่นิยมที่นี่และสร้างสภา

ล็อคอินเซส

คลาส: SessionLockedDataStoreWrapper >

พื้นหลัง

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

เพื่อให้รุ่นนี้ทำงานได้ตามที่ตั้งใจไว้ จึงเป็นเรื่องสำคัญว่าไม่มีเซิร์ฟเวอร์มากกว่าหนึ่งเซิร์ฟเวอร์สามารถโหลดข้อมูลผู้เล่นไปยังหน่วยความจำจาก DataStore ในเวลาเดียวกัน

เช่นเดียวกับตัวอย่างด้านล่าง หากเซิร์ฟเวอร์ A โหลดข้อมูลของผู้เล่น เซิร์ฟเวอร์ B ไม่สามารถโหลดข้อมูลนั้นได้จนกว่าเซิร์ฟเวอร์ A จ

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

  1. เซิร์ฟเวอร์ A ทำการโอนย้ายข้อมูล DataStore เพื่อบันทึกข้อมูลของพวกเขา แต่คำขอล้มเหลวและต้องใช้การลองอีกครั้งหลายครั้งเพื่อสำเร็จ ในระหว่างระยะเวลาการลองอีกครั้งผู้เล่นเข้าร่ว
  2. เซิร์ฟเวอร์ A ทำการเรียก UpdateAsync() มากเกินไปไปยังคีย์เดียวกันและได้รับการจำกัดความเร็ว คำขอการบันทึกสุดท้ายจะถูกวางในคิว ในขณะที่คำขออยู่ในคิวผู้เล่นจะเข้าร่วม
  3. ในเซิร์ฟเวอร์ A บางรหัสที่เชื่อมต่อกับกิจกรรม PlayerRemoving จะปรากฏก่อนที่ข้อมูลของผู้เล่นจะถูกบันทึก ก่อนที่การดำเนินการนี้จะสำเร็จผู้เล่นจะเข้าร่วมเซิร์ฟเวอร์ B
  4. ประสิทธิภาพของเซิร์ฟเวอร์ A ลดลงจนกว่าจะมีการบันทึกครั้งสุดท้ายส่งล่าช้าจนกว่าผู้เล่นจะเข้าร่วมเซิร์ฟเวอร์ B

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

การล็อคเซสชั่นสโนว์เวอร์ได้รับความเสี่ยงนี้โดยการรับประกันว่าเมื่อผู้เล่นกุญแจ DataStore ของเขาถูกอ่านโดยเซิร์ฟเวอร์ก่อน

ใกล้ชิด

An process diagram illustrating the session locking system

SessionLockedDataStoreWrapper เป็น meta-Wraper รอบ DataStoreWrapper คลาส DataStoreWrapper ให้การจัดการคิวและลองทำให้ใหม่ ซึ่ง 0> SessionLockedDataStore0> เสริมด้วยการล็อคเซสชัน

SessionLockedDataStoreWrapper ผ่านทุ

หน้าเฉพาะการเปลี่ยนแปลงจะดำเนินการด้วย UpdateAsync สำหรับแต่ละคำขอที่ดำเนินการต่อไปนี้:

  1. ตรวจสอบว่ากุญแจปลอดภัยในการเข้าถึง และทำลายการดำเนินงานหากไม่ใช่กรณีนั้น "ปลอดภัยในการเข้าถึง" หมายถึง:

    • ตัวแสดงผลของสําคัญไม่รวมค่าที่ไม่รู้จัก LockId ที่ปรับปรุงล่าสุดน้อยกว่าเวลาหมดอายุล็อค

    • หากเซิร์ฟเวอร์นี้ได้วางค่า LockId ของตัวเองในช่อง LockId เมื่อเร็ว ๆ นี้แล้ว ค่านี้ยังคงอยู่ในช่อง ก

  2. UpdateAsync ประมวลผลการดำเนินงาน DataStore ที่ผู้ใช้ขอร้องขอ โดยเฉพาะ Class.GlobalDataStore:GetAsync()|GetAsync() จะแปลเป็น 0> function

  3. ขึ้นอยู่กับพารามิเตอร์ที่ผ่านเข้ามาในคำขอ UpdateAsync จะล็อคหรือปลดล็อคกุญแจ:

    1. หากรหัสถูกล็อกไว้ UpdateAsync ตั้ง LockId ในเมทริกของรหัสให้เป็น GUID หรือไม่สามารถเก็บได้ในหน่

    2. หากต้องการปลดล็อกกุญแจ UpdateAsync จะลบ LockId คีย์

ตัวปรับปรุงการลองใหม่เป็นค่าในตัว DataStoreWrapper เพื่อให้การดำเนินการนี้ดำเนินการใหม่หากมีการหยุดที่ขั้นตอนที่ 1 เนื่องจากการเชื่อมต่อถูกล็อก

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

อุปสรรค

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

อย่างไรก็ตาม การปลดล็อกอาจล้มเหลวในบางสถานการณ์ เช่น:

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

คีย์นี่จะทำโดยปกติเป็นส่วนหนึ่งของวงจรการบันทึกอัตโนมัติที่ทำงานในหลังบาทของร

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

การประมวลผลผลิตภัณฑ์ของผู้พัฒนา

Singleton: ReceiptHandler >

พื้นหลัง

คันบาท ProcessReceipt ทำงานในบทบาทสำคัญในการกำหนดเมื่อใดจะจบการซื้อ ProcessReceipt เรียกในสถานการณ์ที่เฉพาะเจาะจงมาก สำหรับชุดรับประกันของมันดูที่ Class.MarketplaceService.Process

แม้ว่าคำอธิบายของ "การจัดการ" การซื้ออาจแตกต่างกันระหว่างประสบการณ์ เราใช้เกณฑ์ต่อไปนี้

  1. การซื้อไม่ได้รับการจัดการมาก่อน

  2. การซื้อนี้สะท้อนในเซสชันปัจจุบัน

  3. การซื้อถูกบันทึกไว้ใน DataStore

    ในแต่ละการซื้อ, แม้ว่าจะเป็นของใช้หนึ่งครั้งก็ตาม, ควรสะท้อนใน DataStore เพื่อให้ประวัติการซื้อของผู้ใช้รวมอยู่ในข้อมูลเซ션ของพวกเขา

นี่ต้องใช้การดำเนินการต่อไปนี้ก่อนที่จะกลับมา PurchaseGranted :

  1. ตรวจสอบว่า PurchaseId ยังไม่ได้บันทึกเป็นระเบียบเรียนแล้ว
  2. รางวัลการซื้อในข้อมูลผู้เล่นในหน่วยความจำ
  3. บันทึก PurchaseId ในข้อมูลผู้เล่นในหน่วยความจำของผู้เล่น
  4. เขียนข้อมูลผู้เล่นในหน่วยความจำของผู้เล่นไปยัง DataStore

การล็อคเซสชันทำให้กระบวนการนี้เรียบง่าย เนื่องจากคุณไม่จำเป็นต้องกังวลเกี่ยวกับสถานการณ์ต่อไปนี้:

  • ข้อมูลผู้เล่นในหน่วยความจำในเซิร์ฟเวอร์ปัจจุบันอาจไม่ได้รับการปรับปรุง และคุณอาจต้องดึงข้อมูลล่าสุดจาก DataStore ก่อนที่จะตรวจสอบประวัติการซื้อ PurchaseId ของคุณ
  • คันเรียกสำหรับการซื้อเดียวกันที่ดำเนินการในเซิร์ฟเวอร์อื่น ๆ ที่คุณต้องอ่านและเขียนประวัติของ PurchaseId และบันทึกข้อมูลผู้เล่นที่ปรับแต่งด้วยการซื้อสะท้อนอะตอมเพื่อป้องกันสภาพแห่ง

การล็อคเซสชันรับประกันว่าหากการเขียนโค้ดไปยังผู้เล่นของ DataStore สำเร็จไม่มีเซิร์ฟเวอร์อื่นที่อ่านหรือเขียน

ใกล้ชิด

ความคิดเห็นใน ReceiptProcessor ระบุวิธีการ:

  1. ตรวจสอบว่าข้อมูลผู้เล่นถูกโหลดบนเซิร์ฟเวอร์นี้และไม่มีข้อผิดพลาดใด ๆ

    เนื่องจากระบบนี้ใช้การล็อคเซสชัน การตรวจสอบนี้ยังยืนยันว่าข้อมูลในหน่วยความจำเป็นสมบูรณ์ที่สุด

    หากข้อมูลผู้เล่นยังไม่โหลด (ซึ่งคาดว่าจะเกิดขึ้นเมื่อผู้เล่นเข้าร่วมเกม) รอให้ข้อมูลผู้เล่นโหลดเสร็จ ระบบยังรับฟังผู้เล่นที่ออกจากเกมก่อนที่ข้อมูลของพวกเขา

  2. ตรวจสอบว่า PurchaseId ไม่ได้ถูกบันทึกไว้ในข้อมูลผู้เล่นแล้ว

    เนื่องจากการล็อคเซสชัน รายการ PurchaseIds ในหน่วยความจำของระบบจะเป็

  3. อัปเดตข้อมูลผู้เล่นในเซิร์ฟเวอร์นี้เพื่อ "รางวัล" การซื้อ

    ReceiptProcessor ใช้วิธีการเรียกคืนทั่วไปและกำหนดเรียกคืนที่แตกต่างกันสำหรับแต่ละ DeveloperProductId

  4. อัปเดตข้อมูลผู้เล่นในเซิร์ฟเวอร์นี้เพื่อเก็บไว้ใน PurchaseId

  5. ส่งคำขอเพื่อบันทึกข้อมูลในหน่วยความจำไปยัง DataStore โดยการส่งคำขอนี้จะส่งคืน PurchaseGranted หากคำขอนี้สำเร็จ หากไม่สำเร็จ NotProcessedYet กลับ

    หากคำขอบันทึกนี้ไม่สำเร็จ คำขอบันทึกผู้เล่นในหน่วยความจำอาจยังคงสำเร็จได้ ในระหว่างการโทรกลับ ProcessReceipt ครั้งต่อไป สเต็ป 2 จัดการสถานการณ์นี้และกลับมาให้ PurchaseG

ข้อมูลผู้เล่น

Singletons: PlayerData.Server PlayerData.Client>

พื้นหลัง

โมดูลที่ให้ระบบสำหรับการอ่านและเขียนข้อมูลเซสชันของผู้เล่นโดยสามารถใช้ได้ใน Roblox ประสบการณ์ ส่วนนี้ให้ครอบคลุม PlayerData.Server และ PlayerData.Client

ใกล้ชิด

PlayerData.Server และ PlayerData.Client กำลังติดตาม:

  1. กําลังโหลดข้อมูลของผู้เล่นลงในหน่วยความจํา รวมถึงการจัดการกรณีที่ผิดพลาดในการโหลด
  2. ให้ระบบอินเทอร์เฟซเพื่อให้ผู้เล่นสามารถเรียกใช้และเปลี่ยนแปลงข้อมูลผู้เล่นได้
  3. การเลียนแบบการเปลี่ยนแปลงในข้อมูลของผู้เล่นไปยังคลายเอ็นเพื่อให้สามารถเข้าถึงได้
  4. การเรียกร้องให้โหลดและ/หรือบันทึกข้อผิดพลาดให้กับลูกค้าเพื่อให้สามารถแสดงกระบวนการแสดงข้อผิดพลาด
  5. การบันทึกข้อมูลของผู้เล่นอย่างต่อเนื่องเมื่อผู้เล่นออกไปและเมื่อเซิร์ฟเวอร์ปิด

กำลังโหลดข้อมูลผู้เล่น

An process diagram illustrating the loading system
  1. SessionLockedDataStoreWrapper ทำให้มีการโทร getAsync ร้านค้า

    หากคำขอนี้ล้มเหลว ข้อมูลปกติจะถูกใช้และโปรไฟล์ถูกติดป้ายว่า "ผิดพลาด" เพื่อให้แน่ใจว่าไม่เขียนในหน้าเก็บข้อมูลในภายหลัง

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

  2. การโหลดข้อมูลครั้งแรกจะถูกส่งไปยัง PlayerDataClient ที่ประกอบด้วยข้อมูลที่โหลดและสถานะข้อผิดพลาด (ถ้ามี)

  3. กระทู้ใด ๆ ที่ผลิตโดยใช้ 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>)
  • ใช้เหตุการณ์เหล่านี้เพื่อปิดการซื้อของลูกค้าและใช้การแจ้งเตือนบนกระดาษสัญญาณ. รูปภาพนี้แสดงตัวอย่างกระทู้:
A screenshot of an example warning that could be shown when player data fails to load

การบันทึกข้อมูลผู้เล่น

A process diagram illustrating the saving system
  1. เมื่อผู้เล่นออกจากเกม ระบบจะดำเนินการต่อไปตามขั้นตอนต่อไปนี้:

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

  3. เมื่อได้รับคำขอให้ปิดเซิร์ฟเวอร์ สิ่งต่อไปนี้จะเกิดขึ้นใน BindToClose คอลแล็ค:

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