Skip to content

Blueprint Design Patterns & Clean Code โ€‹

๐ŸŽฏ Overview โ€‹

Modern Blueprint development requires disciplined patterns and clean code principles. This guide covers industry-standard approaches for creating maintainable, scalable Blueprint systems using DRY, KISS, and SOLID principles adapted for visual scripting.

Clean Code Architecture Flow โ€‹

mermaid
graph TB
    subgraph "SOLID Principles"
        S[Single Responsibility]
        O[Open/Closed]
        L[Liskov Substitution]
        I[Interface Segregation]
        D[Dependency Inversion]
    end
    
    subgraph "DRY Implementation"
        FL[Function Libraries]
        IF[Interface Abstraction]
        CO[Component Reuse]
    end
    
    subgraph "KISS Approach"
        SR[Single Responsibility]
        CF[Clear Flow]
        SM[Simple Methods]
    end
    
    S --> FL
    O --> IF
    I --> CO
    
    FL --> SR
    IF --> CF
    CO --> SM
    
    style S fill:#e8f5e8
    style FL fill:#f3e5f5
    style SR fill:#e3f2fd

๐Ÿงฑ Core Design Principles โ€‹

DRY (Don't Repeat Yourself) โ€‹

Eliminate duplication through smart Blueprint architecture.

Function Libraries Pattern โ€‹

๐Ÿ”น Create Blueprint Function Libraries for:
  โ€ข Math utilities (distance calculations, interpolations)
  โ€ข String formatting and validation
  โ€ข Array/Map manipulation helpers
  โ€ข Common gameplay calculations
  โ€ข UI state management functions

Interface-Based Abstraction โ€‹

๐Ÿ”น Blueprint Interface: IInteractable
  โ€ข Function: Interact(Actor Instigator)
  โ€ข Function: GetInteractionText() -> Text
  โ€ข Function: CanInteract(Actor Instigator) -> Bool

๐Ÿ”น Implementation across multiple actors:
  โ€ข BP_Door implements IInteractable
  โ€ข BP_Chest implements IInteractable
  โ€ข BP_NPC implements IInteractable

Component-Based Reusability โ€‹

๐Ÿ”น Create reusable components:
  โ€ข AC_Health (health management)
  โ€ข AC_Inventory (item storage)
  โ€ข AC_Interaction (interaction handling)
  โ€ข AC_AudioManager (sound effects)

KISS (Keep It Simple, Stupid) โ€‹

Favor clarity over cleverness in Blueprint design.

Single Responsibility Principle โ€‹

โŒ Bad: One massive Blueprint handling:
  โ€ข Player movement
  โ€ข Combat system
  โ€ข Inventory management
  โ€ข UI updates
  โ€ข Audio management

โœ… Good: Separate focused Blueprints:
  โ€ข BP_PlayerMovement
  โ€ข BP_CombatSystem
  โ€ข BP_InventoryComponent
  โ€ข BP_UIManager
  โ€ข BP_AudioComponent

Clear Node Flow โ€‹

โœ… Linear execution flow:
  Input โ†’ Validation โ†’ Core Logic โ†’ Output โ†’ Cleanup

โŒ Avoid:
  โ€ข Excessive branching
  โ€ข Nested sequence chains
  โ€ข Complex multi-cast delegates

SOLID Principles for Blueprints โ€‹

Single Responsibility โ€‹

Each Blueprint should have one reason to change.

๐Ÿ”น BP_WeaponBase
  โ€ข Handles: Damage calculation, ammo management
  โ€ข Does NOT handle: Player input, UI updates, inventory

๐Ÿ”น BP_PlayerController
  โ€ข Handles: Input processing, camera control
  โ€ข Does NOT handle: Health management, inventory logic

Open/Closed Principle โ€‹

Blueprints should be open for extension, closed for modification.

๐Ÿ”น Create BP_WeaponBase with virtual functions:
  โ€ข FireWeapon() [Virtual]
  โ€ข ReloadWeapon() [Virtual]
  โ€ข GetDamage() [Virtual]

๐Ÿ”น Extend with specific weapons:
  โ€ข BP_Rifle extends BP_WeaponBase
  โ€ข BP_Pistol extends BP_WeaponBase
  โ€ข Override virtual functions as needed

๐Ÿ—๏ธ Architectural Patterns โ€‹

MVC Pattern for Blueprints โ€‹

Model Layer โ€‹

๐Ÿ”น Data-only Blueprints:
  โ€ข BP_GameData (pure data container)
  โ€ข BP_PlayerStats (statistics tracking)
  โ€ข BP_WorldSettings (configuration data)

๐Ÿ”น Characteristics:
  โ€ข No visual components
  โ€ข No input handling
  โ€ข Pure data structures and validation

View Layer โ€‹

๐Ÿ”น UI and Presentation:
  โ€ข BP_HUD (heads-up display)
  โ€ข BP_MainMenu (menu interface)
  โ€ข BP_InventoryWidget (inventory display)

๐Ÿ”น Characteristics:
  โ€ข Handles display only
  โ€ข Receives data from controllers
  โ€ข No direct game logic

Controller Layer โ€‹

๐Ÿ”น Logic Coordination:
  โ€ข BP_GameController (game flow management)
  โ€ข BP_PlayerController (player input coordination)
  โ€ข BP_UIController (UI state management)

๐Ÿ”น Characteristics:
  โ€ข Coordinates between Model and View
  โ€ข Handles business logic
  โ€ข Manages state transitions

Observer Pattern โ€‹

Implement loose coupling through event-driven architecture.

Event Dispatcher System โ€‹

๐Ÿ”น BP_EventManager:
  โ€ข OnPlayerHealthChanged(float NewHealth)
  โ€ข OnInventoryUpdated(TArray<FItemData> Items)
  โ€ข OnLevelComplete(int32 Score)

๐Ÿ”น Subscribers bind to relevant events:
  โ€ข UI elements listen to data changes
  โ€ข Audio systems respond to game events
  โ€ข Analytics track player actions

Gameplay Tag Events โ€‹

๐Ÿ”น Use Gameplay Tags for loose coupling:
  โ€ข GameplayTag: "Event.Player.LevelUp"
  โ€ข GameplayTag: "Event.Combat.WeaponSwitch"
  โ€ข GameplayTag: "Event.UI.MenuOpen"

๐Ÿ”น Components listen for specific tags
๐Ÿ”น Easy to add/remove listeners without code changes

Factory Pattern โ€‹

Centralized object creation with consistent initialization.

Actor Factory System โ€‹

๐Ÿ”น BP_ActorFactory:
  โ€ข CreateEnemy(EnemyType Type) -> BP_EnemyBase
  โ€ข CreateWeapon(WeaponData Data) -> BP_WeaponBase
  โ€ข CreatePickup(ItemData Item) -> BP_PickupBase

๐Ÿ”น Benefits:
  โ€ข Consistent initialization
  โ€ข Easy to modify creation logic
  โ€ข Supports object pooling
  โ€ข Centralized spawn logic

๐ŸŽจ Visual Organization Patterns โ€‹

Node Grouping Standards โ€‹

Color Coding System โ€‹

๐Ÿ”น Input Handling: Light Blue
๐Ÿ”น Core Logic: Default (White/Gray)
๐Ÿ”น Validation: Yellow
๐Ÿ”น Output/Results: Green
๐Ÿ”น Error Handling: Red
๐Ÿ”น Debug/Temporary: Purple

Comment Block Structure โ€‹

๐Ÿ”น Header Comments:
  โ•”โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•—
  โ•‘              INITIALIZATION          โ•‘
  โ•‘  Setup all components and variables  โ•‘
  โ•šโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•

๐Ÿ”น Section Comments:
  โ”Œโ”€ INPUT VALIDATION โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
  โ”‚ Check all inputs before processing โ”‚
  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

๐Ÿ”น Function Comments:
  // Calculate damage with armor reduction

Execution Flow Layout โ€‹

๐Ÿ”น Left-to-Right Flow:
  Input โ†’ Processing โ†’ Validation โ†’ Output

๐Ÿ”น Vertical Grouping:
  โ€ข Main execution path: Center
  โ€ข Error handling: Below main flow
  โ€ข Helper functions: Above main flow
  โ€ข Debug outputs: Right side

Blueprint Organization Hierarchy โ€‹

Folder Structure โ€‹

๐Ÿ“ Blueprints/
โ”œโ”€โ”€ ๐Ÿ“ Core/               (Base classes, interfaces)
โ”‚   โ”œโ”€โ”€ BP_GameModeBase
โ”‚   โ”œโ”€โ”€ BPI_Interactable
โ”‚   โ””โ”€โ”€ BP_ActorBase
โ”œโ”€โ”€ ๐Ÿ“ Player/             (Player-specific)
โ”‚   โ”œโ”€โ”€ BP_Player
โ”‚   โ”œโ”€โ”€ BP_PlayerController
โ”‚   โ””โ”€โ”€ BP_PlayerState
โ”œโ”€โ”€ ๐Ÿ“ Gameplay/           (Game mechanics)
โ”‚   โ”œโ”€โ”€ ๐Ÿ“ Combat/
โ”‚   โ”œโ”€โ”€ ๐Ÿ“ Inventory/
โ”‚   โ””โ”€โ”€ ๐Ÿ“ Interaction/
โ”œโ”€โ”€ ๐Ÿ“ UI/                 (User interface)
โ”‚   โ”œโ”€โ”€ ๐Ÿ“ HUD/
โ”‚   โ”œโ”€โ”€ ๐Ÿ“ Menus/
โ”‚   โ””โ”€โ”€ ๐Ÿ“ Widgets/
โ”œโ”€โ”€ ๐Ÿ“ Environment/        (World objects)
โ”‚   โ”œโ”€โ”€ ๐Ÿ“ Interactables/
โ”‚   โ”œโ”€โ”€ ๐Ÿ“ Hazards/
โ”‚   โ””โ”€โ”€ ๐Ÿ“ Props/
โ””โ”€โ”€ ๐Ÿ“ Utilities/          (Helper functions)
    โ”œโ”€โ”€ BP_MathLibrary
    โ”œโ”€โ”€ BP_StringUtils
    โ””โ”€โ”€ BP_ArrayHelpers

Naming Conventions โ€‹

๐Ÿ”น Classes:
  โ€ข BP_ClassName (main Blueprint)
  โ€ข AC_ComponentName (Actor Component)
  โ€ข BPI_InterfaceName (Blueprint Interface)
  โ€ข E_EnumName (Enumerations)
  โ€ข S_StructName (Structures)

๐Ÿ”น Variables:
  โ€ข bIsValid (boolean)
  โ€ข iPlayerCount (integer)
  โ€ข fMovementSpeed (float)
  โ€ข sPlayerName (string)
  โ€ข aInventoryItems (array)

๐Ÿ”น Functions:
  โ€ข GetHealthPercentage()
  โ€ข SetPlayerState()
  โ€ข CalculateDamage()
  โ€ข OnPlayerDeath()

๐Ÿ”ง Implementation Patterns โ€‹

Validation Patterns โ€‹

Input Validation Chain โ€‹

๐Ÿ”น Standard validation sequence:
  1. Null checks (IsValid nodes)
  2. Range validation (clamp values)
  3. State validation (check prerequisites)
  4. Permission validation (can perform action)
  5. Resource validation (sufficient resources)

๐Ÿ”น Early return on validation failure
๐Ÿ”น Clear error messages for debugging

Defensive Programming โ€‹

โœ… Always validate:
  โ€ข Object references before use
  โ€ข Array indices before access
  โ€ข Division by zero scenarios
  โ€ข Network authority before replication
  โ€ข Component existence before calling functions

Error Handling Patterns โ€‹

Graceful Degradation โ€‹

๐Ÿ”น Example: Weapon System
  โ€ข Primary fire fails โ†’ Switch to secondary
  โ€ข No ammo โ†’ Play empty click sound
  โ€ข Invalid target โ†’ Clear target and continue
  โ€ข Component missing โ†’ Use default behavior

Error Recovery System โ€‹

๐Ÿ”น BP_ErrorHandler:
  โ€ข LogError(String Message, ESeverity Level)
  โ€ข TryRecoverFromError() -> Bool
  โ€ข NotifyPlayerOfError(String UserMessage)
  โ€ข ReportToAnalytics(FErrorData Data)

Performance Patterns โ€‹

Object Pooling โ€‹

๐Ÿ”น BP_PoolManager:
  โ€ข GetFromPool(UClass ObjectClass) -> AActor
  โ€ข ReturnToPool(AActor Object)
  โ€ข PrewarmPool(UClass ObjectClass, int32 Count)

๐Ÿ”น Use for:
  โ€ข Projectiles
  โ€ข Particles
  โ€ข Audio sources
  โ€ข UI elements

Lazy Loading โ€‹

๐Ÿ”น Delay expensive operations:
  โ€ข Load assets only when needed
  โ€ข Initialize components on first use
  โ€ข Cache calculations after first computation
  โ€ข Stream in content based on proximity

State Management Patterns โ€‹

State Machine Implementation โ€‹

๐Ÿ”น Enum-Based State Machine:
  โ€ข E_PlayerState: Idle, Moving, Attacking, Defending
  โ€ข Switch statement for state transitions
  โ€ข Validation before state changes
  โ€ข Entry/Exit actions for each state

๐Ÿ”น State Component Pattern:
  โ€ข AC_StateMachine component
  โ€ข Data-driven state definitions
  โ€ข Event-driven transitions

Command Pattern โ€‹

๐Ÿ”น BP_Command (Base Class):
  โ€ข Execute() [Virtual]
  โ€ข Undo() [Virtual]
  โ€ข CanExecute() -> Bool [Virtual]

๐Ÿ”น Specific Commands:
  โ€ข BP_MoveCommand
  โ€ข BP_AttackCommand
  โ€ข BP_InventoryCommand

๐Ÿ”น Command Queue:
  โ€ข Queue commands for delayed execution
  โ€ข Support for undo/redo systems
  โ€ข Network-safe command replication

๐Ÿš€ Advanced Patterns โ€‹

Dependency Injection โ€‹

Reduce tight coupling through injection patterns.

Service Locator Pattern โ€‹

๐Ÿ”น BP_ServiceLocator:
  โ€ข RegisterService(UClass ServiceClass, UObject Service)
  โ€ข GetService(UClass ServiceClass) -> UObject
  โ€ข UnregisterService(UClass ServiceClass)

๐Ÿ”น Example Services:
  โ€ข Audio Service
  โ€ข Save System Service
  โ€ข Analytics Service
  โ€ข Input Service

Interface Injection โ€‹

๐Ÿ”น Inject dependencies through interfaces:
  โ€ข IHealthSystem for health management
  โ€ข IInventorySystem for item handling
  โ€ข IAudioSystem for sound management

๐Ÿ”น Components request interfaces, not concrete classes
๐Ÿ”น Easy to swap implementations for testing

Data-Driven Design โ€‹

Use data assets for flexible, designer-friendly systems.

Configuration Pattern โ€‹

๐Ÿ”น Data Assets for Configuration:
  โ€ข DA_WeaponConfig (damage, range, fire rate)
  โ€ข DA_PlayerConfig (movement speed, health)
  โ€ข DA_LevelConfig (spawn points, objectives)

๐Ÿ”น Runtime Modification:
  โ€ข Designers can tweak without Blueprint changes
  โ€ข A/B testing support
  โ€ข Mod support through data asset replacement

Table-Driven Logic โ€‹

๐Ÿ”น Data Tables for Complex Logic:
  โ€ข DT_DamageCalculation (armor vs weapon type)
  โ€ข DT_LootTables (item drop probabilities)
  โ€ข DT_DialogueOptions (conversation trees)

๐Ÿ”น Benefits:
  โ€ข Non-programmers can modify behavior
  โ€ข Easy to balance and iterate
  โ€ข Supports localization

Network Patterns โ€‹

Clean patterns for multiplayer Blueprint development.

Authority Validation โ€‹

๐Ÿ”น Network Authority Checks:
  โ€ข Server: Authoritative logic
  โ€ข Client: Prediction and visual feedback
  โ€ข Multicast: Synchronized visual effects

๐Ÿ”น Pattern:
  if (HasAuthority()) {
    // Execute authoritative logic
    MulticastVisualEffect();
  }

Replication Patterns โ€‹

๐Ÿ”น Replicated Variables:
  โ€ข Mark important state as replicated
  โ€ข Use RepNotify for client responses
  โ€ข Minimize replicated data size

๐Ÿ”น RPC Patterns:
  โ€ข Client-to-Server: Input and requests
  โ€ข Server-to-Client: Confirmations and updates
  โ€ข Multicast: Shared visual/audio effects

๐Ÿ“‹ Best Practices Checklist โ€‹

Before Creating New Blueprint โ€‹

  • [ ] Check if existing Blueprint can be extended
  • [ ] Identify single responsibility for the Blueprint
  • [ ] Plan interface requirements
  • [ ] Consider component-based approach

During Development โ€‹

  • [ ] Use descriptive names for all nodes
  • [ ] Group related nodes with comments
  • [ ] Validate all inputs before processing
  • [ ] Implement error handling paths
  • [ ] Add debug output nodes for testing

Code Review Checklist โ€‹

  • [ ] DRY: No repeated logic across Blueprints
  • [ ] KISS: Complex flows are broken into functions
  • [ ] Clear execution flow (left-to-right)
  • [ ] Proper error handling
  • [ ] Performance considerations addressed
  • [ ] Network authority properly handled
  • [ ] Memory management considered

Refactoring Indicators โ€‹

  • [ ] Blueprint has more than 50 nodes
  • [ ] Similar logic exists in multiple places
  • [ ] Complex nested branches (>3 levels)
  • [ ] Difficult to understand execution flow
  • [ ] Performance issues during profiling

๐ŸŽฏ Common Anti-Patterns to Avoid โ€‹

The God Blueprint โ€‹

โŒ Problem: One Blueprint handling everything โœ… Solution: Break into focused, single-purpose Blueprints

Copy-Paste Programming โ€‹

โŒ Problem: Duplicating similar logic across Blueprints โœ… Solution: Create shared functions or components

Magic Numbers โ€‹

โŒ Problem: Hard-coded values throughout Blueprint โœ… Solution: Use variables or data assets for configuration

Deep Nesting โ€‹

โŒ Problem: Excessive branching and nested sequences โœ… Solution: Break into smaller functions, use early returns

Tight Coupling โ€‹

โŒ Problem: Blueprints directly referencing specific other Blueprints โœ… Solution: Use interfaces, events, or dependency injection


This comprehensive pattern guide ensures your Blueprint code follows industry standards for maintainability, scalability, and performance. Apply these patterns consistently across your project for professional-quality results.

๐Ÿš€ Getting Started

4 of 4 completed