# Unreal Build

> Unreal Engine 5 build system, testing framework, and CI/CD patterns

- Skill: `randroids-dojo/unreal-build` (Agent Skill)
- Install (CLI): `npx skillmds@latest add randroids-dojo/unreal-build`
- Raw SKILL.md: https://api.skillmd.com/api/skills/randroids-dojo/unreal-build/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: DevOps & Infra
- Author: randroids-dojo (https://skillmd.com/u/randroids-dojo)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/randroids-dojo/unreal-build

---


## Build System

### Module Setup (Build.cs)

```csharp
// Source/UnrealFrog/UnrealFrog.Build.cs
using UnrealBuildTool;

public class UnrealFrog : ModuleRules
{
    public UnrealFrog(ReadOnlyTargetRules Target) : base(Target)
    {
        PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs;
        PublicDependencyModuleNames.AddRange(new string[] {
            "Core", "CoreUObject", "Engine", "InputCore",
            "EnhancedInput", "UMG"
        });
    }
}
```

### Target Files

- `UnrealFrog.Target.cs` — Game target (shipping build)
- `UnrealFrogEditor.Target.cs` — Editor target (development)

## Testing Framework

### Automation Tests

```cpp
#include "Misc/AutomationTest.h"

// Simple unit test
IMPLEMENT_SIMPLE_AUTOMATION_TEST(
    FScoreSystemTest,
    "UnrealFrog.Gameplay.ScoreSystem",
    EAutomationTestFlags::ApplicationContextMask | EAutomationTestFlags::ProductFilter
)

bool FScoreSystemTest::RunTest(const FString& Parameters)
{
    // Arrange
    UScoreSubsystem* Score = NewObject<UScoreSubsystem>();

    // Act
    Score->AddPoints(100);

    // Assert
    TestEqual("Score should be 100", Score->GetCurrentScore(), 100);
    return true;
}
```

### Functional Tests (In-Game)

```cpp
// AFroggerFunctionalTest inherits from AFunctionalTest
// Place in test maps, run via automation framework
UCLASS()
class AFrogHopTest : public AFunctionalTest
{
    GENERATED_BODY()
public:
    virtual void StartTest() override;
    virtual void Tick(float DeltaTime) override;
};
```

### Running Tests

```bash
# Run all project tests
UnrealEditor-Cmd UnrealFrog.uproject -ExecCmds="Automation RunTests UnrealFrog" -NullRHI -NoSound

# Run specific test group
UnrealEditor-Cmd UnrealFrog.uproject -ExecCmds="Automation RunTests UnrealFrog.Gameplay"

# Run with Gauntlet (CI-friendly)
RunUAT.bat RunUnrealTests -project=UnrealFrog.uproject -test=UnrealFrog
```

## Asset Validation

### Data Validation Plugin

Enable `DataValidation` plugin. Create validators:

```cpp
UCLASS()
class UAssetNamingValidator : public UEditorValidatorBase
{
    GENERATED_BODY()
public:
    virtual EDataValidationResult IsValid(TArray<FText>& ValidationErrors) override;
};
```

### Naming Convention Checks

| Asset Type | Prefix | Example |
|-----------|--------|---------|
| Static Mesh | SM_ | SM_Frog |
| Skeletal Mesh | SK_ | SK_FrogAnimated |
| Material | M_ | M_Road |
| Material Instance | MI_ | MI_Road_Wet |
| Texture | T_ | T_Frog_Albedo |
| Sound Wave | SW_ | SW_Hop |
| Sound Cue | SC_ | SC_HopWithVariation |
| Blueprint | BP_ | BP_FrogCharacter |
| Widget Blueprint | WBP_ | WBP_HUD |
| Level | LVL_ | LVL_MainGame |

## Python Editor Scripting

```python
import unreal

# Import an asset
task = unreal.AssetImportTask()
task.filename = "path/to/model.fbx"
task.destination_path = "/Game/Meshes/Characters"
task.automated = True
task.replace_existing = True
unreal.AssetToolsHelpers.get_asset_tools().import_asset_tasks([task])

# Validate assets
validator = unreal.EditorValidatorSubsystem()
validator.validate_assets_with_settings(assets, settings)
```

