Able Ability System Info and Support Thread

How would I go about instantiating a Context / Ability with additional / pre-set variables? Currently, I need the Player to be able to set the Target beforehand, which would work in a Singleplayer environment since I could just retrieve it from any Blueprint. Looking at 3.29, this should be possible now? But I also cannot renounce client-side prediction. What’s the reasoning for Replicated Instances to break prediction?

There’s an “Target Custom” which asks BP for the targets, or you can use scene query tasks to add them. If you have the Player settings the Target on their end, just forward that Target to the server so the Server can also use it.

Replicated Instances are replicated from the server down to the client. They are one object shared between both (so server writes to Targets or such, will be visible to the client). They can’t be predicted because of that. They came from a request to allow instancing like GAS, which has the same options. I could see it being useful if you wanted to replicate down all the info from the server to display on some UI, but even that seems a bit heavy handed IMO.

I’ve started running into this issue where abilities with certain custom tasks added will crash UE4 when activated. It’s a nullptr error. One of my team’s engineers thinks it might be data corruption, because my custom tasks were not doing this one changelist previous and there were no changes to the custom tasks between those two CLs. The error I see says"Cast of nullptr to AblAbilityTaskScratchPad failed".

The weird thing is that if I open an ability that causes a crash and resave it, it no longer crashes the engine until I revert the file in source control or check it in. Here’s a callstack he provided me:

I’m using the latest Able version and UE4 version 4.24.3

log


UE4Editor-Engine.dll!FTickFunctionTask::DoTask(ENamedThreads::Type CurrentThread, const TRefCountPtr<FGraphEvent> & MyCompletionGraphEvent) Line 285 C++
[5:54](https://whitemoondreams.slack.com/archives/DC17CPQ90/p1589849674022900)
here is the call stack:
  [Inline Frame] UE4Editor-CoreUObject.dll!CastLogError::__l11::<lambda_85a69443e79372a632c30a14da020d5f>::operator()() Line 10 C++
  UE4Editor-CoreUObject.dll!CastLogError(const wchar_t * FromType, const wchar_t * ToType) Line 10 C++
  [Inline Frame] UE4Editor-AbleCore.dll!CastChecked(UAblCustomTaskScratchPad * Src) Line 213 C++
  UE4Editor-AbleCore.dll!UAblCustomTask::CreateScratchPad(const TWeakObjectPtr<UAblAbilityContext,FWeakObjectPtr> & Context) Line 73 C++
  UE4Editor-AbleCore.dll!UAblAbilityContext::AllocateScratchPads() Line 101 C++
  UE4Editor-AbleCore.dll!UAblAbilityComponent::InternalStartAbility(UAblAbilityContext * Context, bool ServerActivatedAbility) Line 1054 C++
  UE4Editor-AbleCore.dll!UAblAbilityComponent::HandlePendingContexts() Line 1186 C++
  UE4Editor-AbleCore.dll!UAblAbilityComponent::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction * ThisTickFunction) Line 168 C++
> [Inline Frame] UE4Editor-Engine.dll!FActorComponentTickFunction::ExecuteTick::__l2::<lambda_8b87dc54ce1db8ca3e3fdcfa35a4582b>::operator()(float) Line 892 C++
  UE4Editor-Engine.dll!FActorComponentTickFunction::ExecuteTickHelper<<lambda_8b87dc54ce1db8ca3e3fdcfa35a4582b> >(UActorComponent * Target, bool bTickInEditor, float DeltaTime, ELevelTick TickType, const FActorComponentTickFunction::ExecuteTick::__l2::<lambda_8b87dc54ce1db8ca3e3fdcfa35a4582b> & ExecuteTickFunc) Line 3388 C++
  UE4Editor-Engine.dll!FActorComponentTickFunction::ExecuteTick(float DeltaTime, ELevelTick TickType, ENamedThreads::Type CurrentThread, const TRefCountPtr<FGraphEvent> & MyCompletionGraphEvent) Line 894 C++
  UE4Editor-Engine.dll!FTickFunctionTask::DoTask(ENamedThreads::Type CurrentThread, const TRefCountPtr<FGraphEvent> & MyCompletionGraphEvent) Line 285 C++
  UE4Editor-Engine.dll!TGraphTask<FTickFunctionTask>::ExecuteTask(TArray<FBaseGraphTask *,TSizedDefaultAllocator<32> > & NewTasks, ENamedThreads::Type CurrentThread) Line 847 C++
  [Inline Frame] UE4Editor-Core.dll!FBaseGraphTask::Execute(TArray<FBaseGraphTask *,TSizedDefaultAllocator<32> > & CurrentThread, ENamedThreads::Type) Line 514 C++
  UE4Editor-Core.dll!FNamedTaskThread::ProcessTasksNamedThread(int QueueIndex, bool bAllowStall) Line 686 C++
  UE4Editor-Core.dll!FNamedTaskThread::ProcessTasksUntilIdle(int QueueIndex) Line 594 C++
  UE4Editor-Engine.dll!FTickTaskSequencer::ReleaseTickGroup(ETickingGroup WorldTickGroup, bool bBlockTillComplete) Line 577 C++
  UE4Editor-Engine.dll!FTickTaskManager::RunTickGroup(ETickingGroup Group, bool bBlockTillComplete) Line 1528 C++
  UE4Editor-Engine.dll!UWorld::RunTickGroup(ETickingGroup Group, bool bBlockTillComplete) Line 782 C++
  UE4Editor-Engine.dll!UWorld::Tick(ELevelTick TickType, float DeltaSeconds) Line 1567 C++
  UE4Editor-UnrealEd.dll!UEditorEngine::Tick(float DeltaSeconds, bool bIdleMode) Line 1683 C++
  UE4Editor-UnrealEd.dll!UUnrealEdEngine::Tick(float DeltaSeconds, bool bIdleMode) Line 410 C++
  UE4Editor.exe!FEngineLoop::Tick() Line 4485 C++
  [Inline Frame] UE4Editor.exe!EngineTick() Line 62 C++
  UE4Editor.exe!GuardedMain(const wchar_t * CmdLine, HINSTANCE__ * hInInstance, HINSTANCE__ * hPrevInstance, int nCmdShow) Line 173 C++
  UE4Editor.exe!WinMain(HINSTANCE__ * hInInstance, HINSTANCE__ * hPrevInstance, char * __formal, int nCmdShow) Line 252 C++
  [External Code]

The moment this started to happen was when I created a new ability, new custom task specifically for that ability, and a scratchpad for that custom task. At some point I made some changes to everything and other abilities without that custom task started to fail. The only common link was this particular ability had a custom task that the other abilities used.

here’s the log on my end:


