Invalid GameplayTags in Blueprint Nodes

On the topic of gameplay tags as blueprint function arguments - if your game has gameplay tags, you might have seen this warning:

Invalid GameplayTag %s found in object %s.

Or maybe

Invalid GameplayTag %s found in property %s

It’s pretty easy to get - you “just” have to submit a blueprint that references a tag you made locally, and then forget to submit the .ini file (apparently this happens a lot) and tracking down which of the many many K2Node_CallFunction nodes is responsible isn’t a great experience.

Our designers are interested in upgrading this warning to a blueprint compilation failure - that’d make it really obvious what node in the blueprint is responsible. Turning the Warnings into Errors isn’t sufficient - that code runs when you *save* the blueprint, not when you compile it…

Does anyone know what to hook in the blueprint compiler to get there? I’m perfectly happy making engine changes to support this. I’d appreciate a clue about where to start.

Thanks!

-S

Steps to Reproduce

  1. Add a new gameplay tag
  2. Call a blueprint-callable function with that gameplay tag, in a blueprint
  3. Submit the blueprint, forget to submit the .ini file with the gameplay tag
  4. Now you have a blueprint referencing an invalid gameplay tag
  5. Observe that blueprint compilation succeeds, but a warning is printed on save or cook

Hi [mention removed]​,

Unreal Engine has already a class that allows you to extend the compiler behavior. This class is called UBlueprintCompilerExtension and it allows you to add any extra information when a blueprint is compiled. You just need to override the following function and add the logic you desire:

virtual void ProcessBlueprintCompiled(const FKismetCompilerContext& CompilationContext, const FBlueprintCompiledData& Data) override;With this function, with the Error call, you will make the Blueprint compile fail. So the main idea will be to go through the different nodes in the graph and check if the gameplay tag that it has cached does it exists.

void UCE_GameplayTag::ProcessBlueprintCompiled(const FKismetCompilerContext& CompilationContext,
	const FBlueprintCompiledData& Data)
{
	Super::ProcessBlueprintCompiled(CompilationContext, Data);
	
	const FString ErrorMsg = TEXT("UCE_GameplayTag::ProcessBlueprintCompiled called.");
 
   CompilationContext.MessageLog.Error(*ErrorMsg);
}

The CompilationContext.MessageLog.Error will make the blueprint compile fail.

You also need to register it. I’ve done this extension in an editor module, as it only relevant in the editor. You also need to register this extension in the UBlueprint class you desire. In my case I did it in the StartupModule from my EditorModule:

void FEM_SC_56Module::StartupModule()
{
	// My Blueprint Compiler Extension class
        Extension = NewObject<UCE_GameplayTag>();
 
	// Apply to all “normal” Blueprints that derive from UBlueprint
	FBlueprintCompilationManager::RegisterCompilerExtension(
		UBlueprint::StaticClass(),
		Extension
	);
}

Let me know if you need any help implementing your function. Also let me know if you prefer to modify the engine. This solution allows you to fail the Blueprint compilation under certain conditions without the need of modifying the engine, but if you prefer we can take a look at the engine itself :blush:

Best,

Joan

Hi [mention removed]​,

I’ll close the case for now. Feel free to open again the thread if you want additional information, but with the previous code you should be able to add the extra steps you wanted.

Best,

Joan