You only want to change the supply crate's ammo count, but you are chasing a line from BeginPlay across several screens. When appearance settings, inventory settings, and debug display all live in the same place, just finding the logic you want to change takes time.
This state — wires and logic tangled so the flow is hard to follow — is called spaghetti code. When organizing, on top of arranging nodes neatly, it is effective to name "which group does what."
This article splits ten techniques into three families, then organizes a small supply crate Blueprint at the end. The watchwords are zone → align → box up. We make it easier to reread later without changing behavior.
What You'll Learn
- Ten techniques for readable graphs across splitting, appearance, and names and values
- Where comment boxes, alignment, and Reroute belong
- How to name a group of logic with Collapse to Function
- How to confirm you get the same result before and after organizing
A readable graph shows you where to change things
In a graph you have not touched for a while, even its author forgets the finer intent. Comments and function names are notes you leave for that future self.

If BeginPlay reads as "set the counts → tidy the appearance → display the result," then changing the ammo count means opening only the first group. You no longer read every node every time.
The purpose of organizing is making the flow and the place to change easy to find. One crossing wire does not make a bad graph, and there is no need to force short logic into pieces.
Ten techniques in three families

| Family | Techniques |
|---|---|
| Splitting | 1 Functions 2 Macros 3 Splitting into Components |
| Appearance | 4 Comment boxes 5 Node alignment 6 Reroute 7 Left-to-right layout |
| Names and values | 8 Meaningful names 9 Local variables 10 Naming tuned values |
You do not need to use all of them at once. Start by confirming the flow with comments and alignment, and consider splitting once groups become visible.
Splitting techniques (1–3)
1. Gather one job into a Function
A Function gives a series of operations a name so they can be called. Beyond "calculate damage," you can also group logic with no return value such as "reset the supply crate's contents to their defaults."
Looking at the function call node tells you the job's name, and you can open it when you want detail. If the same logic is used elsewhere, you call the same function rather than multiplying copies.
The rule of thumb is "can I explain this group in one phrase?" A unit you can call "set the supply crate's counts" makes the change target easier to find than "set various things."
2. Consider a Macro for repeated flows
A Macro also bundles several nodes into one. It becomes a candidate when you want to split exec outputs like success and failure, or when you repeatedly use a flow combining DoOnce and Delay.
But having a Branch does not mean you need a Macro. Functions can also branch and set variables. Conversely, logic that waits partway, such as Delay, cannot go inside a Function. You can try the difference concretely in the Function and Macro article.
3. Split jobs used by several Actors into a Component
If you want health on both an enemy and a crate, one approach is splitting HP management into a Component. A Component is a capability part you attach to an Actor.
Instead of copying the HP calculation into each Actor, attach the same health part. The place to fix shared math becomes one. Split jobs into functions first, and once you see a group you want on several Actors, use the health Component hands-on as a reference.

Appearance techniques (4–7)
4. Show the purpose with a comment box
Select a group of nodes and press C to wrap them in a comment box. Write "what this logic is for" in the frame's heading.
"Line up the starting medkit and ammo counts" tells you the purpose before you read the nodes, unlike "two Sets." For values with a special reason, a short note such as "space by 0.1 s so rapid fire does not stack the sound" also helps.
5. Align nodes and exec lines
Select several nodes, right-click, and align their top or left edges from the "Alignment" items. To straighten connected wires, use "Straighten Connections."
Aligning node tops does not necessarily align exec pin heights. Using the operation that aligns card edges and the one that straightens connections for their respective purposes makes the flow easier to follow.
You can look up shortcuts by searching the command name in "Editor Preferences" → "Keyboard Shortcuts." In environments with different key bindings, running them from the menu is fine.
6. Change a wire's path with Reroute
A Reroute is a waypoint placed along a wire. Double-click a wire, or drag from an output pin and choose "Add Reroute Node."
It is handy for detouring a line hidden behind a node out to the side. Moving the waypoint does not change the relationship between the original output and input. It is not a tool for merging separate values into one wire.

