Install any skill in seconds. Free to start, no credit card required.
Get Started Free →jame581/multithreading
Use when running work off the main thread — WorkerThreadPool, Thread/Mutex/Semaphore, call_deferred, thread-safe scene access, and threaded resource loading
Passed 21 of 23 test cases with the skill, and 14 of 23 without it.
and 6 more in the full report
8 fixed13 passed either way1 still failing1 broke
Tokens, turns and time describe resource use, not a dollar price.
One of 8 test cases the skill fixed. Same model, same prompt, with and without the skill.
In C#, you want to schedule a group task with WorkerThreadPool.AddGroupTask. What type wrapper and delegate signature are required when passing a method that processes elements by index?
| Checked | Without skill | With skill |
|---|---|---|
| Specifies wrapping the callback with Callable.From<int> when calling WorkerThreadPool.AddGroupTask in C#. | Missed | Passed |
The instructions your model reads when the skill loads.
Run expensive work off the main thread without corrupting the scene tree. Prefer WorkerThreadPool for short parallel jobs; reach for Thread/Mutex/Semaphore only when you need a long-lived worker.
Related skills: godot-optimization for profiling before threading, assets-pipeline for asset import, csharp-godot for C# specifics, gdscript-advanced for async/await pitfalls.
The main thread owns the scene tree — interacting with the active scene tree is not thread-safe. Observe these doc-sourced rules:
Rendering > Driver > Thread Model = Separate, Physics > {2D,3D} > Run on Separate Thread). Servers handle thousands of thread-driven instances well.Navigation > Pathfinding > Max Threads.Array/Dictionary: reading/writing existing elements across threads is OK; resizing (add/remove) needs a Mutex.add_child.call_deferred() — only with a single loader thread (multiple threads risk tweaking the same cached resource → crashes).Golden rule: Mutate the scene tree only on the main thread. From a worker, hand results back with
call_deferred/set_deferred.
WorkerThreadPool is a global singleton with threads allocated at startup. A regular task (add_task) runs on one worker; a group task (add_group_task) is distributed across workers, calling the Callable repeatedly for each element index — great for iterating many elements. Every task must be waited on (wait_for_task_completion / wait_for_group_task_completion) or its allocated resources leak. Distributing cheap work can hurt performance — only use it for genuinely expensive work.
var enemies = [] # Filled with enemies elsewhere.
func process_enemy_ai(enemy_index):
var processed_enemy = enemies[enemy_index]
# Expensive per-enemy logic...
func _process(delta):
var task_id = WorkerThreadPool.add_group_task(process_enemy_ai, enemies.size())
# ... other main-thread work ...
WorkerThreadPool.wait_for_group_task_completion(task_id)
test cases passed, vs 14 / 23 without
More skills from the same source and nearby in the registry, with their headline benchmark lift.