godotengine / godot

Godot Engine – Multi-platform 2D and 3D game engine
https://godotengine.org
MIT License
91.42k stars 21.26k forks source link

Reverting is broken for GDExtension types with Resource properties with non-null default values #83108

Open HenryWConklin opened 1 year ago

HenryWConklin commented 1 year ago

Godot version

4.1.1

System information

Ubuntu 22.04.3

Issue description

See also #36372 and https://github.com/godot-rust/gdext/issues/440

Creating a GDExtension type with an exported Resource property that defaults to something other than null causes the Godot editor to use a specific, static instance of that type as the default value to revert that property.

That means it's possible to modify the default, so that reverting behaves in unexpected ways. Same behavior as #36372.

In particular, this makes it very tricky to implement non-null properties in GDExtension types. For example, a custom transform type that has a useful default value and is cheap to construct. Or something like Path2D from #36372 but instead of reverting to null it reverts to an empty path. For the Rust GDExtension bindings in particular this would be very nice to avoid null checks all over the code base.

Steps to reproduce

  1. Create a GDExtension type with an exported Curve2D property that defaults to Curve2D.new() in init
  2. Follow the repro steps in #36372 :
  1. Draw your curve.
  2. Now press the reset button. Curve disappears, but when you now draw a new curve, the reset button is also gone.
  3. If you select "New Curve2D" from the dropdown, and then reset, it will default to the previous curve you had drawn.

Example video with the attached repro project:

godot-obj-nonnull-repro.webm

Minimal reproduction project

obj-nonnull-repro.zip

To build the GDExtension lib:

cd rust/
cargo build
HenryWConklin commented 1 year ago

83105 for a potential fix