Estragon-9B

A Godot 4.7 / GDScript specialist. Qwen3.5-9B fine-tuned (SFT + GRPO with a headless-Godot judge as reward) to write correct, idiomatic, current-API GDScript — and nothing else you didn't ask for.

Godot the engine is named after Beckett's Waiting for Godot — the joke being that the engine would never be finished. Estragon is one of the two tramps who wait for the Godot who never arrives. This model is the reference-to-the-reference, with the inversion as the point: Estragon stopped waiting.

Benchmarks

Measured on GDScript-Eval v2 (gdeval_v2): 300 held-out tasks across 10 categories, judged by a headless Godot 4.7 binary — a task passes only if the generated file parses and its runtime behavior checks pass in-engine. Greedy decoding (pass@1), deployment system prompt. Harness, judge, and all task sets: https://github.com/blugart-dev/estragon.

model params gdeval_v2 %
ibm-granite/granite-4.1-8b 8B 123/300 41.0%
microsoft/phi-4 14B 146/300 48.7%
google/gemma-4-12B-it (Q8 GGUF) 12B 211/300 70.3%
Qwen3-8B (previous lineage base) 8B 115/300 38.3%
Qwen3.5-9B (this model's base) 9B 219/300 73.0%
Estragon-9B (this model, bf16) 9B 248/300 82.7%
Claude Opus 4.8 (reference ceiling) 300/300 100%

All bases measured bare (no system prompt), greedy, same judge — the same protocol that produced the Qwen numbers. Gemma 4 measured via its official Q8_0 GGUF (its bf16 needs a transformers version incompatible with the pinned eval stack); Q8 is near-lossless but treat that row as ±a few tasks.

Sampling headroom: pass@8 = 285/300 — with 8 attempts the model solves 95% of the eval; a "generate 3, keep the first that parses in a headless Godot" wrapper recovers much of this cheaply.

Use it

The system prompt is part of the model. All numbers above were measured with it; without it the model is markedly weaker (prompt-inversion effect — the instruction tuning targets it):

You are Estragon, a Godot 4.7 GDScript specialist. Write correct, idiomatic
Godot 4 GDScript: static typing where practical, tab indentation, and current
Godot 4 APIs (@export/@onready annotations, Callable-based signal
connections, await, FileAccess, Time). Never use Godot 3 APIs or syntax.
Implement exactly what is asked: keep the requested names and signatures, and
do not add exported variables, extra methods, _ready blocks, print
statements, or demo code the task did not request. When asked for code,
respond with one complete GDScript file in a fenced code block, with brief
explanation only if asked.

Ollama

# with the Modelfile from the GGUF repo (bakes in the system prompt + params):
ollama create estragon -f Modelfile
ollama run estragon --think=false "A 2D platformer jump with coyote time, CharacterBody2D"

--think=false (API: "think": false) is required: Ollama's qwen3.5 runtime manages thinking itself and a Modelfile cannot disable it (ollama#14617); this is a non-thinking fine-tune (thinking mode measured −15 tasks).

llama.cpp

llama-server -m estragon-9b-Q4_K_M.gguf -ngl 99 --port 8080 \
  --chat-template-kwargs '{"enable_thinking":false}'
# then chat with the system prompt above; temperature 0.7, top-p 0.8, top-k 20

⚠️ The enable_thinking:false flag is required. The embedded Qwen3.5 chat template otherwise opens a reasoning block; this is a non-thinking fine-tune and will produce empty or degraded answers with thinking enabled (measured: −15 tasks in thinking mode, and unclosed think blocks eat the whole token budget). The Modelfile in this repo already handles it for Ollama.

Q4_K_M runs fully GPU-offloaded on an 8 GB card (it was built on an RTX 3060 Ti). Recommended sampling: temperature 0.7, top_p 0.8, top_k 20 (Qwen3.5 non-thinking); the model is a non-thinking fine-tune — do not enable reasoning/thinking mode (measured: −15 tasks).

Quants

GGUF downloads: https://huggingface.co/Blugart/estragon-9b-gguf (this repo holds the bf16 weights). Every quant was run through the full 300-task eval (same judge, same protocol as the bf16 measurement standard) so the quantization cost is measured, not guessed:

file bits size gdeval_v2 vs bf16 (248)
estragon-9b-Q4_K_M.gguf 4-bit 5.6 GB 229/300 (76.3%) −19 — the 8 GB VRAM pick; API-precision degrades most
estragon-9b-Q5_K_M.gguf 5-bit 6.5 GB 249/300 (83.0%) +1 — statistically identical to bf16; best size/quality trade
estragon-9b-Q8_0.gguf 8-bit 9.5 GB 248/300 (82.7%) ±0 — indistinguishable from bf16

Training

Solo project, ~$100 total compute budget (RunPod + Claude API for synthetic data). Pipeline: ~20k validated SFT pairs (docs-derived, real-repo-derived with permissive licenses, synthetic grounded in doc excerpts, mechanical Godot3→4 reverse-migration pairs — every example parse-validated by headless Godot 4.7 before entering the training set) → GRPO with the eval judge as reward (pass/fail + style-noise penalty + degeneracy detectors) on 254 runtime-verified training tasks (fully disjoint from the eval; shingle-level decontamination enforced). Full method, ADRs, harness, and eval sets: https://github.com/blugart-dev/estragon.

Limitations

  • Godot 4.7 only. It will not write Godot 3; it may reject valid Godot 3 on principle. Untested against future 4.x API changes.
  • The remaining 52/300 eval failures cluster in: rare-API precision (occasional hallucinated method names), long spec-compliance chains, and temporal semantics (timer/tween edge cases).
  • GDScript only — no C#, no shader code beyond trivial cases.
  • 9B params: it is a specialist, not a general assistant; out-of-domain quality is whatever survived from the base model.

License

Apache 2.0 (inherited from Qwen3.5-9B; fine-tuning data is original, doc-derived, or from permissively-licensed repos).

Downloads last month
-
Safetensors
Model size
9B params
Tensor type
BF16
·
Inference Providers NEW
This model isn't deployed by any Inference Provider. 🙋 Ask for provider support

Model tree for Blugart/estragon-9b

Finetuned
Qwen/Qwen3.5-9B
Finetuned
(694)
this model
Quantizations
1 model