--- description: Comprehensive best practices and coding standards for Unreal Engine projects. Covers code organization, performance, security, testing, and common pitfalls to ensure maintainable, efficient, and robust game development. globs: *.h,*.cpp,*.uasset,*.umap,*.ini --- # Unreal Engine Best Practices and Coding Standards This document outlines best practices and coding standards for Unreal Engine projects. Following these guidelines will help ensure maintainability, efficiency, and robustness. ## 1. Code Organization and Structure ### 1.1 Directory Structure * **`Source/`:** Contains all C++ source code. * **`[GameName]/`:** Root directory for your game's code. * **`Public/`:** Header files (.h) for classes and components. * **`Private/`:** Implementation files (.cpp). * **`[Feature]/`:** Subdirectories for specific game features (e.g., `Inventory`, `AI`, `UI`). * **`Core/`:** Classes and functions shared across the project. * **`UMG/`**: Code related to Unreal Motion Graphics (UI) * **`Content/`:** Contains all assets (meshes, textures, materials, blueprints, etc.). * **`[GameName]/`:** Root directory for your game's content. * **`Characters/`:** Character assets. * **`Environments/`:** Environment assets (meshes, textures, materials). * **`UI/`:** User interface assets. * **`Blueprints/`:** Blueprint classes and scripts. * **`Materials/`:** Material assets. * **`Textures/`:** Texture assets. * **`Audio/`:** Audio assets. * **`Animations/`:** Animation assets. * **`Config/`:** Configuration files (e.g., `DefaultGame.ini`, `DefaultEngine.ini`). * **`Plugins/`:** Plugin code and assets. ### 1.2 File Naming Conventions * **C++ Classes:** Use descriptive names with prefixes indicating the class type. * `A[ClassName]` for Actors (e.g., `ACharacter`, `APlayerController`). * `U[ClassName]` for UObjects (e.g., `UInventoryComponent`, `UGameInstance`). * `F[StructName]` for Structs (e.g., `FHitResult`, `FVector`). * `E[EnumName]` for Enums (e.g., `EMovementMode`, `EInventoryItemType`). * `I[InterfaceName]` for Interfaces (e.g., `IInteractable`, `IUsable`). * **Blueprints:** * `BP_[AssetName]` (e.g., `BP_Character`, `BP_Door`). * **Assets:** Use descriptive names with prefixes indicating asset type. * `SM_[AssetName]` for Static Meshes (e.g., `SM_Table`, `SM_Chair`). * `T_[AssetName]` for Textures (e.g., `T_Ground_Albedo`, `T_Wall_Normal`). * `M_[AssetName]` for Materials (e.g., `M_Rock`, `M_Water`). * `MI_[AssetName]` for Material Instances (e.g., `MI_Rock_Dark`, `MI_Water_Shallow`). * `S_[AssetName]` for Sounds (e.g., `S_Explosion`, `S_Footstep`). * `Anim_[AssetName]` for Animations (e.g., `Anim_Run`, `Anim_Jump`). * `Mat_[AssetName]` for Matinee Sequences (Legacy Animation). * **Levels:** * `[LevelName]_Level` or `[LevelName]` (e.g., `MainMenu_Level`, `Gameplay`). ### 1.3 Module Organization * **Game Module:** The main module containing the game's core logic. * **Feature Modules:** Modules dedicated to specific game features (e.g., `InventoryModule`, `AIModule`). * **Plugin Modules:** Modules packaged as plugins, offering reusable functionality. ### 1.4 Component Architecture * **Favor Composition over Inheritance:** Use components to add functionality to actors. * **Create Reusable Components:** Design components to be generic and adaptable. * **Use Interfaces for Communication:** Define interfaces for components to interact with each other. * **Avoid God Components:** Break down complex functionality into smaller, more manageable components. * **Encapsulate Logic:** Keep component logic self-contained and avoid tight coupling. ### 1.5 Code Splitting Strategies * **Feature-Based Splitting:** Organize code by game features. * **Module-Based Splitting:** Create separate modules for distinct functionalities. * **Async Loading:** Load assets and levels asynchronously to avoid hitches. * **Level Streaming:** Divide large levels into smaller, streamed sub-levels. * **Object Pooling:** Reuse frequently created and destroyed objects to reduce garbage collection. ## 2. Common Patterns and Anti-patterns ### 2.1 Design Patterns * **Singleton:** For classes with only one instance (e.g., `GameInstance`). * **Observer:** For event-driven communication between actors and components. * **Factory:** For creating objects without specifying their concrete classes. * **Command:** For encapsulating actions as objects, enabling undo/redo functionality. * **Strategy:** For defining a family of algorithms and making them interchangeable. * **Decorator:** For dynamically adding responsibilities to an object. * **Adapter:** For adapting the interface of a class to another interface clients expect. * **Object Pool:** Reuse objects to avoid frequent allocation and deallocation, especially useful for projectiles or particle effects. ### 2.2 Recommended Approaches for Common Tasks * **Actor Spawning:** Use `GetWorld()->SpawnActor<>()` to spawn actors dynamically. * **Input Handling:** Use Enhanced Input System for flexible and configurable input mappings. * **Timers:** Use `GetWorldTimerManager()` for timed events and actions. * **Collision Handling:** Use collision components and event delegates for collision detection. * **Networking:** Use Unreal Engine's built-in networking system for multiplayer games. * **Animation:** Leverage Animation Blueprints and State Machines for complex character animations. * **UI Design:** Utilize UMG (Unreal Motion Graphics) for creating dynamic user interfaces. ### 2.3 Anti-patterns and Code Smells * **God Classes/Actors:** Avoid overly large classes with too many responsibilities. * **Spaghetti Code:** Avoid complex and unstructured code that is difficult to understand and maintain. * **Magic Numbers:** Avoid hardcoded values without clear explanations. * **Copy-Pasted Code:** Refactor duplicated code into reusable functions or classes. * **Tight Coupling:** Minimize dependencies between classes and components. * **Memory Leaks:** Ensure proper memory management to avoid memory leaks. * **Excessive Casting:** Minimize the use of `Cast<>` as it can impact performance. Consider using interfaces or dynamic dispatch instead. * **Polling:** Avoid constantly checking for conditions; use events or delegates instead. * **Tick Abuse:** Avoid performing expensive operations in the `Tick()` function; use timers or asynchronous tasks. * **Not using the Actor Component System:** Neglecting to leverage components leads to monolithic, inflexible Actor classes. ### 2.4 State Management * **Game Instance:** For storing global game state that persists across levels. * **Game Mode:** For managing game rules and player interactions within a level. * **Player State:** For storing player-specific information (e.g., score, inventory). * **Actor State:** For storing the state of individual actors (e.g., health, position). * **Use Data Assets:** For storing configurable game data (e.g., weapon stats, enemy parameters). * **State Tree:** For handling complex AI behavior. * **Gameplay Abilities:** For managing player abilities and interactions using the Gameplay Ability System (GAS). ### 2.5 Error Handling * **Use `ensure()` for Debug Assertions:** Use `ensure()` to check for conditions that should always be true during development. * **Use `check()` for Critical Assertions:** Use `check()` for conditions that must be true in all builds. * **Use `try-catch` for Exception Handling:** Use `try-catch` blocks to handle exceptions in critical code sections. * **Log Errors and Warnings:** Use `UE_LOG()` to log errors and warnings for debugging and monitoring. * **Handle Potential Null Pointers:** Always check for null pointers before accessing object members. * **Implement Recovery Mechanisms:** Provide mechanisms to recover from errors gracefully (e.g., retry logic, fallback behavior). * **Validate Data:** Implement robust input and data validation to prevent unexpected errors. ## 3. Performance Considerations ### 3.1 Optimization Techniques * **Profiling:** Use Unreal Engine's profiling tools (e.g., Unreal Insights, Stat commands) to identify performance bottlenecks. * **LODs (Level of Detail):** Use LODs to reduce the complexity of meshes at a distance. * **Occlusion Culling:** Use occlusion culling to hide objects that are not visible. * **Distance Culling:** Use distance culling to remove objects that are too far away. * **HLODs (Hierarchical Level of Detail):** Use HLODs to combine multiple static meshes into a single mesh. * **Instanced Static Meshes:** Use instanced static meshes to render multiple copies of the same mesh efficiently. * **Material Optimization:** Optimize material complexity to reduce pixel cost. * **Texture Optimization:** Use appropriate texture resolutions and compression formats. * **Blueprint Nativization:** Convert Blueprint logic to C++ for improved performance. * **Asynchronous Loading:** Load assets and levels asynchronously to avoid hitches. * **Object Pooling:** Reuse frequently created and destroyed objects to reduce garbage collection. * **Avoid Dynamic Allocation:** Minimize dynamic memory allocation during runtime. * **Optimize Collision:** Simplify collision geometry and disable unnecessary collision checks. * **Use Niagara:** Use the Niagara particle system for efficient particle effects. * **Implement Adaptive Resolution:** Dynamically adjust the resolution based on performance. * **Use GPU Profiling tools:** Tools like RenderDoc can help you debug what is happening on the GPU and pin point bottlenecks. ### 3.2 Memory Management * **Use Smart Pointers:** Use `TSharedPtr` and `TWeakPtr` for automatic memory management. * **Avoid Circular Dependencies:** Prevent circular dependencies between smart pointers. * **Unload Unused Assets:** Unload assets that are no longer needed to free up memory. * **Garbage Collection:** Understand and optimize garbage collection behavior. * **Asset References:** Use asset references carefully to avoid unnecessary asset loading. * **Texture Streaming:** Use texture streaming to load only the necessary texture mipmaps. * **Minimize Asset Duplication:** Avoid creating duplicate assets; reuse existing ones whenever possible. * **Monitor Memory Usage:** Regularly monitor memory usage to identify potential leaks or excessive consumption. ### 3.3 Rendering Optimization * **Minimize Draw Calls:** Reduce the number of unique meshes and materials. * **Optimize Shaders:** Simplify shader complexity to reduce rendering time. * **Use Post-Processing Effects Sparingly:** Post-processing effects can be expensive; use them judiciously. * **Optimize Lighting:** Use baked lighting whenever possible to reduce runtime lighting calculations. * **Shadow Optimization:** Optimize shadow settings to reduce shadow rendering cost. * **Use Mobile Rendering Features:** Utilize mobile rendering features for improved performance on mobile devices. * **Consider Nanite Carefully:** For next-gen fidelity, use Nanite, but be aware of its overhead on lower-end platforms. * **Virtual Shadow Maps:** Use virtual shadow maps to improve shadow quality and performance in large open worlds. ### 3.4 Package Size Optimization * **Compress Assets:** Use asset compression to reduce package size. * **Remove Unused Assets:** Delete unused assets from the project. * **Texture Compression:** Use appropriate texture compression formats. * **Audio Compression:** Use appropriate audio compression formats. * **Blueprint Stripping:** Strip debug information from Blueprints in release builds. * **Cook Only Necessary Assets:** Ensure that only necessary assets are cooked for the target platform. * **Use Pak File Compression:** Employ compression when creating .pak files for deployment. ### 3.5 Lazy Loading * **Stream Levels:** Load and unload levels dynamically based on player location. * **Load Assets On-Demand:** Load assets only when they are needed. * **Use Async Load Asset:** Use the `Async Load Asset` node in Blueprints or `LoadObjectAsync` in C++ to load assets asynchronously. * **Lazy Loading Proxies:** Create proxy objects that load the full asset only when accessed. * **Subobject loading:** Defer loading of certain UObject subobjects until needed. ## 4. Security Best Practices ### 4.1 Common Vulnerabilities * **Code Injection:** Prevent code injection by validating all input data. * **Denial of Service (DoS):** Protect against DoS attacks by limiting resource usage. * **Man-in-the-Middle (MitM):** Use encryption to protect data in transit. * **Data Tampering:** Prevent data tampering by using checksums and digital signatures. * **Save Game Manipulation:** Protect save game data from modification to prevent cheating. ### 4.2 Input Validation * **Validate All Input Data:** Validate all input data from players and external sources. * **Sanitize Input Data:** Sanitize input data to remove potentially malicious characters or code. * **Limit Input Length:** Limit the length of input strings to prevent buffer overflows. * **Use Regular Expressions:** Use regular expressions to validate input patterns. * **Implement Whitelists:** Use whitelists to define allowed characters and patterns. ### 4.3 Authentication and Authorization * **Use Secure Authentication Methods:** Use secure authentication methods such as OAuth 2.0 or JWT. * **Implement Role-Based Access Control (RBAC):** Use RBAC to control access to different features and resources. * **Use Strong Passwords:** Enforce the use of strong passwords. * **Implement Multi-Factor Authentication (MFA):** Use MFA for added security. * **Store Credentials Securely:** Store user credentials securely using encryption and salting. * **Avoid Storing Secrets in Code:** Use configuration files or environment variables to store sensitive information. ### 4.4 Data Protection * **Encrypt Sensitive Data:** Encrypt sensitive data at rest and in transit. * **Use Secure Communication Protocols:** Use HTTPS for secure communication over the network. * **Protect Save Game Data:** Encrypt save game data to prevent cheating. * **Implement Data Backups:** Regularly back up data to prevent data loss. * **Comply with Data Privacy Regulations:** Comply with data privacy regulations such as GDPR and CCPA. * **Avoid Exposing Debug Information in Release Builds:** Disable or remove debug information in release builds. ### 4.5 Secure API Communication * **Use API Keys:** Use API keys to authenticate API requests. * **Implement Rate Limiting:** Implement rate limiting to prevent abuse of API endpoints. * **Use Input Validation:** Utilize robust input validation on APIs * **Use Secure Communication Protocols:** Use HTTPS for secure communication over the network. * **Validate API Responses:** Validate API responses to ensure data integrity. * **Log API Requests and Responses:** Log API requests and responses for auditing and monitoring. ## 5. Testing Approaches ### 5.1 Unit Testing * **Test Individual Components:** Write unit tests for individual components and classes. * **Use a Testing Framework:** Use a testing framework such as Unreal Engine's built-in Automation System or third-party frameworks. * **Write Clear and Concise Tests:** Write tests that are easy to understand and maintain. * **Test Edge Cases:** Test edge cases and boundary conditions. * **Use Mock Objects:** Use mock objects to isolate components during testing. * **Test Driven Development:** Consider using Test Driven Development (TDD) principles. * **Focus on Core Logic:** Prioritize testing core logic and critical functionalities. ### 5.2 Integration Testing * **Test Interactions Between Components:** Write integration tests to test the interactions between different components and classes. * **Test Game Logic:** Test the overall game logic and flow. * **Test Data Flow:** Test the flow of data between different systems. * **Simulate Realistic Scenarios:** Simulate realistic game scenarios during integration testing. ### 5.3 End-to-End Testing * **Test the Entire Game:** Test the entire game from start to finish. * **Use Automated Testing Tools:** Use automated testing tools to simulate player interactions. * **Test on Different Platforms:** Test on different platforms to ensure compatibility. * **Test with Real Players:** Test with real players to get feedback on gameplay and usability. ### 5.4 Test Organization * **Organize Tests by Feature:** Organize tests by game features or modules. * **Create a Test Suite:** Create a test suite that can be run automatically. * **Use a Consistent Naming Convention:** Use a consistent naming convention for tests. * **Document Tests:** Document tests to explain their purpose and functionality. * **Keep Tests Up-to-Date:** Keep tests up-to-date with code changes. ### 5.5 Mocking and Stubbing * **Use Mock Objects:** Use mock objects to simulate dependencies during testing. * **Use Stub Functions:** Use stub functions to replace complex or external functions. * **Isolate Components:** Isolate components during testing to avoid unintended interactions. * **Use a Mocking Framework:** Use a mocking framework such as Google Mock or EasyMock. ## 6. Common Pitfalls and Gotchas ### 6.1 Frequent Mistakes * **Incorrect Asset Management:** Failing to properly manage and reference assets. * **Over-Reliance on Blueprints:** Overusing Blueprints for complex logic, leading to performance issues. * **Ignoring Performance Considerations:** Neglecting to optimize code and assets for performance. * **Poor Memory Management:** Creating memory leaks and excessive garbage collection. * **Inadequate Error Handling:** Failing to handle errors and exceptions gracefully. * **Lack of Testing:** Not writing adequate unit and integration tests. * **Incorrect use of transform:** Using world transform directly, instead of relative transform for attached components. * **Not using the Garbage Collector Properly:** Not understanding when and how the Unreal Engine garbage collector reclaims memory. ### 6.2 Edge Cases * **Platform-Specific Issues:** Encountering platform-specific bugs or limitations. * **Device-Specific Issues:** Encountering device-specific performance issues. * **Localization Issues:** Encountering issues with text localization and internationalization. * **Save Game Corruption:** Dealing with corrupted save game data. * **Network Latency:** Handling network latency and packet loss in multiplayer games. ### 6.3 Version-Specific Issues * **API Changes:** Dealing with API changes between Unreal Engine versions. * **Deprecated Features:** Using deprecated features that may be removed in future versions. * **Compatibility Issues:** Encountering compatibility issues between different Unreal Engine versions. * **Shader Model Differences:** Accounting for differences in shader models across different UE versions. ### 6.4 Compatibility Concerns * **Plugin Compatibility:** Ensuring compatibility between different plugins. * **Hardware Compatibility:** Ensuring compatibility with different hardware configurations. * **Operating System Compatibility:** Ensuring compatibility with different operating systems. * **Third-Party Library Compatibility:** Ensuring compatibility with third-party libraries and SDKs. ### 6.5 Debugging Strategies * **Use the Unreal Engine Debugger:** Use the Unreal Engine debugger to step through code and inspect variables. * **Use Logging Statements:** Use logging statements to track the flow of execution and identify errors. * **Use Breakpoints:** Set breakpoints in the code to pause execution at specific points. * **Use the Visual Logger:** Use the Visual Logger to visualize game data and events. * **Use Unreal Insights:** Use Unreal Insights to profile performance and identify bottlenecks. * **Crash Reporting:** Implement crash reporting to collect crash logs and diagnose issues. ## 7. Tooling and Environment ### 7.1 Recommended Development Tools * **Visual Studio:** For C++ development on Windows. * **XCode:** For C++ development on macOS. * **Rider for Unreal Engine:** Cross-platform IDE for Unreal Engine development with C++ and Blueprints. * **Substance Painter:** For creating and texturing materials. * **Blender/Maya/3ds Max:** For creating 3D models and animations. * **Perforce/Git:** For version control. * **RenderDoc/PIX:** For GPU debugging and profiling. ### 7.2 Build Configuration * **Use Development Builds:** Use development builds for debugging and testing. * **Use Shipping Builds:** Use shipping builds for release. * **Configure Build Settings:** Configure build settings such as optimization level and debug information. * **Use Build Automation:** Use build automation tools to automate the build process. * **Set up Build Targets:** Properly configure build targets based on desired device platform (desktop, mobile, console, etc.) ### 7.3 Linting and Formatting * **Use a Code Linter:** Use a code linter to enforce code style and identify potential errors. * **Use a Code Formatter:** Use a code formatter to automatically format code. * **Follow the Unreal Engine Coding Standard:** Follow the Unreal Engine coding standard for consistency. * **Configure Editor Settings:** Configure editor settings to automatically format code on save. ### 7.4 Deployment * **Package the Game:** Package the game for the target platform. * **Test the Packaged Game:** Test the packaged game thoroughly before release. * **Use a Deployment Platform:** Use a deployment platform such as Steam or the Epic Games Store. * **Follow Platform-Specific Requirements:** Follow platform-specific requirements for deployment. ### 7.5 CI/CD Integration * **Use a CI/CD System:** Use a CI/CD system such as Jenkins, Travis CI, or GitLab CI. * **Automate Builds and Tests:** Automate builds and tests as part of the CI/CD pipeline. * **Integrate with Version Control:** Integrate the CI/CD system with the version control system. * **Automate Deployment:** Automate deployment to the target platform as part of the CI/CD pipeline. * **Trigger Builds on Code Changes:** Configure the CI/CD system to trigger builds automatically on code changes.