Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Write Unreal Engine 5 C++ gameplay code: the UCLASS/UPROPERTY/UFUNCTION reflection macros, the Gameplay Framework (GameMode, Pawn, Character, PlayerController, Actor components), and the module Build.cs. Use when writing or debugging UE C++, deriving from AActor/ACharacter/ AGameModeBase, exposing properties to the editor or Blueprints, or when the user mentions Unreal C++, UCLASS, GENERATED_BODY, GameMode, ACharacter, or .Build.cs.
.claude/skills/gamedev-skills-unreal-cpp-gameplay/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-03 | ✓→✗ | ▼ Worse | 73% | 0% |
| case-11 | ✓→✗ | ▼ Worse | 40% | 0% |
| case-01 | ✓→✓ | = Same ✓ | 45% | 0% |
| case-04 | ✓→✓ | = Same ✓ | 72% | 0% |
| case-05 | ✓→✓ | = Same ✓ | 100% | 0% |
Write correct UE5 gameplay C++: the reflection macros that connect C++ to the editor and Blueprints, the Gameplay Framework class roles, and module dependencies. Targets UE 5.8.
AActor, APawn, ACharacter, AGameModeBase,UActorComponent), exposing properties/functions with UPROPERTY/UFUNCTION, setting up a GameMode's default classes, or adding a module dependency in *.Build.cs.
Source/ tree with *.h/*.cpp using UCLASS, and *.Build.cs.When not to use: designer-facing visual logic → unreal-blueprints. Player input binding details → unreal-enhanced-input. AI logic → unreal-behavior-trees. This skill owns the C++ class/reflection foundation those build on.
A = Actor-derived, U = UObject/component-derived,F = plain struct, E = enum, I = interface. The prefix must match the base class.
UCLASS() above the class, GENERATED_BODY()as the first line in the body, and #include "ClassName.generated.h" as the last include in the header.
UPROPERTY (editor/Blueprint visibility and garbage-collectiontracking) and behaviour with UFUNCTION (BlueprintCallable, etc.).
CreateDefaultSubobject<T>(TEXT("Name")) andset the RootComponent.
AGameModeBase sets the rules + default classes; APawn/ACharacter is the controllable body; APlayerController is the player's will; UActorComponent is reusable behaviour.
*.Build.cs (e.g. EnhancedInput) or unresolved-symbollink errors follow.
Ctrl+Alt+F11 for function bodies; full rebuild forheader/UPROPERTY changes) and checking the class/properties appear in the editor.
cpp// Pickup.h #pragma once #include "CoreMinimal.h" #include "GameFramework/Actor.h" #include "Pickup.generated.h" // MUST be the last include UCLASS() class MYGAME_API APickup : public AActor // MYGAME_API = your module's export macro { GENERATED_BODY() public: APickup(); // EditAnywhere = tweak per-instance & on the CDO; BlueprintReadWrite = BP get/set. UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Pickup") int32 ScoreValue = 10; // UPROPERTY on a UObject* pointer is what keeps it from being garbage-collected. UPROPERTY(VisibleAnywhere) TObjectPtr<UStaticMeshComponent> Mesh; // UE5: TObjectPtr instead of raw UStaticMeshComponent* UFUNCTION(BlueprintCallable, Category = "Pickup") void Collect(); protected: virtual void BeginPlay() override; };
cpp// Pickup.cpp #include "Pickup.h" #include "Components/StaticMeshComponent.h" APickup::APickup() { Mesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("Mesh")); RootComponent = Mesh; // the mesh is this actor's root } void APickup::BeginPlay() { Super::BeginPlay(); } // always call Super void APickup::Collect() { Destroy(); }
cpp// MyGameMode.cpp — set in the constructor so the engine spawns your classes. AMyGameMode::AMyGameMode() { DefaultPawnClass = AMyCharacter::StaticClass(); PlayerControllerClass = AMyPlayerController::StaticClass(); }
csharp// MyGame.Build.cs PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore", "EnhancedInput" });
generated.h not last / missing — compile errors like "Cannot find generated header" or"Expected an include". It must be the final include in the header.
GENERATED_BODY() — UHT (Unreal Header Tool) errors; it must be the firstthing inside the class body.
UObject* without UPROPERTY — the garbage collector doesn't see it and may destroyit out from under you. Track every UObject pointer with UPROPERTY (use TObjectPtr in UE5).
changes to UCLASS/UPROPERTY/headers need a full editor restart + rebuild.
UFoo (or a component AFoo) breaks UHT; match theprefix to the base type.
Build.csPublicDependencyModuleNames.
Super:: in overridden BeginPlay/Tick/etc. skips engine setup.UActorComponent creation/attachment, the UPROPERTY garbage-collection ownership rules(TObjectPtr, TArray<TObjectPtr<>>, AddToRoot), and a replication primer, read references/components-and-gc.md.
(https://dev.epicgames.com/documentation/en-us/unreal-engine/gameplay-framework-in-unreal-engine).
unreal-blueprints — exposing C++ to designers; BP/C++ interop.unreal-enhanced-input — binding input in a C++ Pawn/Character.unreal-behavior-trees — C++ AI tasks driven from a behaviour tree.| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-01 | pass→pass | 20,577 | 18,819 | -9% | 1 | 1 | 0% | 2,777 | 4,015 | +45% | 0 | 0 | — |
case-02 | fail→fail | 19,224 | 22,535 | +17% | 1 | 1 | 0% | 2,377 | 4,675 | +97% | 0 | 0 | — |
case-03 | pass→fail | 21,834 | 22,352 | +2% | 1 | 1 | 0% | 2,826 | 4,878 | +73% | 0 | 0 | — |
case-04 | pass→pass | 14,313 | 5,508 | -62% | 1 | 1 | 0% | 1,474 | 2,538 | +72% | 0 | 0 | — |
case-05 | pass→pass | 11,589 | 5,325 | -54% | 1 | 1 | 0% | 1,238 | 2,480 | +100% | 0 | 0 | — |
case-06 | pass→pass | 14,385 | 12,526 | -13% | 1 | 1 | 0% | 1,731 | 2,998 | +73% | 0 | 0 | — |
case-07 | pass→pass | 16,511 | 15,313 | -7% | 1 | 1 | 0% | 2,038 | 3,367 | +65% | 0 | 0 | — |
case-08 | pass→pass | 14,666 | 7,250 | -51% | 1 | 1 | 0% | 1,667 | 2,787 | +67% | 0 | 0 | — |
case-09 | fail→fail | 16,301 | 13,874 | -15% | 1 | 1 | 0% | 1,946 | 3,120 | +60% | 0 | 0 | — |
case-10 | pass→pass | 10,216 | 11,716 | +15% | 1 | 1 | 0% | 1,832 | 2,558 | +40% | 0 | 0 | — |
case-11 | pass→fail | 16,643 | 16,978 | +2% | 1 | 1 | 0% | 1,852 | 2,599 | +40% | 0 | 0 | — |
case-16 | pass→pass | 16,300 | 10,767 | -34% | 1 | 1 | 0% | 2,152 | 3,446 | +60% | 0 | 0 | — |
case-12 | pass→pass | 15,595 | 13,232 | -15% | 1 | 1 | 0% | 1,754 | 2,888 | +65% | 0 | 0 | — |
case-13 | pass→pass | 12,996 | 9,702 | -25% | 1 | 1 | 0% | 1,561 | 2,398 | +54% | 0 | 0 | — |
case-14 | pass→pass | 15,034 | 6,432 | -57% | 1 | 1 | 0% | 1,525 | 2,703 | +77% | 0 | 0 | — |
case-15 | pass→pass | 16,102 | 17,256 | +7% | 1 | 1 | 0% | 1,937 | 3,615 | +87% | 0 | 0 | — |
case-17 | pass→pass | 19,721 | 12,845 | -35% | 1 | 1 | 0% | 3,088 | 4,237 | +37% | 0 | 0 | — |
case-18 | pass→pass | 17,358 | 14,245 | -18% | 1 | 1 | 0% | 2,114 | 3,111 | +47% | 0 | 0 | — |
case-19 | pass→pass | 10,868 | 8,500 | -22% | 1 | 1 | 0% | 1,095 | 2,149 | +96% | 0 | 0 | — |
case-20 | pass→pass | 12,982 | 10,730 | -17% | 1 | 1 | 0% | 1,481 | 2,549 | +72% | 0 | 0 | — |
case-21 | pass→pass | 13,178 | 7,927 | -40% | 1 | 1 | 0% | 1,453 | 2,677 | +84% | 0 | 0 | — |
case-22 | pass→pass | 11,802 | 4,581 | -61% | 1 | 1 | 0% | 1,075 | 2,380 | +121% | 0 | 0 | — |
case-23 | pass→pass | 13,145 | 7,345 | -44% | 1 | 1 | 0% | 1,646 | 2,867 | +74% | 0 | 0 | — |
case-24 | pass→pass | 10,065 | 11,458 | +14% | 1 | 1 | 0% | 1,708 | 2,751 | +61% | 0 | 0 | — |
case-25 | pass→pass | 14,871 | 11,597 | -22% | 1 | 1 | 0% | 1,692 | 2,657 | +57% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 25 cases were attempted. The headline lift of -50 percentage points is the difference between those two pass rates over the 25 comparable cases. 2 cases got worse with the skill loaded, and they are included in that figure.
Other measured skills in the registry, with their headline benchmark lift.