GenericItemization
A flexible Unreal Engine plugin that provides generic Item and Affix generation, utilizing DataTables and Instanced Structs.
Install / Use
/learn @mattyman174/GenericItemizationREADME
Generic Itemization Plugin
<a name="top"></a>
Foreword
The underpinning motivation behind the development of this Plugin and its subsequent free availability to the community was borne out of a desire to simply explore and understand the limitations of the Instanced Struct framework and especially its usefulness towards DataTables. While also providing a useful implementation of Itemization utilizing these features that you might find in a traditional ARPG (similar to Diablo or Path of Exile).
Added in Unreal Engine 5.0 and better developed in later engine versions, Instanced Structs work similarly as instanced UObject* properties but are USTRUCTs. DataTables do not support the usage of instanced UObject* properties and thus the introduction of Instanced Structs brings much needed flexibility to DataTables. This plugin will explore that new relationship.
This Project and Plugin are a work in progress and as stated before, my own exploration into Instanced Structs. I make no guarantee of the accuracy of information or the approach being close to best practice. I will update this plugin as I learn more and get a better understanding of how to make use of Instanced Structs, especially in conjunction with Blueprint.
If you find the Generic Itemization Plugin useful to you, please consider making a donation, although I provide it for free and with no expectations, I have put considerable time into this work and appreciate any contributions.
You can find my contact information on my website: https://fissureentertainment.com/
Latest compiled against: UE 5.7.1
Public Roadmap of future features
Join us on Discord to talk about the plugin!
<a name="table-of-contents"></a>
Table of Contents
1 Intro to Instanced Structs and the Generic Itemization Plugin
2 Sample Project
3 Setting Up a Project Using the Generic Itemization Plugin
4 Class Layout
5 Generic Itemization Concepts5.1 Drop Tables
5.1.1 Drop Table Types
5.1.2 Mutators
5.1.3 Quality Type Bonuses5.2 Items
5.2.1 Item Definition
5.2.1.1 Item Type and Item Identifier
5.2.1.2 Spawnable
5.2.1.3 Pick Chance
5.2.1.4 Quality Type5.2.1.5 Affix Count, Predefined Affixes and the Affix Pool
5.2.1.6 User Data
5.2.1.7 Item Instancing Function
5.2.1.8 Item Stack Settings
5.2.1.9 Item Socket Settings5.2.2 Item Instance
5.2.3 Item Sockets5.3 Affixes
5.3.1 Affix Definition
5.3.1.1 Affix Type
5.3.1.2 Spawnable
5.3.1.3 Pick Chance
5.3.1.4 Occurs for Item Type, Quality Type and Quality Level
5.3.1.5 Required Item Affix Level
5.3.1.6 Modifiers
5.3.1.7 Should Aggregate In Sockets5.3.2 Affix Instance
5.4 Item Instancing Process
5.5 Item Drop Actor
5.6 Item Dropper Component5.6.1 Item Instancing Context and the Context Provider Function
5.7.1 Modifying Item Instances
<a name="intro"></a>
1. Intro to Instanced Structs and the Generic Itemization Plugin
<a name="instanced-structs"></a>
Instanced Structs
As briefly explained above, introduced in Unreal Engine 5.0 is the StructUtils plugin that brings with it the concept of Instanced Structs. They do exactly what their name suggests; provides the same features as instanced objects but embodied as USTRUCTs. This comes with several advantages, the most prominent of which is their light weight nature as compared to their counter parts in instanced UObject*s.
Instanced Structs are also fully polymorphic and serialized across the network. Meaning they support replicated, effectively arbitrary data. It is up to the receiver to interpret that data appropriately.
This documentation is not an exhaustive overview of Instanced Structs but I will provide explanation of my understanding of their usage throughout the document.
A quick example of what an Instanced Struct might look like can be found below.
USTRUCT(BlueprintType)
struct MY_API FMyStructParent
{
GENERATED_BODY()
UPROPERTY(EditAnywhere)
int32 ParentProperty;
};
USTRUCT(BlueprintType)
struct MY_API FMyStructChild : public FMyStructParent
{
GENERATED_BODY()
UPROPERTY(EditAnywhere)
float ChildProperty;
};
USTRUCT(BlueprintType)
struct MY_API FMyStructChildOfChild : public FMyStructChild
{
GENERATED_BODY()
UPROPERTY(EditAnywhere)
bool ChildOfChildProperty;
};
Declared above are 3 regular USTRUCTs which have a hierarchy derived from each of the previous. A great attribute of Instanced Structs is that they do not require any extra or special code of the USTRUCT they are representing in order to work. Declaring the above USTRUCTs as Instanced Structs is as easy as the following:
UPROPERTY(EditAnywhere, meta = (BaseStruct = "MyStructParent"))
FInstancedStruct MyStructParentProperty;
UPROPERTY(EditAnywhere, meta = (ExcludeBaseStruct))
TInstancedStruct<FMyStructChild> MyStructChildProperty;
UPROPERTY(EditAnywhere, meta = (BaseStruct = "MyStructParent", ExcludeBaseStruct))
TArray<TInstancedStruct<FMyStructParent>> MyArrayOfMyStructParentProperties;
The Editor displays them as such.
Take special note of how the BaseStruct meta in conjunction with FInstancedStruct and the TInstancedStruct type are used interchangeably. TInstancedStruct is a type safe wrapper around an FInstancedStruct and can be used in its place without declaring the BaseStruct meta.
There is also an unfortunate quirk where when utilizing Instanced Structs with a TArray you must still include the BaseStruct meta in order for the Editor to understand the type correctly, as utilizing TInstancedStruct, while it does mention in the documentation that it will initialize the BaseStruct meta natively, this is not the case for when the property is exposed in Editor Details Panels via TArrays.
ExcludeBaseStruct also does as its name suggests, it will not display the BaseStruct as a selectable option for the Instanced Struct property within the dropdown.
Another useful meta property that is supported by Instanced Structs is ShowTreeView, which is not documented as working with Instanced Structs but causes them to be displayed in dropdowns in a tree view instead of a straight list.
What is the Generic Itemization Plugin
Itemization is generally speaking the process of defining and creating Items, these Items can apply modifiers to attributes, grant new abilities to their users or affect other changes to gameplay. A typical example of what Itemization is can be found in ARPGs like Diablo or Path of Exile.
The Generic Itemization Plugin implements this process in a way that can be applied to any style of game that requires the instantiation of Items from predefined aggregated tables of Items and Affixes. Some of what the Plugin provides are mechanisms for controlling things like rarity, distribution, stats and their ranges, through Affixes as well as how those Affixes are to be applied to particular Item types.
The plugin manages these things through DataTables. A lot of DataTables. These DataTables describe things like DropTables, ItemDefinitions, AffixDefinitions, ItemQualityRatios and AffixCountRatios. All these DataTables provide the foundational data behind what Items are, what Affixes are, their qualities and how often they appear.
All of these aspects of Itemization and many others are customizable through the Plugin via UObject classes that can be overridden by Blueprints. These Blueprints expose core functions for things like how Items are selected, how they calculate certain attributes, which Affixes and how many of them an ItemInstance can have and much more.
<a name="sp"></a>
2. Sample Project
A sample third person project is included with this documentation and is designed to demonstrate the Generic Itemization Plugins flexibility and ease of use without introducing any additional code.
The goal is to keep the project simple for those that wish to take advantage of what it offers out of the box without having to dive deep into setting up
