Agent skill

Multithreading

by jame581 in jame581/GodotPrompter

A skill your agent uses when running work off the main thread — WorkerThreadPool, Thread/Mutex/Semaphore, calldeferred, thread-safe scene access, and threaded resource loading

MITAuto-check passedGame Development

Install Multithreading

skills CLI
$ npx skills add jame581/GodotPrompter --skill multithreading -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install jame581/GodotPrompter multithreading --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/jame581/GodotPrompter.git skills-src && mkdir -p .claude/skills && cp -r skills-src/skills/multithreading .claude/skills/multithreading && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
multithreading
GitHub stars
792
Token cost
~2.7k tokens
SKILL.md length
625 words
Files
2 (incl. references)
Skills in repo
58
Repo updated
First seen
Licence
MIT

At a glance

A skill your agent uses when running work off the main thread — WorkerThreadPool, Thread/Mutex/Semaphore, calldeferred, thread-safe scene access, and threaded resource loading

  • Works in 6 steps: Threading model & safety rules → WorkerThreadPool (preferred) → Thread / Mutex / Semaphore → …
  • Running work off the main thread — WorkerThreadPool
  • SKILL.md covers 1. Threading model & safety…, 2. WorkerThreadPool (preferred), 3. Thread / Mutex / Semaphore and 4. Handing results back:…, plus 3 more sections
  • Instructions only: no scripts, shell commands, URLs or credentials in SKILL.md

What it does

Multithreading is an agent skill from jame581/GodotPrompter. Use when running work off the main thread — WorkerThreadPool, Thread/Mutex/Semaphore, calldeferred, thread-safe scene access, and threaded resource loading

Its SKILL.md is about 2.7k tokens, which your agent loads only when the skill is triggered. The skill folder holds 2 other files, including reference files (for example `references/pitfalls.md`).

It sits in Game Development, covering Async programming and Game development. It works with Godot and C#. The repository describes itself as: Agentic skills framework for Godot 4.x. Domain-specific skills for AI coding agents (Claude Code, Copilot, Antigravity, Cursor). The licence is MIT.

When your agent uses it

  • Running work off the main thread — WorkerThreadPool
  • Thread/Mutex/Semaphore
  • Thread-safe scene access
  • Threaded resource loading

Example prompts

  • “/multithreading”

Workflow steps

6 steps, taken from the step headings in SKILL.md.

  1. Threading model & safety rules
  2. WorkerThreadPool (preferred)
  3. Thread / Mutex / Semaphore
  4. Handing results back: call_deferred / set_deferred
  5. Threaded resource loading
  6. C# concurrency: Tasks vs Godot threads

What it can do on your machine

Read from SKILL.md and the folder at commit 1e7d79d. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    No scripts in the folder and no shell commands in SKILL.md (its code samples are csharp and gdscript).

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    Links to these hosts (documentation or services it may open):

    • github.com

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names no API keys, tokens, secrets or passwords.

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

Multithreading loads about 2.7k tokens when it runs, and up to ~3.8k if it reads all its reference files. Until then it costs about 43 tokens; SKILL.md has 625 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~43
When it runs · the whole SKILL.md, loaded when a task matches
~2.7k
With references · SKILL.md plus every file in references/, read only if the agent opens them
~3.8k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check passed

The automated check found no risky patterns in SKILL.md.

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.

SKILL.md

The full file from jame581/GodotPrompter at commit 1e7d79d, republished under its MIT licence (© jame581). 625 words, ~2,747 tokens.

