godotengine / godotengine/godot
Default values in PackedArrays are null instead of zero, fail to deserialize when changed to regular Array
- Dominant language
- C++
- Stars
- 117k
- Forks
- 26.8k
- PR merge metrics
- PR metrics pending
Description
### Tested versions
v4.3.stable.official [77dcf97d8]
### System information
Godot v4.3.stable - Windows 10.0.22621 - Vulkan (Forward+) - dedicated AMD Radeon RX 5700 XT (Advanced Micro Devices, Inc.; 31.0.24031.5001) - AMD Ryzen 9 3950X 16-Core Processor (32 Threads)
### Issue description
When adding elements to a `PackedArray` (Int, Float etc.) without modifying it the editor shows zero as expected, but the actual value saved in the .tscn is `null`. If changed to a non-zero number and back to zero, it is then written as `0` instead of `null`.
This works "correctly" for `PackedArray`s (nulls end up as zeros), however if you then change the type of the variable to a regular array i.e. `PackedInt32Array` into `Array[int]`, the values will be unchanged in the editor as expected but the .tscn still has those `null` values.
Running a scene with an `Array` with `null`s in the .tscn results in an error `assign: Unable to convert array index 0 from "Nil" to "int"` and an empty `Array` is read instead, even if there are non-null elements.
It seems that having `null` elements are simply interpreted as zeros/default values in `PackedArray`s but cause deserialization to fail when reading them as `Array`s. This causes mysterious indexing errors on ostensibly populated `Array`s that were switched over from `PackedArray`s.
### Steps to reproduce
1. Write a script with a single exported `PackedArray` (Int, Float, etc.) that is empty by default or if using the MRP skip to step 9
2. Assign this script to a node and add some items without modifying them
3. Save the scene and open it in a text editor to observe that the `PackedArray` has a bunch of `null` values in it
4. Change one of the values to non-zero in the editor (don't forget to click out of the box)
5. Change the value back to zero
6. Save the scene and open it in a text editor again to observe that the `PackedArray` now has `0` instead of `null` for the one value you changed
7. In the script, change the type from a `PackedArray` to an `Array` of the same type
8. In the editor this will seemingly keep the same values
9. Launch the scene and observe the error `assign: Unable to convert array index 0 from "Nil" to "int"` (or equivalent type you used)
10. You can also write some code to index the array/check its length to see that it's empty
### Minimal reproduction project (MRP)
[repro_97165.zip](https://github.com/user-attachments/files/17077787/repro_97165.zip)
Contributor guide
Research direction
Start with the attached repro_97165.zip and follow the listed steps, inspecting the saved .tscn after editing the exported PackedArray. Trace how null elements are serialized and then read after changing the script type to Array[int]. Done means default zero values remain valid and the converted Array loads with its values intact without the Nil-to-int error.
Written by the indexing model from the issue text.
Assessment
- Domain
- game-dev
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 42/100