Skip to content

Extended tag functionality using Flow Identity#351

Open
Bargestt wants to merge 13 commits into
MothCocoon:5.xfrom
Bargestt:FlowIdentity
Open

Extended tag functionality using Flow Identity#351
Bargestt wants to merge 13 commits into
MothCocoon:5.xfrom
Bargestt:FlowIdentity

Conversation

@Bargestt

@Bargestt Bargestt commented Mar 3, 2026

Copy link
Copy Markdown
Contributor

This struct is an optional replacement for GameplayTagContainer to quickly navigate between world and graph
When your project has thousands of tags it is quite irreplaceable to quickly bind to desired actor or find what will be matched with node

image image image

@MothDoctor MothDoctor self-assigned this Mar 3, 2026
@Bargestt

Copy link
Copy Markdown
Contributor Author

I've tried to replace gameplay tag containers in nodes, but it turned to a much bigger change because core redirects are not enough
But by adding custom versioning old properties can be converted to the FlowIdentity struct without data loss

If you are interested, I can raise full replacement PR instead of keeping struct optional
https://github.com/Bargestt/FlowGraph/tree/FlowIdentityReplaceProperties
image

@Bargestt

Copy link
Copy Markdown
Contributor Author

Also, here is example why this struct is needed
Our level designers have no chill. 3400+ tags and some levels haven't left the blockout stage
Had to remove location names, not sure whether this'll break NDA otherwise, but just look at this madness
image

Bargestt and others added 9 commits April 13, 2026 01:41
migration error
nearly invisible in practice, caught by static code analysis
* FFlowIdentity struct should only serve as wrapper for tag container and the Match enum. Actors and components (in submitted PR code) aren't possible to be select by user rendering them non-functional, but that's fine. Even if Trigger and Spawner actors would use the same tag, system designer might simply have separate nodes for specific actors. "Spawn" node would usually require a project-specific Spawn actor.
* Actors and Flow Component TSubclassOf were hard references, which would cause to load actor classes with the graph. This should be controlled by system's logic.
* I removed UFlowIdentityBlueprintFunctionLibrary and UFlowSubystem from the PR.
    * Person authoring code should pass Tag and Match enum to already existing methods.
    * Calling these methods in runtime would case a synchronous loading of Actor and Component classes (as I would convert them to soft pointers). Designers wouldn't have control over this, they wouldn't even know about this happening. This would case loading hitches and would be working against teams tightly controlling memory management.

That being said, I can imagine that some projects would love to have Component/Actor filter here. I would propose to leave for project-specific extensions of FFlowIdentity and its UI customization. Along to implementing blueprint function library and subsystem methods. All of it should be achievable without modifying plugin's code, so teams could easily customize tag picker to their needs :)
If we want to support, we might only try to expose filtering actors in FFlowIdentityCustomization to virtual methods.
@MothDoctor

Copy link
Copy Markdown
Contributor

Finally got here :)

What I love? (and designers gonna love!)

  • A way better flow of assigning and finding assigned actors than by using raw tags. In past, I was thinking about adding GameplayTag filter to the Scene Outliner. Your solution is way more elegant :)
  • Adding here EFlowTagContainerMatchType is a nice bonus. I've realized that we got a bit of chaos in just a few built-in nodes using "Identity Tags". UFlowNode_ComponentObserver implements this check differently than UFlowNode_NotifyActor. Putting this enum into wrapper struct would allow to simplify general queries used in the plugin.
  • Yeah, I'd in favor of adding automatic conversion of existing nodes. This should go in a separate commit :)

What I'm cutting from this PR?

  • This new struct should only serve as wrapper for tag container and the Match enum. Actors and components (in submitted PR code) aren't possible to be select by user rendering them non-functional, but that's fine. Even if Trigger and Spawner actors would use the same tag, system designer might simply have separate nodes for specific actors. "Spawn" node would usually require a project-specific Spawn actor.
  • Actors and Flow Component TSubclassOf were hard references, which would cause to load actor classes with the graph. This should be controlled by system's logic.
  • I removed UFlowIdentityBlueprintFunctionLibrary and UFlowSubystem from the PR.
    • Person authoring code should pass Tag and Match enum to already existing methods.
    • Calling these methods in runtime would case a synchronous loading of Actor and Component classes (as I would convert them to soft pointers). Designers wouldn't have control over this, they wouldn't even know about this happening. This would case loading hitches and would be working against teams tightly controlling memory management.

That being said, I can imagine that some projects would love to have Component/Actor filter here. I would propose to leave for project-specific extensions of FFlowIdentity and its UI customization. Along to implementing blueprint function library and subsystem methods. All of it should be achievable without modifying plugin's code, so teams could easily customize tag picker to their needs :)
If we want to support, we might only try to expose filtering actors in FFlowIdentityCustomization to virtual methods.

What do you think? Once we're synced about design here, I would do an usability pass on the tag picker :)

@Bargestt

Copy link
Copy Markdown
Contributor Author

So it comes to fight between data-only struct and struct as filter
I like second option more because filters can be extended by developer

Component filtering is for when node created for specific component or actor, this is why EditDefaultsOnly was used. Hard refs are unnecessary and were simply missed. In practice this feature was rarely used, but each time life better. For example showing only triggers for trigger nodes is awesome
Here is what we can do to keep it functionality, in order what I like the most.

  • Replace it with soft refs. It will require filtering methods to stay or it'll become dangling field
  • Remove fields, but keep virtual Matches( ) function that is used by customization polymorphically. With extendable customization will provide most extensibility while keeping base struct lean
  • virtual function in customization and people will be able to implement these features without modifying the plugin
  • Read metadata from property in customization is possible, but it limits feature to C++ or require metadata editing plugins for blueprint.
    • Just give broad extensibility to customization at this point and let people implement it themselves

I dislike boilerplate so complete removal of structure methods is too much in my opinion.
compare calls

  • Identity.Matches(FlowComponent); - nice, short and is already there
  • FlowTypes::MatchesIdentity(FlowComponent, Identity) - could be created, but not as elegant
  • FlowTypes::HasMatchingTags(FlowComponent->IdentityTags, Identity.IdentityTags, Identity.IdentityMatchType); - do I need to elaborate on this giant? ;)

I don't care about methods in UFlowSubystem and might've moved them to UFlowIdentityBlueprintFunctionLibrary myself. The only argument for keeping this library is my dislike for boilerplate and in this case it can be taken outside plugin without problem

Also, magnifying glass is broken currently and I hope it was from quick function removal and not intention. It is main feature after all: ability to check what actors on level will match without launching the game

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants