Skip to content

Parallel Work

When a script has expensive, parallelizable compute (generating a heightfield, processing a large array, baking data), the Task library spreads it across the engine’s worker threads. This is the C# mirror of the native Lumina::Task system.

Task.ParallelFor(count, body) splits [0, count) across the worker pool and runs body(i) for each index. It blocks until every index is done, so the results are ready when it returns.

FVector3[] Points = ...;
float[] Heights = new float[Points.Length];
Task.ParallelFor(Points.Length, i =>
{
Heights[i] = SampleNoise(Points[i]); // pure compute, no engine calls
});
// Heights is fully populated here.

Have each index write to its own slot (as above) so the workers never touch the same memory.

Task.Run(body) schedules body to run once on a worker thread and returns a TaskHandle to wait on. You own the handle, Wait() for completion, then dispose it (a using block is the safe pattern).

using TaskHandle Handle = Task.Run(() => BakeLightingData());
// ... do unrelated work on the game thread ...
Handle.Wait(); // block until the bake finishes
CallDoes
Task.ParallelFor(count, body)Run body(i) for each index across workers; blocks until done.
Task.Run(body)Run body once on a worker; returns a TaskHandle.
Task.WaitForAll()Block until every submitted task has completed.
Task.WorkerCountNumber of background worker threads.

C# scripts don’t have coroutines that pause mid-hook. To run something after a delay, or to step through a sequence, drive it from OnUpdate with a small amount of state, accumulate DeltaTime and act when a timer elapses.

private float _OpenIn = -1.0f; // < 0 means "not opening"
public void BeginOpen()
{
_OpenIn = 0.25f; // open a quarter-second from now
}
public override void OnUpdate(float DeltaTime)
{
if (_OpenIn >= 0.0f)
{
_OpenIn -= DeltaTime;
if (_OpenIn < 0.0f)
{
Open();
}
}
}

For multi-step sequences, a small enum state machine advanced in OnUpdate keeps the logic readable without blocking the frame. State held in instance fields is naturally cleaned up when the entity is destroyed.