gdext-v
V bindings for Godot.
Examples
Check out the
demo repository
Setup
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.
Setup library
- 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
cd ..
- Run the generator:
./bin/gen.vsh
Setup project
- Add a
.gdextension
file 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 with gd.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
level
.info
log.set_level(.debug)
-
Add your files and register them in the
init_gd
function as shown above. -
Build the project:
v -shared -enable-globals -o lib/libvlang.so -d no_backtrace .
patchelf --clear-exexstack lib/libvlang.so
The
patchelf
tcc
-cc
tcc
clang
gcc
I do all this and more
in a build script in the demo repo
Another, more minimal, repo you could reference is the
babel
gdext-v
Usage
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.so
Documentation
Check out the
generated API docs
Or generate your own locally:
v doc -m -o docs -f html .
cp .github/templates/index.html docs/
State
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.
Helpful resources
- 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:*.v
queries (👈 pro tip).