Able Ability System Info and Support Thread

It can do broken stuff if the reference passed in falls into the memory range of the list as the removal moves stuff around and effectively changes the value from under the remove parameter., so their CheckAddress is a interesting protection against that edge case.

Ahhhh, I see it. Yea, FindByPredicate returns the address of an actual element from the allocated block - which normally doesn’t matter because you’d copy it off to a temporary variable. But since it’s a double pointer, you end up passing a variable that is within that block and check address fails because the address of the variable being passed in is from that block and will be corrupted when the move happens. That explains why the simple temporary variable fixes it.

Gotcha, yea, I’ll get that in this weekend.

I have a question about able and networking. What is the typical philosophy behind the logic one might want to have implemented inside the CanAbilityExecute function of the ability?.

I have a dash ability that has a CanAbilityExecute function which checks if the owner pawn has any available “dash charges” that recharge over time. When the ability activates, only the server subtracts 1 dash charge. During The dash charge variable is replicated to the client apparently before the ability starts(at least in PIE), so the client fails the custom check and does not activate the ability, while the server does.

How do you normally handle these sorts of data dependencies?

That sounds like the server is initiating the dash. Normally I would have the client initiate it (so it does the dash charge check) and the server just verifies and plays it as well.

Ok, so the issue seems to be that there is a behavioral difference between the client(listen server?) running in the editor window, and the client running in the popup window during PIE.

In the Editor window, the call to UAblAbilityComponent::ActivateAbility call ends up activating the ability server side first, because it takes the code path for authoritative

        // We're authoritative. Start the Ability.
        Result = InternalStartAbility(Context);

While the client in the popup window functions as you describe, where it’s not authoritative, so it sends the ServerActivateAbility RPC and then starts the ability locally, which activates the abilities in the ‘proper’ order of client then server.

How do you handle this inconsistency in PIE ?

Run with the dedicated server option turned on when you run in PIE. That will pop out two instances if you have two clients, then just set them up side by side.

Thanks. So that gets the client->server ability activation order working consistently. I’m still unable to get the clients and server side ability conditionals to work reliably. The replication of the dash charges from the server often still beats the starting of the ability, so while the owning client will activate first, followed by the server, the other client will fail to activate due to getting the replicated dash charge change from the server ability activate before activating the ability on their end.

The failure comes from the call to InternalStartAbility called from OnServerActiveAbilityChanged(), so I wonder if it would be reasonable to add a parameter that allows the client to skip CanActivateAbility when told by the server what the active ability is. Seems reasonable to me that if the server tells you what ability is running, the client should not be doing conditionals that can fail to activate that ability. The CanActivateAbility would still be executed on the client when they activate it locally.

Interestingly, forcing the ability from a boolean parameter only when called from OnServerActiveAbilityChanged also gets non dedicated server mode working correctly.

Hi, My Editor crashed when start up, my Able verison is 3.11 and this crash never happen on 2.x version. If i delete the player blueprint which had add ability component on it then i can start up my editor without crash. this player blueprint has set as preview asset and allowed classes in Able Editor Settings.

3.11 is a few revisions behind. Not sure why that would cause it but I would upgrade to the latest.

OK, I will waiting for new upguade

Sorry to bump, but is the situation I described in my last post a bug? Surely the OnServerActiveAbilityChanged is meant to be authoritative and skip the possibility of failing on the clients?

Sorry to bump, but is that OnServerActiveAbilityChanged issue a bug? Seems like the desired effect is for the server to be authoritative, which it seems to me means that the client should not be checking the conditional and potentially failing to activate the ability that the server activated.

I haven’t gotten through it yet - but I doubt it, it’s likely there for a reason given that code hasn’t changed in a long time and lots of other projects seem to be doing okay. If you want to locally change it while I continue to investigate - you’re more than welcome.

Perhaps others aren’t using activation gating logic in their abilities CanActivateAbility that rely on checking data outside the ability itself(such as replicated variables on the owning actor). The problem becomes apparent pretty quickly in that sort of case.

Edit: I am running with the flag I mentioned now and things are working much better now.

Eh some do, I believe. But yea, it could very well be a bug. I’m just not quite comfortable yet with shipping that out to everyone without a few more tests. :slight_smile:

Minor bug that leads to a mismatch between stuff like collision offsets and the visual model. In FAblAbilityEditor::Tick, I had to comment out the call to


    if (UMeshComponent* MeshComponent = m_PreviewActor->FindComponentByClass<UMeshComponent>())
        {
            MeshComponent->SetRelativeRotation(GetEditorSettings().m_MeshRotation);
        }

Because it was causing the offsets and such from collision query locations to be wrong if you are using a model that has relative rotation on the mesh component. I was getting inconsistent query results in game due to dialing in the position of queries with the debug rendering enabled being inconsistent with the model orientation at runtime. Comenting out that line got them agreeing again. There may be a better way to orient the model in the able editor.

Yea, admittedly the mesh rotation is a hack. The better fix is to put any rotation into your blueprint character. I’ll see if I can’t figure a better solution there though.

What is the purpose of this rotation in the Able editor? Is it just to have it face into the default view of the editor camera? Couldn’t you just rotate the actor rather than manipulating the MeshComponent of the actor?

Normally the actor itself is pointing down X (if you add an arrow component, you can see that). However a bunch of the default meshes in UE4 are authored to point down Y and so required a rotation to make it match the direction of the Actor. Again, this is a non-issue if you author your mesh to point down X, or you setup the mesh component in a blueprint actor and Able can just instantiate that rather than trying to cobble together an actor from bits and pieces (e.g. just a static mesh).