Skip to content

gdls v1.0.0 — first release

Choose a tag to compare

@kurushimee kurushimee released this 09 Jun 21:23

The first release of gdls — a standalone GDScript language server: a faithful Rust port of
Godot 4.6.3-stable's GDScript frontend (tokenizer → parser → analyzer) speaking LSP over stdio,
with no Godot engine or editor process at runtime. Built for type-aware diagnostics and
navigation at the 3,000–10,000+ .gd file scale.

Highlights

  • Godot-fidelity diagnostics — parser conformance 186/186, analyzer 300/300 against the
    vendored Godot 4.6.3-stable golden corpus; the full warning set (45 active + 3 deprecated-gated)
    with godot / strict / off profiles and per-warning overrides.
  • LSP surface — per-file publishDiagnostics, hover (member/call/preload signatures +
    engine/GDExtension doc prose), definition (incl. class_name-in-expression, preload/load
    res:// strings, autoload names), project-wide references, hierarchical documentSymbol,
    documentLink on res:// literals, implementation (class subtypes + method overrides),
    workspace/symbol, and call hierarchy — the last three exceed Godot's own LSP, which doesn't
    offer them.
  • Autoload-singleton typingGlobal.popup_error(...) resolves like Godot's editor: full
    hover signatures and cross-file references through singleton members.
  • Persistent warm-start cache<project>/.gdls/, keyed on gdls version + native-API content
    hash + project.godot fingerprint with per-file (size, mtime) stat validation; atomic
    last-writer-wins writes make concurrent gdls processes (e.g. Claude Code + an IDE) safe. Warm
    start is >5× faster than a cold scan (14.7× on the 3,000-file synthetic gate); reconcile
    re-parses only stat-changed files.
  • Never crash, never lie — partial ASTs on any input (fuzzed: parse/analyze/index-invariants),
    clamped position conversions, graceful degradation on doc-less GDExtensions, corrupt caches fall
    back to a cold index.

Verification

Final acceptance for this release: the parameterized capability walk
(scripts/m6-acceptance/) passes every row on a real Godot 4.6.3 OSS project (Pixelorama —
committed session), and a Windows-native walk on a 2,338-script production project returns
correct data on every row with the cache stat-diffing 2338 unchanged, 0 reparsed over NTFS.

Install

Download the binary for your platform below (SHA256SUMS included), unpack it onto PATH, or
build from source:

cargo install --path crates/gd_server   # installs `gdls` into ~/.cargo/bin

Generate extension_api.json once per engine rebuild (from inside your project, so installed
GDExtensions are captured), then point initializationOptions.extensionApiPath at it:

godot --dump-extension-api-with-docs

Client wiring (Claude Code plugin manifest, configuration schema): see the
README and docs/05-lsp-cc-integration.md.

Known limitations

  • references/definition don't yet reach signal/var member-access sites through typed bases
    (obj.sig.emit(...) across files — method calls and in-file signal uses work; hover renders
    func/signal member signatures): #13.
  • On Windows/NTFS, startup wall-clock is dominated by the reconcile backstop walk, which masks
    the warm-cache win there (the cache itself validates correctly): #14.
  • Phase 2 (by design): .tscn node typing for $/% (they're deliberately permissive in v1 —
    never a false positive on node access), completion, signatureHelp, rename,
    documentHighlight.

Full details in CHANGELOG.md.


Known issues — fixed in v1.0.1. A post-release full-project diagnostics sweep found error-level false positives in ~45–55% of files on real layered projects (cross-file inheritance typing, builtin-constant folds, packed-array iteration, const chains, and a long tail). Upgrade to v1.0.1, which also makes extension_api.json fully automatic and fixes the Windows/NTFS startup cost.