# الحفظ السحابي لألعاب PlayDrop

احفظ تقدم اللاعب وحمّله باستخدام sdk.me.appData وupdateAppData، للضيوف والمسجّلين، مع قواعد الكتابة والمعاينات واللعب دون اتصال.

Source: https://www.playdrop.ai/ar/create/learn/cloud-saves

يحتفظ الحفظ السحابي بتقدم كل لاعب في لعبتك على PlayDrop، فيرافقه من الموقع إلى التطبيقات. يُخزَّن كائن JSON واحد لكل لاعب ولعبة؛ ولا حاجة إلى خادم أو غرفة لعب جماعي.

## القراءة والكتابة

بعد `init()`، تمثل `sdk.me.appData` اللقطة المحفوظة: `{ data, seq, ts_event, ts_arrival }`، أو `null` قبل أول حفظ. اقرأ كائنك من `data`. واكتب الكائن كله باستخدام `updateAppData`، التي تعيد اللقطة المحفوظة وتحدّث `sdk.me.appData`.

```js
const sdk = await playdrop.init();
let progress = { level: 1, coins: 0, ...(sdk.me.appData?.data ?? {}) };
let queue = Promise.resolve();

// Resolves with the saved snapshot; rejects when the save failed.
function save(changes) {
  progress = { ...progress, ...changes };
  const snapshot = { ...progress };
  const attempt = queue.then(() => sdk.me.updateAppData(snapshot));
  queue = attempt.catch(() => {}); // a failed save must not block the next one
  return attempt;
}

try {
  await save({ level: 2 });
  showSaved();
} catch (error) {
  showSaveError(); // progress stays in memory; the next save sends it again
}
```

- تستبدل كل عملية كتابة الكائن المحفوظ بالكامل: احتفظ بكل حقل ما زلت تحتاج إليه.
- نفّذ عمليات الكتابة بالتتابع، كما في المثال، حتى لا يصل حفظ أقدم بعد حفظ أحدث، وأبقِ الطابور يعمل بعد أي فشل.
- لا تعرض «تم الحفظ» إلا بعد نجاح الوعد. تغيير `appData.data` في الذاكرة لا يحفظ أي شيء.
- لا تملك `appData` الدوال `get` أو `set` أو `save`.

## متى تحفظ

احفظ عند نقاط التفتيش ونهايات المراحل والمشتريات بدل الحفظ في كل إطار. لا تحفظ أبدًا أثناء المعاينات أو الالتقاطات: اكتب فقط عندما تكون قيمة `sdk.host.phase` هي `play`. أبقِ الحفظ صغيرًا ومرقّمًا بإصدار في حقل خاص بك، مثل `saveVersion: 2`، ليتمكن إصدار لاحق من اللعبة من ترحيله.

## الضيوف واللاعبون المسجّلو الدخول

لا تحتاج إلى التحقق من `sdk.me.isLoggedIn` قبل الحفظ: يحتفظ ضيوف PlayDrop بحفظهم أيضًا. أما اللاعب الذي ليست لديه جلسة على الإطلاق فيبقى حفظه في الذاكرة طوال تلك الزيارة، لذا فاكتمال الكتابة لا يثبت وصول الحفظ إلى السحابة. استخدم `isLoggedIn` فقط للميزات التي تحتاج إلى حساب حقيقي، مثل المشتريات واللعب الجماعي المستضاف.

## دون اتصال

في المتصفح، يحتاج الحفظ إلى اتصال ولا يوجد طابور للعمل دون اتصال: واصل اللعب عند الفشل وأعد المحاولة عند نقطة التفتيش التالية. أما البيئات المضيفة التي تعلن دعم بيانات الجهاز، مثل تطبيقات PlayDrop القادرة على العمل دون اتصال، فتحتفظ بالحفظ على الجهاز وتزامنه عند توفر الاتصال.

## ما ليس من الحفظ

الحفظ خاص بلاعب واحد ولعبة واحدة. وهو منفصل عن [لوحات المتصدرين](https://www.playdrop.ai/ar/create/learn/leaderboards) و[الإنجازات](https://www.playdrop.ai/ar/create/learn/achievements)، التي لها واجهات برمجية خاصة بها وتظهر على PlayDrop. أما الحالة المشتركة بين اللاعبين، مثل مباراة أو عالم، فمكانها [خادم اللعبة](https://www.playdrop.ai/ar/create/learn/game-servers) في مجموعات MongoDB (collections) الخاصة بلعبتك.

## الاختبار

ينتمي الحفظ إلى لعبة مرفوعة. ارفع إصدارًا خاصًا مرة واحدة على الأقل، ثم اختبر من `url` في الإيصال أو من إطار التطوير المحلي الموضّح في [النشر من تطبيق الذكاء الاصطناعي](https://www.playdrop.ai/ar/create/learn/mcp-publishing).

## أدلة ذات صلة

- [لوحات المتصدرين](https://www.playdrop.ai/ar/create/learn/leaderboards): صرّح بلوحات المتصدرين في catalogue.json، وأرسل النقاط عبر sdk.leaderboards، واعرض المراتب الأولى وجيران اللاعب. أنواع النقاط والحدود وقواعد التحديث.
- [الإنجازات](https://www.playdrop.ai/ar/create/learn/achievements): صرّح بإنجازات قياسية وتدريجية مع أيقوناتها في catalogue.json، ثم افتحها وأبلغ عن التقدم باستخدام sdk.achievements.
- [خوادم الألعاب الفورية](https://www.playdrop.ai/ar/create/learn/game-servers): شغّل خادم Colyseus 0.17 مستضافًا مع قاعدة بيانات MongoDB للعبتك، واتصل به من المتصفح عبر SDK، واختبره بلاعبَين، واعرف حدوده.
