Overview
FlowKit replaces timers, tick functions and hand-written state machines with one-line latent actions. Start a delay, ticker, timeline or conditional wait from C++ with a lambda, or from Blueprints with an async node. Actions run inside a game-instance subsystem (UFKSubsystem), are bound to an owner object, and are removed automatically when that owner is destroyed.
- Timing: Delay, Delay Ticks, Ticker (for a duration, forever or until stopped).
- Timelines: float, Vector and LinearColor value timelines with linear, cubic and ease blending, plus custom timelines driven by curve assets.
- Conditions: Wait And Execute (run once a predicate is true) and While True Execute (tick while a predicate is true), both with optional time-outs.
- Gates: Time Lock, Do Once, Do N Times and Do No More Than X Time, keyed by instance ids.
- Async: run a task on a background thread and continue on the game thread; load soft object paths asynchronously.
- Control: every action returns a handle to pause, resume, reset, stop or re-time it; stop all actions, by class or by label; pause the whole subsystem.
- Coroutines (UE 5.8, C++20): write a whole sequence top to bottom with
co_await.
Requirements
| Requirement | Details |
|---|---|
| Unreal Engine | 4.27 and 5.8 (verified clean on both). The coroutine API requires 5.8. |
| Modules | FlowKit (Runtime, loading phase Default) |
| Dependencies | None |
| Language | Blueprints and C++ (coroutines: C++ only) |
| Platforms | Win64 only - the plugin descriptor allows Win64 alone, and Win64 is the platform built and verified by Alpha XP. |
Installation
- Copy the
FlowKitfolder into your project'sPlugins/folder (create it if needed), or install the plugin to the engine from Fab. - Open the project. For a C++ project, let the editor build the module or build it from your IDE.
- Enable FlowKit in Edit > Plugins (category Programming) and restart the editor.
- C++ only: add
"FlowKit"toPublicDependencyModuleNamesin your module'sBuild.csand includeFlowKit.h.
stat FlowKit shows the number of running actions.Quick start
Blueprint
- In an actor's Event Graph, add FlowKit - Delay after Event BeginPlay and set Delay Time to 2.
- Connect your logic to the On Complete output pin; its Stopped value is true when the delay was stopped early. The top exec pin continues immediately.
- Promote the Handle output to a variable. Later, call FlowKit - Stop Action with that handle to cancel the delay, or FlowKit - Pause Action / FlowKit - Resume Action to pause it.
- Expand Settings (advanced pins) to set a tick interval, a first delay, ignore game pause or time dilation, start paused, or a Label.
C++
#include "FlowKit.h"
void AMyActor::BeginPlay()
{
Super::BeginPlay();
// Run code after 2 seconds; dropped automatically if this actor is destroyed.
DelayHandle = FFlowKit::Delay(this, 2.f, [this]()
{
UE_LOG(LogTemp, Log, TEXT("Two seconds later"));
});
// Blend a value from 0 to 1 over 3 seconds with ease-in-out.
FFlowKit::AddTimeline(this, 0.f, 1.f, 3.f, [this](float Value, float Time)
{
FadeAlpha = Value;
}, [this](float Value, float Time, bool bStopped)
{
UE_LOG(LogTemp, Log, TEXT("Fade finished"));
}, EFKBlendFunc::FKBlend_EaseInOut, 2.f);
// Tick every 0.5 s for 10 s, ignoring game pause.
FFlowKit::AddTicker(this, 10.f, [this](float DeltaTime)
{
UpdateRadar();
}, [this](bool bStopped)
{
UE_LOG(LogTemp, Log, TEXT("Ticker finished"));
}, FFKActionSettings().WithTickInterval(0.5f).WithIgnorePause());
// Run once a condition is true, with a 5 second time-out.
FFlowKit::WaitAndExecute(this, [this]() { return bIsReady; }, [this](bool bTimedOut)
{
StartMatch();
}, 5.f);
}
void AMyActor::CancelDelay()
{
FFlowKit::StopAction(this, DelayHandle); // FFKHandle DelayHandle member; the handle is invalidated
}
Concepts
Owner and world
The first argument of every launch function is the owner. It also provides the world, whose game instance hosts UFKSubsystem. When the owner is destroyed the action is removed without calling its callback. Actions only tick in game and Play-In-Editor worlds, and must be started from the game thread.
Handles
Launch functions return an FFKHandle (Blueprint: FFKHandleBP). An invalid handle means the action could not start (for example a negative time or an empty callback; the reason is logged to LogFlowKit). A handle stays valid after its action ends; use FlowKit - Is Action Running / IsActionRunning to check it.
Stopping and completing
Stop functions take bComplete: false (default) removes the action silently, true runs its completion callback with bStopped = true.
Instance ids
Gates (Time Lock, Do Once, Do N Times, Do No More Than X Time) take an FFKInstanceId (Blueprint: FFKInstanceIdBP). Only one action runs per instance id; launching it again re-triggers the running one. Create ids with FFKInstanceId::NewId() or FlowKit - Get New Instance Id.
Action settings
| Field (FFKActionSettings) | Default | Description |
|---|---|---|
| TickInterval | 0 | Seconds between ticks; 0 ticks every frame. Builder: WithTickInterval(float), macro FLOWKIT_TICKINTERVAL(x). |
| FirstDelay | 0 | Delay before the first tick. WithFirstDelay(float), FLOWKIT_DELAYFIRST(x). |
| bIgnorePause | false | Keeps ticking while the game is paused. WithIgnorePause(), FLOWKIT_IGNOREPAUSE. |
| bIgnoreGlobalTimeDilation | false | Uses undilated delta time. WithIgnoreGlobalTimeDilation(), FLOWKIT_IGNORETIMEDILATION; both flags: FLOWKIT_IGNOREPAUSEDILATION. |
| bStartPaused | false | Starts the action paused; resume it with its handle. WithStartPaused(), FLOWKIT_STARTPAUSED. |
| Label | empty | Free text used by FlowKit - Stop All Actions With Label and the label queries. WithLabel(FString), FLOWKIT_LABEL(x). |
Blend functions
EFKBlendFunc: FKBlend_Linear, FKBlend_Cubic, FKBlend_EaseIn, FKBlend_EaseOut, FKBlend_EaseInOut. BlendExp (default 1) is the exponent of the ease functions. EFKAsyncPrio: Normal, HiPriority (background thread priority).
Blueprint async nodes
Category FlowKit. Each node returns immediately through its top exec pin, outputs a Handle, and fires the listed output pins later. Settings is an advanced pin.
| Node | Type | Description |
|---|---|---|
| FlowKit - Delay | Async | Inputs: Delay Time. Output: On Complete (Stopped). |
| FlowKit - Delay Ticks | Async | Inputs: Delay Ticks (frames). Output: On Complete (Stopped). |
| FlowKit - Ticker | Async | Inputs: Ticking Time (-1 ticks until stopped). Outputs: On Tick (Delta Time), On Complete (Stopped). |
| FlowKit - Wait And Execute | Async | Inputs: In Time Out (0 = none). On Wait fires every tick with the action object: call FlowKit - Predicate (WaitAndExecute) on it with true to finish. Output On Execute (Timed Out, Stopped). |
| FlowKit - Predicate (WaitAndExecute) | Callable | Called on the Action output of Wait And Execute; Has Finished = true runs On Execute. |
| FlowKit - While True Execute | Async | Inputs: Time Out. On While asks for the condition (call the predicate below), On Execute fires every tick while it is true (Delta Time), On Complete fires at the end (Timed Out, Stopped). |
| FlowKit - Predicate (WhileTrueExecute) | Callable | Called on the Action output of While True Execute; Is True = false ends the loop. |
| FlowKit - Timeline | Async | Inputs: Start Value, Stop Value, Time, Blend Func, Blend Exp. Outputs: On Tick and On Finished (Value, Time, Stopped). |
| FlowKit - Timeline Vector | Async | Same as Timeline with Vector values. |
| FlowKit - Timeline LinearColor | Async | Same as Timeline with LinearColor values. |
| FlowKit - Custom Timeline | Async | Input: Curve Float asset; plays the curve from the start to its last key. Outputs: On Tick, On Finished (Value, Time, Stopped). |
| FlowKit - Custom Timeline Vector | Async | Same with a Curve Vector asset. |
| FlowKit - Custom Timeline LinearColor | Async | Same with a Curve Linear Color asset. |
| FlowKit - Do No More Than X Time | Async | Inputs: Time, Instance Id, Max Execs Enqueued (default 1). On Execute fires at once, then at most once per Time; extra calls are queued up to the maximum. |
| FlowKit - Run Async Then | Async | Inputs: In Time Out, Priority. Async Task fires on a background thread; On Execute fires on the game thread when it is done (Timed Out, Stopped). |
| FlowKit - Load Objects Async | Async | Input: Objects To Load (soft object paths). Output: On Complete (Stopped) once all are loaded. |
Blueprint utility nodes
Static functions of UFKBPLibrary, category FlowKit.
| Node | Type | Description |
|---|---|---|
| FlowKit - Time Lock | Callable | Exec outputs Exec / Locked: runs Exec at most once per Lock Time for an Instance Id; otherwise Locked. |
| FlowKit - Set Pause Subsystem | Callable | Pauses or resumes every FlowKit action of the world's game instance. |
| FlowKit - Get Pause Subsystem | Pure | Returns whether the subsystem is paused. |
| FlowKit - Is Action Running | Pure | True while the action of the handle is running or pending. |
| FlowKit - Is Action Paused | Pure | Outputs Is Running and Is Paused. |
| FlowKit - Pause Action | Callable | Pauses one action. |
| FlowKit - Resume Action | Callable | Resumes one action. |
| FlowKit - Reset Action | Callable | Restarts an action that supports resetting (optionally calling its update); returns whether it was reset. |
| FlowKit - Get Action Time | Pure | Current time value of a delay, ticker, timeline or lock; -1 if unsupported. |
| FlowKit - Set Action Time | Callable | Sets that time value (optionally calling the update); returns false if unsupported. |
| FlowKit - Stop Action | Callable | Stops one action and invalidates the handle; Complete runs its callback. |
| FlowKit - Stop Instanced Actions | Callable | Stops the action of an instance id. |
| FlowKit - Stop All Actions | Callable | Stops every action, optionally only those of In Owner. |
| FlowKit - Stop All Actions Of Class | Callable | Stops every action of a class (for example FKDelay), optionally per owner. |
| FlowKit - Stop All Actions With Label | Callable | Stops every action with a label, optionally per owner. |
| FlowKit - Get Actions Handles By Class | Pure | Handles of running or pending actions of a class. |
| FlowKit - Get Actions Handles By Label | Pure | Handles of running or pending actions with a label. |
| FlowKit - Get Action Label By Handle | Pure | Label of the action of a handle. |
| FlowKit - Is Handle Valid | Pure | True if the handle refers to an action that was started. |
| FlowKit - Get New Instance Id | Pure | Creates a new instance id. |
| FlowKit - Validate Instance Id | Pure | Returns the id, creating a new one when it is invalid. |
| FlowKit - Is Instance Id Valid | Pure | True if the instance id is valid. |
| FlowKit - Convert Soft Objects To Soft Paths | Callable | Converts soft object references to soft object paths for FlowKit - Load Objects Async. |
| FlowKit - Convert Soft Classes To Soft Paths | Callable | Converts soft class references to soft object paths. |
| ToString (FFKHandleBP) | Pure | Auto-cast of a handle to a string. |
| ToString (FFKInstanceIdBP) | Pure | Auto-cast of an instance id to a string. |
Deprecated nodes
Kept for compatibility and marked deprecated in the editor; use FlowKit - Stop All Actions Of Class instead.
| Node | Type | Description |
|---|---|---|
| FlowKit - Remove All Time Locks | Callable | Stops all time locks. |
| FlowKit - Remove All Delays | Callable | Stops all delays. |
| FlowKit - Remove All Wait And Executes | Callable | Stops all Wait And Execute actions. |
| FlowKit - Remove All While True Executes | Callable | Stops all While True Execute actions. |
| FlowKit - Remove All Run Async Thens | Callable | Stops all Run Async Then actions. |
| FlowKit - Remove All Tickers | Callable | Stops all tickers. |
| FlowKit - Remove All Timelines | Callable | Stops all float timelines. |
| FlowKit - Remove All Timelines Vector | Callable | Stops all Vector timelines. |
| FlowKit - Remove All Timelines LinearColor | Callable | Stops all LinearColor timelines. |
| FlowKit - Remove All Custom Timelines | Callable | Stops all float custom timelines. |
| FlowKit - Remove All Custom Timelines Vector | Callable | Stops all Vector custom timelines. |
| FlowKit - Remove All Custom Timelines LinearColor | Callable | Stops all LinearColor custom timelines. |
| FlowKit - Remove All Do No More Than X Times | Callable | Stops all Do No More Than X Time actions. |
C++ API
All functions are static members of FFlowKit (header FlowKit.h). Launch functions take the owner first and return an FFKHandle; callbacks are lambdas, and most have overloads with and without the bStopped / bTimedOut parameters. The last parameter is an optional FFKActionSettings.
| Function | Kind | Description |
|---|---|---|
| Delay | Launch | (Owner, DelayTime, Callback); callback void() or void(bool bStopped). |
| DelayTicks | Launch | (Owner, int32 Ticks, Callback). |
| AddTicker | Launch | (Owner, [TickingTime], TickFunc, [Callback]); tick void(float) or void(float, FFKHandle); without a time (or -1) it ticks until stopped. |
| WaitAndExecute | Launch | (Owner, Predicate, Callback, TimeOut = 0); predicate bool() or bool(float DeltaTime). |
| WhileTrueExecute | Launch | (Owner, Predicate, TickFunc, CompleteFunc, TimeOut = 0). |
| AddTimeline / AddTimelineVector / AddTimelineLinearColor | Launch | (Owner, Start, Stop, Time, TickFunc, [Callback], BlendFunc, BlendExp). |
| AddCustomTimeline / AddCustomTimelineVector / AddCustomTimelineLinearColor | Launch | (Owner, Curve, TickFunc, [Callback]) with UCurveFloat, UCurveVector or UCurveLinearColor. |
| TimeLock | Launch | (Owner, LockTime, ExecFunc, InstanceId); runs at once, then ignores calls until the lock time passes. |
| DoOnce | Launch | (Owner, ExecFunc, InstanceId); runs once per instance id; further launches are ignored until the action is reset or stopped. |
| DoNTimes | Launch | (Owner, Times, ExecFunc(int32 Counter), InstanceId). |
| DoNoMoreThanXTime | Launch | (Owner, ExecFunc, Time, MaxExecsEnqueue, InstanceId). |
| RunAsyncThen | Launch | (Owner, AsyncTaskFunc, Callback, TimeOut = 0, Priority); the task runs on a background thread, the callback on the game thread. |
| LoadObjectsAsync | Launch | (Owner, TArray<FSoftObjectPath>, Callback). ConvertSoftPtrToSoftPath converts soft pointer arrays. |
| IsActionRunning / IsActionPaused | Query | State of an action. |
| PauseAction / ResumeAction / ResetAction | Control | Control one action. |
| GetActionTime / SetActionTime | Control | Read or set the time value of an action. |
| StopAction / StopInstancedAction | Control | Stop one action (bComplete runs its callback). |
| StopAllActions / StopAllActionsOfClass / StopAllActionsWithLabel | Control | Stop groups of actions; StopAllActionsOfClass<UFKDelay>(this) has a template form. |
| SetPause / GetPause | Control | Pause the whole subsystem. |
| GetActionsHandlesByClass / GetActionsHandlesByLabel | Query | Find handles. |
| GetAllActions / GetActionsCount / GetActionFromHandle / GetActionLabelFromHandle / GetActionFromInstancedId | Debug | Inspect running actions. |
The RemoveAll... functions of FFlowKit are deprecated in favour of StopAllActionsOfClass. Action classes: UFKDelay, UFKDelayTicks, UFKTicker, UFKWaitAndExecute, UFKWhileTrueExecute, UFKTimeline, UFKTimelineVector, UFKTimelineLinearColor, UFKCustomTimeline, UFKCustomTimelineVector, UFKCustomTimelineLinearColor, UFKTimeLock, UFKDoOnce, UFKDoNTimes, UFKDoNoMoreThanXTime, UFKRunAsyncThen, UFKLoadObjectsAsync.
Coroutines (UE 5.8)
On Unreal Engine 5.8 (C++20) FLOWKIT_WITH_COROUTINES is 1 and a member function returning FFKCoroutine can co_await FlowKit awaiters. On UE 4.27 the macro is 0 and FFKCoroutine is void, so the declaration still compiles; guard the body as shown when the same source must build on both engines.
// MyComponent.h
FFKCoroutine IntroSequence();
// MyComponent.cpp
#include "FlowKit.h"
FFKCoroutine UMyComponent::IntroSequence()
{
#if FLOWKIT_WITH_COROUTINES
const bool bStopped = co_await FFlowKit::WaitSeconds(this, 2.f);
if (bStopped)
{
co_return;
}
co_await FFlowKit::WaitTicks(this, 1);
const FFKCoroutineAwaiter_ResultWithTimeout Ready = co_await FFlowKit::WaitUntil(this, [this]() { return bIsReady; }, 5.f);
if (Ready.bTimedOut == false)
{
co_await FFlowKit::RunAsyncAndWait(this, []() { /* background work */ });
}
#endif
}
| Awaiter | Kind | Description |
|---|---|---|
| WaitSeconds | co_await | Waits a time; returns bool bStopped. |
| WaitTicks | co_await | Waits a number of ticks; returns bStopped. |
| WaitUntil | co_await | Waits for a predicate (bool() or bool(float)) with optional time-out; returns FFKCoroutineAwaiter_ResultWithTimeout (bStopped, bTimedOut). |
| WaitForFlag | co_await | Waits until a bool* becomes true, with optional time-out. |
| LoopAndWait | co_await | Ticks a function while a predicate is true, with optional time-out. |
| RunAsyncAndWait | co_await | Runs a task on a background thread and resumes on the game thread. |
| WaitLoadObjects | co_await | Loads soft object paths or primary asset ids asynchronously; returns bStopped. |
If the owner is destroyed while a coroutine is suspended, the coroutine is destroyed without resuming.
Profiling and logs
stat FlowKitshows the number of actions, instanced actions and action objects;stat FlowKitDetailsshows the tick cost per action type.- Unreal Insights shows FlowKit - ... Tick scopes while
FLOWKIT_INSIGHT_PROFILINGis 1 (default). - Messages use the
LogFlowKitcategory.FLOWKIT_LOGSandFLOWKIT_LOGS_VERBOSEare set inSource/FlowKit/FlowKit.Build.cs.
Troubleshooting
| Symptom | Cause and fix |
|---|---|
| Action never runs and the handle is invalid | Setup failed: check LogFlowKit for the reason (for example a negative or zero time, an empty callback or a missing curve). |
| Nothing happens in an editor utility or editor world | The subsystem only ticks in game and Play-In-Editor worlds. Start actions from gameplay objects. |
| Error: Can't obtain GameInstance from WorldContextObject | The owner has no world with a game instance (for example a default object or an asset). Pass an actor, component or other object that lives in the game world. |
| Callback did not fire after the actor was destroyed | By design: actions are removed silently when their owner is destroyed. Use an owner that lives long enough, or stop the action with bComplete = true before destroying it. |
| Action stops while the game is paused | Paused worlds pause FlowKit actions unless bIgnorePause is set in the action settings. |
| AddTicker / AddTimeline call is ambiguous | Each of these functions has callback overloads with and without bStopped, so a missing or nullptr callback cannot pick one. Always pass a callback lambda (it may be empty), for example [](bool bStopped) {}. |
| Crash or assert when starting an action from another thread | Actions must be started from the game thread. Use RunAsyncThen to move work to a background thread and back. |
| co_await does not compile on UE 4.27 | Coroutines require UE 5.8 (C++20). Guard coroutine bodies with #if FLOWKIT_WITH_COROUTINES. |
Credits
© 2026 Alpha XP — alphaxp.net · Support: support@alphaxp.net. Built and verified for Unreal Engine 4.27 and 5.8.