gdext: Exported game panics due to missing `ResourceImporterOggVorbis` methods

I have been encountering the following panic when running exported games using the custom-godot feature:

ERROR: Parameter "mb" is null.
   at: gdextension_classdb_get_method_bind (core\extension\gdextension_interface.cpp:1347)
ERROR: Rust function panicked in file godot-ffi\src\toolbox.rs at line 248. Context: failed to initialize GDExtension level `Scene`
   at: <function unset> (godot-core\src\lib.rs:155)
ERROR: Panic msg:
  Failed to load class method ResourceImporterOggVorbis::load_from_buffer (hash 354904730).
  Make sure gdext and Godot are compatible: https://godot-rust.github.io/book/gdext/advanced/compatibility.html
   at: <function unset> (godot-core\src\lib.rs:101)

This same issue seems to happen when using the custom-godot feature with the example extension. Here are the steps that I have verified to reproduce the issue (I have only checked on Windows, I can check on Linux too if that would be helpful):

  1. Build editor and template_debug targets for custom godot version (I am using ad72de508 , corresponding to 4.2 rc1).
  2. Point GODOT4_BIN environment variable at the custom editor build
  3. Enable the custom-godot feature in examples/dodge-the-creeps/rust/Cargo.toml and run cargo build.
  4. In the editor, use the custom template_debug to export a Windows Desktop build of the dodge-the-creeps example.
  5. Run the game, receive the error above.

About this issue

  • Original URL
  • State: closed
  • Created 7 months ago
  • Comments: 21 (12 by maintainers)

Most upvoted comments

Thanks @coder137 and @Xylord, I overlooked that the default dependencies of dodge-the-creeps only have a minimal set of classes.

Changed its Cargo.toml to:

[dependencies]
godot = { path = "../../../godot" }
rand = "0.8"

And built with:

cargo build -p dodge-the-creeps --release

Then indeed, I can reproduce it! 👍

ERROR: Parameter "mb" is null.
   at: gdextension_classdb_get_method_bind (core/extension/gdextension_interface.cpp:1347)
ERROR: Rust function panicked in file godot-ffi\src\toolbox.rs at line 249. Context: failed to initialize GDExtension level `Scene`
   at: <function unset> (godot-core\src\lib.rs:159)
ERROR: Panic msg:
  Failed to load class method ResourceImporterOggVorbis::load_from_buffer (hash 354904730).
  Make sure gdext and Godot are compatible: https://godot-rust.github.io/book/gdext/advanced/compatibility.html
   at: <function unset> (godot-core\src\lib.rs:105)
ERROR: Cannot get class 'Main'.
   at: (core/object/class_db.cpp:358)
WARNING: Node Main of type Main cannot be created. A placeholder will be created instead.
     at: instantiate (scene/resources/packed_scene.cpp:254)
ERROR: Cannot get class 'Player'.
...

So that’s a start 🙂

Confirmed with Godot developers and tracked as https://github.com/godotengine/godot/issues/86206.

I will implement a workaround in gdext, until there is an official way to know about methods that are unavailable in Release mode.

@Xylord

I did as you said. Upon starting the game the output below pops up in the console. I had to modify the dodge the creeps project a bit to get it to run. First, in Cargo.toml, I changed the godot dependency to: godot = { git = "https://github.com/godot-rust/gdext", branch = "master", features = ["experimental-wasm"] }

Second, in the .gdextension file, I moved the .dll files to a bin folder in the godot directory, and pointed the .gdextension path there: windows.debug.x86_64 = "res://bin/debug/dodge_the_creeps.dll" windows.release.x86_64 = "res://bin/release/dodge_the_creeps.dll"

The game seems to work properly in-editor.

Initialize GDExtension API for Rust: Godot Engine v4.2.stable.official
Godot Engine v4.2.stable.official.46dc27791 - https://godotengine.org

ERROR: Parameter "mb" is null.
   at: gdextension_classdb_get_method_bind (core/extension/gdextension_interface.cpp:1347)