Download SKILL.mdSave it as .claude/skills/multithreading/SKILL.md (or your agent's skills folder). This skill also uses 1 other file; get the full folder from GitHub.
name
multithreading
description
Use when running work off the main thread — WorkerThreadPool, Thread/Mutex/Semaphore, call_deferred, thread-safe scene access, and threaded resource loading

Multithreading

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.


1. Threading model & safety rules

The main thread owns the scene tree — interacting with the active scene tree is not thread-safe. Observe these doc-sourced rules:

  • Servers (RenderingServer, PhysicsServer) are thread-safe only after enabling it in Project Settings (Rendering > Driver > Thread Model = Separate, Physics > {2D,3D} > Run on Separate Thread). Servers handle thousands of thread-driven instances well.
  • NavigationServer2D/3D are thread-safe and thread-friendly (true parallel queries); tune Navigation > Pathfinding > Max Threads.
  • AStar2D/3D/Grid2D are NOT thread-safe — one dedicated thread per object only; sharing one object across threads corrupts data.
  • GDScript Array/Dictionary: reading/writing existing elements across threads is OK; resizing (add/remove) needs a Mutex.
  • No GPU work off the main thread (texture creation, image read/modify) — causes RenderingServer sync stalls.
  • Build scene chunks off-tree in a thread, then add them on the main thread via 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.


2. WorkerThreadPool (preferred)

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.

GDScript
gdscript
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)
    # Safe to read results now.
C# Equivalent
csharp
private List<Node> _enemies = new(); // Filled with enemies elsewhere.

private void ProcessEnemyAI(int enemyIndex)
{
    Node processedEnemy = _enemies[enemyIndex];
    // Expensive per-enemy logic...
}

public override void _Process(double delta)
{
    long taskId = WorkerThreadPool.AddGroupTask(Callable.From<int>(ProcessEnemyAI), _enemies.Count);
    // ... other main-thread work ...
    WorkerThreadPool.WaitForGroupTaskCompletion(taskId);
    // Safe to read results now.
}

This relies on the element count staying constant during the multithreaded part.


3. Thread / Mutex / Semaphore

Real signatures: Thread.start(callable: Callable, priority := PRIORITY_NORMAL), wait_to_finish() (blocks; join before free), is_alive(). Mutex is reentrant (lock/unlock/try_lock). Semaphore exposes wait() / post(count := 1).

GDScript

The canonical semaphore producer/consumer + clean-shutdown idiom:

gdscript
var counter := 0
var mutex: Mutex
var semaphore: Semaphore
var thread: Thread
var exit_thread := false

func _ready():
    mutex = Mutex.new()
    semaphore = Semaphore.new()
    thread = Thread.new()
    thread.start(_thread_function)

func _thread_function():
    while true:
        semaphore.wait() # Block until there is work.

        mutex.lock()
        var should_exit = exit_thread
        mutex.unlock()
        if should_exit:
            break

        mutex.lock()
        counter += 1
        mutex.unlock()

func increment_counter():
    semaphore.post() # Wake the worker.

func _exit_tree():
    mutex.lock()
    exit_thread = true
    mutex.unlock()
    semaphore.post()        # Unblock so it can see exit_thread.
    thread.wait_to_finish() # Join.
C# Equivalent

Godot.Mutex/Godot.Semaphore also exist, but System.Threading is idiomatic in C#:

csharp
using Godot;
using System.Threading;

public partial class Worker : Node
{
    private int _counter;
    private readonly object _lock = new();
    private readonly SemaphoreSlim _semaphore = new(0);
    private Thread _thread;
    private volatile bool _exitThread;

    public override void _Ready()
    {
        _thread = new Thread(ThreadFunction) { IsBackground = true };
        _thread.Start();
    }

    private void ThreadFunction()
    {
        while (true)
        {
            _semaphore.Wait();           // Block until there is work.
            if (_exitThread) break;
            lock (_lock) { _counter++; }
        }
    }

    public void IncrementCounter() => _semaphore.Release(); // Wake the worker.

    public override void _ExitTree()
    {
        _exitThread = true;
        _semaphore.Release();            // Unblock so it can see _exitThread.
        _thread.Join();                  // Join.
    }
}

Thread creation is slow (especially on Windows) — pre-create before heavy work, not just-in-time. Over-locking mutexes is also costly.


4. Handing results back: call_deferred / set_deferred

