Notes of practices I noted.

Resources

For Devs

For new UE Devs

Project setup

  • Disable Widget Bindings (Projet PreferencesProperty 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: AMyActor becomes APGMyActor
    • for example if the codename is Kaos: AMyActor becomes AKaosMyActor
  • 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(...))
  • OnRep replicated variables:

    • OnRep_FullVariableName() Call OnFullVariableNameReplicated
    • OnFullVariableNameReplicated()
  • RPCs function:

    • DoSomething_ServerRPC
    • DoSomething_ClientRPC
    • DoSomething_MulticastRPC
  • Headers for specific content:

    • For enums: XXXEnum.h
    • For struct: XXXStruct.h
    • For GameplayTags: XXXGameplayTags.h

Folder Structure

  • Define early how we split the source into folders, example:

  • AI
  • Core
    • GameMode
      • Base
        • <ProjectCode>BaseGameMode class
        • Components
          • <ProjectCode><SomeName>BaseGameModeComponent class
      • InGame
      • Lobby
    • GameState
      • <ProjectCode>GameState class
      • Components
        • <ProjectCode><SomeName>GameStateComponent class
  • Possessed
    • Base
      • BasePawn
        • <ProjectCode>BasePawn class
        • Components
          • <ProjectCode><SomeName>BasePawnComponent class
      • BaseCharacter
        • <ProjectCode>BaseCharacter class
        • Components
          • <ProjectCode><SomeName>BaseCharacterComponent class
      • BaseController
        • <ProjectCode>BaseController class
        • Components
          • <ProjectCode><SomeName>BaseControllerComponent class
    • Player
      • PlayerCharacter
        • Base
          • <ProjectCode>PlayerBaseCharacter class Child of <ProjectCode>BaseCharacter
          • Components
            • <ProjectCode><SomeName>PlayerCharacterComponent class
        • PlayerCharacterType1
      • PlayerController
        • Base
          • <ProjectCode>BasePlayerController class
          • Components
            • <ProjectCode><SomeName>PlayerControllerComponent class
        • InGame
        • Lobby/MainMenu
    • AI
      • Base
        • AIPawn
          • <ProjectCode>AIBasePawn class Child of <ProjectCode>BasePawn
          • Components
        • AICharacter
          • <ProjectCode>AIBaseCharacter class Child of <ProjectCode>BaseCharacter
          • Components
        • AIController
          • <ProjectCode>BaseAIController class Child of <ProjectCode>BaseController
          • Components
  • UI
    • HUD
      • Base
        • <ProjectCode>HUD class
        • Components
          • <ProjectCode><SomeName>HUDComponent class
      • InGame
      • Lobby/MainMenu
  • Systems
    • InventorySystem
      • Data
      • UI
    • EquipmentSystem
  • GAS
    • Abilities
    • Effects
    • Cues
  • Data
    • Core
      • AssetManager
  • Utility
  • Objects
  • WorldObjects

  • Structure the header and source file using #pragma region SomeCategory and /*-------[…]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 const if not meant to be modified

We work with and for designers

  • Add Tooltips of exposed variables and events for designers
  • Beware of the Visible specifiers on UPROPERTY to avoid unexpected flooding
  • Usage of IsDataValid() for BP compilation for sanity assurance
  • Use Categories meta 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
    • if its a custom K2 node, check UK2Node class
  • Use UDeveloperSettings to 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:

VCS

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)

  • 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
        • Levels

Misc

  • Set an empty level as the startup map to gain in iteration when launching the project.