ERROR: Rust function panicked in file /home/xylord/.cargo/git/checkouts/gdext-76630c89719e160c/ef5f388/godot-ffi/src/toolbox.rs at line 249. Context: failed to initialize GDExtension level `Scene`
   at: <function unset> (/home/xylord/.cargo/git/checkouts/gdext-76630c89719e160c/ef5f388/godot-core/src/lib.rs:159)
ERROR: Panic msg:
  Failed to load class method ResourceImporterOggVorbis::load_from_buffer (hash 354904730).
  Make sure gdext and Godot are compatible: https://godot-rust.github.io/book/gdext/advanced/compatibility.html
   at: <function unset> (/home/xylord/.cargo/git/checkouts/gdext-76630c89719e160c/ef5f388/godot-core/src/lib.rs:105)
ERROR: Cannot get class 'Main'.
   at: (core/object/class_db.cpp:358)
WARNING: Node Main of type Main cannot be created. A placeholder will be created instead.
     at: instantiate (scene/resources/packed_scene.cpp:254)
ERROR: Cannot get class 'Player'.
   at: (core/object/class_db.cpp:358)
WARNING: Node Player of type Player cannot be created. A placeholder will be created instead.
     at: instantiate (scene/resources/packed_scene.cpp:254)
ERROR: In Object of type 'Node': Attempt to connect nonexistent signal 'body_entered' to callable 'Node::on_player_body_entered'.
   at: (core/object/object.cpp:1344)
ERROR: Cannot get class 'Hud'.
   at: (core/object/class_db.cpp:358)
WARNING: Node Hud of type Hud cannot be created. A placeholder will be created instead.
     at: instantiate (scene/resources/packed_scene.cpp:254)
ERROR: In Object of type 'Node': Attempt to connect nonexistent signal 'hit' to callable 'Node::game_over'.
   at: (core/object/object.cpp:1344)
ERROR: In Object of type 'Node': Attempt to connect nonexistent signal 'start_game' to callable 'Node::new_game'.
   at: (core/object/object.cpp:1344)

It’s probably worth noting that the library was compiled on WSL1 (Linux Ubuntu) using cargo build -p dodge-the-creeps --target=x86_64-pc-windows-gnu --release

Seems like there is a problem only with ResourceImporterOggVorbis

Commented out the panic , on exporting and running the game got the following dump

ERROR: Parameter "mb" is null.
   at: gdextension_classdb_get_method_bind (core/extension/gdextension_interface.cpp:1347)
ResourceImporterOggVorbis load_from_buffer with 354904730 is null // my prints
ERROR: Parameter "mb" is null.
   at: gdextension_classdb_get_method_bind (core/extension/gdextension_interface.cpp:1347)
ResourceImporterOggVorbis load_from_file with 797568536 is null // my prints

Can replicate the problem with this repository example

  • examples/dodge-the-creeps/rust/Cargo.toml
    • Change to godot = { path = "../../../godot" } (experimental wasm seems to work properly)
  • Create a simple export_presets for your platform (tested on Windows)
  • Following build commands, make sure the ../build folder is created
# From `examples/dodge-the-creeps/godot` folder
cd ../rust
cargo build
cd ../godot
%GODOT4_BIN% --headless --verbose --export-debug "Windows Desktop" ../build/GodotTest.exe
  • Run the game with console output from the build folder

@Bromeon can you try the steps listed above. Need to update the Cargo.toml file in the Dodge the creeps example

Seems like there is a problem only with ResourceImporterOggVorbis

Commented out the panic , on exporting and running the game got the following dump

ERROR: Parameter "mb" is null.
   at: gdextension_classdb_get_method_bind (core/extension/gdextension_interface.cpp:1347)
ResourceImporterOggVorbis load_from_buffer with 354904730 is null // my prints
ERROR: Parameter "mb" is null.
   at: gdextension_classdb_get_method_bind (core/extension/gdextension_interface.cpp:1347)
ResourceImporterOggVorbis load_from_file with 797568536 is null // my prints

Can replicate the problem with this repository example

  • examples/dodge-the-creeps/rust/Cargo.toml
    • Change to godot = { path = "../../../godot" } (experimental wasm seems to work properly)
  • Create a simple export_presets for your platform (tested on Windows)
  • Following build commands, make sure the ../build folder is created