GDScript
gdscript
# Unsafe from a worker thread:
world.add_child(enemy)
# Safe:
world.add_child.call_deferred(enemy)
Show full SKILL.md (261 more words)Show less
C# Equivalent
csharp
// Unsafe from a worker thread:
world.AddChild(enemy);
// Safe — use the MethodName StringName constant, NOT "AddChild":
world.CallDeferred(Node.MethodName.AddChild, enemy);

In C#, CallDeferred("AddChild") fails — the deferred/Call/Connect APIs use Godot's snake_case names. Prefer the Node.MethodName.* constants (avoids the pitfall and an allocation).


5. Threaded resource loading

ResourceLoader.load_threaded_request(path) starts the load. Poll load_threaded_get_status(path, progress) each frame (progress[0] is the 0–1 ratio); on THREAD_LOAD_LOADED call load_threaded_get(path). load_threaded_get blocks like load() if the load is not finished — always poll first. Statuses: THREAD_LOAD_INVALID_RESOURCE / THREAD_LOAD_IN_PROGRESS / THREAD_LOAD_FAILED / THREAD_LOAD_LOADED.

GDScript
gdscript
const SCENE_PATH := "res://enemy.tscn"
var _progress: Array = []

func _ready():
    ResourceLoader.load_threaded_request(SCENE_PATH)

func _process(_delta):
    var status := ResourceLoader.load_threaded_get_status(SCENE_PATH, _progress)
    match status:
        ResourceLoader.THREAD_LOAD_IN_PROGRESS:
            $ProgressBar.value = _progress[0] * 100.0
        ResourceLoader.THREAD_LOAD_LOADED:
            var scene: PackedScene = ResourceLoader.load_threaded_get(SCENE_PATH)
            add_child(scene.instantiate())
            set_process(false)
        ResourceLoader.THREAD_LOAD_FAILED, ResourceLoader.THREAD_LOAD_INVALID_RESOURCE:
            push_error("Threaded load failed: %s" % SCENE_PATH)
            set_process(false)
C# Equivalent
csharp
private const string ScenePath = "res://enemy.tscn";
private readonly Godot.Collections.Array _progress = new();

public override void _Ready() => ResourceLoader.LoadThreadedRequest(ScenePath);

public override void _Process(double delta)
{
    var status = ResourceLoader.LoadThreadedGetStatus(ScenePath, _progress);
    switch (status)
    {
        case ResourceLoader.ThreadLoadStatus.InProgress:
            GetNode<ProgressBar>("ProgressBar").Value = (double)_progress[0] * 100.0;
            break;
        case ResourceLoader.ThreadLoadStatus.Loaded:
            var scene = (PackedScene)ResourceLoader.LoadThreadedGet(ScenePath);
            AddChild(scene.Instantiate());
            SetProcess(false);
            break;
        case ResourceLoader.ThreadLoadStatus.Failed:
        case ResourceLoader.ThreadLoadStatus.InvalidResource:
            GD.PushError($"Threaded load failed: {ScenePath}");
            SetProcess(false);
            break;
    }
}

Godot 4.7+: 4.7 shipped several threaded-load correctness fixes — load_threaded_get() deadlocks (GH-119757, GH-120077), a race in load_threaded_request() (GH-118824), and resources returned by load_threaded_get() never being unloaded (GH-119394). No API change; if you carry workarounds for rare threaded-load hangs or leaks from earlier versions, re-test on 4.7 before keeping them. The poll-before-get rule above still applies.


6. C# concurrency: Tasks vs Godot threads

In C#, prefer System.Threading.Tasks.Task.Run / async-await for fire-and-forget CPU work; never touch Godot objects or await ToSignal(...) from a background thread — marshal results back with CallDeferred. Use WorkerThreadPool when you want Godot's pool and engine integration; use Task when you want .NET idioms. (GDScript users: use WorkerThreadPool or Thread from the sections above.)

csharp
public override void _Process(double delta)
{
    if (Input.IsActionJustPressed("compute"))
    {
        _ = System.Threading.Tasks.Task.Run(() =>
        {
            int result = ExpensiveComputation();   // Pure CPU work, no Godot objects.
            CallDeferred(MethodName.OnComputed, result); // Marshal back to main thread.
        });
    }
}

