godotengine / godotengine/godot-cpp
Not able to call C++ _process(), _ready() reliably
- Dominant language
- C++
- Stars
- 2.7k
- Forks
- 809
- Avg merge
- 1d 3h
- Merged PRs (30d)
- 8
Description
Godot beta 16
@outobugi and I are building a GDExtension terrain plugin. I have a C++ class with _ready() and _process() that I want to run. However some cases work, some cases don't. I can't tell what the right path without testing every possibility because it's so inconsistent, and there's no clear way to have it work properly in all cases.
**Legend:**
T - `@tool` mode
Ed - Editor mode
Gm - Running in Game
C - C++
GD - GDScript
rd - _ready() in C++ or GDScript
pr - _process() in C++ or GDScript
Symbols: Blank = N/A | + = Yes | X = No and it's likely a problem | E = Error, and maybe a problem
| Script | T | Ed_C_rd | Ed_C_pr | Ed_GD_rd | Ed_GD_pr | Gm_C_rd | Gm_C_pr | Gm_GD_rd | Gm_GD_pr |
|--|--|--|--|--|--|--|--|--|--|
| 1. None | | + | + | | | + | + | | |
| 2. extend | | + | X | | | + | X |
| 3. extend | Y | + | X | | | + | X |
| 4. funcs | | + | + | | | X | X | + | + |
| 5. funcs | Y | X | X | + | + | X | X | + | + |
| 6. super| | + | + | | | X | X | E | E |
| 7. super| Y | X | X | +E | +E | X | X | E | E |
1. No script attached to the node. C++ functions work fine.
2. Attached to the node is a script with only `extends MyNode`, my C++ plugin. **Issue: C++ runs one function but not the other!!**
3. w/ Tools mode. Same results.
4. Above plus simple _ready() and _process() functions that print a message. **Issue: This calls the C++ functions in the editor and the GDScript functions in the game!!**
5. w/ Tools. **Issue: Different results from w/o tools mode. C++ won't run at all.**
6. Above, plus adding `super._ready()`, `super._process(delta)`. **Issue: In game, the debugger broke in and complained that these functions do not exist.**
7. w/ Tools. **Issue: Only gdscript runs in editor, but dumps errors in the console about missing functions. In game won't run at all w/o debugger coming up.**
**Adding C++ Bindings**
By binding _ready() and _process() in C++ w/ bind_method, we get console errors: `ERROR: Method 'Terrain3D::_process()' already registered as non-virtual.`, and also for ready. This applies to all. Initially, it seems these tests are worthless, but that turns out to not be true.
| Script | T | Ed_C_rd | Ed_C_pr | Ed_GD_rd | Ed_GD_pr | Gm_C_rd | Gm_C_pr | Gm_GD_rd | Gm_GD_pr |
|--|--|--|--|--|--|--|--|--|--|
| 1. None | | X | X | | | X | X | | |
| 2. extend | | X | X | | | X | X |
| 3. extend | Y | X | X | | | X | X |
| 4. funcs | | X | X | | | X | X | + | + |
| 5. funcs | Y | X | X | + | + | X | X | + | + |
| 6. super| | X | X | | | + | + | + | + |
| 7. super| Y | + | + | + | + | + | + | + | + |
1-6. C++ doesn't work at all, and notably does not work if a script is not attached!
7. Here we see 7 works across the board.
### Summary
In summary, if we want a plugin that runs C++ _ready() and _process() we either have to:
1. Compile w/o bindings, AND require that the user never attaches a script to the Terrain node, or it will break.
2. Compile w/ bindings, AND require the user to ignore the errors, AND always have a script attached to the Terrain node that implements _ready() and _process() AND calls the super functions.
Neither of these are good options as it stands.
Presumably there are similar inconsistencies with _enter_tree() and others.
Is there a better way to bind _ready() and _process? I'm using this:
```
ClassDB::bind_method(D_METHOD("_ready"), &Terrain3D::_ready);
ClassDB::bind_method(D_METHOD("_process", "delta"), &Terrain3D::_process);
```
Similar to https://github.com/godotengine/godot-cpp/issues/562, but for Godot 4
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.