# From `examples/dodge-the-creeps/godot` folder
cd ../rust
cargo build
cd ../godot
%GODOT4_BIN% --headless --verbose --export-debug "Windows Desktop" ../build/GodotTest.exe
  • Run the game with console output from the build folder

It’s likely that there are many others, yes.

Will need to reproduce this at some point and see if there’s a pattern.

@Xylord and others: Can you try enabling the lazy-function-tables gdext feature and trying again? We found a similar problem while debugging WASM and that feature fixed it. Perhaps the problem we found actually affects all export targets, not just WASM?

cc @Bromeon

This seems to be a more serious issue than initially thought.

I don’t think anybody can export a project right now, custom-godot feature or not.

[lemi@nixos testing-grounds]$ steam-run ./testing-grounds.x86_64 
Initialize GDExtension API for Rust: Godot Engine v4.2.stable.official
Godot Engine v4.2.stable.official.46dc27791 - https://godotengine.org
Vulkan API 1.3.260 - Forward+ - Using Vulkan Device #1: NVIDIA - NVIDIA GeForce GTX 1050
 
ERROR: Parameter "mb" is null.
   at: gdextension_classdb_get_method_bind (core/extension/gdextension_interface.cpp:1347)
ERROR: Rust function panicked in file /home/lemi/.cargo/git/checkouts/gdext-76630c89719e160c/9920e2b/godot-ffi/src/toolbox.rs at line 249. Context: failed to initialize GDExtension level `Scene`
   at: <function unset> (/home/lemi/.cargo/git/checkouts/gdext-76630c89719e160c/9920e2b/godot-core/src/lib.rs:155)
ERROR: Panic msg:
  Failed to load class method ResourceImporterOggVorbis::load_from_buffer (hash 354904730).
  Make sure gdext and Godot are compatible: https://godot-rust.github.io/book/gdext/advanced/compatibility.html
   at: <function unset> (/home/lemi/.cargo/git/checkouts/gdext-76630c89719e160c/9920e2b/godot-core/src/lib.rs:101)
use godot::prelude::*;

struct MyExtension;

#[gdextension]
unsafe impl ExtensionLibrary for MyExtension {}

#[derive(GodotClass)]
#[class(init, base=Node)]
struct Player {
    speed: f64,
    angular_speed: f64,

    #[base]
    base: Base<Node>
}

The game will export, but attempting to play the exported project will result in a panic.

I am not using ResourceImporterOggVorbis anywhere. Which is the main concerning thing (could something be wacky about this, specifically? Not sending the proper hash or defaults?)

It’s not an issue of the library missing, since if the library isn’t found, it will report a missing library:

ERROR: Can't open dynamic library: lib/libtesting.so. Error: /home/lemi/Projects/Godot/testing-grounds/../lib/libtesting.so: cannot open shared object file: No such file or directory.
   at: open_dynamic_library (drivers/unix/os_unix.cpp:660)
ERROR: GDExtension dynamic library not found: lib/libtesting.so
   at: open_library (core/extension/gdextension.cpp:719)
ERROR: Failed loading resource: res://testing.gdextension. Make sure resources have been imported by opening the project in the editor at least once.
   at: _load (core/io/resource_loader.cpp:274)
ERROR: Error loading extension: res://testing.gdextension
   at: load_extensions (core/extension/gdextension_manager.cpp:234)
Godot Engine v4.2.stable.official.46dc27791 - https://godotengine.org
Vulkan API 1.3.260 - Forward+ - Using Vulkan Device #1: NVIDIA - NVIDIA GeForce GTX 1050

In fact, just merely registering the library seems to cause this issue, no actual GodotClass required…

Looking into the mb is null error, it seems to come from this snippet: https://github.com/godotengine/godot/blob/master/core/extension/gdextension_interface.cpp#L1327-L1349

MethodBind *mb = ClassDB::get_method_with_compatibility(classname, methodname, p_hash, &exists);

mb here seems to be null. Putting the context clues together, could ResourceImporterOggVorbis::load_from_buffer be doing something funky?