Skip to content

hidalgob/graphify-godot

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

206 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

graphify-godot

A fork of safishamsi/graphify that adds first-class Godot / GDScript support to the knowledge-graph pipeline.

Upstream graphify ingests code, docs, papers, and media into a clustered graph you can query from your AI assistant. It ships AST extractors for ~23 languages — Python, TypeScript, Go, Rust, Swift, etc. — but nothing for Godot, so any Godot project gets treated as docs-only.

This fork adds:

  • .gd — tree-sitter AST extraction (via the gdscript grammar bundled in tree-sitter-language-pack)
  • .tscn — regex-based scene extraction (ext_resource paths, script attachment, node instancing, signal connections)
  • .tres — regex-based resource extraction (ext_resource paths, script class binding)

What gets extracted

.gd (GDScript)

Construct Graph effect
class_name X File gets an alias node X so external refs resolve by class name
extends Y (top-level) file --inherits--> Y
class Inner extends Base: file --contains--> Inner, Inner --inherits--> Base, methods hang off Inner
func foo() Function node, file --contains--> foo()
signal bar(...) Signal node, file --contains--> bar(signal)
preload("res://x.gd") / load("res://x.gd") file --imports_from--> x.gd (res:// resolved via project.godot root)
signal.emit(...) caller_fn --emits--> signal
signal.connect(cb) signal --connected_to--> cb (when both are local)
Function body caller_fn --calls--> callee (local + cross-file INFERRED)

.tscn (scene)

Construct Graph effect
[ext_resource path="res://..."] scene --imports_from--> target
[node ... instance=ExtResource("id")] scene --instances--> target_scene
[connection signal=X to=Y method=M] Deferred call to method M — resolved to the method node in the script attached to the scene

.tres (resource)

Construct Graph effect
[ext_resource path="res://..."] resource --imports_from--> target

Validation

Tested against a 1,000-file Godot 4.6 project (Meridian: Breach Zones — ~500 .gd, 50 .tscn, 660 .tres):

AST extraction: 1031 files in ~7s, 0 errors
Resulting graph: 6,872 nodes · 13,431 edges
  calls:         6,274
  contains:      5,316
  imports_from:    856
  inherits:        311
  aliases:         216
  emits:           103
  instances:         8
  connected_to:      4

Before this fork, graphify treated the same project as 0 code files / 54 docs.

Install

Works on Windows, macOS, Linux. Requires Python 3.10–3.13.

# Clone
git clone https://github.com/hidalgob/graphify-godot.git
cd graphify-godot

# Install as editable replacement for upstream graphifyy
pip install -e .

If upstream graphifyy was previously installed via pip, its package files may sit in site-packages and shadow this fork. Either:

pip uninstall graphifyy      # then re-run pip install -e .

or drop a priority .pth file into your user site-packages:

python -c "import site, pathlib; p = pathlib.Path(site.getusersitepackages()) / '_graphify_godot_priority.pth'; p.write_text(f'import sys; sys.path.insert(0, r\"{pathlib.Path.cwd()}\")')"

Verify:

python -c "import graphify; print(graphify.__file__)"
# → .../graphify-godot/graphify/__init__.py

Usage is identical to upstream:

python -m graphify update /path/to/your/godot/project

How res:// paths resolve

The GDScript extractor walks up from each source file looking for project.godot — that marks Godot's project root, and all res://foo/bar.gd references resolve relative to it. The result is cached per parent directory so it's cheap.

Recommended .graphifyignore

Godot projects typically want to exclude:

# Third-party / generated
addons/
.godot/
imported_models/

# Build outputs
bin/
/android/
*.apk

# Graph output (auto-skipped, but explicit is cleaner)
graphify-out/

# Tests (optional — they inflate communities around assert_*)
tests/

Put this in .graphifyignore at your project root.

Known gaps

  • No .gdshader parsing. Shaders are ignored.
  • Cross-file signal.connect(cb) is partial. When a file calls EventBus.enemy_killed.connect(_on_enemy_killed), the signal lives in event_bus.gd (a different file) and the connect call sits in your file. The connected_to edge is emitted only when signal + callback are in the same file. Cross-file wiring shows up as a generic calls edge on the callback instead.
  • No inner-class scope awareness. A method call inside class InnerData that targets another inner method is resolved by global label lookup, which can collide with a top-level function of the same name.
  • Dynamic loads (load(some_var), directory scans) are invisible. Godot projects that enumerate res://balance/achievements/ at runtime will have those .tres files appear as orphan nodes. This is a limitation of static extraction — no way around it without running Godot itself.

Relationship to upstream

This is a personal fork, not a merge candidate (yet). Upstream is moving fast (~1.5 releases/day as of April 2026) and has a low merge rate on community language PRs — nine competing language backends sit open unmerged. If you want GDScript support and don't want to track upstream churn, use this. If upstream adds official Godot support later, I'll deprecate this in favor of that.

Base version: upstream graphifyy==0.4.23. Periodically rebased.

License

MIT — same as upstream. Credit to Safi Shamsi for the graphify base.

About

Fork of graphify with GDScript/Godot support — tree-sitter .gd AST + .tscn/.tres regex extraction

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages