Use when writing acceptance criteria for a task - express each as an observable Given/When/Then that QA can execute, including negative cases
日本語の概要は準備中です。原文の説明を表示しています。
Use when writing Unreal Engine 5 C++ - the gameplay framework classes and where logic belongs, UObject/AActor/UActorComponent lifecycle, UPROPERTY/UFUNCTION and GC-safe pointers (TObjectPtr, TWeakObjectPtr), subsystems, the C++/Blueprint boundary, Enhanced Input, tick discipline, and compiling from the command line.
インストール方法を見るインストールする前に、エージェントに与えられる指示の中身を確認できます。
Unreal gives you a full gameplay framework, a reflection system and a garbage collector. Most bugs in Unreal C++ come from fighting them: raw UObject* members the GC frees underneath you, gameplay logic in constructors that only ever run on the class default object, logic on the wrong framework class (GameMode code running on clients), and everything ticking every frame.
Core principle: Put each piece of logic on the framework class that owns it, keep every UObject reference visible to the GC, and let C++ own systems while Blueprints own content and tuning.
| Class | Lives on | Owns |
|---|---|---|
AGameModeBase | Server only | Rules of the match: spawning, scoring rules, win conditions |
AGameStateBase | Server + replicated to all | Match state everyone sees (time left, team scores) |
APlayerController | Owning client + server | Input routing, UI ownership, camera for that player |
APlayerState | Replicated to all | Per-player persistent data (name, score); survives pawn death |
APawn / ACharacter | Replicated | The body: movement, the components that act in the world |
UActorComponent | With its actor | Reusable behaviour (health, inventory, interaction) |
UGameInstanceSubsystem / UWorldSubsystem / ULocalPlayerSubsystem | Process / world / local player | Services (save, matchmaking, spawning registries) — instead of singletons |
A client asking GetWorld()->GetAuthGameMode() gets nullptr — that is the design, not a bug to work around.
AHeroCharacter::AHeroCharacter() {
// Constructor: defaults and subobjects only. It runs for the class default object too,
// so no world access, no spawning, no gameplay.
PrimaryActorTick.bCanEverTick = false;
Health = CreateDefaultSubobject<UHealthComponent>(TEXT("Health"));
}
void AHeroCharacter::BeginPlay() {
Super::BeginPlay(); // always call Super
Health->OnDied.AddDynamic(this, &AHeroCharacter::HandleDied);
}
void AHeroCharacter::EndPlay(const EEndPlayReason::Type Reason) {
GetWorldTimerManager().ClearAllTimersForObject(this);
Super::EndPlay(Reason);
}
Order to remember: constructor → PostInitializeComponents → BeginPlay → Tick → EndPlay. Components: InitializeComponent (if bWantsInitializeComponent) → BeginPlay.
UCLASS()
class UInventoryComponent : public UActorComponent {
GENERATED_BODY()
public:
UFUNCTION(BlueprintCallable, Category = "Inventory")
bool TryAdd(const UItemDefinition* Item, int32 Count);
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnInventoryChanged, const UInventoryComponent*, Inventory);
UPROPERTY(BlueprintAssignable) FOnInventoryChanged OnChanged;
private:
// ❌ UItemDefinition* Cached; invisible to the GC: freed under you, then a crash
// ✅ visible to the GC, editor-tunable, null-safe
UPROPERTY(EditDefaultsOnly, Category = "Inventory", meta = (ClampMin = "1"))
int32 SlotCount = 20;
UPROPERTY(Transient) TArray<FInventorySlot> Slots;
UPROPERTY() TObjectPtr<const UItemDefinition> LastAdded;
TWeakObjectPtr<AActor> LastInteractor; // non-owning: check IsValid() before use
};
UObject* member is a UPROPERTY (TObjectPtr<T> for members in UE5), a TWeakObjectPtr, or a TStrongObjectPtr (from non-UObject code). Raw pointers only as locals and parameters.NewObject<T>(Outer), CreateDefaultSubobject (constructor only) or GetWorld()->SpawnActor — never new.IsValid(Ptr) before using anything that may have been destroyed (IsValid also catches "pending kill").EditDefaultsOnly for tuning on the Blueprint class, EditAnywhere only when level instances should differ, VisibleAnywhere for components.BlueprintCallable for actions, BlueprintPure for queries, BlueprintImplementableEvent / BlueprintNativeEvent for designer hooks. No gameplay rule that exists only in a Blueprint graph nobody can test.TSoftObjectPtr) so loading one class does not pull the whole content graph (game-asset-pipeline).void AHeroController::BeginPlay() {
Super::BeginPlay();
if (auto* Subsystem = ULocalPlayer::GetSubsystem<UEnhancedInputLocalPlayerSubsystem>(GetLocalPlayer())) {
Subsystem->AddMappingContext(DefaultContext, /*Priority*/ 0);
}
}
void AHeroCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent) {
auto* Input = CastChecked<UEnhancedInputComponent>(PlayerInputComponent);
Input->BindAction(MoveAction, ETriggerEvent::Triggered, this, &AHeroCharacter::Move);
Input->BindAction(JumpAction, ETriggerEvent::Started, this, &ACharacter::Jump);
}
void AHeroCharacter::Move(const FInputActionValue& Value) {
const FVector2D Axis = Value.Get<FVector2D>();
AddMovementInput(GetActorForwardVector(), Axis.Y);
AddMovementInput(GetActorRightVector(), Axis.X);
}
Input actions and mapping contexts are assets (data); the legacy BindAxis/BindAction string API is not used in new code.
PrimaryActorTick.bCanEverTick = false by default; enable only where per-frame work is needed, with SetActorTickInterval where 60 Hz is not needed.GetWorldTimerManager().SetTimer) and events instead of polling in Tick.TActorIterator, GetAllActorsOfClass or FindComponentByClass per frame — cache, or register with a subsystem.# macOS (Win64: Engine/Build/BatchFiles/Build.bat ... Win64; Linux: Engine/Build/BatchFiles/Linux/Build.sh ... Linux)
"<UE>/Engine/Build/BatchFiles/Mac/Build.sh" <Project>Editor Mac Development \
-Project="$PWD/<Project>.uproject" -WaitMutex > /tmp/tt-<task key>/build.log 2>&1; echo "exit=$?"
-unattended, an out-of-date module fails instead of prompting.<Module>.Build.cs (PublicDependencyModuleNames / PrivateDependencyModuleNames), e.g. EnhancedInput, GameplayAbilities.Binaries/, Intermediate/, Saved/, DerivedDataCache/; .uasset/.umap go through LFS (asset-hygiene).DEFINE_LOG_CATEGORY_STATIC(LogInventory, Log, All); UE_LOG(LogInventory, Warning, TEXT("..."));. check() for programmer errors that must crash in development; ensure() for recoverable ones.UObject* members without UPROPERTY.Super:: calls in overridden lifecycle functions.new UMyObject or new AMyActor anywhere.GetAllActorsOfClass inside Tick.Binaries/ or Intermediate/ in the diff.まだレビューはありません。使ってみた感想をお寄せください。
概要と使いどころ
Use when writing acceptance criteria for a task - express each as an observable Given/When/Then that QA can execute, including negative cases
日本語の概要は準備中です。原文の説明を表示しています。
Use when the diff adds or changes an endpoint, resolver, RPC, job or query that takes an object id, a role check, a request binding or a tenant filter - BOLA/IDOR, function-level authorization, mass assignment and tenant scoping
日本語の概要は準備中です。原文の説明を表示しています。
Use on every UI change - semantic HTML, labels for controls, keyboard-navigable dialogs/menus, visible focus, and never color as the only signal
日本語の概要は準備中です。原文の説明を表示しています。
Use when a task changes any screen, form, dialog, menu or control - Lighthouse/axe scan of the changed screens, a keyboard walk, and the thresholds that fail a task
日本語の概要は準備中です。原文の説明を表示しています。
How to work a task returned with review, QA or UAT findings. Use when a task is in need_revision or PR review comments are in your context.
日本語の概要は準備中です。原文の説明を表示しています。
Use when deciding whether a request needs an analiz task before implementation - the conditions that require the architect's analysis versus going straight to implementation
日本語の概要は準備中です。原文の説明を表示しています。