Managing an item's "name", "attack", and "durability" as separate variables means lining up three values every time you pass that item around. As your inventory grows, so does the work of checking "does this name belong to the same sword as this durability?"
A struct is the type for bundling that information together. It lets you pass "one item's worth of information" down a single wire.
In this article we build data for an iron sword and change its durability from 100 to 90. Along the way we confirm the moment where the copy in hand is 90 while the inventory still holds 100 . Once you can tell which value you changed, updating arrays stops being confusing.
What You'll Learn
- Bundling name, attack, and durability into a struct
- Assembling with Make and extracting what you need with Break
- Reading the copy and the original array, then confirming the write-back
This is for people who have created Blueprint variables and connected nodes. We do not build an inventory screen; we check how the data moves with Print String first.
A struct is one; an array is many
Each item inside a struct is called a member . Here we have three: name, attack, and durability. Whether to bundle them depends less on how many there are and more on whether you want to handle them together as information about the same thing .
An array , on the other hand, holds values of the same type in order. If a struct is "one sword's worth of information", an array of structs is "an inventory list holding several swords".

The number for a position inside an array is the index . It counts from 0: first is 0, next is 1. You could split names and durabilities into separate arrays, but making one item a struct keeps that information together at the same position.
A struct is not a feature that places a sword in the world. We are handling "information" about a sword. Spawning a visible Actor or showing it in an inventory UI is the job of whatever receives that information.
Create the struct and meet Make and Break
In a practice folder, right-click in the Content Browser and create S_DemoItem from "Blueprints" → "Structure". The S_ prefix is a naming convention for spotting structs, not a UE requirement.
Open it, add members with "Add Variable", and use the following names and types. A type is the kind of value a member can hold.
| Member name | Type | Meaning here |
|---|---|---|
DisplayName | Text | The item name shown on screen |
Attack | Integer | Attack power, handled as an integer |
Durability | Integer | Current durability, as an integer |
Under "Default Values", set DisplayName empty, Attack to 0, and Durability to 100, then save. A default value is the starting point when no value is specified. It is not a setting that restores every sword you already created.
Using this type in Blueprint gives you two nodes.
| Node | What it does | Iron sword example |
|---|---|---|
Make S_DemoItem | Assembles a struct value from members | Iron sword, 10, 100 → one item's worth |
Break S_DemoItem | Extracts each member from a struct | One item's worth → name, attack, durability |

Break means "read the members separately". It does not break the item or remove it from an array.
Make and Break have no white exec pins. Such pure nodes are evaluated when the work that uses the value needs it. Their role differs from Set and Print String, which chain execution order with white wires.
Changing the copy does not change the original
A struct is a value type : assigning it copies the values inside. The Get (a copy) we use on the array likewise returns a copy of the item information at that position.
Say the iron sword in your inventory has durability 100. Extract that information and change it to 90, and what changed is the extracted side. To make the original array 90, put the modified information back at the same position.

That last step of "extract, change, put back" is what we call a write-back here. It is not saving to a file; it updates the running array.
Arrays also offer
Get (a ref). That reference handles the value inside the array itself. "Get always copies" is not true. Here we useGet (a copy)and an explicit write-back, since the difference is easier to follow.
Hands-On: confirming the difference between 90 and 100
We build an experiment that, on Play, prints the copy's durability 90 and then the original array's 100. After that we add the write-back and confirm that reading the array again gives 90.
1. Prepare an inventory on a practice Actor
Create a Blueprint BP_StructPractice with Actor as its parent, and place exactly one in the level. Every variable and node below lives inside this Blueprint.
| Variable name | Type | Purpose |
|---|---|---|
Inventory | Array of S_DemoItem | The original inventory list |
WorkingItem | S_DemoItem (single value) | A temporary place for the modified information |
Choose S_DemoItem as the variable type and set only Inventory 's container type to "Array". Compile, then expand Inventory in "Class Defaults" and add one element with "+".
Set element 0 to DisplayName = Iron Sword , Attack = 10 , and Durability = 100 . WorkingItem's initial value gets overwritten later, so leave it as-is.
It matters that we start from an array where element 0 exists. Leaving the array empty trips you up on the very first read.
2. Extract the information at index 0
Drag Inventory into the Event Graph and choose "Get". That is the variable node for using the whole array. From its output create Get (a copy) and set the position input to 0. From that output, create Break S_DemoItem .

These three are the reading side. They are not connected to any executing work yet, so next we build "where the value we read goes".
3. Set only durability to 90 and store it in WorkingItem
Create Make S_DemoItem and Set WorkingItem . Connect DisplayName and Attack from the Break to the inputs of the same names on Make. Type 90 directly into Make's Durability .

