Complete Data-Driven RPG System for Unreal Engine 5
Edit → Plugins → search "RPG Game Framework" → check Enabled → restart editor.
Open your Character Blueprint → Add Component → search and add any of these 9 components:
Right-click Content Browser → Miscellaneous → DataTable → pick the Row Structure → fill in rows → assign to component in Details panel. See the DataTables section for exact column names.
In BeginPlay: Inventory→AddItemByID("HealthPotion", 5), Inventory→AddGold(100) → Press Play.
The Save Component auto-discovers all other RPG components. No manual wiring needed.
Every DataTable with every column. ★ Required = you should fill this. Optional = has a default, skip if not needed.
In Content Browser: Right-click → Miscellaneous → DataTable. In the popup, search the Row Structure name (e.g. type "RPGItemData"). Name your table (e.g. "DT_Items"). Double-click to open and add rows. Row Name = unique ID string (e.g. "HealthPotion").
Row Structure: FRPGItemData. Assign to RPG Inventory Component → Item Data Table.
| Column | Type | Default | Description |
|---|---|---|---|
ItemID ★ | FName | None | Unique ID — must match Row Name |
DisplayName ★ | FText | — | Name shown in UI ("Health Potion") |
Description | FText | — | Tooltip description |
Icon | UTexture2D* | null | Inventory icon |
ItemType ★ | ERPGItemType | Miscellaneous | Consumable / Equipment / Weapon / Material / QuestItem / Currency / Miscellaneous |
Rarity | ERPGItemRarity | Common | Common / Uncommon / Rare / Epic / Legendary / Mythic |
MaxStackSize | int32 | 99 | How many per stack (1 = no stacking) |
Weight | float | 0.1 | Weight per unit |
BuyPrice | int32 | 0 | Shop buy price |
SellPrice | int32 | 0 | Shop sell price |
EquipmentSlot | ERPGEquipmentSlot | None | For Equipment/Weapon: Head, Chest, Legs, Feet, MainHand, OffHand, etc. |
WeaponType | ERPGWeaponType | None | For Weapons: Sword, Axe, Bow, Staff, etc. |
ArmorType | ERPGArmorType | None | For Equipment: Cloth, Leather, Mail, Plate |
StatBonuses | FRPGItemStatBonus | all 0 | Stats this equipment gives (see sub-struct below) |
SetID | FName | None | Equipment set ID (matches DT_SetBonuses) |
MaxDurability | int32 | 100 | 0 = no durability system |
ConsumableEffect | FRPGConsumableEffect | all 0 | What happens when consumed (see sub-struct below) |
Cooldown | float | 0 | Cooldown after use (seconds) |
Requirements | FRPGItemRequirements | all 0 | Level/stat requirements to equip |
WorldMesh | TSoftObjectPtr<StaticMesh> | null | Mesh for dropped item in world |
EquippedMesh | TSoftObjectPtr<SkeletalMesh> | null | Mesh when equipped on character |
bCanSell | bool | true | Can be sold to shops |
bCanDrop | bool | true | Can be dropped on ground |
bCanDestroy | bool | true | Can be destroyed/discarded |
bIsUnique | bool | false | Only one can exist in inventory |
bBindOnPickup | bool | false | Soulbound on pickup |
bBindOnEquip | bool | false | Soulbound when equipped |
Expand the StatBonuses row in the DataTable editor to see these fields. Set only what you need — everything defaults to 0.
| Field | Type | Description |
|---|---|---|
Strength | int32 | +STR bonus |
Dexterity | int32 | +DEX bonus |
Intelligence | int32 | +INT bonus |
Vitality | int32 | +VIT bonus |
Wisdom | int32 | +WIS bonus |
Luck | int32 | +LCK bonus |
MaxHealth | float | Flat HP bonus |
MaxMana | float | Flat Mana bonus |
MaxStamina | float | Flat Stamina bonus |
PhysicalDamage | float | Flat phys damage bonus |
MagicDamage | float | Flat magic damage bonus |
PhysicalDefense | float | Flat phys defense |
MagicDefense | float | Flat magic defense |
CriticalChance | float | +Crit chance % |
CriticalDamage | float | +Crit damage % |
Evasion | float | +Evasion |
Accuracy | float | +Accuracy |
AttackSpeed | float | +Attack speed |
Only for Consumable items. Expand in editor. All defaults to 0 / false.
| Field | Type | Description |
|---|---|---|
HealthRestore | float | HP to restore (e.g. 50) |
ManaRestore | float | Mana to restore |
StaminaRestore | float | Stamina to restore |
bIsPercentage | bool | true = values are % of max (e.g. 0.5 = 50%) |
Duration | float | 0 = instant, >0 = over time (seconds) |
TemporaryStatBonus | FRPGItemStatBonus | Temp buff stats (same struct as above) |
XPGain | int64 | XP granted on use |
ApplyBuffID | FName | Custom buff ID to apply |
RemoveDebuffID | FName | Custom debuff ID to remove |
Equipment requirements. All default to 0 (no requirement). Level defaults to 1.
| Field | Type | Description |
|---|---|---|
RequiredLevel | int32 | Min character level (default: 1) |
RequiredStrength | int32 | Min STR needed |
RequiredDexterity | int32 | Min DEX needed |
RequiredIntelligence | int32 | Min INT needed |
RequiredVitality | int32 | Min VIT needed |
RequiredWisdom | int32 | Min WIS needed |
To add a simple Health Potion, you only need: Row Name = "HealthPotion", ItemID = "HealthPotion", DisplayName = "Health Potion", ItemType = Consumable, ConsumableEffect → HealthRestore = 50. Everything else can stay at defaults.
Row Structure: FRPGSkillData. Assign to RPG Skill Component → Skill Data Table.
| Column | Type | Default | Description |
|---|---|---|---|
SkillID ★ | FName | None | Unique ID |
DisplayName ★ | FText | — | Name shown in UI |
Description | FText | — | Skill tooltip |
Icon | UTexture2D* | null | Skill icon |
SkillType ★ | ERPGSkillType | Active | Active / Passive / Toggle / Ultimate |
TargetType | ERPGSkillTarget | Self | Self / SingleEnemy / SingleAlly / AllEnemies / AoE / Cone / Line / Ground |
DamageType | ERPGDamageType | Physical | Physical / Magic / Fire / Ice / Lightning / Poison / Holy / Dark / Pure |
Cost | FRPGSkillCost | 0 | Mana / Stamina / Health cost |
DamageScaling | FRPGSkillScaling | — | Damage formula scaling |
Cooldown | float | 0 | Seconds between uses |
MaxLevel | int32 | 1 | Max upgradeable level |
RequiredCharacterLevel | int32 | 1 | Min level to learn |
RequiredSkillIDs | TArray<FName> | empty | Prerequisite skills |
Row Structure: FRPGSkillTreeData. Assign to RPG Skill Component → Skill Tree Data Table.
| Column | Type | Default | Description |
|---|---|---|---|
TreeID ★ | FName | None | Unique tree ID ("CombatTree") |
TreeName ★ | FText | — | Display name ("Combat") |
Description | FText | — | Tree description |
Icon | UTexture2D* | null | Tree icon |
AllowedClassIDs | TArray<FName> | empty | Which classes can access (empty = all) |
Nodes ★ | TArray<FRPGSkillTreeNode> | empty | Skill nodes in this tree |
| Field | Type | Description |
|---|---|---|
SkillID ★ | FName | Must match a row in DT_Skills |
Position | FVector2D | X/Y for UI layout |
PrerequisiteSkillIDs | TArray<FName> | Skills that must be unlocked first |
RequiredPointsInTree | int32 | Min skill points spent in this tree |
Row Structure: FRPGQuestData. Assign to RPG Quest Component → Quest Data Table.
| Column | Type | Default | Description |
|---|---|---|---|
QuestID ★ | FName | None | Unique quest ID |
DisplayName ★ | FText | — | Quest name in journal |
Description | FText | — | Quest description |
QuestType | ERPGQuestType | — | Main / Side / Daily / etc. |
Objectives ★ | TArray<FRPGQuestObjective> | empty | Quest objectives |
Rewards | FRPGQuestReward | — | XP, Gold, Items |
RequiredLevel | int32 | 0 | Level requirement |
RequiredCompletedQuests | TArray<FName> | empty | Prerequisite quests |
TimeLimit | float | 0 | 0 = no time limit |
bCanAbandon | bool | true | Player can abandon |
bAutoComplete | bool | true | Complete when all objectives done |
Row Structure: FRPGDialogueData. Assign to RPG Dialogue Component → Dialogue Data Table.
| Column | Type | Default | Description |
|---|---|---|---|
DialogueID ★ | FName | None | Unique ID |
DialogueName | FText | — | Editor reference name |
NPCID ★ | FName | None | Which NPC this dialogue belongs to |
StartNodeID ★ | FName | None | First node in conversation |
Nodes ★ | TArray<FRPGDialogueNode> | empty | All dialogue nodes |
Priority | int32 | 0 | Higher = checked first |
StartConditions | TArray<FRPGDialogueCondition> | empty | Conditions to start dialogue |
bOneTimeOnly | bool | false | Can only play once |
bMarkAsSeen | bool | true | Mark as seen after playing |
bIsCinematic | bool | false | Disable player control |
bCanSkip | bool | true | Player can skip |
Row Structure: FRPGPrimaryStatConfig. Assign to RPG Stats Component → Stats Config Table.
Without it, hardcoded defaults apply: VIT×10 → HP, INT×5+WIS×5 → Mana, STR×1 → PhysDmg, etc. Create this table to customize exactly how each stat scales.
| Column | Type | Default | Description |
|---|---|---|---|
StatType ★ | ERPGPrimaryStat | Strength | Which stat: Strength / Dexterity / Intelligence / Vitality / Wisdom / Luck |
DisplayName | FText | — | Name shown in UI |
Description | FText | — | Tooltip for stat |
BaseValue | int32 | 10 | Starting value |
MinValue | int32 | 1 | Minimum allowed |
MaxValue | int32 | 999 | Maximum allowed |
Icon | UTexture2D* | null | Stat icon for UI |
MaxHealthPerPoint | float | 0 | HP gained per 1 point in this stat |
MaxManaPerPoint | float | 0 | Mana per point |
MaxStaminaPerPoint | float | 0 | Stamina per point |
PhysicalDamagePerPoint | float | 0 | PhysDmg per point |
MagicDamagePerPoint | float | 0 | MagicDmg per point |
PhysicalDefensePerPoint | float | 0 | PhysDef per point |
MagicDefensePerPoint | float | 0 | MagicDef per point |
CritChancePerPoint | float | 0 | Crit % per point |
CritDamagePerPoint | float | 0 | Crit damage % per point |
EvasionPerPoint | float | 0 | Evasion per point |
AccuracyPerPoint | float | 0 | Accuracy per point |
Row Name = "Vitality", StatType = Vitality, BaseValue = 10, MaxHealthPerPoint = 10.0, MaxStaminaPerPoint = 5.0, PhysicalDefensePerPoint = 0.5
Row Structure: FRPGCharacterClassData. Assign to RPG Stats Component → Class Data Table.
| Column | Type | Default | Description |
|---|---|---|---|
ClassID ★ | FName | None | Unique ID ("Warrior") |
ClassName | FText | — | Display name |
Description | FText | — | Class description |
Icon | UTexture2D* | null | Class icon |
BaseStrength | int32 | 10 | Starting STR |
BaseDexterity | int32 | 10 | Starting DEX |
BaseIntelligence | int32 | 10 | Starting INT |
BaseVitality | int32 | 10 | Starting VIT |
BaseWisdom | int32 | 10 | Starting WIS |
BaseLuck | int32 | 10 | Starting LCK |
StrengthGrowth | float | 1.0 | STR gained per level |
DexterityGrowth | float | 1.0 | DEX per level |
IntelligenceGrowth | float | 1.0 | INT per level |
VitalityGrowth | float | 1.0 | VIT per level |
WisdomGrowth | float | 1.0 | WIS per level |
LuckGrowth | float | 1.0 | LCK per level |
StartingSkillIDs | TArray<FName> | empty | Skills unlocked at start |
AllowedWeaponTypes | TArray<FName> | empty | Weapon types this class can equip |
AllowedArmorTypes | TArray<FName> | empty | Armor types this class can equip |
Row Structure: FRPGLevelData. Assign to Leveling Component.
| Column | Type | Default | Description |
|---|---|---|---|
Level ★ | int32 | 1 | Level number |
XPRequired ★ | int64 | 0 | XP needed for this level |
TotalXPToLevel | int64 | 0 | Cumulative XP |
StatPointsAwarded | int32 | 5 | Stat points given |
SkillPointsAwarded | int32 | 1 | Skill points given |
UnlockedSkillIDs | TArray<FName> | empty | Auto-unlock skills at this level |
UnlockedQuestIDs | TArray<FName> | empty | Quests that become available |
HealthBonus | float | 0 | Flat HP bonus at this level |
ManaBonus | float | 0 | Flat Mana bonus |
StaminaBonus | float | 0 | Flat Stamina bonus |
Row Structure: FRPGSetBonusData. Assign to Equipment Component.
| Column | Type | Default | Description |
|---|---|---|---|
SetID ★ | FName | None | Must match SetID on items in DT_Items |
SetName | FText | — | Display name ("Dragon Armor") |
SetItemIDs | TArray<FName> | empty | All item IDs in the set |
PieceBonuses | TMap<int32, FRPGItemStatBonus> | empty | Key = piece count → Value = stat bonus. Example: 2→{+50HP}, 4→{+100HP, +20Def} |
PieceAbilities | TMap<int32, FName> | empty | Key = piece count → Value = ability ID unlocked |
| Component | Property Name (Details Panel) | DataTable | Row Structure | Required? |
|---|---|---|---|---|
| RPG Inventory | Item Data Table | DT_Items | FRPGItemData | ★ Yes |
| RPG Skill | Skill Data Table | DT_Skills | FRPGSkillData | ★ Yes |
| RPG Skill | Skill Tree Data Table | DT_SkillTrees | FRPGSkillTreeData | Optional |
| RPG Quest | Quest Data Table | DT_Quests | FRPGQuestData | ★ Yes |
| RPG Dialogue | Dialogue Data Table | DT_Dialogues | FRPGDialogueData | ★ Yes |
| RPG Stats | Stats Config Table | DT_StatsConfig | FRPGPrimaryStatConfig | Optional |
| RPG Stats | Class Data Table | DT_Classes | FRPGCharacterClassData | Optional |
| RPG Leveling | Level Data Table | DT_LevelData | FRPGLevelData | Optional |
| RPG Equipment | Set Bonus Data Table | DT_SetBonuses | FRPGSetBonusData | Optional |
6 primary stats (STR, DEX, INT, VIT, WIS, LCK) → 16 derived stats → 3 resources (HP/MP/Stamina) with regeneration.
GetPrimaryStat, AllocateStatPoint, ModifyHealth/Mana/Stamina, ApplyDamage, ApplyHealing, RollCritical, AddStatModifier, RemoveModifiersBySource, GetDerivedStat, GetHealthPercent, SetHealthToMax, ResetAllocatedStats
OnStatChanged, OnDerivedStatChanged, OnHealthChanged, OnManaChanged, OnStaminaChanged, OnResourceChanged, OnDeath, OnStatsRecalculated
AddXP, AddXPWithBonus, GetCurrentLevel, GetCurrentXP, GetXPForNextLevel, GetXPProgressPercent, GetUnspentStatPoints, GetUnspentSkillPoints, SpendStatPoint, SpendSkillPoint, RefundAllStatPoints
OnXPGained (Amount, Source), OnLevelUp (FRPGLevelUpEvent), OnLevelChanged, OnStatPointsChanged, OnSkillPointsChanged
AddItemByID, RemoveItem, HasItem, GetItemCount, GetItemInSlot, GetItemData, GetAllSlots, UseItem, AddGold, RemoveGold, GetGold, SwapSlots, SplitStack, SortInventory, IsInventoryFull
OnItemAdded, OnItemRemoved, OnItemUsed, OnGoldChanged, OnInventoryFull, OnInventoryChanged
EquipItem, UnequipItem, CanEquipItem, GetEquippedItem, GetTotalEquipmentStats, GetTotalWeaponDamage, GetTotalArmorValue, MeetsRequirements, GetRequirementFailReason, GetSetPieceCount
OnItemEquipped, OnItemUnequipped, OnEquipmentChanged, OnSetBonusChanged
UnlockSkill, LevelUpSkill, UseSkill, UseSkillFromHotkey, CanUseSkill, GetSkillUseFailReason, IsSkillOnCooldown, GetSkillCooldownRemaining, AssignSkillToHotkey, GetSkillInHotkey, GetAvailableSkills
OnSkillUnlocked, OnSkillLevelUp, OnSkillUsed, OnSkillCooldownStarted, OnSkillCooldownEnded
AcceptQuest, AbandonQuest, CompleteQuest, AddObjectiveProgress, OnEnemyKilled, OnItemCollected, OnLocationReached, TrackQuest, GetActiveQuests, GetCompletedQuests, GetFailedQuests, GetQuestData, IsQuestCompleted
OnQuestAccepted, OnQuestCompleted, OnQuestFailed, OnObjectiveProgress, OnObjectiveCompleted
When bAutoTrackQuests = true on Navigation Component, quest objectives with bShowOnMap = true and valid MarkerLocation auto-appear on minimap, world map, and compass.
StartDialogue, StartDialogueWithNPC, SelectResponse, AdvanceDialogue, GetCurrentNode, GetAvailableResponses, SetFlag, HasFlag, EndDialogue, HasDialogueAvailable, GetBestDialogueForNPC
OnDialogueStarted, OnDialogueEnded, OnDialogueNodeChanged, OnResponseSelected, OnFlagSet
Content Browser → Right-click → Miscellaneous → DataTable. In the popup, search RPGItemData and select it. Name it DT_Items.
Double-click DT_Items to open. Click Add at the top. Set Row Name to HealthPotion.
Set ItemID = HealthPotion, DisplayName = "Health Potion", ItemType = Consumable.
Expand ConsumableEffect → set HealthRestore = 50. Leave everything else at defaults.
Select your RPG Inventory Component in the character → Details panel → Item Data Table → pick DT_Items.
Now AddItemByID("HealthPotion", 5) works. For equipment items, also fill EquipmentSlot and StatBonuses. For weapons, set WeaponType too.
ItemID = IronSword, DisplayName = "Iron Sword", ItemType = Weapon
EquipmentSlot = MainHand, WeaponType = Sword
Expand StatBonuses → PhysicalDamage = 15, Strength = 3
Expand Requirements → RequiredLevel = 5. Player below level 5 can't equip it.
OnResourceChangedInventoryComponent→GetItemInSlot(Index)EquipmentComponent→CanEquipItem(Item) → false? → show fail reasonEquipmentComponent→EquipItem(Item) → old item auto-returns to inventoryQuestComponent→IsQuestCompleted(QuestID)? → turn-in dialogueAcceptQuest(QuestID)OnEnemyKilled("GoblinID")SaveComponent→QuickSave()SaveComponent→QuickLoad()SaveGame("Slot_01"), LoadGame("Slot_01"), GetAllSaveSlots()GetMinimapRenderTarget()GetMinimapRotation()GetMinimapMarkers() → place icons at MinimapPosition × WidgetRadiusNavigationComp→AddActorMarker(Self, "Goblin", Enemy, Red) → store MarkerIDRemoveMarker(StoredMarkerID)| Enum | Values |
|---|---|
| ERPGPrimaryStat | Strength, Dexterity, Intelligence, Vitality, Wisdom, Luck |
| ERPGDerivedStat | MaxHealth, MaxMana, MaxStamina, PhysicalDamage, MagicDamage, PhysicalDefense, MagicDefense, CriticalChance, CriticalDamage, Evasion, Accuracy, AttackSpeed, MovementSpeed, HealthRegen, ManaRegen, StaminaRegen |
| ERPGItemType | Consumable, Equipment, Weapon, Material, QuestItem, Currency, Miscellaneous |
| ERPGItemRarity | Common, Uncommon, Rare, Epic, Legendary, Mythic |
| ERPGEquipmentSlot | None, Head, Chest, Hands, Legs, Feet, Shoulders, Back, MainHand, OffHand, TwoHand, Ring1, Ring2, Necklace, Trinket1, Trinket2 |
| ERPGWeaponType | None, Sword, Axe, Mace, Dagger, Spear, Bow, Crossbow, Staff, Wand, Shield, Greatsword, Greataxe, Scythe |
| ERPGArmorType | None, Cloth, Leather, Mail, Plate |
| ERPGSkillType | Active, Passive, Toggle, Ultimate |
| ERPGSkillTarget | Self, SingleEnemy, SingleAlly, AllEnemies, AllAllies, AreaOfEffect, Cone, Line, Ground |
| ERPGDamageType | Physical, Magic, Fire, Ice, Lightning, Poison, Holy, Dark, Pure |
| ERPGQuestState | Locked, Available, Active, Completed, Failed, Abandoned |
| ERPGObjectiveType | Kill, Collect, Deliver, TalkTo, Escort, Explore, Interact, Reach, Survive, Craft, UseSkill, Custom |
| ERPGMarkerType NEW | Player, Waypoint, QuestObjective, QuestTurnIn, NPC, Enemy, Shop, Chest, SavePoint, Teleporter, AreaEntrance, PartyMember, Custom |
| ERPGPOIState NEW | Hidden, Discovered, Visited, Completed |
FRPGItemData — search "RPGItemData" in the popupItemID matches the Row Name exactly (case-sensitive)IsInventoryFull()AddItemByID — false means it failedThese are optional DataTables. The plugin works without them using hardcoded defaults. To create them:
FRPGPrimaryStatConfig → assign to Stats Component → Stats Config TableFRPGSkillTreeData → assign to Skill Component → Skill Tree Data TableFRPGCharacterClassData → assign to Stats Component → Class Data TablebEnableMinimap = true?MinimapCaptureHeight — too low = inside geometryGetMinimapRenderTarget() returns valid reference?bAutoTrackQuests = true?bShowOnMap = true AND MarkerLocation ≠ (0,0,0)?StatBonuses filled in DataTable? (expand the struct)Use Print String to verify values. Bind to component events and print when they fire. Check Output Log for warnings. For DataTable issues: open DT in editor and verify your row data is correct.