Engineering Notes

Quick-reference bullets derived from project work. Class names, patterns, and gotchas that come up repeatedly in Unreal Engine C++ development.

Gameplay Ability System

  • UAbilitySystemComponent must be initialized on both server and client via InitAbilityActorInfo
  • UGameplayEffect is a data-only class - never override business logic in it
  • FGameplayAttributeData requires both Base and Current values for replication to work
  • Tag-based activation is safer than class-based when multiple abilities share logic
  • GE duration of 0 = Instant, -1 = Infinite; HasDuration requires manual cancellation

Lyra Architecture

  • ULyraExperienceDefinition drives pawn data, ability sets, and component lists per map
  • ULyraHeroComponent handles pawn extension and defers setup until experience is loaded
  • Ability sets are granted via FLyraAbilitySet_GrantedHandles - store to revoke later
  • Input tag bindings in ULyraInputConfig map InputActions → GameplayTags for GAS
  • B_Hero_ShooterMannequin is the canonical pawn reference in Lyra shooter content

Editor Tooling (FEdMode)

  • Override HandleClick() in FEdMode to intercept viewport click events
  • Custom toolkits provide the left-side panel via SWidget returned in MakeWidget()
  • FEditorModeTools::ActivateMode() must be called from the editor module, not runtime
  • Always deregister editor mode handles in ShutdownModule to avoid editor crashes
  • IDetailsView can be embedded in a custom Slate panel for property editing

Multiplayer & Replication

  • UFUNCTION(Server) requires _Implementation and _Validate suffixes
  • GetLifetimeReplicatedProps must call Super and list all UPROPERTY(Replicated) vars
  • bReplicates = true in constructor; call SetReplicates(true) for dynamically spawned actors
  • Server authority: check HasAuthority() before mutating gameplay state
  • OnRep_ functions fire on clients but NOT on the server - guard design accordingly

CommonUI

  • UCommonActivatableWidget manages focus and input pass-through - override NativeActivated()
  • UCommonUISubsystem handles root navigation layer and push/pop stack operations
  • Input routing: set InputConfig on each widget to declare which inputs it consumes
  • Activatable widgets require a UCommonActivatableWidgetContainerBase as their parent
  • Always call DeactivateWidget() before garbage-collecting activatable instances

Derived from Projects