Logic Driver - Easily Design Gameplay Systems with State Machines

Thank you! Those cutscene nodes are just user created node classes. And node classes can be defined in C++ for both states and transitions. They still need to be assembled with the Blueprint Editor but it’s possible to have all of your node logic written in C++.

That icon… heh, XP styled is a good way of wording it-- I’m not exactly an artist (which is why it looks like it does) but I agree with you I’d like it to be updated. I’ll see what can be done about that.

Hi! Can I make a feature request to allow us to expose the public variables in a state machine in the start state machine node? It is really not convenient to manually set those variables when you have to do iteration a lot. Thanks!

Could you post a screenshot of your current implantation manually setting the variables please? That will help me decide the best way to implement this feature.

Sure!

As you can see, this can go longer and longer if you have many variables you want to set. And sometimes you want the state machine only start after all these variables are initialized then you will have to make a state to wait for these to be set or use a delay command so the state machine will not run with wrong data.

Well, the simplest way would be just defining a function on your SM Instance that takes all of your variables as input and sets them internally. That would simplify the number of nodes you need when starting it. Also, you should be able to set your variables before calling start. The state machine will have been initialized if you left InitializeOnBeginPlay checked.

Some other possibilities I’d like your opinion on:

I have been thinking of improving the actor component details panel. One new thing in 2.0 is you’ll be able to auto start component SMs on begin play. I’ve also considered exposing a template for the instance similar to how state machine references work.

ComponentTemplate.PNG
Picture selecting the SM class and then template options for your individual SM instance automatically appear. Would that help you at all?

Another possibility that currently works in 2.0 would be to define a state class node which accepts your variables and will create and start a new SM. Then place this node in a new SM graph. You would move your variables off of the actor and into the new SM graph. That would look like this:

And the state definition would look sort of look like this (Basically your original code but in one place that gets re-used):


The second option may not play well with replication however.

Would either of those work for you? I like option 1 but that would only work with default values. Perhaps a combination of that plus writing your own variable initialize function in the state machine? I’m not completely against exposing variables on the start node. It’s just a fairly extensive task (probably much more so than setting up template support) and I wouldn’t be able to try to implement that for some time.

Thank you for your reply!

I have one question on using a function to set variables, can I call that function before state machine starts?

Yeah, I think I like the first option, too. If I can call my custom function to set the variables before starting the state machine, and combine with option 1 I think that will work fine.

Yes, it shouldn’t be a problem as long as the state machine is initialized. Actor components do that by default on their BeginPlay, which should happen before the Actor BeginPlay is called. If you turned off InitializeOnBeginPlay then you need to call Initialize on the component first.

If you’re not using an actor component (I don’t think that’s the case from your example) then you can call your function after the CreateStateMachineInstance function.

I’ll add state machine component template support to the backlog and try to get that in for 2.0.

I’m struggling to get my project to work online. To be up front, I am a novice and I don’t fully understand the ins and outs of online networking but I think my problem might be more basic than that.

My state machine is not updating properly in online sessions and my character appears frozen.

In the event graph of the state machine itself I have used the tick to print some of the information used in transition rules to make sure it’s getting the right information and it appears that it is. For example, it is correctly recognizing that when the character spawns in above the ground that the character Is Falling and when the character hits the ground it correctly updates to Is Walking and but then the transition at the topmost level of the SM is exactly that - (Walking)<–>(Falling) - and this does not transition. Furthermore, during the brief fall to the ground the (Falling) sm should go down a few levels, (falling)->(controlled)->(idle)… etc but it does not do this either, it gets stuck at the first transition.

Any help is appreciated.
Thank you!

Just to check a few things first… everything works properly in single player?
How are you configuring the SM tick & transitions for multiplayer- Client, server, both?

On your event graph in the SM when you overload the tick function, make sure you still call the parent tick and pass in delta seconds.

Yep, this are fine when i run it not-online.

The “sm tick & transitions for multiplayer” are set in the character’s SM Component settings, right? Ah, maybe this is it. Tick config is Client, Network Transition is Client, Net state config is Client & Server. So thse need to change based on if its local or online?

Client just means processing occurs on the client before notifying the server and should be fine as long as its information is current.

Sent you a PM.

Hi Recursoft and others, Im using this plugin as a way for artists to easily create asset decision trees based off of a json struct built by ML. One of the issues im hitting here is that we never really want the system to idle on any state. We have a lot of sub-StateMachines for each feature, and we are moving through them each using HasStateMachine Reached EndState.

This works well, but sometimes our graph will not be able to find a valid transition and so it stays active on a node before the end of the sub State Machine. This is clearly ideal for tracking states, but we are using this more for a interactive decision tree.

i have tried to override
IsInEndState() on both the State Machine instance and the state instance in order to do a check if they have no available/valid transitions to report that it is in fact a End state, but i cant seem to get it to work. Some pointers on what to look at would be really useful! (Additional info, we are using the beta)


