Advanced Modular Leveling system

إضافة وحدوية لنظام الخبرة (XP) والمستويات في Unreal Engine (بدعم C++ وBlueprint) مع مزامنة عبر الشبكة (Replication). تتضمن منحنيات تعتمد على البيانات، وحدودًا قصوى للمستوى عبر نظام الصعود (Ascension)، ومكافآت المراحل، وتحويل الخبرة الفائضة (Overflow XP).

الميزات 

مكوّن جاهز للإضافةأضِف AMLSLevelComponent إلى أي Actor: اللاعبون أو الأعداء أو الأسلحة أو المباني.
3 أنواع من منحنيات الخبرة (XP)مصفوفة صريحة، أو صيغة رياضية، أو أصل Float Curve من Unreal.
تقييد التقدّم عبر الصعود (Ascension)حدود قصوى صارمة للمستوى لا يمكن تجاوزها إلا باستدعاء Ascend.
مكافآت المراحلمكافآت قائمة على Gameplay Tag لكل مستوى، إضافةً إلى معالِجات مكافآت مخصّصة بـ Blueprint أو C++.
الخبرة الفائضة (Overflow XP)حوِّل الخبرة المكتسبة عند بلوغ أقصى مستوى إلى عملة باستخدام وسم (Tag) ومُعامِل ضرب.
جاهز للعب الجماعينظام يعتمد على سلطة الخادم، مع مزامنة المستوى والخبرة ومرحلة الصعود عبر الشبكة.
ربط مع نظام الحفظبنية SaveGame لحفظ التقدّم واستعادته.
متوافق مع Blueprintدوال جلب Pure، ودوال استدعاء للسلطة (Authority) فقط، وأحداث قابلة للربط.

البدء السريع

  1. فعِّل الإضافة وتأكّد من أن وحدة GameplayTags متاحة في مشروعك.
  2. أنشئ أصل بيانات (Data Asset): Content Browser → Miscellaneous → Data Asset → AMLSLevelUpConfigDataAsset.
  3. حدِّد Max Level، واختر XP Curve Method، وأضِف مراحل المكافآت اختياريًا.
  4. أضِف AMLS Level Component إلى الـ Actor (شخصيتك) وعيِّن أصل البيانات في الحقل Level Config Data.
  5. على الخادم، استدعِ AddXP كلما اكتسب الـ Actor خبرة.
  6. اربط OnLevelUpDelegate / OnXPChangedDelegate لتشغيل واجهة المستخدم (UI).

