To test out development in Godot and in particular GDScript I am going to do a few days in Advent of Code in a year I haven’t done yet. The goal is to get a feel for the language, and experiment with some command line centric workflows I know and love from my time with bevy. I’ve got some bevy-fatigue and maybe this is the time to explore other options.
Why godot
It has almost opposite goals than bevy. Not performance centric, no ECS, scripting, finished workflows.
I’ve been running into some roadblocks with bevy when I had to deal with less ergonomic parts of the engine. UI, spawning scenes and I think in general some friction when I rather want to experiment than work in Rust’s straitjacket.
Goals
- How much can I work from my code editor vs the godot editor?
- How mature is the UI stuff?
- GDScript, how much will I miss rust?
- How do shaders / gpu programming work in Godot?
- How feasible is the godot-rust escape hatch?
Running from the command line
To work from my editor (#kakoune) I would want to be able to run godot scripts from the command line.
godot --headless -s /path/to/script.gd
This generally results in errors: “Can’t load the script “/path/to/script.gd” as it doesn’t inherit from SceneTree or MainLoop”
An example of a file that does work:
This means the actual code you want to develop should live in a file you can include.
Testing
I added the Godot Unit Test addon to my project and it worked fine from the cli.
Added a small config:
Every file will immediately be picked up if it starts with test_.
Kakoune integration
I’m using kakoune and found it really extensible for tools that work well from the cli. I’m not very happy with the output of those cli commands, it’s not a very structured way.
External editor
In godot you want to set your editor to external and add a shell script to open a file in kakoune.
The above shell script will try to open a file in a kakoune session with the name “godot”.
This means you need to have it running somewhere kak -s godot file.gd
.
The jumpclient
refers to the name of the client, a kakoune session can have multiple clients and jumpclient
is generally used to view code.
Neat!
LSP
Kakoune while great when working with cli tools, has a more dificult time integrating with tools that require tighter integration. Kakoune-lsp is a very impressive project that works great, but can be finicky about config. Got it to work after dozens of threads about vim integration with the godot lsp.
hook -group lsp-filetype-gdscript global BufSetOption filetype=gdscript %{
set-option buffer lsp_servers %{
[gdscript]
filetypes = ["gd", "gdscript"]
root_globs = [".import", "project.godot"]
command = "nc"
args = ["localhost", "6008"]
offset_encoding = "utf-16"
}
}
The trick was in using nc
instead of starting a godot instance from the command line.
It does require the editor to be open, but for now this will do.
I did need to make a small change to the godot source and compile myself to get it fully working. Autocomplete removes text when you select an option with Godot 4.3, this PR fixes that for me: https://github.com/godotengine/godot/pull/96725/files. I cherry picked the commit and build, and it works!
Running files
The above CLI commands are combined with running the code from kakoune using compilation-mode.md. eg.
define-command godot-run-test -docstring 'Run godot tests in current file' %{
evaluate-commands %sh{
rootdir="$(git rev-parse --show-toplevel)"
absolute_path="$kak_buffile"
relative_path="${absolute_path#"$rootdir/"}"
echo "run-in-fifo ' godot -d -s --path "$rootdir" addons/gut/gut_cmdln.gd -gtest=res://$relative_path --headless -gprefix="XX"' godot"
}
}
Parse the current file and get the relative path from the git root, and prefix it with res://
and see the result in the toolsclient right from the editor!
Turns out you can actually run scenes from kakoune as well.
define-command \
-docstring "Run Godot scene file based on the current buffer file name" \
-params 0 \
godot-current %{ evaluate-commands %sh{
rootdir="$(git rev-parse --show-toplevel)"
absolute_path="$kak_buffile"
relative_path="${absolute_path#"$rootdir/"}"
echo "run-in-fifo 'godot $relative_path' godot"
}
}
Open my-scene.tscn
in kakoune and run :godot-current
and it will run the Godot Scene in a Player window.
Auto formatting
Indentation sensitive code is never a good idea in my book, but I’m giving it a fair chance. Running an auto format command from you editor helps, as unfortunately the LSP doesn’t come with one.
To install it:
You need to get that executable on your path and bind it to a kakoune command:
define-command godot-run-format -docstring 'Run gdformat' %{
nop %sh{
~/.venv/godot/bin/gdformat --use-spaces=4 $kak_buffile
}
# needed to reload the file as gdformat writes to disk
edit!
}