[2020.05.19-21.11.35:838][161]LogWindows: Error: === Critical error: ===
[2020.05.19-21.11.35:838][161]LogWindows: Error:
[2020.05.19-21.11.35:838][161]LogWindows: Error: Fatal error: [File:D:/WDI/Acn/UE4/Engine/Source/Runtime/CoreUObject/Private/Templates/Casts.cpp] [Line: 10]
[2020.05.19-21.11.35:838][161]LogWindows: Error: Cast of nullptr to AblAbilityTaskScratchPad failed
[2020.05.19-21.11.35:838][161]LogWindows: Error:
[2020.05.19-21.11.35:838][161]LogWindows: Error:
[2020.05.19-21.11.35:838][161]LogWindows: Error: [Callstack] 0x00007fff63f0a799 KERNELBASE.dll!UnknownFunction ]
[2020.05.19-21.11.35:838][161]LogWindows: Error: [Callstack] 0x00007fff0851df56 UE4Editor-Core.dll!ReportAssert() [d:\wdi\acn\ue4\engine\source\runtime\core\private\windows\windowsplatformcrashcontext.cpp:1341]
[2020.05.19-21.11.35:838][161]LogWindows: Error: [Callstack] 0x00007fff08520db1 UE4Editor-Core.dll!FWindowsErrorOutputDevice::Serialize() [d:\wdi\acn\ue4\engine\source\runtime\core\private\windows\windowserroroutputdevice.cpp:79]
[2020.05.19-21.11.35:838][161]LogWindows: Error: [Callstack] 0x00007fff0830449d UE4Editor-Core.dll!FOutputDevice::LogfImpl() [d:\wdi\acn\ue4\engine\source\runtime\core\private\misc\outputdevice.cpp:71]
[2020.05.19-21.11.35:838][161]LogWindows: Error: [Callstack] 0x00007fff06b3e363 UE4Editor-CoreUObject.dll!CastLogError() [d:\wdi\acn\ue4\engine\source\runtime\coreuobject\private	emplates\casts.cpp:11]
[2020.05.19-21.11.35:838][161]LogWindows: Error: [Callstack] 0x00007ffee615ec14 UE4Editor-AbleCore.dll!UAblCustomTask::CreateScratchPad() [d:\wdi\acn\ue4\engine\plugins\able\source\ablecore\private	asks\ablcustomtask.cpp:73]
[2020.05.19-21.11.35:838][161]LogWindows: Error: [Callstack] 0x00007ffee6157c20 UE4Editor-AbleCore.dll!UAblAbilityContext::AllocateScratchPads() [d:\wdi\acn\ue4\engine\plugins\able\source\ablecore\private\ablabilitycontext.cpp:101]
[2020.05.19-21.11.35:838][161]LogWindows: Error: [Callstack] 0x00007ffee6184d74 UE4Editor-AbleCore.dll!UAblAbilityComponent::InternalStartAbility() [d:\wdi\acn\ue4\engine\plugins\able\source\ablecore\private\ablabilitycomponent.cpp:1054]
[2020.05.19-21.11.35:838][161]LogWindows: Error: [Callstack] 0x00007ffee61827dd UE4Editor-AbleCore.dll!UAblAbilityComponent::HandlePendingContexts() [d:\wdi\acn\ue4\engine\plugins\able\source\ablecore\private\ablabilitycomponent.cpp:1186]
[2020.05.19-21.11.35:838][161]LogWindows: Error: [Callstack] 0x00007ffee61ada39 UE4Editor-AbleCore.dll!UAblAbilityComponent::TickComponent() [d:\wdi\acn\ue4\engine\plugins\able\source\ablecore\private\ablabilitycomponent.cpp:168]
[2020.05.19-21.11.35:838][161]LogWindows: Error: [Callstack] 0x00007fff04091588 UE4Editor-Engine.dll!FActorComponentTickFunction::ExecuteTickHelper<<lambda_b80b67805432a32119ae0b418e9a4616> >() [d:\wdi\acn\ue4\engine\source\runtime\engine\classes\gameframework\actor.h:3388]
[2020.05.19-21.11.35:838][161]LogWindows: Error: [Callstack] 0x00007fff040c2534 UE4Editor-Engine.dll!FActorComponentTickFunction::ExecuteTick() [d:\wdi\acn\ue4\engine\source\runtime\engine\private\components\actorcomponent.cpp:894]
[2020.05.19-21.11.35:838][161]LogWindows: Error: [Callstack] 0x00007fff04e372e3 UE4Editor-Engine.dll!FTickFunctionTask::DoTask() [d:\wdi\acn\ue4\engine\source\runtime\engine\private	icktaskmanager.cpp:285]
[2020.05.19-21.11.35:838][161]LogWindows: Error: [Callstack] 0x00007fff04e45316 UE4Editor-Engine.dll!TGraphTask<FTickFunctionTask>::ExecuteTask() [d:\wdi\acn\ue4\engine\source\runtime\core\public\async	askgraphinterfaces.h:847]
[2020.05.19-21.11.35:838][161]LogWindows: Error: [Callstack] 0x00007fff080ca152 UE4Editor-Core.dll!FNamedTaskThread::ProcessTasksNamedThread() [d:\wdi\acn\ue4\engine\source\runtime\core\private\async	askgraph.cpp:686]
[2020.05.19-21.11.35:838][161]LogWindows: Error: [Callstack] 0x00007fff080ca40a UE4Editor-Core.dll!FNamedTaskThread::ProcessTasksUntilIdle() [d:\wdi\acn\ue4\engine\source\runtime\core\private\async	askgraph.cpp:594]
[2020.05.19-21.11.35:838][161]LogWindows: Error: [Callstack] 0x00007fff04e6376d UE4Editor-Engine.dll!FTickTaskSequencer::ReleaseTickGroup() [d:\wdi\acn\ue4\engine\source\runtime\engine\private	icktaskmanager.cpp:577]
[2020.05.19-21.11.35:838][161]LogWindows: Error: [Callstack] 0x00007fff04e69882 UE4Editor-Engine.dll!FTickTaskManager::RunTickGroup() [d:\wdi\acn\ue4\engine\source\runtime\engine\private	icktaskmanager.cpp:1528]
[2020.05.19-21.11.35:838][161]LogWindows: Error: [Callstack] 0x00007fff045e9a1f UE4Editor-Engine.dll!UWorld::RunTickGroup() [d:\wdi\acn\ue4\engine\source\runtime\engine\private\leveltick.cpp:782]
[2020.05.19-21.11.35:838][161]LogWindows: Error: [Callstack] 0x00007fff045f50ce UE4Editor-Engine.dll!UWorld::Tick() [d:\wdi\acn\ue4\engine\source\runtime\engine\private\leveltick.cpp:1567]
[2020.05.19-21.11.35:838][161]LogWindows: Error: [Callstack] 0x00007fff01dcae90 UE4Editor-UnrealEd.dll!UEditorEngine::Tick() [d:\wdi\acn\ue4\engine\source\editor\unrealed\private\editorengine.cpp:1683]
[2020.05.19-21.11.35:838][161]LogWindows: Error: [Callstack] 0x00007fff02632576 UE4Editor-UnrealEd.dll!UUnrealEdEngine::Tick() [d:\wdi\acn\ue4\engine\source\editor\unrealed\private\unrealedengine.cpp:410]
[2020.05.19-21.11.35:838][161]LogWindows: Error: [Callstack] 0x00007ff62c267f62 UE4Editor.exe!FEngineLoop::Tick() [d:\wdi\acn\ue4\engine\source\runtime\launch\private\launchengineloop.cpp:4485]
[2020.05.19-21.11.35:838][161]LogWindows: Error: [Callstack] 0x00007ff62c27c3ec UE4Editor.exe!GuardedMain() [d:\wdi\acn\ue4\engine\source\runtime\launch\private\launch.cpp:173]
[2020.05.19-21.11.35:838][161]LogWindows: Error: [Callstack] 0x00007ff62c27c4ca UE4Editor.exe!GuardedMainWrapper() [d:\wdi\acn\ue4\engine\source\runtime\launch\private\windows\launchwindows.cpp:134]
[2020.05.19-21.11.35:838][161]LogWindows: Error: [Callstack] 0x00007ff62c28ceae UE4Editor.exe!WinMain() [d:\wdi\acn\ue4\engine\source\runtime\launch\private\windows\launchwindows.cpp:263]
[2020.05.19-21.11.35:838][161]LogWindows: Error: [Callstack] 0x00007ff62c28fcbe UE4Editor.exe!__scrt_common_main_seh() [d:\agent\_work\2\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:288]
[2020.05.19-21.11.35:838][161]LogWindows: Error: [Callstack] 0x00007fff64bd7bd4 KERNEL32.DLL!UnknownFunction ]
[2020.05.19-21.11.35:838][161]LogWindows: Error: [Callstack] 0x00007fff661cce51 ntdll.dll!UnknownFunction ]