// مثال C++
if (UAMLSLevelComponent* Level = Actor->FindComponentByClass<UAMLSLevelComponent>()) { Level->OnLevelUpDelegate.AddDynamic(this, &AMyClass::HandleLevelUp); Level->AddXP(250); // على الخادم فقط }
إذا لم يتم تعيين أصل الإعدادات، يتم تسجيل تحذير في السجل وتُستخدم قيم احتياطية (الحد الأقصى للمستوى 50، الخبرة المطلوبة = المستوى × 100).


مكوّن المستوى (UAMLSLevelComponent)

تبدأ من المستوى 1، و0 خبرة، ومرحلة الصعود 1. الدوال المُعلَّمة بـ Authority تعمل على الخادم فقط.

الدالةالنوعالوصف
AddXP(Amount)Authorityتضيف الخبرة وتعالج الارتقاءات المتتالية في المستوى. عند بلوغ أقصى مستوى مطلق، تُحوَّل الخبرة إلى التحويل الفائض.
SetLevel(NewLevel)Authorityتضيف الخبرة وتعالج الارتقاءات المتتالية في المستوى. عند بلوغ أقصى مستوى مطلق، تُحوَّل الخبرة إلى التحويل الفائض.
AddLevels(LevelsToAdd)Authorityتمنح عددًا ثابتًا من المستويات مع احترام حدود الصعود القصوى.
Ascend()Authorityتنتقل إلى مرحلة الصعود التالية إذا كانت CanAscend() تساوي true.
ResetProgression()Authorityتعيد المستوى والخبرة والمرحلة إلى القيم الافتراضية (مفيدة لنظام الـ Prestige).
LoadProgressionSaveData(Data)Authorityتستعيد التقدّم من بنية الحفظ.
GetProgressionSaveData()Pureتُرجِع لقطة من النوع FAMLSProgressionSaveData.
GetCurrentLevel /GetCurrentXPPureالقيم الحالية.
GetXPRequiredForNextLevelPureالخبرة اللازمة لإتمام المستوى الحالي.
GetRemainingXPToNextLevelPureالخبرة اللازمة لإتمام المستوى الحالي.
GetXPProgressPercentagePureقيمة شريط التقدّم من ⁦0.0 – 1.0⁩.
GetCurrentLevelCapPureقيمة شريط التقدّم من ⁦0.0 – 1.0⁩.
GetCurrentLevelCapPureالحد الأقصى الصارم لمرحلة الصعود الحالية.
IsAtCurrentLevelCap/IsAtAbsoluteMaxLevelPureفحوصات الحد الأقصى.
CanAscendPureتكون true عند بلوغ الحد الحالي مع عدم بلوغ أقصى مستوى مطلق.
GetCurrentAscensionPhasePureالمرحلة الحالية (تبدأ من 1).
GetRequiredAscensionPhaseForLevelPureالمرحلة المطلوبة لبلوغ مستوى معيّن.
HasReachedLevel(Level)Pureتكون true إذا كان المستوى الحالي ≥ المستوى المستهدف.
GetLevelStatus(Level)Pureتُرجِع FAMLSLevelStatusData: bHasReached, bRequiresAscension, bIsAbsoluteMaxLevel, bIsInvalid. مثالية لواجهات خريطة المستويات.
GetRewardsForLevel(Level)Pureعناصر المكافآت المُعدّة لمستوى معيّن.

أصل بيانات الإعدادات (UAMLSLevelUpConfigDataAsset)

الخاصيةالافتراضيالوصف
Max Level50أعلى مستوى مطلق (الحد الأدنى 2).
XP Curve MethodFormulaicExplicit Array أو Formulaic أو Float Curve Asset.
System IDPlayerمعرّف يُستخدم لمطابقة معالِجات المكافآت مع هذا الأصل.
Use Ascension Systemfalseتُفعِّل حدودًا قصوى للمستوى تتطلب استدعاء Ascend().
Ascension Level Capsفارغالحد الأقصى لكل مرحلة، مثال: [20, 40].
Explicit XP Thresholdsفارغالفهرس 0 = الخبرة اللازمة لمغادرة المستوى 1. تعود المدخلات المفقودة إلى Level × FormulaBaseXP.
Formula Base XP / Multiplier / Exponent100 / 1.2 / 1.5راجع الصيغة أدناه.
Visual Curve Assetلا شيءمنحنى Float: المحور X = المستوى، والمحور Y = الخبرة المطلوبة.
Reward Milestonesفارغقوائم لكل مستوى من (RewardTag, RewardCount).
Custom Processor Milestonesفارغفئة معالِج المكافآت لكل مستوى.
Convert Overflow XP To Currencyfalseتُفعِّل تحويل الفائض عند أقصى مستوى.
Overflow Currency Tagلا شيءالوسم (Tag) الذي يُرسَل مع حدث التحويل.
Overflow Conversion Multiplier10.0العملة = ⁦max(1, round(XP × multiplier))⁩.

منحنى الصيغة الرياضية (Formulaic)

XP required = round( FormulaBaseXP × Level ^ FormulaExponent × FormulaMultiplier )   (minimum 1)

بالإعدادات الافتراضية، يحتاج المستوى 1 إلى 120 خبرة، ويحتاج المستوى 10 إلى نحو 3,795 خبرة. لا تُطلب أي خبرة عند Max Level أو بعده.


نظام الصعود (Ascension)

يتيح لك الصعود تقييد التقدّم بحدوث إجراء من اللاعب (مواد، مهمة، زعيم). فعِّل Use Ascension System وحدِّد الحدود القصوى:

AscensionLevelCaps = [20, 40, 50]   // الحد في المرحلة 1 هو 20، وفي المرحلة 2 هو 40، وفي المرحلة 3 هو 50
    1. يرتقي اللاعب في المستويات بشكل طبيعي حتى يبلغ الحد الأقصى؛ وتبقى الخبرة الزائدة محفوظة.
    2. تتحقق لعبتك من التكلفة، ثم تستدعي Ascend() على الخادم.
    3. تزداد المرحلة، ويُطلَق OnAscendedDelegate، وتستمر الخبرة المحفوظة في رفع المستوى.
    استخدم CanAscend() لتفعيل زر Ascend، وGetLevelStatus() لعرض أقفال الصعود على خريطة المستويات.

    المكافآت والمعالِجات

    مراحل المكافآت

    أضِف مدخلات إلى Reward Milestones مع مستوى مستهدف وقائمة بعناصر المكافآت (Gameplay Tag + العدد). عند بلوغ المستوى، يقوم OnRewardsProcessedDelegate ببثّ العناصر حتى تتمكن لعبتك من منحها.

    معالِجات المكافآت المخصّصة

    للمنطق المخصّص، أنشئ فئة فرعية من UAMLSLevelUpRewardProcessor (في C++ أو Blueprint) وسجِّلها ضمن Custom Processor Milestones للمستوى المطلوب.

    // C++
    class UMyRewardProcessor : public UAMLSLevelUpRewardProcessor
    {
    protected:
        virtual void NativeProcessTag(AActor* Target, const TArray<FAMLSLevelRewardItem>& Items, int32 Level) override;
    };

    واجهة Levelable (IAMLSLevelableInterface)

    طبّقها على الـ Actors التي يجب أن تتلقى الاستدعاءات. يمكن تنفيذها عبر Blueprint.

    الدالةالوصف
    GetLevelComponent()تُرجِع المكوّن UAMLSLevelComponent الخاص بالـ Actor.
    OnLevelUp(NewLevel)يُستدعى عند رفع المستوى: لتطبيق الإحصاءات أو الشفاء أو فتح المحتوى.

    الأحداث (Delegates)

    الحدثالمعاملاتمتى يُطلَق
    OnLevelUpDelegateNewLevel, Ownerعند اكتساب مستوى (وعلى العملاء أيضًا عند مزامنة المستوى).
    OnXPChangedDelegateCurrentXP, XPToNextLevel, Percentعند تغيّر الخبرة أو المستوى؛ وكذلك عند BeginPlay.
    OnRewardsProcessedDelegateLevelAchieved, Rewards, Ownerعند بلوغ مستوى له مكافآت أو معالِج.
    OnOverflowXPConvertedDelegateWastedXP, CurrencyEarned, CurrencyTag, Ownerعند اكتساب خبرة في أقصى مستوى مع تفعيل التحويل.
    OnAscendedDelegateNewAscensionPhase, Ownerعند تغيّر مرحلة الصعود.

    الحفظ والتحميل

    FAMLSProgressionSaveData تحتوي على SavedLevel, SavedXP, SavedAscensionPhase وهي موسومة بـ SaveGame. خزِّنها في كائن SaveGame الخاص بك.

    // حفظ
    SaveObj->Progression = LevelComp->GetProgressionSaveData();
    // تحميل (الخادم)
    LevelComp->LoadProgressionSaveData(SaveObj->Progression);

    عند التحميل، يتم التحقق من القيم مقابل الحدود الحالية ومعالجة الخبرة المعلّقة.

    اللعب الجماعي والمزامنة (Replication)

    • جميع الدوال التي تغيّر الحالة تعمل على الخادم فقط.
    • CurrentLevel، CurrentXP وCurrentAscensionPhase تتم مزامنتها إلى العملاء عبر RepNotify، الذي يُعيد إطلاق المفوّضات (Delegates) المطابقة لتحديث واجهة المستخدم.
    • تتم معالجة المكافآت وتحويل الفائض على الخادم؛ قم بمزامنة العناصر الناتجة عبر أنظمتك الخاصة.

    ملاحظات

    • يضبط المكوّن bCanEverTick = false، لذلك لا توجد أي تكلفة في كل إطار.
    • يجب أن توجد وسوم المكافآت مثل Reward.Stat في Gameplay Tags الخاصة بمشروعك.
    • تتم مطابقة مراحل المكافآت والمعالِجات بحسب رقم المستوى المطابق تمامًا.


    Copyright KhalidBen 2026. جميع الحقوق محفوظة.