# BladeSmith Agent Development Guide ## Project Overview BladeSmith is a UE5.6 C++ blacksmith simulation game featuring physics-based metal forging with GPU-accelerated compute shaders and dynamic mesh deformation. **Core Technologies:** - Unreal Engine 5.6 - Geometry Scripting API - Custom Compute Shaders (MiceShaders plugin) - Dynamic Mesh System - Enhanced Input - Voxel-based physics simulation --- ## Build Commands ### Building the Project ```bash # Build game target (run from UE5 engine directory) "C:\Program Files\Epic Games\UE_5.6\Engine\Build\BatchFiles\Build.bat" BladeSmith Win64 Development "E:\MiceCola\work\BladeSmith\BladeSmith.uproject" # Build editor target "C:\Program Files\Epic Games\UE_5.6\Engine\Build\BatchFiles\Build.bat" BladeSmithEditor Win64 Development "E:\MiceCola\work\BladeSmith\BladeSmith.uproject" # Alternative: Open BladeSmith.sln in Visual Studio ``` ### Running Tests UE5 uses the Automation System, not traditional test runners: - **Editor**: Window → Developer Tools → Automation Sessions - **Command line**: `UE5Editor.exe BladeSmith.uproject -ExecCmds="Automation RunTests"` - **Single test**: Run specific test class from Automation Sessions panel ### Development Workflow 1. Open `BladeSmith.uproject` in UE5.6 editor 2. Use hot reload for C++ changes (Ctrl+F11 in editor) 3. Test via "Play In Editor" (Alt+P) 4. Use Visual Studio for compilation --- ## Code Style Guidelines ### File Structure - **Header files (.h)**: Class declarations, forward declarations, USTRUCT/UCLASS definitions - **Source files (.cpp)**: Implementations, includes in dependency order - **Shader files (.usf)**: HLSL compute shaders in `Plugins/MiceShaders/Shaders/Private/` ### Import Ordering **Header Files:** ```cpp // Copyright Epic Games, Inc. All Rights Reserved. #pragma once #include "CoreMinimal.h" #include "GameFramework/Actor.h" #include "ProjectModule.generated.h" class UForwardDeclaredClass; // Forward declarations ``` **Source Files:** ```cpp // Copyright Epic Games, Inc. All Rights Reserved. #include "ClassName.h" #include "SystemHeader1.h" #include "SystemHeader2.h" ``` **Pattern:** 1. Epic copyright header (required) 2. `#pragma once` guard 3. Core UE5 headers (`CoreMinimal.h` first) 4. Engine framework headers 5. Project headers 6. Forward declarations (headers only) ### Naming Conventions **Classes:** PascalCase with UE5 prefixes - `ABladeSmithCharacter` - Actor classes (A prefix) - `UBladeSmithWeaponComponent` - Component classes (U prefix) - `FDeformationVoxel` - Structs (F prefix) - `EGameStateEnum` - Enums (E prefix) **Functions:** PascalCase ```cpp public: void SwingHammer(); FVector GetHammerHeadLocation() const; private: void PerformHammerHit(); // Private helpers use PascalCase ``` **Variables:** camelCase ```cpp float HammerForce = 1000.0f; FVector HammerHeadOffset; UMaterialInstanceDynamic* DynamicMaterialInstance; TArray TemperatureGrid; ``` **Constants:** PascalCase ```cpp const int32 MaxResolutionPerAxis = 200; const float DefaultTemperature = 20.0f; ``` ### Formatting **Indentation:** 4 spaces (no tabs) **Braces:** Allman style - opening brace on new line ```cpp void ABladeSmithCharacter::Move(const FInputActionValue& Value) { FVector2D MovementVector = Value.Get(); // implementation } ``` **Line Length:** Under 120 characters, wrap parameters as needed **Spacing:** Spaces around operators, after commas ### UE5 Macros and Attributes **UPROPERTY Specifiers:** ```cpp UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Category") UPropertyType* VariableName; UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Category|Subcategory", meta = (ClampMin = "0.0", ClampMax = "1.0")) float PropertyWithConstraints; UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Category", meta = (AllowPrivateAccess = "true")) UComponentType* PrivateComponent; ``` **UFUNCTION Specifiers:** ```cpp UFUNCTION(BlueprintCallable, Category = "Category Name") ReturnType FunctionName(Parameters); UFUNCTION(BlueprintImplementableEvent) void BlueprintEventName(); ``` **USTRUCT:** ```cpp USTRUCT(BlueprintType) struct FStructName { GENERATED_BODY() UPROPERTY() Type VariableName; }; ``` ### Type Annotations **UE5 Types (preferred):** - `TArray` instead of std::vector - `TMap` instead of std::map - `TSet` instead of std::unordered_set - `FVector`, `FVector2D`, `FRotator`, `FQuat` for math - `FString` for strings (TEXT() macro for string literals) - `FName` for names, `FText` for localized text - `float` not double (unless precision critical) - `int32` not int, `uint8` for bytes - `bool` for booleans **Smart Pointers:** - Use UE5's garbage collection for UObject-derived classes - `TSharedPtr` for non-UObject smart pointers - `TWeakObjectPtr` for weak references to UObjects ### Error Handling **Null Checks:** ```cpp if (DynamicMeshComp == nullptr) { UE_LOG(LogTemp, Error, TEXT("DynamicMeshComponent not found")); return; } ``` **Logging:** ```cpp UE_LOG(LogTemp, Log, TEXT("Temperature: %.1f°C"), Temperature); // Info UE_LOG(LogTemp, Warning, TEXT("Temperature system disabled")); // Warning UE_LOG(LogTemp, Error, TEXT("Failed to initialize GPU buffers")); // Error ``` **Validation:** ```cpp if (!IsValid(InputParam)) { return false; } // Early return pattern if (Condition) { return; } ``` ### Documentation **Chinese Comments:** Domain-specific logic uses Chinese comments ```cpp /** 锤子组件 */ /** 温度体素结构 - 存储单个体素的温度和塑性数据 */ ``` **Function Documentation:** ```cpp /** * 函数简述 * @param ParameterName 参数说明 * @return 返回值说明 */ ``` ### Threading and GPU Operations **Atomic Flags:** ```cpp std::atomic bGPUBuffersReady{false}; ``` **Render Thread Operations:** ```cpp ENQUEUE_RENDER_COMMAND(CommandName)( [Params](FRHICommandListImmediate& RHICmdList) { // GPU operations here } ); ``` ### Component Structure Pattern **Actor Template:** ```cpp UCLASS() class BLADESMITH_API AClassName : public AParentClass { GENERATED_BODY() public: AClassName(); UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Category") UComponentType* Component; UFUNCTION(BlueprintCallable, Category="Category") ReturnType PublicFunction(); protected: virtual void BeginPlay() override; virtual void Tick(float DeltaTime) override; private: void PrivateHelper(); }; ``` --- ## Module Dependencies **BladeSmith.Build.cs:** - GeometryScriptingCore, GeometryFramework, DynamicMesh - GeometryCore, GeometryAlgorithms, ModelingComponents - RenderCore, RHI, Renderer, PhysicsCore - EnhancedInput, AudioExtensions, AudioMixer - Custom: MiceShaders (plugin) --- ## Performance Guidelines - **Deformation calculations:** <7ms per frame target - **60 FPS:** Maintain during hammer operations - **High-poly meshes:** ~100k vertices with GPU acceleration - **Voxel resolution:** 50x50x50 typical (balance performance/quality) - **Use RDG (Render Dependency Graph)** for GPU compute operations --- ## Common Patterns **Material Parameters:** ```cpp UMaterialInstanceDynamic* DynMaterial = UMaterialInstanceDynamic::Create(BaseMaterial, this); DynMaterial->SetScalarParameterValue(TEXT("ParameterName"), Value); DynMaterial->SetVectorParameterValue(TEXT("VectorParam"), FLinearColor(R,G,B,A)); DynMaterial->SetTextureParameterValue(TEXT("TextureParam"), Texture); ``` **Dynamic Mesh Editing:** ```cpp UDynamicMesh* DynMesh = DynMeshComp->GetDynamicMesh(); DynMesh->EditMesh([&](FDynamicMesh3& EditMesh) { for (FVertexID VertexID : EditMesh.VertexIndicesItr()) { EditMesh.SetVertex(VertexID, NewPosition); } }, EDynamicMeshChangeType::GeneralEdit); ``` **Input Binding (Enhanced Input):** ```cpp if (UEnhancedInputComponent* EnhancedInput = Cast(InputComponent)) { EnhancedInput->BindAction(Action, ETriggerEvent::Triggered, this, &ClassName::Handler); } ``` --- ## Plugin System **MiceShaders Plugin:** - Custom compute shaders for temperature simulation and deformation - Located in `Plugins/MiceShaders/` - Add new shaders: Create `.h` and `.cpp` in Source/MiceShaders, HLSL in Shaders/Private/ - Use RDG for shader dispatch --- ## Git Workflow - **Ignore:** `Binaries/`, `Intermediate/`, `DerivedDataCache/`, `Saved/`, `.vs/`, `.idea/` - **Commit:** Source/, Content/, Plugins/, Config/, docs/ - **No binary assets** in Git (use version control for assets) --- ## Documentation **Technical docs:** Located in `docs/plans/` - Reference existing design docs before implementing new features - Update plans when architecture changes - Use markdown for design documents