Hello,

How would you go about setting up “multiple branches” based on target distance (or any other variable other than a bool)?
For instance, if distance is less than 400, branch to ability A; if distance is greater than 400 but less than 600, branch to ability B; If distance is greater than 600, do nothing.

My second question is if there’s a way to determine the end of a combo and feed that info into a behavior tree?
My current behavior tree set up gets the length of the chosen ability and delays by that length and finish execute after.
The problem I’m having with that set up is it leaves no room for branching combo abilities since the behavior tree will move on to the next thing.
I was hoping to use “On ability end” as a delegate of some kind, but i cannot bind to it. I’m pretty sure It’s just me being ignorant about the system.

@DrTasty Looks like it’s failing to cast your scratch pad. I’ve seen this crash before, but never been able to repro it. I’ll see if I can’t through some extra info and try and make that code a bit more flexible in the meantime (I’m working on an update for later today).

You can add a Custom Branch condition and just get the distance, or add a dynamic delegate to the Custom Branch Ability, and do the distance check there and return the appropriate ability.
There is a Behavior Tree “Is Playing Ability” decorator you can use which would work in your case. There is also a “On Ability End” delegate on the Able Ability System Component that you should be able to hook into.

Hi there, first of all great product. However i’ve ran into an issue. I cant get the move to and turn to nodes to work. I tried to use Able to implement a dodge roll like Dark Souls.
Is it possible to get an working example for those or an updated documentation?
I figured out most of functionality of the plugin (e.g how location or Targets are set), but for me “turn to” always turns towards the global x-Axis and “Move to” simply does nothing although the values i entered look correct for me.
Apologies if i missed something obvious
Regards

