I am currently investigating ways in which to spread out intensive Blueprint work across multiple ticks where possible, especially with Loops & AI.
It’s not possible to add an ‘Event Recieve Tick’ into Macros so I could really do with a new ‘Wait For New Tick’ Node that I can add to Blueprints and has an output that fires once the current Tick has ended.
Based on work on other projects, I can see as a valuable Node that will help with Blueprint optimisations across many different projects and so think the community would benefit from it too.
Hope you take no offense, but what prevents you to give a macro multiple input to say a gate, and you can always drive a CustomEvent that fires right after EventTick?
(loop with break is a perfect example for multiple input/output with local vars)
To me request raise a big red flag to parallelism, all of a sudden you can now have a wait for something in events, people would then exploit it and then complaint why the performance is bad.
Event are suppose to be fire and forget, you know it will complete, you don’t know when, you don’t know if it ends with success/fail branch, it is suppose to be independent tasks and run off whatever they can get off available variables.
It’s already bad enough if you have one event that relies on result of another, there was a thread I helped debug shows exactly how a problem might occur if you don’t take UE4’s event system serious.
No offense taken, an idea challenged guarantees a good result
First, I think we’re getting our terminlogy confused though, I’m not asking for an Output to be added to the ‘Event Recieve Ticket’ event, but a new self-contained Node. I assume a Node is Blueprint’s equivilant of Kismet’s Actions. I know UE3 & UE4’s Event systems well, and after trying to tutor other Desingers in good Event etiquette in UE3 (chains of Remote Events = pain!) I’m relieved that Epic have introduced formalities into the Event system to make it harder to abuse.
Now personally, a Macro shouldn’t have to rely on an external events to drive its core logic. The user should just be plugging in data for the Macro to process.
Regarding parallelism, is something that people will be getting used to anyway when it comes to handling delays in logic. I’m used to being able to end a frame in code (almost) anywhere in my logic so I can spread data out across multiple frames. AI is usually an area where logic gets spread across multiple frames in many games, so if someone is looking to work on sophisticated AI in Blueprints, it should be easy to them to be able to do the same.
If Blueprints are about empowering people to do what they could do in C++ without the need to learn C++ then it shouldn’t hold something back because a user might not be able to handle it, instead there should be the support to learn how to handle it. Unless it’s garbage collection. C++ can keep that
Following up on TheJamsh’s comment, doing the following (see attached) will cause the tick event to only fire 10 times per second (.1 duration), you can customize the amount to get every other tick, or whatever you are wanting to do. It is fairly basic, but works.
I didn’t know tick was that easy to carve up, though I haven’t yet needed it in my project. I have seen a lot of people have problems though. At first I thought the tick would have just called lots of delays which would have piled up and fired many times anyway, but thinking it through the delay makes perfect sense.
DH, that will cause my Blueprints to swell up to ridiculous sizes. is why Macros exist.
Jamish, again, surely the point of a Macro is to perform lots of logic on a stream of data.
, your idea is precisely what I’m trying to avoid (but using as a work around for now). I don’t want to spread Blueprint logic checking out across time, during which framerates will vary in different parts of the game and from machine to machine, but spread them evenly across Ticks.
There are always going to be a few cases where you can do something already within BP but an all encompassing hard coded node is better. Epic could ditch the Delay node and let everyone work out timings for themselves using the Delta Seconds output from the Event Recieve Tick. They could ditch the Vector Length node and let you handle that yourself.
Considering the amount of times I and others have used a simple command to end a frame or tick before progressing with logic, mainly for optimisation purposes, I feel that it would be a valuable command.
Zeustiak, a Tick is how long a particular component of the engine takes to complete during a frame. The combined tick lengths will be how long a frame is.
Unreal Script in UE3 was 20 x slower than C++. I’ve heard that Blueprints, which are exported to a more optimial form of Unreal Script, are around 10 x slower than C++. I don’t know what upcoming speed gains for BPs are in 4.5, but it will still lag behind C++. BP AI will certainly be an area people will be looking to claw back performance from in the future.
I want to be able to spread intensive Blueprint work evenly across ticks in order to distribute heavy workloads over a short period of time. In practical terms is mostly applies to the amount of traces I’m doing for AI characters. Alot of AI characters.
The best way to do is to add a ‘Wait For Tick To End’ delay Node (if it was created) into my array loops. It’s common practice in AI optimisations and something I’ve done alot of times before in code.
I don’t want to do using the Delay node or the interval option in BTs in loops because they don’t take into account framerate. You would have ticks where no work is being done and then ticks where alot of work is being done and all of would vary between different hardware configurations, rather than an even spread of work across all ticks.
Using the ‘Event Recieve Tick’ isn’t ideal isn’t ideal because you cannot add ‘Events’ to Macros. Whilst using combining it with gates and ints to do are possible, they’re unnecessary complicated and defeat the point of what a Macro should be there to do.
Considering how easy it is to wait for a tick to end in Code & how useful it is for optimastion it makes sense for a simple ‘Wait for Tick to End’ Node to be created. You could also do with a tick box option on the ‘Delay’ node but Blueprints are about moving away from the tickbox heavy actions found in Kismet.
At the moment I’m working on a game with a large amount of enemies and a large amount of data fed to them from custom objects the world around them that are interlinks. As a result there are a large amounts of arrays on each AI gathering information around them. is currently done every frame. I want to distribute these checks evenly over multiple ticks.
I have created a custom ForEachLoop that has a ‘Delay’ input, similar to the Epic YouTube tutorial, which I use for alot of data gathering and checking. However, if the delay is 0 (default) then I want the Delay to just wait for the current tick to end before proceeding with the next pass of the loop.
At a higher level & at a later date I also want to use new Node in a global AI that allows me to spread other checks across ticks, such as path creating, and possibly some collision detection too.
You’ll even see good A* searches (on low end hardware) spread their searches over multiple frames and final paths updating in realtime to reflect .
I’ve scripted in Lua, UnrealScript & C# in the past, but as a Designer I’ve not gotten used to the nitty gritty of C++ and have had the benefit of working alongside Code departments to handle that for me. As a result I want to use my first UE4 to bring me up to speed with all areas of the engine, and then my next one will involve me delving into C++. I have budgets and deadlines to consider so doing both isn’t feasible.
From past experience, UE3 wasn’t very efficient with characters, in earlier versions you’d get jsut 8 AI characters (before crowd actors came along) running well on consoles without going through kind of optimising process, and that was coming from working on Wii & Gamecube games where I was used to working with 40+ bipeds and 4 or 5 physics vehicles working on screen at once at 30fps.
There are plenty of articles across the web on distributing AI and collision checks over time to save performance. But doing over ticks is alot more efficient than just adding delays between results whilst dealing with variable framerates.
In some cases you could also take the previous delta time (or average over a number of frames) and use that as a multiplier so that if a user is going above certain thresholds then the code is more willing to do more checks per tick. But I’m not going anywhere near that now
Lets look at a single enemy, how exactly are you gathering the information from around the enemy. Lets say you have 1 enemy and 10 objects spread throughout the world. How would each enemy check these 10 objects, and what are they looking for from them?
Edit: There are certain things that do run very slow in blueprint compared to C++.
I have created set of custom target points around the world, each detailing specfics about that area, usually tactical information such as height, low cover, dead ends etc. These frequently have slots in them for adjacent or other target points that may be relevent.
I will gather some node information by radius, and some by LoS, then cast to them to get the nodes they refer to (if needed). Then store the data in a variety of arrays that I run through to check against other data.
is all used to determine where an enemy should go relevent to the player’s current position, the player’s estimated position and / or other enemy positions.
radius may be the player’s current position*, the enemy’s current position or a prediction of where the player may be based on when the was spotted last. As you can imagine, the amount of data that needs to be run through increases significantly with the size and complexity of rooms and the number of enemies around.
*I actually have a timestamp of the player’s previous location every frame for 0.5 seconds and each enemy follows that, with the delay based on a variety of factors to mimic reaction times, such as distance from and direction to the target.
Also, I’ve also just realised that in the Behaviour Tree itself you can only set the main Service to run in periods defined by seconds, not frames. makes timings more complicated too with ticks being wasted on doing nothing & it’s not clear how mulitple BTs spread their work load across frames.
I appreciate that people here may not be used to doing it but after working on so many titles that do handle AI like , it makes perfect sense to me. The suggestions on the rest of thread don’t work to me because:
Using delays based on fractions of a second result in spikes and troughs rather than an even spread of workloads.
Events can’t be added to Macros
Due to its frequent use, should be something that can be slotted in anywhere into a Blueprint as easily as a delay.
I said I don’t want to use an Event, but it’s the only way to currently know when a new tick has begun. Ideally I want to be able to insert Wait quickly into my Blueprints via a single node, which is reason why I tried creating a Macro. However the fact that it requires an event to sit outside of it doesn’t help, and that is the reason why I’m asking Epic for as a hard coded Node is so that it can be easily placed anywhere in Blueprints and not copy & pasted about.
I have different types of traces (single, multi, line & sphere) for different checks. I have my own LoS cone system that searches first by radius, then by cone and then does a visibility check to be as efficient as possible. I don’t need help with the structure of my Blueprints or the order of my checks, they’re as efficent as they can be currently.
I haven’t finished the AI yet, nor have I locked down specs or final enemy counts, but if I can build an AI system to be as efficient as possible based on commonly used techniques now then I would prefer to do that and not have to retrofit those optimisations in further down the line.
JamesG, I’m currently using timers, but it’s not the most optimal solution because at high framerates you end up with lots of ticks where nothing is happening, whilst at low framerates delayed work can bunch up and slow a frame down further.
also affects the intervals that Services in Behaviour Trees run at.
It’s also worth noting that another area could be useful is when Spawning Pawns.
was quite an intensive process in UE3 and if you spawned too many in a single frame then the tick length could be pretty high (working out an initial physics state was one of the culprits here) and the user would notice pauses larger than a second. Epic recommend manually staggering the spawning across time in Kismet, however it was more efficient and quicker to spawn large groups if you queued them up in an array and spawn them once at a time in a tick. was done in US.
I don’t know if is going to be as much an in UE4, however I will also be dealing with much larger enemy numbers too.