# DA\_CoreItem

***

This is the data asset that is responsible for the base information for your items. I highly suggest looking at the <mark style="color:yellow;">**DA\_CoreItem.h**</mark> file to see all the settings, functions and comments.

You can show and hide certain settings depending on your setup, and I use that a lot with the <mark style="color:purple;">**ItemType**</mark> enum. Look at all the options, check out the meta properties (EditCondition and EditConditionHides) to see how it’s done, and you can then implement your own options and rulesets for their visibility.

Keep in mind, these settings are only HIDDEN, not disabled in the data asset editor, you can still access those variables from the data asset in blueprints and C++ and you have to remember that when making your functions and gameplay logic.&#x20;

One of the most important settings to set up here is <mark style="color:purple;">**EItemType**</mark> as many functions use this enum to do casts to the proper children of this asset. Whenever you make a new child, remember to go into the .cpp file and set the default value. You can see an example inside all the .cpp children of this.

If you are new to C++ or Unreal Engine, I suggest looking [**here**](https://benui.ca/unreal/uproperty/) to find all the specifiers you can give each variable.

***

## Creating new items

[**Video documentation**](https://youtu.be/GzxE6spwgCQ) (slightly outdated, for example the content browser and item actor name have been changed, but majority of it is still relevant. The only thing that should be ignored is around `06:23`, I state that you should import the containers from the data asset into the item actor. This is no longer needed, only the first index needs to be setup.)

Creating new items is very simple. To start off, you'll need to go into the engine and find your content browser, right click and go to **Inventory Framework -> Inventory Item Asset** and a pop up will appear asking you what parent your data asset should derive from. You might have your own children or have removed some of the children that come with the asset, but whatever asset you choose must derive from <mark style="color:yellow;">**DA\_CoreItem**</mark> at some point in its hierarchy.

I suggest creating a folder for your item and placing the data asset in there.

To create a blueprint actor for your item, you will have to create an actor who at some point in its hierarchy is a child of <mark style="color:yellow;">**A\_ItemActor**</mark> (The blueprint child is called <mark style="color:yellow;">**BP\_ItemActor**</mark>), then set that as your <mark style="color:purple;">**ItemActor**</mark>

The actor will automatically get the blueprint inventory component assigned to it. You will need to go into the component settings and change a few things.

1. Set <mark style="color:purple;">**InventoryType**</mark> to "**Pickup**"
2. Add one index to <mark style="color:purple;">**ContainerSettings**</mark> and set the <mark style="color:purple;">**ContainerType**</mark> to "**ThisActor**". This will then hide most of the settings except for the items array.
3. Your items array should only have one index, which will be your newly created data asset. All settings can be left to their default.
4. (Optional) If your item has containers associated with it, the data asset should have an array of <mark style="color:purple;">**DefaultContainers**</mark>. You will want to populate these with your containers and also assign the widget. Only available to supported data assets, such as <mark style="color:yellow;">**IDA\_Equippable**</mark> and <mark style="color:yellow;">**IDA\_Weapon**</mark>, to create your own item asset with container support, override the <mark style="color:red;">**GetDefaultContainers**</mark>. An example can be found in the example project with the gun and backpack item.

To have the asset manager pick up your data asset, it can not be identical to another data asset. (This includes the base file, so if all your variables are set to default, the asset will not get picked up.) Typically you want to immediately give your item a name and a developer image for the InventoryHelper.

***

### Creating new C++ children of DA\_CoreItem

You might want to create your own category of items, and since the engine does not allow you to mix C++ and blueprint children of data assets, you are unfortunately forced to create C++ children.

I suggest installing the plugin directly to your project, and then creating new children inside the **Items** folder, which is found inside the plugins **Core** folder.

***

## Changing the Item Actor class

Currently your item actors must be a child of <mark style="color:yellow;">**AA\_ItemActor**</mark>. If you want to change this, you can change it like so:&#x20;

{% tabs %}
{% tab title="From" %}

```
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category="CoreSettings")
TSoftClassPtr<AA_ItemActor> ItemActor = nullptr;
```

{% endtab %}

{% tab title="To" %}

```
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category="CoreSettings")
TSoftClassPtr<AActor> ItemActor = nullptr;
```

{% endtab %}
{% endtabs %}

AActor can be swapped out for any class, it does not need to be AActor, but it must be a child of AActor. +++

***

## Custom shapes

This inventory system features container styles where items can be different lengths and different heights.&#x20;

The way you define your shape is by adding the Custom Shape trait to your <mark style="color:purple;">**TraitsAndComponents**</mark> array and using the <mark style="color:purple;">**DisabledTiles**</mark> array. Though this is not very pleasant to work with in its raw array format. It is recommended to use the [ItemEditor](/varian-docs/inventoryframework/inventory-framework/tools/item-editor.md), where you'll find a toolbox with a few tools inside of it, one being the shape editor. Which gives you a much better UI to work with.

***

## Asset verification

To aid quality assurance, the data asset will run custom data verification when the asset is saved. The verification validates everything in the following process:

1. Use the <mark style="color:purple;">**ValidationClass**</mark> in the <mark style="color:purple;">**DeveloperSettngs**</mark> category to execute its <mark style="color:red;">**VerifyData**</mark> function. (Because we can't access a blueprint graph in each instance of a data asset, we do this to get around that limitation.)
2. <mark style="color:purple;">**ValidationClass**</mark> -> <mark style="color:red;">**VerifyData**</mark> will run some code to check if any mistakes have been made. Since every project is different, it is suggested to create your own child of <mark style="color:yellow;">**O\_ItemAssetValidation**</mark> and write your own code. To validate the data of trait references, an interface function from the <mark style="color:yellow;">**I\_Validation.h**</mark> interface also named <mark style="color:red;">**VerifyData**</mark> is called. You can see an example of this inside of <mark style="color:yellow;">**O\_BasicItemValidation**</mark> and <mark style="color:yellow;">**IT\_Consumable**</mark>
3. If any error messages are created during any of the <mark style="color:red;">**VerifyData**</mark> functions, you'll get a message at the bottom right stating the error message. If the <mark style="color:purple;">**ErrorMessages**</mark> array is empty, the item passes the verification.

Do note, if an item does not pass the verification, it does NOT prevent you from playing the game.

{% hint style="info" %}
Remember, modifying any variables from a data asset's object reference will change the base asset. This feature is great for a system like this.

For example, if you want a specific setting to always be set to something specific, you could programatically change the setting inside these validators. Ensuring these settings remain consistent across a large data-base.

I personally use this to ensure all my first-person meshes always have their shadows and collision disabled. If I ever have to change this setting, I just have to change the validator and resave all of my assets and my changes will be reflected across all current and future assets.
{% endhint %}

***

## Where to store runtime logic

As the plugin has grown, more and more features have been added, blurring the definition of what an "item" is and where any gameplay logic should be stored.

All items are data assets. Then when the inventory is made, a struct is made, which contains all data that can be modified during runtime and this data is replicated under specific conditions.

* Data inside of data assets should NOT be modified during runtime. If you have 2 guns in your inventory, then change any data inside the asset, it'll change for both of the guns. But modifying the struct for a gun will only modify that specific struct.

The four primary options below leave you with many options to tackle where to store your data and logic. It's up to you to resolve which method is best for what you are trying to accomplish.

### GAS abilities or helper components

What I, and many others have been doing, is simply constructing one object, a GAS ability or helper actor component, and having that run the logic for, let's say, a gun item. Whenever you swap weapons, you'd just send an event to the ability or component and it would update what weapon is equipped.&#x20;

This approach has a host of benefits:

* Many performance benefits.
* Simpler for source control.
* Easier to find gameplay logic that might not have been touched in some time.
* Easier to maintain.
* Far fewer points of failure. For each blueprint you create to handle runtime logic, it's another point of failure. This approach minimizes the amount of blueprints, and thus reducing the amount of point of failures.

I would recommend using GAS over all other options whenever you can, but of course, not all use cases are the same. There is no ultimate solution that covers every scenario.

I personally recommend using [**GAS Companion**](https://www.unrealengine.com/marketplace/en-US/product/gas-companion) and/or [**Gameplay Blueprint Attributes**](https://www.unrealengine.com/marketplace/en-US/product/gameplay-blueprint-attributes) to help with your GAS implementation.

* The only downside of GAS that I've found is that it is extremely difficult to have abilities be "instanced per item". As in, a new ability instance is created for each item instance without overriding a lot of C++ code and having a really good understanding of how GAS works under the hood. This type of logic can be achieved with the [`ItemAbility`](/varian-docs/inventoryframework/inventory-framework/systems/ability-system-integration.md#item-component-ability) item component.

### Traits and Components

Data assets have "[traits" and "components](#traits-and-components)", which I recommend you read the documentation for, but in essence, they are:

* Traits: Extra data you can add to any specific asset without creating a new parent. Essentially giving you "horizontal" hierarchy, just like how interfaces add functions to a class without reparenting it.
  * Example: You have a sword and a health potion asset. Both of these can be crafted, but you don't want to create a "Craftable" item asset to insert into their hierarchy. Not all swords and not all potions might be craftable. You can now add an trait to any asset that has a recipe and have that trait link to that recipe data asset. You can now ask your data asset if it is "craftable" without asking your entire recipe data base if it has a recipe for that item.
* Components: Actor components that can be created during runtime and are attached to the same actor that the inventory component lives on. These can run gameplay logic and destroyed during runtime, just like any other actor component. These are tied to traits so they can also be thought of as "horizontal" hierarchy.

### Item actor

Then there's the optional actor to spawn when the item is dropped, or in some cases equipped. These can be destroyed and created frequently, so it shouldn't really be trusted with a lot of gameplay logic. This should be treated as just the "visual representation" of your item.

### Item Instance

`ItemInstance`'s are optional objects created when an item struct is created, and they're tied together. Unlike actors, `ItemInstance`'s can be trusted to handle gameplay logic.

* **Assigning an instance with an item**: There are two ways to assign an `ItemInstance`'s with an `ItemAsset`:
  1. **Data Asset Default**: The default instance is set in the data asset. This is the recommended way.
  2. **Override per Struct**: Individual struct instances can override variables for more customization.
  3. **Recommendation**: I highly recommend using the first method as that is soft-referenced.
* **Replication**: Fully supported and can be optimized with custom replication conditions.
* **Restrictions**: By default, assigning an `ItemInstance` in the item struct has 2 rules:
  1. "Wild" `ItemInstance`'s are not allowed. This refers to items which have no default `ItemInstance` assigned in the item asset, but you still want to add one to the item struct. It is highly advised to keep this rule enabled to prevent random items having random item instances as keeping track of this is extremely difficult in medium to large projects.
  2. You are not allowed to select `ItemInstance`'s that do not match the same class that was assigned in the item asset. This is to prevent two identical items having two different ItemInstance classes, leading to odd behavior.\*/
  3. To disable either or both of these restrictions, modify <mark style="color:yellow;">**FL\_InventoryFramework**</mark> -> <mark style="color:red;">**ProcessContainerAndItemCustomizations**</mark>
* **Serialization (Experimental)**: Item Instances can be serialized, saving only variables marked with the `SaveGame` flag. This feature is experimental and may change in future updates, so it's not recommended for production. I recommend going with a much more robust serialization system that covers much more than just the inventory.

***

#### Creation & Destruction

* **Creation**: Item Instances are created during `StartComponent` and remain tied to the item until the item is destroyed, unless you enable <mark style="color:purple;">**ConstructOnRequest**</mark>. Then it will only be constructed when you call <mark style="color:red;">**GetItemsInstance**</mark>.
* **Destruction**: They stay alive until garbage collection activates, just like widgets. Use `IsDestroyed` to check their status.

***

#### Networking

* `ItemInstances`'s replicate to all clients relevant to the inventory owner. However, the item struct data itself isn't replicated and shouldn't be trusted on non-owner clients due to networking optimizations `IFP` enforces.
* `ItemInstances`'s can declare their own replication conditions, allowing for optimized network performance (e.g., replicating only to the owner or server-only).
* **Important**: If you move the inventory component to the player state for seamless travel, `ItemInstance`'s will replicate to every client. To avoid this, use replication conditions or consider not using `ItemInstance`'s, depending on your game's needs.

#### Performance

* Constructing these `ItemInstance`'s is cheap, but if you plan on using hundreds of these, the small cost can pile up. I highly recommend leaving the <mark style="color:purple;">**ConstructOnRequest**</mark> option set to true. The main worry you might need to consider is the garbage collector. The developers of Hogwarts Legacy had this problem where they abused instanced objects so much that the garbage collector would cause hitches, though I am not sure as to how many objects they were making. I suggest only making these instances for items that actually need it.
* If you have a pooling system, then I will continue recommending having <mark style="color:purple;">**ConstructOnRequest**</mark> enabled, then overriding the <mark style="color:red;">**RemoveObject**</mark> function to no longer mark the object as garbage and move the `ItemInstance` into your pooling system, then modifying <mark style="color:red;">**GetItemsInstance**</mark> to access your pooling system.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://varian.gitbook.io/varian-docs/inventoryframework/inventory-framework/classes-and-settings/da_coreitem.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