Submitted Able v3.31:

Move To requires the Player Movement Component IIRC (or a Nav agent). Turn to should work as expected, I know some people are using it as expected. You should be able to turn on Verbose mode for Turn To and Move To and see if you get more info.

As for a Dark Souls-style dodge, I would actually make that as a new Custom Movement state (again, assuming you’re using the Character Movement Component). That way you can tweak a lot of things and the check for if you should play your dodge roll animation / ignore damage or whatever - simply becomes “Am I in the Dodge movement state?”. It also works will roll backs and all that fun networking stuff.

Thanks so much!

I’m not sure how helpful this will be, but the issue seems to be branching out for me. I’m running into another problem where new custom tasks I’ve created (to replace the crashy ones) don’t even execute until I open the ability in the editor and save it. Not sure if it’s just a compounding issue with creating new assets after this crash started to occur or it’s something with how it interacts with source control. I’m using Perforce.
I inserted an IsValid check in CreateScratchPad with a breakpoint for one of my tasks, but it doesn’t even make it to that. The game crashes before that function runs.

It works for Actors, but TurnTo had no Implementation for TargetType Location.

Also, variables set for Blueprint CustomTasks (haven’t tried cpp ones yet) in Ability->TaskProperties keep getting reset to defaults after recompilation of said Task.

Ah, that could be. Location Target Type came in pretty late.

C++ variables should be fine. Blueprint variables are a different cat. The class gets re-instantiated after recompile, so it’s possible it could lose properties. I would definitely suggest C++ tasks over Custom Tasks if possible, or use a “Measure twice, cut once” approach to custom tasks (use one Ability to hammer out all the required changes to your custom task - then use it in other Abilities, so you aren’t constantly recompiling the task).

Hi there, thanks in advanced for any help on this, i’m getting a crash when querying for targets during a melee animation, if multiple targets are in sight usually.



Unhandled Exception: EXCEPTION_ACCESS_VIOLATION writing address 0x00000028

UE4Editor_Engine
UE4Editor_Engine
UE4Editor_Engine
UE4Editor_CoreUObject
UE4Editor_CoreUObject
UE4Editor_CoreUObject
UE4Editor_CoreUObject
UE4Editor_CoreUObject
UE4Editor_CoreUObject
UE4Editor_CoreUObject
UE4Editor_CoreUObject
UE4Editor_CoreUObject
UE4Editor_CoreUObject
UE4Editor_AbleCore!UAblAbility::CalculateDamageForActorBP() [d:\build\++portal+promotion\sync\localbuilds\plugintemp\hostproject\plugins\able\intermediate\build\win64\ue4editor\inc\ablecore\ablability.gen.cpp:483]
UE4Editor_AbleCore!<lambda_bc0e834bf2a1af60dbceb985d90ac1e5>::operator()() [d:\build\++portal+promotion\sync\localbuilds\plugintemp\hostproject\plugins\able\source\ablecore\private	asks\abldamageeventtask.cpp:67]
UE4Editor_AbleCore!SetPromise<float,TUniqueFunction<float __cdecl(void)> &>() [d:\rocketsync\4.24.0-10570792+++ue4+release-4.24\working\engine\source\runtime\core\public\async\async.h:50]
UE4Editor_AbleCore!TGraphTask<TAsyncGraphTask<float> >::ExecuteTask() [d:\rocketsync\4.24.0-10570792+++ue4+release-4.24\working\engine\source\runtime\core\public\async	askgraphinterfaces.h:847]
UE4Editor_Core
UE4Editor_Core
UE4Editor_Core
UE4Editor_Core
UE4Editor_Core
kernel32
ntdll

