Notes of practices I noted. Needs some updates.
Resources
For Devs
- Setting up the workspace for the long run: Post - Video
- For version control:
- Use Perforce if possible
- if not, using Git efficiently for UE as a team: https://miltoncandelero.github.io/unreal-git
- or try https://github.com/ProjectBorealis/UEGitPlugin
- or have everyone install VS and compile automatically
- Use Perforce if possible
For new UE Devs
- Read the following:
- https://landelare.github.io/2023/01/07/cpp-speedrun.html
- Regarding what you can DO with Live coding: Link Imgur
- Common issues answered here, no need to read all before trying stuff: https://tackytortoise.github.io/2022/06/24/common-slacker-issues.html
- https://landelare.github.io/2023/01/07/cpp-speedrun.html
- Use
TObjectPtrinstead of raw ptrs for class members (UObjects only) for Engine 5.4 and above- More details here
Project setup
- Disable Widget Bindings (
Projet Preferences→Property Binding Rule)
Naming convention
-
Prefix all classes by the project/game codename (1-5 letters) (after the type prefix!), this help knowing what is from the engine and what’s from us.
- for example if the codename is
PG:AMyActorbecomesAPGMyActor - for example if the codename is
Kaos:AMyActorbecomesAKaosMyActor
- for example if the codename is
-
Delegates:
- Declaration of delegate ends with
Signature(e.g:F<CodeName>OnScoreChangedSignature) - Declaration of property delegate ends with
Delegate(e.g:FOnScoreChangedSignature OnScoreChangedDelegate) - Declaration of functions bonded to delegates ends with
Callback(e.g:void OnScoreChangedCallback(...))
- Declaration of delegate ends with
-
OnRep replicated variables:
OnRep_FullVariableName()→ CallOnFullVariableNameReplicatedOnFullVariableNameReplicated()
-
RPCs function:
DoSomething_ServerRPCDoSomething_ClientRPCDoSomething_MulticastRPC
-
Headers for specific content:
- For enums:
XXXEnum.h - For struct:
XXXStruct.h - For GameplayTags:
XXXGameplayTags.h
- For enums:
Folder Structure
- Define early how we split the source into folders, example:
- AI
- …
- Core
- GameMode
- Base
<ProjectCode>BaseGameModeclass- Components
<ProjectCode><SomeName>BaseGameModeComponentclass- …
- InGame
- …
- Lobby
- …
- Base
- GameState
<ProjectCode>GameStateclass- Components
<ProjectCode><SomeName>GameStateComponentclass- …
- GameMode
- Possessed
- Base
- BasePawn
<ProjectCode>BasePawnclass- Components
<ProjectCode><SomeName>BasePawnComponentclass- …
- BaseCharacter
<ProjectCode>BaseCharacterclass- Components
<ProjectCode><SomeName>BaseCharacterComponentclass- …
- BaseController
<ProjectCode>BaseControllerclass- Components
<ProjectCode><SomeName>BaseControllerComponentclass- …
- BasePawn
- Player
- PlayerCharacter
- Base
<ProjectCode>PlayerBaseCharacterclass ← Child of<ProjectCode>BaseCharacter- Components
<ProjectCode><SomeName>PlayerCharacterComponentclass- …
- PlayerCharacterType1
- …
- Base
- PlayerController
- Base
<ProjectCode>BasePlayerControllerclass- Components
<ProjectCode><SomeName>PlayerControllerComponentclass- …
- InGame
- …
- Lobby/MainMenu
- …
- Base
- PlayerCharacter
- AI
- Base
- AIPawn
<ProjectCode>AIBasePawnclass ← Child of<ProjectCode>BasePawn- Components
- …
- AICharacter
<ProjectCode>AIBaseCharacterclass ← Child of<ProjectCode>BaseCharacter- Components
- …
- AIController
<ProjectCode>BaseAIControllerclass ← Child of<ProjectCode>BaseController- Components
- …
- AIPawn
- Base
- Base
- UI
- HUD
- Base
<ProjectCode>HUDclass- Components
<ProjectCode><SomeName>HUDComponentclass- …
- InGame
- …
- Lobby/MainMenu
- …
- Base
- HUD
- Systems
- InventorySystem
- Data
- UI
- …
- EquipmentSystem
- …
- …
- InventorySystem
- GAS
- Abilities
- Effects
- Cues
- …
- Data
- Core
- AssetManager
- …
- Core
- Utility
- …
- Objects
- …
- WorldObjects
- …
- Structure the header and source file using
#pragma region SomeCategoryand/*-------[…]SomeSubCategory[…]-------*/to make navigation faster, and easy collapse/uncollapse example :
#pragma region Properties
protected:
/*----------------------------------------------------------------------------
Base job info
----------------------------------------------------------------------------*/
bool bJobIsFinished = false;
FGameplayTag CurrentJobGT;
/*----------------------------------------------------------------------------
Location
----------------------------------------------------------------------------*/
FGameplayTag CurrentJobLocationGT;
UPROPERTY(ReplicatedUsing=OnRep_JobLocationVolume)
AJobLocationVolume* CurrentJobLocationVolume = nullptr;
/* Job locations where the player can go into */
UPROPERTY(BlueprintReadOnly)
TArray<FGameplayTag> JobLocationsAccess;
#pragma endregion
#pragma region Defaults
public:
APGPlayerCoreCharacter(const FObjectInitializer& ObjectInitializer);
virtual void Tick(float DeltaTime) override;
protected:
virtual void PostInitializeComponents() override;
virtual void BeginPlay() override;
virtual void PossessedBy(AController* NewController) override;
virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;
#pragma endregion
#pragma region Interfaces
// Implemented interfaces methods
#pragma endregion
// Other needed categories ...Readability
- Design systems before writing code (using for example
excalidraw) - Comment functions, variable and logic inside functions bodies so any dev can understand the code at first glance.
- Comment if on server/client/local if not in the name (see RPC naming convetion)
- Make a variable
constif not meant to be modified
We work with and for designers
- Add Tooltips of exposed variables and events for designers
- Beware of the
Visiblespecifiers onUPROPERTYto avoid unexpected flooding - Usage of
IsDataValid()for BP compilation for sanity assurance - Use
Categoriesmeta specifier to help selection of GameplayTags - For any functions that needs to be exposed to designers, create a custom function:
- if its a class node:
- The function is prefixed with
K2_(ex:K2_GetSomeThing) - Set a specific display name for the function (ex: “Get Something”) to hide the prefix and make it more readable
- The function is prefixed with
- if its a custom K2 node, check
UK2Nodeclass
- if its a class node:
- Use
UDeveloperSettingsto make project-wide settings, easier to define and change than using an Actor/Data Asset/Components/… in most cases- Example of a Inventory System Settings:

