V bindings for Godot.
Check out the demo repository for examples.
I (obviously) don't have a lot of docs yet and haven't spent time making this project user-friendly yet. But here are the steps that should get you started. These will definitely improve over time.
- Clone/download this repo somewhere:
git clone https://github.com/rosshadden/gdext-v.git- Point a symlink to it from V's module directory (or make this where you clone it):
ln -s /absolute/path/to/gdext-v ~/.vmodules/gd- Dump the extension API from Godot into
./data/:
cd data
godot --headless --dump-extension-api-with-docs
cd ..- Run the generator:
./bin/gen.vsh- Add a
.gdextensionfile to your Godot project (I put mine at./lib/v.gdextension):
[configuration]
entry_symbol = "gdext_v_init"
compatibility_minimum = 4.4
reloadable = true
[libraries]
linux.debug.x86_64 = "res://lib/libvlang.so"- Make a V file in your Godot project that will serve as the entry point:
module main
import gd
import gd.gdext
import src.entities.actors
import services
pub fn init(v voidptr, l gd.GDExtensionInitializationLevel) {
if l == .initialization_level_scene {
// This is where you register your classes
gd.register_class[actors.Player]('Node2D')
gd.register_class_with_name[services.Debug]('Node', 'ThisIsHowYouCanGiveACustomClassName')
}
}
pub fn deinit(v voidptr, l gd.GDExtensionInitializationLevel) {
if l == .initialization_level_scene {}
}
@[export: 'gdext_v_init']
fn init_gdext(gpaddr fn (&i8) gd.GDExtensionInterfaceFunctionPtr, clp gd.GDExtensionClassLibraryPtr, mut gdnit gd.GDExtensionInitialization) gd.GDExtensionBool {
gdext.setup(gpaddr, clp)
gdnit.initialize = init
gdnit.deinitialize = deinit
return 1
}Note: This is
export, not to be confused withgd.export. This is V's built-in way of exporting to the C FFI.
If you want your logs to go through Godot, you can set up the gd.Log.
import log
@[export: 'gdext_v_init']
fn init_gdext(gpaddr fn (&i8) gd.GDExtensionInterfaceFunctionPtr, clp gd.GDExtensionClassLibraryPtr, mut gdnit gd.GDExtensionInitialization) gd.GDExtensionBool {
// ☝️all the above setup stuff
log.set_logger(gd.Log{})
return 1
}This is not necessary, and in fact I prefer it off, because for some reason if there is a crash Godot doesn't output any logs,
whereas logging through V's default logger works great.
Note that the default logger has a level of .info, so I like to lower it: log.set_level(.debug).
-
Add your files and register them in the
init_gdfunction as shown above. -
Build the project:
v -shared -enable-globals -o lib/libvlang.so -d no_backtrace .
patchelf --clear-exexstack lib/libvlang.soThe patchelf step is to remove exec bit from the library, which is set by tcc.
Thus if using another compiler (with the -cc flag) that step may be omitted.
However, tcc is leaps and bounds faster than clang or gcc in my testing,
so I recommend using it throughout development and using a different compiler for release builds.
I do all this and more in a build script in the demo repo.
Another, more minimal, repo you could reference is the babel project,
which is meant to showcase using basic functionality of many Godot language bindings, including gdext-v.
Once everything is set up, you just have to run the step above whenever you make changes to your V code:
v -shared -enable-globals -o lib/libvlang.so -d no_backtrace .
patchelf --clear-exexstack lib/libvlang.soCheck out the generated API docs.
Or generate your own locally:
v doc -m -o docs -f html .
cp .github/templates/index.html docs/Everything needed to make games with V has been implemented. And it's pretty damn ergonomic. I have a really low tolerance for friction and I want to make this project as pleasant as realistically possible to work with.
- godot-cpp
- godot-rust
- gdext-nim
- jcweaver997's work on his vgdextension was invaluable to this project.
I found it while bashing my head against the wall on something specific and searching Github with
NOT is:fork path:*.vqueries (👈 pro tip).