bool UWECLFeatureNode::IsInEndState() const
{
    if (Super::IsInEndState())
    {
        return true;
    }

    if (const FSMState_Base* Node = (FSMState_Base*)GetOwningNode())
    {
        for (FSMTransition* Transition : Node->GetOutgoingTransitions())
        {
            const bool bCanEval = Transition->bCanEvaluate;
            if (bCanEval && Transition->CanTransition())
            {
                return false;
            }

        }
    }
    return true;

Another solution we could do is check the states achieve time for being over a certain amount, but that seems pretty dirty.
Keen for any advice here!

Really impressed with the editor side of this plugin and its been very easy to navigate the code.

Wow, that looks really cool and is a whole new way to use this! I’d love to see this in action.

So the traditional FSM solution would be to just add an empty state leading out of Wavy_VeryLong_Hair if the other transitions don’t pass. You might get away with just making it a higher priority and set it to true. That way you have an end state available that gets evaluated after the other transitions.

Is your goal to have everything happen at once? Because you could also change the individual state nodes to evaluate their transitions on the initial tick with bEvalTransitionsOnStart. It’s an advanced display option for state nodes in the sm graph. That should make it possible for an entire sub state machine to run through all of its states in a single tick. Then you could remove the HasStateMachineReachedEndState check all together.

The reason overloading the IsInEndState on the instances isn’t working is because that just reads the NodeOwner value by default. The owning state machine struct doesn’t actually check the node instance for that, so there really isn’t anything you can easily do on the instance to make the state machine think it’s in an end state when it isn’t. All though this is an interesting case and may be worth allowing that to be configurable in some way.

Also please feel free to join the discord server too if you haven’t already. It’s primarily for 2.0 support and if I can help more with your use case I’d like to. The links in the readme of the project.

Logic Driver Version 2.0 is now released!

Full patch notes will be out later… there’s a lot of new content.

For now check out the new docs site.

And a refreshed example project.

Hey there @Recursoft,

waited for a long time to try out the final state of version 2.0 and today I started to testing some basic FSM-s with it and after a short time I noticed a strange behavior, so here is what I found:

if I use a “Create State Machine Instance” with a class reference and start the FSM with the “Start” function, just like this:


…after a while the whole State Machine just disappears like if it was destroyed by something (and the “Event On State Machine Stop” inside the in question FSM also never fires, which is suspicious too, I think, because not event the “Shutdown” function can destroy a State Machine like this as I see).

On the other hand, if I use a custom created variable after the “Create State Machine Instance”, just like this for example:


…this will never happens.

Do you mind to look at it, please? : ]

Hey @JimPhoenix, that’s normal behavior for UE4 and should have happened prior to 2.0. You need to store the state machine in a member variable like in your second approach or UE4 will garbage collect the object since there are no open references to it.

Oh my, got it, thanks! : ]

Maybe a real (not too big) issue here; after starting the editor with the Plugin turned on my main project, the Output log shows these warnings:


LogStreaming: Warning: Failed to read file '../../../Engine/Plugins/Marketplace/LogicDriver/Content/Brushes/Button.png' error.
LogSlate: Could not find file for Slate resource: ../../../Engine/Plugins/Marketplace/LogicDriver/Content/Brushes/Button.png
LogStreaming: Warning: Failed to read file '../../../Engine/Plugins/Marketplace/LogicDriver/Content/Brushes/Button_Hovered.png' error.
LogSlate: Could not find file for Slate resource: ../../../Engine/Plugins/Marketplace/LogicDriver/Content/Brushes/Button_Hovered.png
LogStreaming: Warning: Failed to read file '../../../Engine/Plugins/Marketplace/LogicDriver/Content/Brushes/Button_Pressed.png' error.
LogSlate: Could not find file for Slate resource: ../../../Engine/Plugins/Marketplace/LogicDriver/Content/Brushes/Button_Pressed.png
LogStreaming: Warning: Failed to read file '../../../Engine/Plugins/Marketplace/LogicDriver/Content/Brushes/Button_Disabled.png' error.
LogSlate: Could not find file for Slate resource: ../../../Engine/Plugins/Marketplace/LogicDriver/Content/Brushes/Button_Disabled.png

What do you think? : ]

@JimPhoenix I bet that has to do with the new TextGraphProperties. Variables that are parsed technically have buttons made for them in the UI. The buttons don’t do anything (yet) but it may be trying to load resources for them locally first (not intended) before defaulting to UE4’s included images.

As long as the text graph properties look like this when you drop a variable on them it’s working as expected.
(The variables will be colored differently based on their type)
TextGraph.png

I’ll work on resolving those warnings in a future update. Thanks for pointing them out!

Alright, it’s not a big deal, so I can live with it until you’ll fix it.

Anyway, You’re welcome! : ]