Fundamental Blueprint Practices

Blueprint as programming language The best feature of blueprints: it allows us to start coding video games logic without any programming knowledge. The worst feature of blueprints: it allows us to ...

Updated over 3 years ago

Blueprint as programming language

The best feature of blueprints: it allows us to start coding video games logic without any programming knowledge.
The worst feature of blueprints: it allows us to start coding video games logic without any programming knowledge.
There's no accidental copy-pasting text above. Visual scripting is a huge step forward giving people freedom of creation.
Nowadays everyone can create a new project and start with prototyping their idea. Learning engine and programming on the go.
The only problem is that official documentation fails to explain anything beyond "how to click into blueprints".

If you are lucky, you could already encounter people or YouTube videos explaining to you a few basic concepts of "engineering thinking".

  • How to avoid killing your framerate and start asking yourself "how much performance do these scripts cost us"?
  • How to avoid creating "gigabyte blueprints" - scripts that reference half of the game and you don't even know it, so you end up loading half of the game while opening Player's blueprint.
  • Concepts of code architecture and Object-Oriented Programming. These what you touch every day, but probably you didn't know the name for it.

These are relatively easy things to grasp if someone explains it to you, but it can a lot of new concepts to "digest" at once.
No worries, you can simply learn one thing, use it to compose better blueprints, repeat it, improve your skills. And come back to this resource to learn the next things.

And don't let anybody fool you. Your job title maybe not a "gameplay programmer" and you may be unable to use classic programming languages yet, but blueprint visual scripting is still programming.

Official treasures

Epic did a great job of explaining many things about blueprint lately, although these materials are scattered on their sites.
This is a convenient list for you. This wiki guide gonna repeat and rephrase a lot of advice from official materials, you can approach it any order.

Critical issues you can easily avoid

Use Timers instead of Tick and Delay

Note: Actually you should never use Set Timer by Function Name in blueprints. It's an unsafe practice. If someone would change the name of function, this timer will stop working.
Use Set Timer by Event mentioned at the end of this article.

Avoid casting to blueprint classes

As official documentation Balancing Blueprint and C++ says

Avoid Casting to Expensive Blueprints: Whenever you cast to a Blueprint class BP_A (or declare it as a variable type on a function or other Blueprint) from BP_B it creates a load dependency on that Blueprint. Then if BP_A references four large Static Meshes and 20 sounds, every time you load BP_B it will have to load four large Static Meshes and 20 sounds, even if the cast would fail. This is one of the primary reasons it’s essential to have either native base classes or minimal Blueprint base classes that define the important functions and variables. Then, you should make your expensive Blueprints as child classes.

How to avoid that?

  • Try to cast to blueprints that you now are already loaded into memory
  • Use event dispatcher instead of calling a function on the target blueprint
  • Use interfaces
  • Use components containing specific feature i.e. Inventory Component instead of putting this code into MyShopkeeper blueprint
  • Use systems identifying actor instances by something else than class, i.e. Gameplay Tags
  • Create native C++ base classes - it can be crazy useful if you write most of your logic in blueprints

Learn about hard references, soft references, and reference chain

  • Hard references is default type object references in the blueprint, so you already use it all the time. If blueprint A references to blueprint B, opening A in the editor or loading it in-game automatically loads blueprint B.
  • Reference chain. If blueprint A loads blueprint B automatically, this also means that blueprint B loads all his referenced blueprints automatically and all the assets used by these blueprints. That's why super-easy mess this up. If your Player Blueprint references all game systems directly, loading this blueprint will load all the game systems and assets used by these systems. So you end loading gigabytes of data and waiting a minute to open a Player Blueprint. No worries, designers in professional studios often do this mistake.

Solving this requires using 2 "solutions" all the time.

  • Soft references. It's the way to connect things without automatically loading references. You have to manually call loading it only when it's needed, i.e. loading sound or cutscene just before you want to play it, not at the beginning of the game.
  • Clean code architecture. This is a big topic, but a fundamental part of the programmer's work.

Clean code architecture

You need to think about how to decouple things: isolate systems, features, classes and assets. It could be initially difficult to understand which way of doing things is clean. It will come by practice and constant thinking "is it proper way of doing things? can this be improved?".

In properly implemented game Player Blueprint does never know about the existence of a door or shopkeeper. Interaction of player with door or shopkeeper is executed by the Interaction Component. This component doesn't know about the existence of any actor class using it, i.e. Player, Door, Shopkeeper. You could eventually create enums or gameplay tags to define interaction types.