معرّف جهاز محفوظ وإعدادات اللاعب المسجّل دخوله
- معرّف جهاز تصنعه الحزمة مرة واحدة وتحفظه (
ThisDeviceId، وفي Blueprint Flock Get This Device Id): اترك معرّف الجهاز فارغًا فيLoginWithDeviceوRegisterWithDeviceوLinkDevice(أو عُقدها) لاستخدامه. واللعبة التي تمرّر معرّفًا خاصًا بها تواصل تمريره، فلا يتغيّر لاعبوها. راجع اللاعبون والمصادقة. - قراءة الإعدادات بعد تسجيل الدخول تعطي قيم اللاعب نفسه: تأتي إعدادات اللعب والميزات مع تجاوزات شرائح اللاعب وتجاوزاته الخاصة. اقرأها من جديد بعد تسجيل الدخول؛ وتبقى الإعدادات الأخرى والقراءة دون لاعب مسجّل على قيم اللعبة كلها. راجع الإعدادات عن بُعد.
- قائمة العملات المولَّدة لا تضم إلا عملات اللعبة: لم تعد عملة العنصر المبيع بالمال الحقيقي من أعضائها. شغّل Sync Schemas من جديد.
- لم يعد فحص إعداد المتجر الناجح يكتب تحذيرًا وخطأً بسبب الإيصال المختلَق الذي يرسله.
معرّف جهاز محفوظ وإعدادات اللاعب المسجّل دخوله
- معرّف جهاز تصنعه الحزمة مرة واحدة وتحفظه (
Authentication.ThisDeviceId): أغفل المعرّف فيLoginWithDeviceAsyncوRegisterWithDeviceAsyncوLinkDeviceAsyncلاستخدامه. واللعبة التي تسجّل دخول لاعبيها بمعرّف خاص بها يجب أن تواصل تمريره، وإلا حصل هؤلاء اللاعبون على حساب جديد. راجع اللاعبون والمصادقة. - قراءة الإعدادات بعد تسجيل الدخول تعطي قيم اللاعب نفسه: تأتي إعدادات اللعب والميزات مع تجاوزات شرائح اللاعب وتجاوزاته الخاصة. اقرأها من جديد بعد تسجيل الدخول؛ وتبقى الإعدادات الأخرى والقراءة دون لاعب مسجّل على قيم اللعبة كلها. راجع الإعدادات عن بُعد.
- لا يضم
FlockFundIdإلا عملات اللعبة: لم تعد عملة العنصر المبيع بالمال الحقيقي من أعضائه. شغّل Sync Schemas من جديد. - الدفع عبر الويب الذي توقفت قراءته قبل انتهائه يُبلَّغ عنه بنتيجة غير معروفة (
OutcomeUnknown) لا بإخفاق، فلا يُعرض العنصر من جديد ما دام اللاعب يستطيع الدفع في صفحته. - في Advanced Settings بطاقة Offline Cache (Enable Offline Cache وOffline Cache Directory)، ويسجّل مثال Quick Start جهازًا عند تشغيله الأول.
الشراء بالمال الحقيقي من Blueprint، ومثال المتجر
- عُقد المتجر (Flock | Store): اربط المتجر، واعرض أسعاره، واستعد المشتريات، وافحص إعداده، وابدأ الدفع عبر الويب أو اقرأه؛ ويبقى الشراء بعقدة Flock Purchase المعتادة. وتسترد Flock Redeem Store Receipt عملية شراء أجرتها شيفرة المتجر الخاصة باللعبة.
- حدثان في مركز أحداث Flock،
OnStorePurchaseCompletedوOnStorePurchaseNotDelivered، فيسمع الربطُ الذي يُجرى مرة عند البدء كلَّ اتصال بالمتجر. - فحص إعداد المتجر جاهز في الدفع عبر الويب حين لا يُعثر على ما يُصلَح؛ كان يُقرأ غير جاهز في كل دفع عبر الويب، فيُخفى المتجر المشروط به على Windows وMac وLinux.
- عملية الشراء التي تنتظر دفعها تُجيب رغم ذلك حين يزول الـ Blueprint الذي بدأها.
- مثال المتجر، مصنوع من Blueprint وحدها (
Content/Samples/Shop): شاشة متجر تسجّل دخول جهاز، وتعرض المحفظة والأسعار وما يملكه اللاعب، وتشتري وتستخدم وتستعيد. راجع المتاجر والمخزون. - السجلّ الذي يُضبط في أي وقت يصل إلى كل أجزاء الحزمة، ويمكن ترك أول عقدة في سلسلة Blueprint دون توصيل.
- تُبنى الحزمة لـ Android على UE 5.8 من جديد.
الشراء بالمال الحقيقي
- بِع عناصر المتجر بالمال الحقيقي بالاستدعاء نفسه الذي تشتري به أي عنصر آخر،
FFlockShopProvider::Purchase. ويربطUFlockStore::Connectطريقة الدفع الخاصة بالمنصة: Google Play على Android وApp Store على iOS، عبر نظام المحرك الفرعي للخدمات عبر الإنترنت، والدفع عبر الويب من خلال Stripe أو Tap أو Moyasar على Windows وMac وLinux. لا شيء إضافي يُثبَّت. راجع الدفع عبر الويب والمتاجر والمخزون. - يتحقق خادم Flock من كل عملية شراء قبل تسليمها، مرة واحدة لكل عملية شراء من المتجر. ولا تُنهى عملية الشراء
في المتجر إلا بعد أن تسلّمها Flock، فما قطعه تعطّل يُرسَل من جديد عند التشغيل التالي؛ ويستعيد
Restoreما اشتراه اللاعب من قبل، ويستردRedeemStoreReceiptعملية شراء من المتجر أجرتها اللعبة بنفسها. والدفع عبر الويب الذي تركه اللاعب مفتوحًا يُعثر عليه عند تسجيل الدخول التالي ويُبلَّغ عنه بعد دفعه. - ما تقرؤه شاشة المتجر: هل يُشترى العنصر بالمال الحقيقي (
IsRealMoney) ومعرّف منتجه في كل متجر، ومحفظة اللاعب حسب رمز العملة (FFlockPlayerProvider::GetWallet)، والعناصر التي يملكها ولم يستخدمها (GetOwnedItemCountsوConsumeOne)، والسعر الذي يُعرض (GetPrice: سعر المتجر نفسه على الهاتف، وسعر العنصر نفسه في الدفع عبر الويب). - يُرفض العنصر المضبوط على Inactive قبل أن يُفتح مربع حوار المتجر، ويُسلَّم رغم ذلك ما دفع اللاعب ثمنه.
- كل إخفاق في الدفع يذكر سببه وطريقة إصلاحه: 19 رمز خطأ جديدًا، والمتجر الذي لم يقبل الدفع يذكر السبب
(
FlockStoreFailureReasons، ومنهاExpired). وعملية الشراء التي ضاع ردّها تقول ذلك (bOutcomeUnknown)؛ ويُعاد إرسال الشراء من المحفظة بأمان بمفتاحه الواحد، ولا يُحتسب الدفع مرتين أبدًا. - يحتاج Google Play إلى UE 5.8 أو أحدث. ولا يجوز للعبة تُباع على Steam أن تأخذ المدفوعات عبر الدفع عبر الويب، وتكتب نسخة Steam التي تربط واحدًا منها تحذيرًا في السجل. ويعمل Mac وLinux بالشيفرة نفسها التي يعمل بها Windows، لكنهما لم يُختبرا بعد.
جلسات اختبار مرتبطة باللاعب، وشعارات في نموذج الملاحظات
- جلسة الاختبار التي تبدأ ولاعب مسجّل دخوله تحمل تسجيل دخوله، فيستطيع Protokite ربطها بحسابه في Qwacks Community. ودون لاعب مسجّل تبدأ الجلسة كما كانت.
- يحمل نموذج الملاحظات شعارات اللعبة نفسها (Feedback Form Logos وFeedback Form Logo Height) في صف فوق عنوانه، وPowered by Qwacks في أسفله على اليسار، ويستبدل به Feedback Form Footer Logo شعار اللعبة نفسها. راجع Protokite في Unreal.
- لم يعد تجديد الرمز الذي ما زال في طريقه حين توقف اللعبة Flock يصل إلى التهيئة التالية، والتجديد المرفوض لأن تشغيلًا آخر جدّد تسجيل الدخول أولًا يكمل بذلك التجديد بدل تسجيل خروج اللاعب.
- عنوان API المكتوب دون علامات اقتباس في ملف إعدادات (يقرؤه المحرك
http:وحده) يوقف التهيئة ويذكر السبب.
جلسات اختبار مرتبطة باللاعب، وشعارات في نموذج الملاحظات
- جلسة الاختبار التي تبدأ ولاعب مسجّل دخوله تحمل تسجيل دخوله، فيستطيع Protokite ربطها بحسابه في Qwacks Community. ودون لاعب مسجّل تبدأ الجلسة كما كانت.
- يحمل نموذج الملاحظات شعارات اللعبة نفسها في صف فوق عنوانه، وPowered by Qwacks في أسفله على اليسار، ويستبدل به شعار تذييل من اللعبة نفسها. راجع Protokite في Unity.
- تجديد تسجيل الدخول الذي يُجاب بعد
FlockClient.Shutdown()يحفظ رموزه الجديدة لـCreateالتالي، والتجديد المرفوض لأن تشغيلًا آخر جدّد أولًا يكمل بذلك التجديد، والعميل الذي توقف لا يُعلن شيئًا لمستمعي العميل التالي.
الشراء بالمال الحقيقي
- بِع عناصر المتجر بالمال الحقيقي باستدعاء واحد لكل عنصر هو
Shop.PurchaseAsync. ويربطFlockStore.ConnectAsyncطريقة الدفع الخاصة بالمنصة: Google Play على Android وApp Store على iOS، كلاهما عبر Unity IAP 5، والدفع عبر الويب من خلال Stripe أو Tap أو Moyasar على أجهزة سطح المكتب وWebGL. راجع الشراء بالمال الحقيقي والدفع عبر الويب. - يتحقق خادم Flock من كل عملية شراء قبل تسليمها، مرة واحدة لكل عملية شراء من المتجر. وما اكتمل
واللعبة مغلقة، أو قطعه تعطّل، يُسلَّم عند التشغيل التالي؛ ويستعيد
RestoreAsyncما اشتراه اللاعب من قبل. - ما تقرؤه شاشة المتجر: محفظة اللاعب (
Player.GetWalletAsync)، والعناصر التي يملكها ولم يستخدمها (Shop.GetOwnedItemCountsAsyncوConsumeOneAsync)، والسعر الذي يُعرض (GetPrice: سعر المتجر نفسه على الهاتف، وسعر العنصر نفسه في الدفع عبر الويب). - يُرفض العنصر المضبوط على Inactive قبل أن يُفتح مربع حوار المتجر، ويُسلَّم رغم ذلك ما دفع اللاعب ثمنه.
- كل إخفاق في الدفع يذكر سببه وطريقة إصلاحه. وعملية الشراء التي ضاع ردّها تقول ذلك (
OutcomeUnknown)؛ ويُعاد إرسال الشراء من المحفظة بأمان، ولا يُحتسب الدفع مرتين أبدًا.
الشبكات التي تحجب UDP
- يصل اللاعب الذي تحجب شبكته UDP عن وسيط Flock إليه الآن من طريق آخر: UDP عبر IPv6، ثم TCP، ثم TLS. تُسقط بعض نقاط الاتصال في الهواتف والمكاتب والمدارس والفنادق UDP عبر IPv4، فلم يكن هذا اللاعب يستطيع الاستضافة أو الانضمام عبر الوسيط. ولا يكلّف الطريق المحجوب إلا ثانيتين تقريبًا، والمنفذ الآخر من النوع نفسه نصف ثانية.
- يصل اللاعب على شبكة لا تعرف إلا IPv6 إلى الوسيط عبر عنوانه في IPv6، ويلعب مع الجميع.
- يصل اللاعب المنضمّ إلى وسيط المضيف عبر أي طريق إليه، فيلعب مضيف على UDP ولاعب على TLS معًا.
- حين لا ينجح أي طريق، يسمّي
relay_unreachableكل طريق جُرِّب وسبب إخفاقه. - يتبع
InitializeWithConfigخيار Enable Debug Logs في إعداده حين تكتب الحزمة في السجل قبله (كما تفعل حين يكون Auto-Initialize On Load معطّلًا)؛ إذ كان يُؤخذ بخيار الإعدادات بدلًا منه.
الشبكات التي لا تمرّر إلا حركة الويب
- يصل اللاعب على شبكة لا تمرّر إلا حركة الويب إلى الوسيط في نحو 5 ثوانٍ بدل 10. تضيف Flock منافذ الويب للوسيط (80 و443)، فتجرّب الحزمة منفذًا آخر من النوع نفسه بعد نصف ثانية من منفذ لا يرد، والطرق الأخرى بفاصل ثانيتين.
الشبكات التي تحجب UDP
- يصل اللاعب الذي تحجب شبكته UDP عن وسيط Flock إليه الآن من طريق آخر: UDP عبر IPv6، ثم TCP، ثم TLS. تُسقط بعض نقاط الاتصال في الهواتف والمكاتب والمدارس والفنادق UDP عبر IPv4، فلم يكن هذا اللاعب يستطيع الاستضافة أو الانضمام عبر الوسيط. ولا يكلّف الطريق المحجوب إلا ثانيتين تقريبًا.
- يصل اللاعب على شبكة لا تعرف إلا IPv6 إلى الوسيط عبر عنوانه في IPv6، ويلعب مع الجميع.
- يصل اللاعب المنضمّ إلى وسيط المضيف عبر أي طريق إليه، فيلعب مضيف على UDP ولاعب على TLS معًا.
- حين لا ينجح أي طريق، يسمّي
relay_unreachableكل طريق جُرِّب وسبب إخفاقه.
الوسيط الذي يكفّ عن الرد
- يُعَدّ الوسيط الذي يكفّ عن الرد على هذا الجهاز مفقودًا خلال دقيقة، فيُعيد
RelayLostاللعبة: يفتح تشغيل Netcode من جديد وسيطًا آخر. وكان يُعَدّ مفقودًا من قبل حين يحين تجديده فقط، بعد دقائق. - لم يعد تسجيل اختبار اللعب على بطاقة رسوميات NVIDIA يعرّض اللعبة للتعطّل حين ينتهي. إذ لا يُترك المُرمِّز إلا بعد أن يُنهي عمله.
- تُرسَل أحداث التحليلات المُضافة إلى الطابور في اللحظة نفسها بالترتيب الذي جاءت به، على Windows أيضًا.
- تُقرأ سطور السجل ورسائل الإخفاق بالشكل نفسه على كل جهاز: تُكتب الكسور العشرية بنقطة أيًّا كانت إعدادات لغة الجهاز، وتُسمّى الملفات المحفوظة بالتاريخ الميلادي.
Android
- تُبنى الحزمة وتعمل على Android. لم تكن تُبنى لـ Android من قبل، ولمّا بُنيت لم تستطع أن تعرف عنوان الوسيط من اسمه هناك، فلم يكن اللاعب على Android يصل إلى وسيط Flock. قيس ذلك على هاتف متصل ببيانات الجوال، لعب عبر وسيط Cloudflare ثم على مسار مباشر مع مضيف على شبكة أخرى.
المسارات المباشرة للاعبين المارّين عبر الوسيط
- ينتقل اللاعب الذي جاء عبر وسيط Flock إلى مسار مباشر حين يتمكّن هو والمضيف من الوصول أحدهما إلى
الآخر (
WhenNeeded)، ويعود إلى الوسيط حين يسكت ذلك المسار 4 ثوانٍ. ويستمرّ اتصال اللعبة عبرهما، ولا يحمل الوسيط شيئًا لذلك اللاعب في أثناء ذلك. ولا ينتقلAlwaysأبدًا، فتبقى العناوين كلها مخفية. راجع المسارات المباشرة. - يعود اللاعب المارّ عبر الوسيط الذي تتصل لعبته من جديد خلال ثوانٍ، لا بعد أن يُنهي المحرّك اتصاله القديم لانقضاء مهلته بعد دقيقة.
اللعب الجماعي
- الفرق ومطابقة اللاعبين والجلسات. يكوّن الأصدقاء فريقًا برمز دعوة، ويجدون مطابقة منفردين أو مع الفريق، أو ينضمون إلى لعبة صديق برمز الانضمام. وتحفظ الحزمة كل مقعد، وتتابع الفريق والبحث والجلسة في الخلفية، وتطلق أحداثًا عند تغيّرها. راجع اللعب الجماعي.
- يصل Travel To Session بين لاعبي الجلسة عبر شبكة المحرّك نفسه: يفتح المضيف مستواه للاستماع ويُعلن كيف يُوصَل إليه، وينتقل كل لاعب إليه. يتصل اللاعبون على شبكة المضيف مباشرة، ويمرّ الآخرون عبر وسيط Flock، فلا يحتاج أحد إلى فتح منفذ. ولا يُدخل نمط اللعب لدى المضيف إلا لاعبي الجلسة. راجع اتصال اللاعبين.
- حين يغادر المضيف، يتولّى لاعب آخر (1.35.0): تستدعي كل لعبة Travel To Session من جديد عند On Host Changed، وعند On Relay Lost حين يتوقف وسيطها عن العمل.
- Blueprint: عقدة لكل استدعاء، وFlock Game Mode Base لتحقّق المضيف.
- عيّنة (1.36.0): عيّنة لعب جماعي مبنية بـ Blueprint فقط، في مجلد Content/Samples/Multiplayer في الإضافة.
- يُعَدّ الوسيط الذي يكفّ عن الرد مفقودًا خلال دقيقة (1.37.0)، فيُعيد On Relay Lost اللعبة: وُجد ذلك أثناء اللعب عبر وسيط Flock على شبكة حقيقية.
- رموز أخطاء اللعب الجماعي، ولكل منها إصلاح، ضمن
EFlockErrorCode.
اللعب الجماعي
- الفرق ومطابقة اللاعبين والجلسات. يكوّن الأصدقاء فريقًا برمز دعوة، ويجدون مطابقة منفردين أو مع الفريق، أو ينضمون إلى لعبة صديق برمز الانضمام. وتحفظ الحزمة كل مقعد، وتتابع الفريق والبحث والجلسة في الخلفية، وتطلق أحداثًا عند تغيّرها. راجع اللعب الجماعي.
- يصل
session.StartNetcodeAsync(networkManager)بين لاعبي الجلسة عبر Netcode for GameObjects بالإصدار 1.x أو 2.x. يتصل اللاعبون على شبكة المضيف مباشرة، ويمرّ الآخرون عبر وسيط Flock، فلا يحتاج أحد إلى فتح منفذ. ولا يُدخل المضيف إلا لاعبي الجلسة. راجع اتصال اللاعبين. - ينتقل اللاعبون المارّون عبر الوسيط إلى مسار مباشر إلى المضيف حين يتمكّن الطرفان من الوصول أحدهما
إلى الآخر، ويبقى الوسيط جاهزًا إن سكت ذلك المسار (مع
WhenNeededفقط). - وسيط Flock على شبكة Cloudflare (1.84.0): يُخبر كل لاعب المضيف بعنوانه على الوسيط، فتعمل الوسطاء التي تمنح عنوان كل لاعب عنوان IP خاصًا به، وتواصل الحزمة المحاولة حتى تجد طريقًا إلى خادم وسيط لا يجيب على كل اتصال. وصارت الهواتف على بيانات الجوّال تعرف عنوانها هي أيضًا، فتصل إلى اللاعبين الآخرين مباشرةً أكثر من قبل.
- حين يغادر المضيف، يتولّى لاعب آخر. تبدأ كل لعبة شبكتها من جديد عند
HostChanged، وعندRelayLostحين يتوقف وسيطها عن العمل. - عيّنات: Play With Friends وQuick Match، مكوّن واحد لكل منهما، في مجلد Samples/Multiplayer في الحزمة.
- رموز أخطاء اللعب الجماعي، ولكل منها تلميح للإصلاح، ضمن
FlockErrorCode.
Unreal Engine 5.4
- أصبح Unreal Engine 5.4 مدعومًا، فصار النطاق من 5.4 إلى 5.8، ويثبّت مشروع 5.4 الإضافة دون أي تغيير. يُبنى 5.4 ويُربط في مشروع حقيقي، لكن مجموعة الاختبارات الكاملة لم تُشغَّل عليه بعد كما تُشغَّل على 5.5 إلى 5.8.
- مشكلة معروفة في المحرّك على 5.4 و5.5: تنتهي حزمة Development بخطأ وصول إلى الذاكرة بعد نحو 60 ثانية من إغلاقها. الخلل في المحرّك، وقد أصلحته Epic في 5.6. راجع دليل حزمة Unreal.
مكافآت المتجر والتذكيرات المدعومة من الخادم
- تمنح عمليات الشراء محتواها من جهة الخادم، وتخبرك الحزمة بما مُنح. تُكمل
PurchaseبالنوعFFlockPurchaseResult— المكافآت الممنوحة، والمحفظة بعد المنح، ومدخل المخزون إن أنشأ العنصر واحدًا. راجع المتاجر والمخزون. - جديد: تستهلك
Consume(InventoryId)عنصرًا مملوكًا وتعيد ما منحه، بالأمان المالي نفسه الذي يحمله الشراء: يُظهر الفشلَ الملتبس بدل إعادة إرساله، فلا تُمنح المكافأة مرتين. وفي Blueprint هي عقدة Flock Consume Inventory Item. - يعلن
Rewardsفي عنصر الفهرس عمّا سيمنحه قبل شرائه، ويميّزTypeحزمةَ العملة عن العنصر القابل للاستهلاك أو العنصر العادي. - تغيير كاسر: تُكمل
PurchaseبالنوعFFlockPurchaseResultبدلFFlockPlayerInventory. وانتقل مدخل المخزون إلى.Inventory، ويكون فارغًا في حالة حزمة العملة التي تسلّم محتواها مباشرة ولا تنشئ ما يُملك — استخدم Has Inventory Row قبل قراءته. كما أُعيدت تسمية طرف الخرج في ماكروPurchaseالمُولَّد؛ فأعد التوليد بعد الترقية. - جديد: عقدتا Flock Cancel All Scheduled Notifications وFlock Get Pending Schedules في Blueprint. كانتا متاحتين في C++ فقط، فلم يكن بالإمكان بناء زر «امسح تذكيراتي» في مخطط — والبديل البديهي، حلقة ForEach على Flock Cancel Scheduled Notification، يُطلق كل عمليات الإلغاء في إطار واحد فتتسابق على القائمة المخزَّنة. أما العقدة فتمشي عليها بالتتابع.
- عقد صرفة جديدة لأنواع المكافآت — Is Currency Reward وFlock Currency Reward Type — لأن نوع المكافأة نصّ يملكه الخادم. ومقارنته بقيمة مكتوبة يدويًا تُخاطر بأن يُقرأ الخطأ المطبعي على أنه «ليست مكافأة عملة» فيتخطّى المنح بصمت.
- تسأل
GetScheduled()الخادمَ عن التذكيرات المعلّقة لدى اللاعب، فترى التذكيرات التي ضُبطت قبل إعادة التثبيت أو على جهاز آخر. رشِّح باستخدامFlockScheduledNotificationStatuses::Pendingأو::Deliveredأو::Canceled، أو عقد Flock Schedule Status في Blueprint. راجع الإشعارات. - تلغي
CancelAllScheduled()الآن كل ما لدى اللاعب من تذكيرات معلّقة، أينما جُدولت. ولا تلجأ إلى السجل المحلي إلا عند تعذّر الوصول إلى الخادم. - لم تتغيّر
GetPendingSchedules()، وتبقى متزامنة ولا تحتاج شبكة؛ وهي الآن البديل دون اتصال بدل أن تكون القائمة الأساسية.
قراءة تذكيرات اللاعب المجدولة
- تسأل
GetScheduledAsync()الخادمَ عن التذكيرات المعلّقة لدى اللاعب. كانت القائمة الوحيدة حتى الآن سجلَّ الحزمة الخاص بما جدولته هذه النسخة، فتضيع المرجعية بعد إعادة التثبيت أو على جهاز ثانٍ ولا يستطيع اللاعب إلغاء تذكيراته. راجع الإشعارات. - رشِّح حسب الحالة عبر
ScheduledNotificationStatuses.Pendingأو.Deliveredأو.Canceled، والحالة الافتراضية هي المعلّقة. - تلغي
CancelAllScheduledAsync()الآن كل ما لدى اللاعب من تذكيرات معلّقة أيًّا كان مكان جدولتها، لا ما تتبّعته النسخة الحالية فقط. وترجع إلى السجل المحلي إن تعذّر الوصول إلى الخادم، فيظل المستدعي دون اتصال قادرًا على إلغاء ما يعرفه. - أما
GetPendingSchedules()فلم تتغيّر، ولا تزال متزامنة ولا تحتاج شبكة؛ وصارت البديل دون اتصال بدل أن تكون القائمة الأساسية.
عناصر متجر تمنح مكافآت
- تمنح عمليات الشراء محتوياتها من جهة الخادم، وتخبرك الحزمة بما مُنح. تُعيد عملية الشراء
PurchaseResult— المكافآت الممنوحة، والمحفظة بعدها، ومدخل المخزون إن أنشأ العنصر واحدًا — فتستطيع اللعبة عرض «+500 ذهب» دون استدعاء ثانٍ. راجع المتاجر والمخزون. - جديد: تستهلك
ConsumeAsync(inventoryId)عنصرًا مملوكًا وتُعيد ما منحه. والاستهلاك ينقل عملة، فيحمل أمان المال نفسه الذي يحمله الشراء: يُظهر الفشلَ الملتبس بدل إعادة إرساله، فلا تُمنح المكافأة مرتين. - تُعلن
ShopItem.Rewardsعمّا سيمنحه العنصر قبل شرائه، ويميّزShopItem.Typeحزمةَ العملة عن العنصر القابل للاستهلاك عن العنصر القياسي. - تغيير كاسر: تُعيد
PurchaseAsyncالآنPurchaseResultبدلPlayerInventory، وانتقل مدخل المخزون إلىresult.Inventory. ومواضع الاستدعاء التي كانت تستخدم القيمة المُعادة مباشرة تحتاج هذا التعديل وحده، وسيشير المُصرِّف إلى كل واحد منها. - ولا تكون
GrantedولاRewardsقيمتهاnullأبدًا — فالعنصر الذي لا يمنح شيئًا يُعيد قائمة فارغة.
أخطاء تسمّي الحل
- الأخطاء صارت تقول ماذا تفعل، لا ما الذي تعطّل فحسب. كان الاستدعاء الفاشل يظهر بصيغة
Validation failed (HTTP 400)، بينما شرح الخادم نفسه مدفون في جسم الاستجابة الخام. أما الآن فتحملFlockException.Messageالاستدعاء الذي أخفق، وسبب الخادم، والمعرّف المُرمَّز، وسطرFix:— حتى إن الدخول بجهاز غير مسجَّل يسمّيRegisterWithDeviceAsyncصراحةً. راجع معالجة الأخطاء. - والحل خاصّ بنوع بيانات الاعتماد: فالرمز
player.invalid_login_credentialsنفسه يعني «سجّل هذا الجهاز أوّلًا» عند الدخول بالجهاز، و«كلمة المرور خاطئة» عند الدخول بالبريد الإلكتروني. - إضافات على الاستثناء:
ServerMessageوHintوOperation، لتصوغ نصّك الخاص بدل تحليل الرسالة. وتُعيدFlockErrorHints.For(errorCode)صياغة الخطوة التالية نفسها لأي رمز. وابقَ متفرّعًا علىErrorCode— فالرموز ثابتة والصياغة ليست كذلك. - أخطاء الطلبات غير الصالحة صارت مقروءة. فالاستجابات التي تسمّي الحقل المخالف تظهر الآن بصيغة
body.player_data: Input should be a valid dictionaryبدل «Validation failed» المجرّدة. - وسيط الوصول المُولَّد الناقص صار يشرح نفسه. فاستدعاء وسيط مُولَّد قبل تشغيل Sync Schemas خطأ ترجمة، ولذلك لم يكن بوسع أي خطأ من الحزمة أن يظهر أصلًا. صارت الحزمة تراقب الترجمة وتطبع الخطوة الناقصة، ويعرض تبويب Code Generation ما إذا كانت مزامنة قد جرت. راجع اعمل مع بيانات لعبتك.
إشعارات اللعبة
- إشعارات اللعبة. صندوق وارد لكل لاعب مع عدد غير المقروء ووضع العلامة كمقروء فرديًا أو دفعة واحدة، وتذكيرات تجدولها لعبتك وتلغيها من جهة الخادم، وكتالوج القوالب القابل للقراءة، وتسجيل رموز الأجهزة للإشعارات الفورية. ولكل استدعاء عقدة في Blueprint. راجع الإشعارات.
- تُعنون الجدولة باسم القالب — الاسم الذي تراه في لوحة التحكم — ويُستخرج المعرّف نيابة عنك.
- رموز الإشعارات تُسجَّل ولا تُجلَب. احصل على الرمز من إضافة الإشعارات لديك (Firebase Cloud
Messaging أو OneSignal) ومرّره إلى
RegisterDeviceToken. فلا يوفّر Unreal وسيلة للحصول على رمز Android بنفسه، ولذلك فإن الإضافة ضرورية هناك لا اختيارية. - والتسجيل على منصّة لا تدعم الإشعارات الفورية يفشل بخطأ تحقّق بدل تخمين منصّة — تحقّق من
Flock Get Current Device Platformقبل عرض الخيار. - قراءات صندوق الوارد مخزَّنة مؤقتًا دون اتصال؛ وإيصالات القراءة لا تُصفّ أبدًا، والجدولة لا يُعاد إرسالها بعد إخفاق غامض، فلا يترك انقطاع شبكي عابر تذكيرين متطابقين.
لوحات الصدارة
- لوحات الصدارة. اقرأ صدارة اللوحة، ورتبة اللاعب المسجَّل دخوله، ومن حوله من اللاعبين، مع التصفية حسب النافذة الزمنية والدولة. وتُعنون اللوحات بالاسم. ولا تحتاج النتائج إلى استدعاء إرسال — فهي تأتي من حقل بيانات اللاعب الذي أُعدّت اللوحة عليه. راجع لوحات الصدارة.
- والترتيبات وإعدادات اللوحة ومواضع اللاعبين مخزَّنة مؤقتًا دون اتصال، فتعرض شاشة الصدارة آخر لوحة معروفة عند انقطاع الشبكة.
لوحات الصدارة والإشعارات وربط الحسابات
- لوحات الصدارة. اقرأ صدارة اللوحة، ورتبة اللاعب المسجَّل دخوله، ومن حوله من اللاعبين، مع التصفية حسب النافذة الزمنية والدولة. ولا تحتاج النتائج إلى استدعاء إرسال — فهي تأتي من حقل بيانات اللاعب الذي أُعدّت اللوحة عليه. راجع لوحات الصدارة.
- إشعارات اللعبة. صندوق وارد لكل لاعب مع أعداد غير المقروء، ووضع العناصر كمقروءة فرادى أو
دفعة واحدة، وتسجيل الأجهزة للإشعارات الفورية، وتذكيرات مجدولة محليًا يمكن للعبتك إلغاؤها.
وكتالوج القوالب قابل للقراءة من داخل اللعبة، ويُطلَق
FlockEvents.OnNotificationReceivedعند وصول عناصر جديدة. راجع الإشعارات. - ربط الحسابات. يمكن للاعب الواحد أن يحمل عدّة بيانات اعتماد — الجهاز، والبريد الإلكتروني، وGoogle وApple وFacebook وSteam وDiscord — وأن يربطها أو يفكّ ربطها أثناء التشغيل. وكل استدعاء يُعيد قائمة بيانات الاعتماد بعد التحديث. راجع ربط الحسابات.
- تغيير كاسر: أصبحت
Notification.ScheduleAsyncتأخذ اسم القالب لا معرّفه. والوسيط ما يزال نصًّا في الموضع نفسه، ولذلك تستمر الاستدعاءات القائمة في الترجمة وتفشل عند التشغيل بدلًا من ذلك. للترحيل: مرّر الاسم الذي أعطيته للقالب في لوحة التحكم. - اكتمال سطح المصادقة — إعادة تعيين كلمة المرور، والتحقق من البريد الإلكتروني، وإبطال الرموز من جهة الخادم، والتحقّق المسبق من توفّر الاسم المعروض.
- كل خطأ صار يحمل رمزًا. التقط
FlockExceptionوفرّع علىErrorCodeالمكتوب النوع، مثلFlockErrorCode.ShopInsufficientFunds، بدل مطابقة نص الرسالة. - إصلاحات: فشل
Commands.UpdatePlayerDataAsyncبالخطأ HTTP 422، ومسافة زائدة في عنوان الواجهة البرمجية المُعدّ كانت تعطّل كل الطلبات على WebGL.
نطاق محرّكات موثَّق من 5.5 إلى 5.8
- حزمة Unreal متاحة — مصادقة اللاعبين، وحفظ البيانات، والاقتصاد، والتكوينات عن بُعد، والأصول القابلة للتنزيل، والتحليلات، ضمن إضافة أصلية. وتعمل كل ميزة من Blueprint كعقدة غير متزامنة قائمة بذاتها، دون الحاجة إلى توصيل طرف Target. راجع دليل حزمة Unreal.
- توليد كود مكتوب الأنواع من مخططاتك أنت. نقرة واحدة تحوّل القوالب والإعدادات والمتاجر إلى بنى Blueprint وتعدادات مكتوبة الأنواع، وعمليات قراءة وكتابة وشراء من عقدة واحدة — بلا C++ ولا خطوة ترجمة. أما المشاريع التي تفضّل C++ فيمكنها تبديل الهدف والحصول على وحدة مولَّدة بدلًا من ذلك.
- آمنة دون اتصال بالتصميم. تُخزَّن قراءات الإعدادات واللعبة وكتالوج المتجر والقوالب على القرص وتُقدَّم دون اتصال؛ أما عمليات الكتابة في بيانات اللاعب فتُصفّ وتُعاد لاحقًا. ومنح العملات لا يُصفّ عمدًا، حتى لا يُقيَّد مرتين.
- دعم المحرّكات نطاق موثَّق: من UE 5.5 إلى 5.8 — كل إصدار في النطاق يُترجَم ويُختبر بمجموعة الاختبارات الكاملة قبل الإصدار. أما المحرّكات الأحدث فتُصدر تحذيرًا بدل المنع.
- لوحات الصدارة والإشعارات وربط الحسابات مقتصرة على Unity حاليًا.
تتبّع الإنهاء وواجهة سجلات متزامنة
- اكتشاف الإنهاء غير المتوقع. أي تشغيل ينتهي دون خروج نظيف يُبلَّغ عنه عند التشغيل التالي
كحدث
app_terminationتلقائي، مصنَّفbackground_killأوabnormal— راجع التحليلات والأحداث. - تغيير كاسر: أصبحت
LogExceptionAsyncوLogErrorAsyncوLogEventAsyncمتزامنة تحت الأسماءLogExceptionوLogErrorوLogEvent. فهي لم تكن تفعل سوى الإضافة إلى طابور محلي، أي أنawaitالقديم كان يُحلّ عند الإضافة لا عند التسليم. للترحيل: احذفawaitواللاحقةAsync. Analytics.FlushAsync()الجديدة — انتظار حقيقي يفرّغ كل ما في الطابور إلى الخادم، للحظات النادرة التي يجب فيها تأكيد التسليم. أما التفريغ التلقائي فما يزال يعمل كما كان.- حزمة Unreal: تحديث مماثل قيد الإنجاز.
ميزات لوحة التحكم
- لوحات الصدارة — رتّب اللاعبين حسب أي حقل رقمي في بيانات اللاعب، مع نوافذ أسبوعية وموسمية، ونطاقات حسب الدولة، واستثناءات للاعبين.
- إشعارات اللعبة — قوالب، وحملات (لجميع اللاعبين أو لشريحة؛ فورية أو مجدولة أو متكرّرة)، وصندوق وارد لكل لاعب عبر التطبيق والبريد والإشعارات المدفوعة.
- تنبيهات المطوّرين — قواعد تنبيه قائمة على عتبات السجلات، بدرجات خطورة، وفترات تهدئة، وسجل للتنبيهات في مركز التنبيهات.
- بوابة توثيق عامة للمطوّرين، مع دليلَي حزمتَي Unity وUnreal.