/ue-gameplay-framework
Use this skill when working with Unreal Engine's gameplay framework classes: GameMode, GameState, PlayerController, PlayerState, Pawn, Character, or GameInstance. Also use when the user mentions 'gameplay framework', 'game rules', 'player management', 'match flow', or 'player
$ npx -y skills add quodsoler/unreal-engine-skills --skill ue-gameplay-framework --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
- You can call itInvoke it directly when you want it.
- Slash command
/ue-gameplay-framework
Context preview
The summary Claude sees to decide when to auto-load this skill.
Use this skill when working with Unreal Engine's gameplay framework classes: GameMode, GameState, PlayerController, PlayerState, Pawn, Character, or GameInstance. Also use when the user mentions 'gameplay framework', 'game rules', 'player management', 'match flow', or 'player
SKILL.md
ue-gameplay-framework.SKILL.mdname: ue-gameplay-framework
description: "Use this skill when working with Unreal Engine's gameplay framework classes: GameMode, GameState, PlayerController, PlayerState, Pawn, Character, or GameInstance. Also use when the user mentions 'gameplay framework', 'game rules', 'player management', 'match flow', or 'player spawning'. See references/framework-class-map.md for the full authority/presence matrix. For networking/replication, see ue-networking-replication. For input setup, see ue-input-system."
metadata:
version: 1.0.0
UE Gameplay Framework
You are an expert in Unreal Engine's gameplay framework architecture.
Context Check
Read `.agents/ue-project-context.md` before proceeding. The game type (single player, co-op, competitive multiplayer, dedicated vs listen server) determines which classes to subclass and which replication patterns apply. Resolve: single-player or multiplayer? Dedicated or listen server? What are you implementing?
---
Class Responsibility Map
Each class exists on specific machines for specific reasons. Getting this wrong is the primary source of multiplayer bugs.
AGameModeBase / AGameMode — Server Only
**Exists on:** Server and standalone only. Never instantiated on clients.
**Why server-only:** GameMode is the authoritative referee. It decides who joins, when the match starts, where players spawn, and what the win conditions are. Client execution would allow cheating via local state manipulation.
**AGameMode adds** the full match-state machine (`EnteringMap` → `WaitingToStart` → `InProgress` → `WaitingPostMatch` → `LeavingMap`; `Aborted` on failure) with `ReadyToStartMatch` and `ReadyToEndMatch` hooks. Use `AGameModeBase` for lobby/simple games, `AGameMode` for match flow.
**Key API from source (GameModeBase.h):**
// Class assignments — set in constructor
TSubclassOf<APawn> DefaultPawnClass;
TSubclassOf<AGameStateBase> GameStateClass;
TSubclassOf<APlayerController> PlayerControllerClass;
TSubclassOf<APlayerState> PlayerStateClass;
TSubclassOf<AHUD> HUDClass;
uint32 bUseSeamlessTravel : 1;
// Server startup and player join lifecycle (server only)
virtual void InitGame(const FString& MapName, const FString& Options, FString& ErrorMessage);
virtual void PreLogin(const FString& Options, const FString& Address,
const FUniqueNetIdRepl& UniqueId, FString& ErrorMessage);
virtual APlayerController* Login(UPlayer* NewPlayer, ENetRole InRemoteRole,
const FString& Portal, const FString& Options,
const FUniqueNetIdRepl& UniqueId, FString& ErrorMessage);
virtual void PostLogin(APlayerController* NewPlayer); // first safe point for RPCs (DispatchPostLogin deprecated 5.6 — override PostLogin directly)
virtual void Logout(AController* Exiting);
virtual void HandleStartingNewPlayer(APlayerController* NewPlayer);
// Spawn pipeline
virtual AActor* FindPlayerStart(AController* Player, const FString& IncomingName = TEXT(""));
virtual void RestartPlayer(AController* NewPlayer);
virtual APawn* SpawnDefaultPawnFor(AController* NewPlayer, AActor* StartSpot);
// Travel
virtual void ProcessServerTravel(const FString& URL, bool bAbsolute = false);
virtual void GetSeamlessTravelActorList(bool bToTransition, TArray<AActor*>& ActorList);---
AGameStateBase / AGameState — Server + All Clients
**Exists on:** Everywhere. Fully replicated.
**Why everywhere:** Clients cannot read GameMode (it does not exist on them). Any global data clients need — scores, match timer, phase — belongs in GameState. `PlayerArray` exposes all connected `APlayerState` instances to every machine.
**Key API from source (GameStateBase.h):**
// All PlayerStates, always replicated
UPROPERTY(Transient, BlueprintReadOnly)
TArray<TObjectPtr<APlayerState>> PlayerArray;
// The GameMode class (not instance) replicated to clients
UPROPERTY(Transient, BlueprintReadOnly, ReplicatedUsing=OnRep_GameModeClass)
TSubclassOf<AGameModeBase> GameModeClass;
// Server-authoritative clock, automatically synced
virtual double GetServerWorldTimeSeconds() const;
virtual bool HasBegunPlay() const;
virtual bool HasMatchStarted() const;
virtual bool HasMatchEnded() const;
**Custom replicated match data:**
UCLASS()
class AMyGameState : public AGameStateBase
{
GENERATED_BODY()
public:
UPROPERTY(Replicated, BlueprintReadOnly) int32 TeamAScore;
UPROPERTY(Replicated, BlueprintReadOnly) int32 TeamBScore;
UPROPERTY(ReplicatedUsing=OnRep_MatchTimer) float MatchTimeRemaining;
virtual void GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const override;
};
void AMyGameState::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const
{
Super::GetLifetimeReplicatedProps(OutLifetimeProps);
DOREPLIFETIME(AMyGameState, TeamAScore);
DOREPLIFETIME(AMyGameState, TeamBScore);
DOREPLIFETIME(AMyGameState, MatchTimeRemaining);
}---
APlayerController — Server (all) + Owning Client (own only)
**Exists on:** Server holds one per connected player. Each client holds only its own. Remote clients do not see other players' PlayerControllers.
**Why this split:** The PlayerController bridges one human to the server. Both ends run it for client-side prediction and server validation. A client has no reason to know another player's input state.
**Key API from source (PlayerController.h):**
TObjectPtr<APlayerCameraManager> PlayerCameraManager; // camera, local only
TObjectPtr<APawn> AcknowledgedPawn; // server-confirmed possession
TObjectPtr<AHUD> MyHUD; // local only
uint32 bShowMouseCursor : 1;
uint32 bEnableStreamingSource : 1; // drives World Partition loading for this viewport
void SetInputMode(const FInputModeDataBase& InData); // FInputModeGameOnly, UIOnly, GameAndUI
virtual void PlayerTick(float DeltaTime); // only ticked locally
virtual void SetupInputComp
Read more
name: ue-gameplay-framework description: "Use this skill when working with Unreal Engine's gameplay framework classes: GameMode, GameState, PlayerController, PlayerState, Pawn, Character, or GameInstance. Also use when the user mentions 'gameplay framework', 'game rules', 'player management', 'match flow', or 'player spawning'. See references/framework-class-map.md for the full authority/presence matrix. For networking/replication, see ue-networking-replication. For input setup, see ue-input-system." metadata: version: 1.0.0
UE Gameplay Framework
You are an expert in Unreal Engine's gameplay framework architecture.
Context Check
Read `.agents/ue-project-context.md` before proceeding. The game type (single player, co-op, competitive multiplayer, dedicated vs listen server) determines which classes to subclass and which replication patterns apply. Resolve: single-player or multiplayer? Dedicated or listen server? What are you implementing?
---
Class Responsibility Map
Each class exists on specific machines for specific reasons. Getting this wrong is the primary source of multiplayer bugs.
AGameModeBase / AGameMode — Server Only
**Exists on:** Server and standalone only. Never instantiated on clients.
**Why server-only:** GameMode is the authoritative referee. It decides who joins, when the match starts, where players spawn, and what the win conditions are. Client execution would allow cheating via local state manipulation.
**AGameMode adds** the full match-state machine (`EnteringMap` → `WaitingToStart` → `InProgress` → `WaitingPostMatch` → `LeavingMap`; `Aborted` on failure) with `ReadyToStartMatch` and `ReadyToEndMatch` hooks. Use `AGameModeBase` for lobby/simple games, `AGameMode` for match flow.
**Key API from source (GameModeBase.h):**
// Class assignments — set in constructor
TSubclassOf<APawn> DefaultPawnClass;
TSubclassOf<AGameStateBase> GameStateClass;
TSubclassOf<APlayerController> PlayerControllerClass;
TSubclassOf<APlayerState> PlayerStateClass;
TSubclassOf<AHUD> HUDClass;
uint32 bUseSeamlessTravel : 1;
// Server startup and player join lifecycle (server only)
virtual void InitGame(const FString& MapName, const FString& Options, FString& ErrorMessage);
virtual void PreLogin(const FString& Options, const FString& Address,
const FUniqueNetIdRepl& UniqueId, FString& ErrorMessage);
virtual APlayerController* Login(UPlayer* NewPlayer, ENetRole InRemoteRole,
const FString& Portal, const FString& Options,
const FUniqueNetIdRepl& UniqueId, FString& ErrorMessage);
virtual void PostLogin(APlayerController* NewPlayer); // first safe point for RPCs (DispatchPostLogin deprecated 5.6 — override PostLogin directly)
virtual void Logout(AController* Exiting);
virtual void HandleStartingNewPlayer(APlayerController* NewPlayer);
// Spawn pipeline
virtual AActor* FindPlayerStart(AController* Player, const FString& IncomingName = TEXT(""));
virtual void RestartPlayer(AController* NewPlayer);
virtual APawn* SpawnDefaultPawnFor(AController* NewPlayer, AActor* StartSpot);
// Travel
virtual void ProcessServerTravel(const FString& URL, bool bAbsolute = false);
virtual void GetSeamlessTravelActorList(bool bToTransition, TArray<AActor*>& ActorList);---
AGameStateBase / AGameState — Server + All Clients
**Exists on:** Everywhere. Fully replicated.
**Why everywhere:** Clients cannot read GameMode (it does not exist on them). Any global data clients need — scores, match timer, phase — belongs in GameState. `PlayerArray` exposes all connected `APlayerState` instances to every machine.
**Key API from source (GameStateBase.h):**
// All PlayerStates, always replicated UPROPERTY(Transient, BlueprintReadOnly) TArray<TObjectPtr<APlayerState>> PlayerArray; // The GameMode class (not instance) replicated to clients UPROPERTY(Transient, BlueprintReadOnly, ReplicatedUsing=OnRep_GameModeClass) TSubclassOf<AGameModeBase> GameModeClass; // Server-authoritative clock, automatically synced virtual double GetServerWorldTimeSeconds() const; virtual bool HasBegunPlay() const; virtual bool HasMatchStarted() const; virtual bool HasMatchEnded() const;
**Custom replicated match data:**
UCLASS()
class AMyGameState : public AGameStateBase
{
GENERATED_BODY()
public:
UPROPERTY(Replicated, BlueprintReadOnly) int32 TeamAScore;
UPROPERTY(Replicated, BlueprintReadOnly) int32 TeamBScore;
UPROPERTY(ReplicatedUsing=OnRep_MatchTimer) float MatchTimeRemaining;
virtual void GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const override;
};
void AMyGameState::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const
{
Super::GetLifetimeReplicatedProps(OutLifetimeProps);
DOREPLIFETIME(AMyGameState, TeamAScore);
DOREPLIFETIME(AMyGameState, TeamBScore);
DOREPLIFETIME(AMyGameState, MatchTimeRemaining);
}---
APlayerController — Server (all) + Owning Client (own only)
**Exists on:** Server holds one per connected player. Each client holds only its own. Remote clients do not see other players' PlayerControllers.
**Why this split:** The PlayerController bridges one human to the server. Both ends run it for client-side prediction and server validation. A client has no reason to know another player's input state.
**Key API from source (PlayerController.h):**
TObjectPtr<APlayerCameraManager> PlayerCameraManager; // camera, local only TObjectPtr<APawn> AcknowledgedPawn; // server-confirmed possession TObjectPtr<AHUD> MyHUD; // local only uint32 bShowMouseCursor : 1; uint32 bEnableStreamingSource : 1; // drives World Partition loading for this viewport void SetInputMode(const FInputModeDataBase& InData); // FInputModeGameOnly, UIOnly, GameAndUI virtual void PlayerTick(float DeltaTime); // only ticked locally virtual void SetupInputComp
A collection of 27 AI agent skills for Unreal Engine C++ development. Built for game developers who want AI coding agents to help write correct, production-quality UE5 C++ code.
Other skills on unreal-engine-skills.
- /ue-actor-component-architecture
Use this skill when working with Actor and component design in Unreal Engine. Triggers on: Actor, component, BeginPlay, Tick, SpawnActor, lifecycle, CreateDefaultSubobject, composition, EndPlay, PostInitializeComponents, UActorComponent, USceneComponent, UINTERFACE, attachment,
Open skill - /ue-ai-navigation
Use this skill when implementing AI, AIController, behavior tree, blackboard, AI perception, NavMesh, EQS, navigation, pathfinding, State Tree, or Smart Objects in Unreal Engine. See references/behavior-tree-patterns.md for BT patterns and references/eqs-reference.md for EQS
Open skill - /ue-animation-system
Use this skill when working with Unreal Engine animation: AnimInstance, montage playback, blend space, state machine, anim notify, IK, AnimGraph, skeletal mesh, or linked anim graphs. See references/anim-notify-reference.md for notify patterns and references/locomotion-setup.md
Open skill - /ue-async-threading
Use this skill when working with Unreal Engine async operations, threading, parallel execution, or concurrency. Also use when the user mentions 'FRunnable', 'FAsyncTask', 'TaskGraph', 'UE::Tasks', 'ParallelFor', 'TFuture', 'TPromise', 'Async()', 'thread safety',
Open skill - /ue-audio-system
Use this skill when working with audio, sound, music, UAudioComponent, PlaySoundAtLocation, SoundCue, MetaSound, attenuation, submix, concurrency, SFX, or spatial audio in Unreal Engine. See references/audio-setup-patterns.md for music system and ambient soundscape
Open skill - /ue-character-movement
Use this skill when working with character movement, CharacterMovementComponent, CMC, movement modes, walking, falling, swimming, flying, custom movement, network prediction, FSavedMove, root motion, floor detection, step-up, or character physics. Also use for 'PhysWalking',
Open skill

