godotengine / godotengine/godot
Exporting raw variant fields in scripts have different results in the editor inspector depending on how it's written
- Dominant language
- C++
- Stars
- 117k
- Forks
- 26.8k
- PR merge metrics
- PR metrics pending
Description
### Tested versions
v4.5.beta7.official [4ebf67c12]
### System information
Godot v4.5.beta7 - Windows 10 (build 19044) - Multi-window, 2 monitors - OpenGL ES 3/ANGLE (Compatibility) - ANGLE (NVIDIA, NVIDIA GeForce GTX 1050 Ti (0x00001C82) Direct3D11 vs_5_0 ps_5_0, D3D11-31.0.15.4617) - Intel(R) Core(TM) i7-7700 CPU @ 3.60GHz (8 threads) - 15.93 GiB memory
### Issue description
There are four different ways of writting the export for a raw variant field, and only one of them has the result a common user would expect when learning about the possibility of exporting raw variant fields:
```gdscript
@export var m_with_type_without_default: Variant
@export var m_with_type_with_default: Variant = 'm_with_type_with_default'
@export var m_without_type_with_default = 'm_without_type_with_default'
@export var m_without_type_without_default
```
Of these four usages, only the first one works, drawing a field that let you change the type
```gdscript
@export var m_with_type_without_default: Variant
```
the next two exports become tied to the type of the initial value and do not let you change it.
And lastly, the fourth type doesn't work at all, it raises a parser error with the message ```Error at (, ): Cannot use simple "@export" annotation with variable without type or initializer, since type can't be inferred.```
Even though I think most users whould expect all four syntaxes to be possible, the ones where a default value is provided are the most important, since it is pretty common for anyone to export a field with a default value, but none of the exports that have a default value allow changing the type.
The exports with default value are being tied to the initial type but please note that I'm assigning the value with ```=```, not with ```:=```. We could even argue that makes sense for the value to the 'locked' when using ```:=``` but not when using ```=```
### Steps to reproduce
1. create a new project in godot 4.5 beta 7
2. create a new scene
3. create a script in the root node
4. paste the code bellow in the script
```gdscript
extends Node
# this is the only one that allows changing the type in the inspector
@export var m_with_type_without_default: Variant
# this one does not allow changing the type in the inspector even though is typed as 'Variant'
@export var m_with_type_with_default: Variant = 'm_with_type_with_default'
# this one is untyped (and thus should be identical to typing as Variant) but also does not allow changing the type in the inspector
@export var m_without_type_with_default = 'm_without_type_with_default'
# this one could work but raises a parser error
# @export var m_without_type_without_default
# Error at (13, 1): Cannot use simple "@export" annotation with variable without type or initializer, since type can't be inferred.
```
Or just check the Main.tscn scene in the attached MRP
### Minimal reproduction project (MRP)
[ExportVariantBug.zip](https://github.com/user-attachments/files/22101500/ExportVariantBug.zip)
Contributor guide
Research direction
Open the attached ExportVariantBug.zip and reproduce the four GDScript declarations in the Godot editor inspector, including the parser error. The payload names no source files or tests, so begin by tracing the export handling and inspector behavior for these examples. Done means the supported raw Variant declarations produce the intended inspector behavior and regression coverage exists.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- godot
- Domain
- game-dev, tooling
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100