private void OnComputed(int result) => GD.Print($"Done: {result}");

Deeper: see Pitfalls & deadlocks for data races, the ERR_BUSY nested-wait deadlock, and when threading hurts.


Implementation Checklist

  • Profiled first — confirmed the work is genuinely CPU-expensive (see godot-optimization)
  • Scene-tree mutations happen only on the main thread (call_deferred / set_deferred)
  • Every WorkerThreadPool task is waited on (wait_for_*_completion)
  • Shared state guarded by a Mutex / lock; container resizes are locked
  • Threads joined (wait_to_finish / Join) before the owning node frees
  • No GPU calls, no AStar sharing, no same-resource loads across threads
  • Threaded loads poll status before calling load_threaded_get

© jame581, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

SKILL.md and 1 other file (references) in skills/multithreading of jame581/GodotPrompter.

  • SKILL.md
  • references/pitfalls.md

Open the folder on GitHubat commit 1e7d79d

Compare with similar skills

Multithreading next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

Multithreading compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Multithreading this skilljame581/GodotPrompter792—~2.7kAutomated safety check: PassMIT
Release Managerpoingstudios/godot-admob-plugin631—~357Automated safety check: PassMIT
Godot Admob App Openpoingstudios/godot-admob-plugin631—~1kAutomated safety check: PassMIT
Godot Admob Bannerpoingstudios/godot-admob-plugin631—~718Automated safety check: PassMIT
Godot Admob Get Startedpoingstudios/godot-admob-plugin631—~1kAutomated safety check: PassMIT
Godot Admob Interstitialpoingstudios/godot-admob-plugin631—~1.1kAutomated safety check: PassMIT

Similar skills

  • Release Manager

    poingstudios/godot-admob-plugin

    Manage and execute AdMob plugin releases. An agent skill from poingstudios/godot-admob-plugin.

    631 GitHub stars~357 tokensUpdated 6 days ago
    Game DevelopmentAuto-check passed
  • Godot Admob App Open

    poingstudios/godot-admob-plugin

    Provides instructions to implement, load, show, and destroy App Open ads (shown on application startup or app resume) in GDScript and C.

    631 GitHub stars~1k tokensUpdated 6 days ago
    Game DevelopmentAuto-check passed
  • Godot Admob Banner

    poingstudios/godot-admob-plugin

    Provides instructions to implement, load, and destroy banner ads (AdView) using custom or adaptive sizes in GDScript and C.

    631 GitHub stars~718 tokensUpdated 6 days ago
    Game DevelopmentAuto-check passed
  • Godot Admob Get Started

    poingstudios/godot-admob-plugin

    Provides instructions to initialize the Godot AdMob SDK and configure user consent (UMP Flow) in GDScript and C.

    631 GitHub stars~1k tokensUpdated 6 days ago
    Game DevelopmentAuto-check passed
  • Godot Admob Interstitial

    poingstudios/godot-admob-plugin

    Provides instructions to implement, load, show, and destroy interstitial ads (full-screen image/text ads) in GDScript and C.

    631 GitHub stars~1.1k tokensUpdated 6 days ago
    Game DevelopmentAuto-check passed
  • Godot Admob Native Overlay

    poingstudios/godot-admob-plugin

    Provides instructions to implement, load, show, and destroy Native Overlay ads (customized/native-looking Control node template overlays) in GDScript and C.

    631 GitHub stars~1k tokensUpdated 6 days ago
    Game DevelopmentAuto-check passed

More from jame581/GodotPrompter

