Files
integration/Plugins/BlueprintMCP/Source/BlueprintMCP/Private/Handlers/UMCPHandler_DumpMaterial.Notes.md
2026-03-10 04:12:27 -04:00

3.6 KiB

UMCPHandler_DumpMaterial Refactoring Notes

What was done

  • Switched to plain-text output. The handler now overrides Handle(FStringBuilderBase&) instead of Handle(FJsonObject*). The plain-text format is significantly more concise and LLM-friendly.

  • Removed UE_LOG calls. Both log statements (one for materials, one for material instances) were removed.

  • Used FormatName consistently. All object names now use MCPUtils::FormatName() — materials, material instances, textures, and texture parameters. The old code used raw GetName() / GetPathName() throughout.

  • Used EnumToString. Material domain and blend mode now use MCPUtils::EnumToString with prefix stripping instead of hand-rolling StaticEnum<>()->GetNameStringByValue().

  • Removed UrlDecode. The old code manually called MCPUtils::UrlDecode(Material). MCPAssetFinder's Exact() handles this internally.

  • Trimmed includes. Removed ~15 unused includes (MaterialFunction, MaterialExpressionConstant variants, MaterialExpressionCustom, MaterialExpressionComponentMask, MaterialExpressionTextureCoordinate, MaterialExpressionFunctionInput/Output/Call, MaterialGraph nodes, BlueprintEditorUtils, AssetRegistry, EdGraph).

  • Concise output format. Usage flags only print enabled ones instead of listing all as true/false. Non-default settings (OpacityMaskClipValue, DitheredLODTransition, AllowNegativeEmissiveColor) are only printed when they differ from defaults. Sections like "Parameters" and "Referenced Textures" only appear if there's content.

  • Split into helper methods. EmitMaterial and EmitMaterialInstance keep the main Handle method clean and under two nesting levels.

What's good

  • The MCPAssetFinder usage with NoScans() + explicit Scan<UMaterial>() / Scan<UMaterialInstanceConstant>() is precise about what asset types to search.
  • Error handling flows naturally through Assets.Errors(Result) — no manual error message construction needed.
  • The parent of a material instance is handled for both UMaterial and UMaterialInstance parent types.

Areas of uncertainty / conservative choices

  • FormatName for texture parameters in material instances. FTextureParameterValue::ParameterValue is a UTexture*, so MCPUtils::FormatName(UTexture*) is used. This should be correct, but I haven't verified that all texture subclasses format nicely.

  • Shading models enumeration. I kept the original manual enumeration loop for shading models because MCPUtils::EnumToString works on a single enum value, not a bitfield. This is the one place where raw StaticEnum usage remains, since FMaterialShadingModelField is a bitmask, not a single value.

  • OpacityMaskClipValue default. I used 0.3333f as the default threshold for suppressing this line. Unreal's actual default for OpacityMaskClipValue is 0.3333... but the exact floating-point comparison could theoretically miss edge cases. This is a minor concern.

  • MCPFetcher not used. The handler searches by asset name/path (not by a walker path like "/Game/Foo,graph:Bar"), so MCPAssetFinder is the right tool here, not MCPFetcher. MCPFetcher would be appropriate if the handler accepted a walker path to navigate into sub-objects.

Potential future improvements

  • Could add a MaterialFunction path: the handler currently only supports UMaterial and UMaterialInstanceConstant. Material functions are a separate asset type that users might want to inspect.
  • The parameter output could include MCPUtils::FormatName(Expr) for each parameter expression, which would let callers reference those expressions in other tools.