The Break in the diagram is the one you just created, reused. We are not adding a subtraction mechanism here; we set durability to 90. Name and attack are passed too, so the members you are not changing survive . Leaving Make's inputs empty does not automatically carry over the original sword's values.
Next connect Make's output to Set WorkingItem, and Event BeginPlay 's white exec output to Set WorkingItem's exec input. BeginPlay is the event called when this Actor starts play.

The diagrams show the same graph in parts. Do not add extra Make or Set WorkingItem nodes per diagram; continue from the previous connections.
4. Print the copy and the original array separately
First Get WorkingItem and pass it to a Break. Drag Break's Durability onto Print String 's In String and a small conversion node appears that turns an integer into a string. The diagram draws it as To String (Integer) .
Print String displays text , so displaying the integer 90 needs that conversion. Connect Set WorkingItem's white exec output to Print String as well.

Compile and Play at this point and you see 90. Stop, then continue with reading the original array.
Create Inventory's Get → Get (a copy) at 0 → Break → integer-to-string on durability → a second Print String. Connect the first Print String's exec output to the second one's exec input.

On Play, the first prints 90 and the second prints 100. New messages can stack upward on screen, so do not judge by vertical order alone; check the output order in the "Output Log" if needed. If the display vanishes too fast, open each Print String's detail pins and set Duration to 10.
The 90 you put in WorkingItem is not in Inventory index 0 yet. Nothing failed in the connections up to Set WorkingItem; you updated a different variable.
5. Write back to the array and read it again
After the second Print String, add Set Array Elem . That node puts a value at a specified position in an array.
| Input | What to connect or set |
|---|---|
| Exec input | The second Print String's exec output |
Target Array | Inventory's Get |
Index | 0, the same position you read from |
Item | WorkingItem's Get |
Size to Fit | OFF |

Size to Fit grows the array when the specified position is outside it. We are replacing an existing index 0, so leave it OFF.
Finally, duplicate the "read from Inventory and pass to Print String" group from step 4 to create a third Print String. Connect Set Array Elem's white exec output to that Print String's exec input. The final display also reads Inventory index 0, not WorkingItem.
The final white exec chain is:
- Event BeginPlay → Set WorkingItem
- Print String: display WorkingItem's durability
- Print String: display Inventory index 0's durability
- Set Array Elem: write back to Inventory index 0
- Print String: re-read Inventory index 0 and display it
Compile and Play, and if the output order is 90 → 100 → 90 , it worked. If the last one stays 100, check Set Array Elem's exec wire, Target Array, Index, and Item in that order.

Now try setting Make's durability to 70. The result becomes 70 → 100 → 70. Every time you stop and restart Play, Inventory starts from the 100 specified in Class Defaults. Runtime updates and saving state until the next launch are separate things.
Once this works, you can think about "reduce durability when the sword is used" the same way: read the original value → build the modified information → put it back at the same position . When handling several items, pass the same Index to both the read and the write-back, and confirm that position exists first with Is Valid Index .
Care when adding members
With three members there are not many wires into Make. Add price and icon, and changing only durability means wiring more and more members you are not changing.
That is where Set Members in Struct helps. For our type it is named Set members in S_DemoItem . Create it from the target struct variable and expose only Durability as an input in the node's Details, and you can change durability while keeping name and attack. Members you do not expose are left alone.

That said, if you modify WorkingItem, the target is WorkingItem. Using this node does not automatically write back to the original Inventory. Just as in the experiment, confirm where you are changing things.
Also, changing one sword's durability and adding a member to S_DemoItem itself are different operations. The latter changes the shape of the data , so Blueprints and Data Tables using that type need checking too.
Before deleting members or changing types, commit the project to version control or take a backup. Afterwards, compile the users, and check unconnected pins, default values, and Data Table rows. Exporting a CSV helps as a supplement, but it is no substitute for the whole project.
Bonus: Good to Know Up Front
- A struct can hold "current state" too : durability here is the example. Rather than having the player and the UI each try to keep a correct value, decide on the Actor or Component that owns Inventory and update the value there, and it stays easy to trace.
- Separate type settings from a single instance's state : an iron sword's base attack is a per-type setting; the remaining durability of one well-used sword is per-instance state. Once you have many types, move on to managing shared settings with Data Table or Data Asset.
- Copying a struct does not multiply Actors : if the struct contains an Object reference such as an Actor, the copy's reference points to the same Object. Do not conclude from this Text-and-Integer example that "everything inside gets duplicated independently".
Summary
A struct is the type for handling name, attack, and durability as "one item's worth". Assemble with Make and read the members you need with Break.
When array updates confuse you, check whether what you changed was the copy or the original array . The 90 → 100 → 90 output here is a small experiment for watching that difference with your own eyes.
Add "pick up" and "use" operations plus UI to this data next, and you are on the way to an inventory system.