Any ideas?

Also cone query seems to yield no results, but switching to box or capsule or sphere , works again.

Thanks again

Looks like something is going on in your CalculateDamageForBP method. You can also try turning off Async in the Able options as you may be doing something unsafe there (you can turn it back on once you figure out what’s going on).

You can set Cone to verbose and see what’s going on.

Verbose results in nothing being printed…
Im doing a raycast to determine bone that was hit during the collision detection… Then multiplying damage up or down based on that, feeding the float into the output.

Just a quick theoretical. If a character had 2 swords in their hands… a flaming one on the right, and an ice one on the left. During the melee, how would one determine damage type based on weapon in hand, when weapons are dynamic? How would one spawn and attach the correct particles onto the correct bone that was hit?

thanks again for the prompt reply

You can grab this collision test map (it was built for 4.24 but it should be fine for 4.25) and check the cone settings there versus your own:
https://www.dropbox.com/s/zlwu2ixgmpzclwv/AbleCollisionTest.7z?dl=0

You’d have to tie some rotating number to your animation / attack so that you know if you hit with your left or right hand (maybe use animation notifies), then when go to apply your damage, ask the character which weapon is in that hand and what the element is.

Thanks for the sample map, i’ll check it out, i’m on .24 as well.

As for that solution, it makes sense, what would be the most efficient way to read notifies on an ability/timeline?
Also, i’m still getting crashes during that raycast call and setting a couple variables onto the hit target actor… Is there a specific way to get which bone was struck during the collision query?
And thanks again for the prompt reply.

Notifies should just be reading/writing to the owning actor. The Timeline shouldn’t care. When you go to calculate damage, or apply a particle effect - you can use the Dynamic Bindings on those tasks (the + sign on some of the fields), to ask the owning Actor what weapon/effect/damage to use.

As for the raycast call, I’m not sure what’s going on there without a callstack (if you turned off the Async behavior, then it should be a new callstack). Likely you’re either accessing a null component / actor (meaning you aren’t checking the results with an IsValid check), or you’re trying to set a property on an object that doesn’t want to be written to. There should be a Blueprint helper node to get the closest bone to a ray hit - but I don’t remember the name off hand. Queries can’t get closest bone (as they just determine if something is in/out of a volume), Raycasts can as they are more precise and determine the point of a collision.

Aight. I’m slowly starting to love the System, even though I keep getting stuck on some basics.

Before I try to implement it, there’s currently no way to specify a Task TargetActor?
E.g. the first ApplyDamage Task is supposed to hit TargetActor[0], the next [1] and so on.

I tried to use the Custom Target Logic, but this will only be called initially. (which also would be my first idea, to add an additional Ability TargetType that reruns the Custom Target Logic)

Or maybe adding a BP overridable TargetSelection function that gets run on Actor TargetTypes.

Am I missing something, or am I thinking too far out of the box again?

You can add targets during an Ability using the Query tasks with “Copy to Context” turned on. If you want to specify a Target, you would have to set it up through the “Custom Target” option on the Ability itself (which just runs once, as you point out).

Hi ,

Superb plugin! I’m making a multiplayer RPG and am wondering how you would implement haste that affects the Ability playrate? This would be per character, ie if one person buffed themselves with a haste buff and then wanted to cast a hastened fireball.

From what I can see I can set the cooldown of an ability once I’ve created an ability context, perhaps it would be possible to modify the playrate here? Sorry if I missed something obvious :slight_smile:

Cheers

You can override the Ability Play Rate / Cooldown and mark the Cooldown to be updated in real time (so, if you cast a normal fireball, but then buff yourself - you can retroactively decrease the in-progress cooldown). So when you cast Haste, just put a tag on the Player “Effect.Haste” or something like that, and in the Play Rate you can check for that flag and modify the play rate as you wish.