- Example of a Inventory System Settings:
VCS
- Ideally use perforce for BP and asset locking and safety
- Perforce training: https://training.perforce.com/learn
- Commit per feature change and not a bunch
Code checks
- Use asserts to check conditions that should never happen.
Miscs
- Collisions Management
- Have a authorative documentation for collision channels and profiles (Example)
- Always use profiles
For Designers
Naming convention (Asset & blueprint prefixs)
See also Official Docs and Unreal Directive
-
Blueprints (prefix ends with
BP_):-
Actor:
ABP_ -
Actor Component:
ACBP_ -
Scene Component:
SCBP_ -
Pawn:
PBP_ -
Character:
CBP_ -
Game Instance:
GIBP_ -
Game Mode:
GMBP_ -
Game State:
GSBP_ -
Player State:
PSBP_ -
Player Controller:
PCBP_ -
HUD:
HUDBP_ -
Widget:
WBP_ -
Gameplay Abilities:
GABP_ -
Gameplay Effects:
GEBP_ -
Gameplay Cues:
GCBP_
-
-
Other Assets:
-
Level:
L_ -
Static mesh:
SM_ -
Material:
M_ -
Material Instance:
MI_ -
Input Mapping Context:
IMC_ -
Input Action:
IA_ -
Data assets:
DA_
-
Readability
- Comment nodes and groups of nodes so anyone can understand the code at first glance
For Designers and devs
Naming convention
- Define early how we structure the editor folders (the structure has a lot of similarities with the source code structure):
- Content
<ProjectName>- Game
- Core
- …
- Possessed
- …
- Systems
- …
- UI
- …
- Assets
- …
- …
- Core
- Levels
- …
- Game
- Content
Misc
- Set an empty level as the startup map to gain in iteration when launching the project.