All 58 skills in this repo
  • Godot 2D Essentials

    jame581/GodotPrompter

    Covers Godot 4.3+ 2D systems with GDScript and C# examples: canvas layers, draw order, TileMaps, parallax, lights and shadows, particles and custom drawing.

    792 GitHub stars~2.3k tokensUpdated yesterday
    Auto-check passed
  • Godot 3D Essentials

    jame581/GodotPrompter

    Covers Godot 4.3+ 3D systems such as materials, lighting, shadows, environment, global illumination, fog, LOD, occlusion culling and decals, with GDScript first and C# second.

    792 GitHub stars~3.7k tokensUpdated yesterday
    Auto-check passed
  • Godot Ability System

    jame581/GodotPrompter

    Builds a data-driven ability system in Godot 4 from Resources and a component node, with cooldowns, buffs, stat modifiers, gameplay tags and HUD binding.

    792 GitHub stars~3k tokensUpdated yesterday
    Auto-check passed
  • Godot Addon Development

    jame581/GodotPrompter

    Covers Godot 4.3+ editor plugins: plugin folders, @tool scripts, the EditorPlugin lifecycle, custom inspectors, dock panels and gizmos, in GDScript and C#.

    792 GitHub stars~3.3k tokensUpdated yesterday
    Auto-check passed
  • Godot AI Navigation

    jame581/GodotPrompter

    Covers pathfinding and enemy movement in Godot 4.3 and later: navigation regions, NavigationAgent nodes, steering, behavior trees and patrol routes.

    792 GitHub stars~3.5k tokensUpdated yesterday
    Auto-check passed
  • Godot Animation System

    jame581/GodotPrompter

    Covers animation in Godot 4.3 and later: AnimationPlayer basics, AnimationTree blend trees and state machines, sprite animation, skeleton IK and code-driven motion.

    792 GitHub stars~3.8k tokensUpdated yesterday
    Auto-check passed

Works with

Questions about Multithreading

What does Multithreading do?

A skill your agent uses when running work off the main thread — WorkerThreadPool, Thread/Mutex/Semaphore, calldeferred, thread-safe scene access, and threaded resource loading. Multithreading is an agent skill from jame581/GodotPrompter.

When should I use Multithreading?

Multithreading fits situations like: running work off the main thread — WorkerThreadPool; thread/Mutex/Semaphore; thread-safe scene access; threaded resource loading.

How do I install Multithreading in Claude Code?

Run `npx skills add jame581/GodotPrompter --skill multithreading -a claude-code`. Or copy the skill folder (skills/multithreading in jame581/GodotPrompter) into .claude/skills/multithreading in your project. Claude Code loads it when a task matches its description.

How do I install Multithreading in Codex?

Run `npx skills add jame581/GodotPrompter --skill multithreading -a codex`. Or copy the skill folder (skills/multithreading in jame581/GodotPrompter) into .agents/skills/multithreading in your project. Codex loads it when a task matches its description.

Can I use Multithreading in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add jame581/GodotPrompter --skill multithreading -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/multithreading, .gemini/skills/multithreading, .github/skills/multithreading and .opencode/skills/multithreading in your project.

What does Multithreading need to run?

SKILL.md names no scripts, command-line tools or credentials: Multithreading is instructions for the agent only.

Does Multithreading access the network?

SKILL.md names 1 domain. As links in the text: github.com. This is read from the text; nothing was executed.

Is Multithreading safe to install?

Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.

What licence does Multithreading use?

Multithreading is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Multithreading use?

About 2.7k tokens (SKILL.md is roughly 11k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full. Its references folder adds about 1k tokens, read only when the agent opens those files.

What are the alternatives to Multithreading?

Skills that share tags, products or a category with Multithreading: Release Manager (poingstudios/godot-admob-plugin, 631 stars), Godot Admob App Open (poingstudios/godot-admob-plugin, 631 stars), Godot Admob Banner (poingstudios/godot-admob-plugin, 631 stars) and Godot Admob Get Started (poingstudios/godot-admob-plugin, 631 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Multithreading?

jame581 (a GitHub user) maintains it in jame581/GodotPrompter, which has 792 GitHub stars. The repository holds 58 skills in this directory. The repository was last updated on October 6, 2026.

Source: jame581/GodotPrompter on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.