7. Lay the main flow out left to right
Place things so the white exec line reads left to right first, and move value-producing nodes near the logic that uses them.
When one row gets long, break it into tiers by meaning. Some connections go back to the left by design, such as the line returning to DoOnce's Reset. Rather than forcing every line one direction, prioritize a layout where the start and the destination are clear.
Name and value techniques (8–10)
8. Make names reveal meaning
DamageAfterArmor over Temp1; Ammo over NewVar. Names that reveal a value's purpose save you from investigating what is stored every time.
For Booleans, names that read as yes/no such as bIsLocked work well. Align prefix and capitalization conventions within your project. Epic's C++ naming conventions and the constraints on variable names you can type in Blueprint are separate, so it does not mean "you cannot use it in Blueprint without a b."
9. Put a function's own intermediate values in local variables
A local variable is a temporary spot used only inside that function. An in-progress total, for example, can live inside the function rather than in a variable the whole Actor holds.
Move values you need later, such as HP or inventory counts, into locals and you cannot keep them after the call. Choose by "is this needed only during this calculation, or is it something the Actor remembers?" For details, see Blueprint Variables Basics.
10. Name the numbers you tune
Find a 500 in a tower defense graph and the number alone does not say whether it is range, price, or health. Values whose meaning is hard to read like this are called magic numbers.
Make the range a variable MaxRange and reference it from everywhere that range is used, and meaning and tuning point line up. But even at the same value of 500, range and price are different settings. Do not merge them into one just because the number matches.

Making it a named variable does not stop you from changing the value. What you are doing here is gathering the tuning values in one place. There is no need to turn every number into a variable, such as adding 1 to a count where the purpose is obvious.
Hands-On: organizing the supply crate's BeginPlay
From here we build the same small Blueprint and organize it. It only sets the supply counts, shows the crate, and prints the contents on screen, so no audio or UI assets are needed. We do not build item pickup.

Create a UE5 Third Person template in Blueprint, choosing None if there is a Variant option. Work in a new practice folder.
1. Build the unorganized supply crate
Create BP_SupplyCrate with Actor as parent, add a Static Mesh under DefaultSceneRoot, and name it CrateMesh. Set the standard Cube with relative location and rotation 0 and Scale 1. Cube can be selected from Engine/BasicShapes with "Show Engine Content" on in the asset picker.
Set CrateMesh's Mobility to Movable, Collision Presets to NoCollision, and Simulate Physics off. Under "Rendering," turn Visible off and leave "Hidden in Game" off. The startup logic turns Visible on so the crate appears.
Create variables Medkits and Ammo, both Integer with default 0. Medkits is the number of healing items and Ammo is the number of rounds.
In the Event Graph, connect BeginPlay's white exec line in this order.
| Order | Node | Setting |
|---|---|---|
| 1 | Set Medkits | 3 |
| 2 | Set Ammo | 30 |
| 3 | Set Relative Scale 3D | Target is CrateMesh, New Scale 3D is (1.2, 1.2, 1.2) |
| 4 | Set Visibility | Target is CrateMesh, New Visibility on, Propagate to Children off |
| 5 | Print Text | Duration 10, Print to Screen and Print to Log on |
Build them laid out directly in the Event Graph at first. For Set Relative Scale 3D and Set Visibility, dragging CrateMesh from Components into the graph and building from the retrieved reference makes Targets easy to align.

The second half of the same flow tidies the appearance.

The "from" and "to" in the diagrams are notes showing what connects before and after. They are not new node names. The blue comment frames are added in the next stage, so building only the nodes and connections at first is fine.
Build the sentence passed to Print Text's In Text like this.
- Place a Format Text and enter
Medkits: {Medkits} / Ammo: {Ammo}in Format. - Connect Get Medkits and Get Ammo to the Medkits and Ammo inputs that appear.
- Connect Format Text's Result to Print Text's In Text.
Format Text is a node that embeds values into the {name} slots. Print Text outputs that Text to screen and log. The point is displaying the values actually stored in the variables rather than writing 3 and 30 into the sentence directly.

Compile, save, and place one BP_SupplyCrate in front of the Player Start. Set the Actor's Scale to 1 with its center about 60 cm above the floor. Since Visible is off, you can adjust its position by selecting it in the Outliner.
Play and confirm that the crate appears and Medkits: 3 / Ammo: 30 shows for 10 seconds. That is the result we preserve after organizing. Stop here and save.
2. Zone with comments and tidy the flow

