Another problem with networked branching abilities.
Setup:
BaseAbility - the only task it has is a branch task with custom ability chosen by GetBranchAbilityBP(). This branch is immidiate (the task is the only thing on full timeline). The ability duration is something short or even zero. Im using 0.01 just to make sure.
Now the abilities to which this can branch can be whatever, for example play a montage, just make sure they have some cooldown. Im using 0.1f
I put a PrintString inside “GetBranchAbilityBP” to see what’s calling it.
Now trying to activate it from server/client, sometimes it gets called twice, once for server and once for client and then the ability and then those abilities kinda get canceled and doesnt work.
Log is saying something like “Activating ability X” and immidately after “Could not activate ability X because it is on cooldown”
It seems to happen randomly. 50% of the time it works as intended and the other half it drops this into the log and doesn’t work as it should
An update on the networked branching problem with cooldowns.
I’m not 100% sure, but (since branch task isnt exported :/) I had to recreate your branch ability giving myself possibility to change realm of that task.
Upon changing the realm to server only the bug is gone, which leads me to believe that branches should happen only on server as they seem to be replicated by the AbilityComponent itself. Though I might not be correct
Branch task is called on the client for prediction purposes. So what could be happening is the Client and Server both play the Ability (as both are running the Tasks in tandem). Client tells the server to branch to Ability Y, but Server is already on Ability Y, so it prints the error - but if that’s the case, the Server should be still playing the Ability.
It is a listen server (if that’s what you mean by when you press play in editor and get 2 game windows).
It might be the thing you are saying though I just tried my more cases with branching and cooldowns. All my branches get messed up if i add any cooldown to the branched-to abilities.
Once I change branches to my own (server only ones) it works perfect.
Anyway for some reason if this warning happens then the ability isn’t playing out correctly. Animations get cancelled and other tasks kinda seem like only play out Task Started but not going anywhere as my own debug lines are drawn out, but the logic in tick isnt happening.
EDIT: I have a combo attack made just like in your video tutorial for sword combo, but adding cooldowns to second attack of the combo ability brings out the result i am talking about and the ability doesnt start on the server as I am able to walk normally on the server and the same character on the client plays out the ability but gets dragged around
Again, about 50% of the time it eithre plays out correctly or i get this in my log and it fails on the server aka just doesnt play the ability.
Now the ----- logs are just PrintString nodes attached to OnTaskStartedBP and OnTaskEndedBP
EDIT:
void UAblAbilityComponent::HandlePendingContexts()
...
if (const UAblAbility* PendingAbility = m_PendingContext*->GetAbility())
I whenever it gets buggy I keep getting AttackCombo2 ability context duplicated on m_PendingContext list. There are 2 entries of that context. I’m not sure this is supposed to happen as a little later in the same function ActiveAbility gets nulled and the second ability won’t fire off since it’s still on cooldown?
Ok, I THINK found it. It’s exactly as you said. The Ability gets fired on both Server and Client exactly at the same moment since on a local machine there is zero lag, and it would work exactly the way you said, the server would play out the ability anyway BUT in
HandlePendingContexts()
you get the branch request twice, since one just happened on the server and then another one came in from the client, your PendingContext on the server gets duplicated on the list.
Everytime you have some pending Context you do this:
ablAbilityComponent.cpp : 891
And then continue to play out the ability from the pending context - except this time the ability is on cooldown so it prints a warning to the log and doesn’t fire.
So in the end I assume you should only play the real branch on the server while on the client you should do some kinda fake branch as part of the “prediction” or not do it at all.
Well, I assume that for the system these are 2 completely separate and new instances on the list, as one was generated locally and the other one was requested from client.
I think instead of just avoiding duplicates you should check if you can start a new ability and only assign null to m_ActiveAbilityInstance if you indeed can, maybe?
Can I ask when will you be submitting new version of Able?
3.0 has taken me a long time and has no ETA yet. I make progress on it every day but there’s still a lot to iron out. I’ve completely reskinned the editor and added the ability to dynamically override various fields (much like you can do in UMG), so no more “I wish I could overload this field at runtime”, you’ll just pick the field, mark it as dynamic, and it’ll automatically create the binding and populate a method on the Ability blueprint for you to pass it when the Ability is executed.
Another bug is that math behind your CONE targetting and queries is valid only for Cones 2D. 3D cones draw proper debug shape but the math you do later to filter targets is just wrong.
Basically if something is to the left or to the right (is not aligned to X axis of the world) it will get filtered out.
That’s because you base your vertical filter on X and Z axis, but when instigator that you base your cone rotation on, will be rotated in a way the he alignes himself to Y axis, your X is 0 and you get nothing.
I fixed it locally by adding my own Cone implementation, but basically what you want to do, for vertical part, is to, instead of taking X, take length of 2D Vector from X and Y as first axis and then add Z axis.
Actually now when I started testing all the queries they seem to be broken. Even the debug shapes seem to be translated badly.
Mostly likely in this function:
If I understand correctly, you wanted to rotate the shape itself but since you transform OutTransform you end up rotating the entire OutTransform taken from the source actor, along with it’s world space location.
There should be no difference (unless that changed recently). TransformA *= TransformB breaks out into A.Rotation *= B.Rotation, A.Translation += B.Translation.
Well I dunno what’s under the transforms as I get easily lost in there, but it seems to be working correctly with ConcatenateRotation and with *= it doesnt.
Anyway the bug can be reproduced with cone or box (anything but sphere ofc) by simply adding some kind of rotation in Targeting>TargetLogic->Query Location->Rotation
Then enable debug shapes, start walking around and keep activating ability to see the shapes. As you get further from 0.0.0 point of the world, it gets more and more offset from the character
@ Hey, I was just wondering how this plugin differs from the Gamplay Ability System. Does this plugin expand that builtin system’s functionality? Does this plugin offer anything notably different? Would this plugin support dynamically creating abilities at runtime and then using them?
I’m also wondering if it would be possible to allow multiple passive abilities to be activated simultaneously. A simple use case could be like in Morrowind where you have a list of buffs and debuffs on your character.
As much as I fiddled with it and it’s source it looks like this plugin completely ignores Gameplay Ability System that’s built-in unreal engine.
It’s a separate system.
What’s different is how abilities are executed and probably most notable difference and a nice addition overall is the ability timeline that you can setup tasks on, deciding over which part of ability (time wise) which tasks do their job.
You could somewhat create abilities at runtime but you would need c++ knowledge to expand on this plugin’s system for that.
I haven’t used passives yet, but I assume 1 AbilityComponent can have multiple passives at once but only 1 active ability at a time
@Pablo1517 Pretty much nailed it but to elaborate:
Able was built as my replacement for Gameplay Ability System since that system was heavily built around Paragon at the time and it was really difficult to quickly throw together a simple Ability. That doesn’t mean the two systems (Able and GAS) can’t work side by side, but it was definitely meant as a way to replace GAS.
You can create Abilities at runtime, but you would have to do it in C++. However, Able allows for various runtime parameters so if you can create a basic framework of an Ability (I know I need to play some animation and then do a query and apply some amount of damage), then you can use those runtime parameters to fill in the details (play X animation, use this logic for my query, and then here’s the damage based on my stats/etc).
And yes, you can an unlimited amount of Passives active. The whole Active vs Passive separation is entirely a design one that fits with most games, but under the hood the two are treated almost identically.
I have a problem with cooking the game while using Able. Apparently it makes UE4 build editor stuff when packaging a game (so no editor code there) and we get a bunch of errors.
In
And we aren’t sure if this isn’t causing the problem.
Because for example in
AbleCore.Build.cs
you have this if
if (Target.bBuildEditor == true)
{
...
PrivateDependencyModuleNames.Add("GameplayTagsEditor");
}
Here is a log from Unreal Build Tool thrown out from Packaging process:
EDIT:
Additionally I just now went to editor->Settings->Plugins, Found GameplayTagsEditor plugin and clicked “Package” only to get instantly interrupted by an error saying this
UATHelper: Package Plugin Task (Windows): ERROR: Engine module 'Engine\Plugins\Marketing\Able\Source\AbleCore\AbleCore.Build.cs' should not depend on game module 'D:\RogueOvercooked\GameplayTagsEditor\HostProject\Plugins\GameplayTagsEditor\Source\GameplayTagsEditor\GameplayTagsEditor.Build.cs'
UATHelper: Package Plugin Task (Windows): (see D:\UE4_Projects\RogueEngine\Engine\Programs\AutomationTool\Saved\Logs\UBT-UE4Editor-Win64-Development.txt for full exception trace)
UATHelper: Package Plugin Task (Windows): Took 2,2769716s to run UnrealBuildTool.exe, ExitCode=5