Select each of the following ranges and wrap them with C.
| Comment heading | Nodes to wrap |
|---|---|
| Set the supply counts | Set Medkits, Set Ammo |
| Tidy the crate's look | Get CrateMesh, Set Relative Scale 3D, Set Visibility |
| Display the supply counts | Get Medkits, Get Ammo, Format Text, Print Text |
Leave BeginPlay outside the frames. If you placed two CrateMesh Gets, include both in the appearance frame.
Move each range to a position that reads left to right and align it. Keep the white line in the order counts → appearance → display. There is no need to add Reroutes in this short example. Use them only when a line is hidden.
Since comments do not execute logic, wrapping alone changes nothing about behavior. Adding zones first shows you what to group.
3. Collapse contiguous ranges into Functions
Select only the two Set nodes in "Set the supply counts," right-click → "Collapse to Function." Name the function that appears in My Blueprint InitSupplyStock. Do not select BeginPlay.
Init is short for Initialize, meaning lining up the values you start with. Here the job is setting medkits to 3 and ammo to 30.
Collapse to Function moves the selected logic into a function and places a node calling that function in its place. Add no inputs or return values to InitSupplyStock here. Since the order of setting variables matters, leave Pure off and call it on the white exec line.
Group the rest the same way.
| Original range | Function name |
|---|---|
| Set the supply counts | InitSupplyStock |
| Tidy the crate's look | ApplySupplyAppearance |
| Display the supply counts | ReportSupplyStock |
Select Get CrateMesh in the appearance range and the variable Gets plus Format Text in the display range. Selecting only nodes with white lines leaves the value retrieval outside the function, so when you want to group the whole job as here, include the value-producing nodes too.
Double-click a function and confirm the original logic is inside. All three functions live in the same BP_SupplyCrate and handle its own variables and Components. The call Target is Self.
In the Event Graph, connect the three functions in order from BeginPlay. Confirm the pre-collapse call order survives and remove old comment frames if they are no longer needed.

Now BeginPlay reads as "set the counts → tidy the look → display the counts." The detailed values live inside the functions and the overall order is visible in the Event Graph.
4. Confirm the same result and where to change things
Compile, save, and Play. If the crate appears the same and Medkits: 3 / Ammo: 30 shows, you preserved the pre-organization result.
Next, imagine "I want to raise ammo to 60" and find where to change it. Open InitSupplyStock and change only Set Ammo's value to 60. Play again and Medkits: 3 / Ammo: 60 means the display side reads the variable correctly. Restore 30 afterwards.
If you reorder so display is called first, it may read the pre-set 0. Organizing nodes and changing execution order are separate changes. Preserving the same behavior first and changing the spec afterwards makes causes easier to trace.
When it doesn't work
| Symptom | Where to check |
|---|---|
| The crate doesn't appear | Target on CrateMesh, New Visibility, Hidden in Game, the white exec line |
| The numbers stay 0 | The order from Set to display, and a missed function call |
| Changing ammo still shows 30 | Whether the number is hard-typed in Format Text, and whether Get Ammo is used |
| Unexpected inputs appeared after Collapse | Whether you left variable Gets or Component references out of the selection |
| Collapse to Function is unavailable | Whether the selection includes events like BeginPlay, or nodes that cannot go in a function such as Delay |
The three functions here are a practice split for making the order easy to follow. If your real graph is short enough to read, stopping at comments alone is fine.
Bonus: Good to Know Up Front
What's the difference between Collapse Nodes and a Function?
Collapse Nodes folds a graph in place into a smaller graph. You can open it by double-clicking, but it differs from a Function, which creates a shared definition you call from anywhere.
Choose by purpose: Collapse Nodes for local clarity, Function or Macro when you want to call the same job by name. For details, go to Function and Macro.
Keep visual organizing separate from making logic lighter
Hiding a hundred operations inside a function does not reduce how many times they run. If you have many per-frame checks, also review choosing between Tick, Timer, and events.
But doing organizing and behavior changes at once makes it harder to isolate why a result changed. Organizing into a readable state, confirming the same result, and then changing execution frequency makes comparison easier.
Splitting into functions also lets you choose your inspection scope
In the Blueprint Debugger you can use Step Into to enter a function and Step Over to run it and continue on the calling side. Step Over does not mean the function is skipped.
That lets you choose what to follow, as in "the display is correct, so today I want to inspect the count settings." For the operations, see the Blueprint Debugger article.
Summary
Organizing graphs uses three views.
- Splitting: find the group that does one thing and split it into a function, macro, or Component.
- Appearance: use comments, alignment, and Reroute so you can trace from start to destination.
- Names and values: give variables and functions meaningful names and gather your tuning points.
With the supply crate, we made BeginPlay readable in the order zone → align → extract, preserving the original result. Next time you add a feature, first wrap the place you want to change and check whether you can explain that group in one phrase.
To get ahead of common stumbles, 10 common Blueprint mistakes also helps.