Skip to content

Apply rtos_fix hack for handling 32-bit floats on all calls to rtos_fix#110616

Merged
Repiteo merged 1 commit into
godotengine:masterfrom
aaronfranke:fix-rtos-fix-32bit
Sep 30, 2025
Merged

Apply rtos_fix hack for handling 32-bit floats on all calls to rtos_fix#110616
Repiteo merged 1 commit into
godotengine:masterfrom
aaronfranke:fix-rtos-fix-32bit

Conversation

@aaronfranke
Copy link
Copy Markdown
Member

This PR was made in response to this comment #98750 (comment)

I don't think there is any harm in always applying this hack to all float serialization. As a brief reminder, in all cases, this is strictly better than the behavior in Godot 4.4.

In Godot 4.4 and earlier, it would always serialize 6 digits of a float, which resulted in precision loss when serializing. In Godot 4.5, it uses Grisu2 instead to precisely serialize, however this can cause problems when Godot tells Grisu2 to serialize a double when the underlying data was a 32-bit float. I added a hack in PR #98750 that checks if it's equivalent to the 32-bit float value, and then serializes assuming the value is a 32-bit float, which seamlessly avoids issues for users, though it does mean that for double sources, 1 in 2^29 values will be off by 2^-23.

This PR changes this to apply to all floats, including Vector2, Vector3, Packed*Arrays, etc. In practice, this only changes behavior for Vector2, Vector3, etc for double-precision builds of Godot, and it has just one behavior change for single-precision builds of Godot, PackedFloat64Array. Test code:

func _ready() -> void:
	var vec := Vector2(0.1, 0.2)
	print(var_to_str(vec))
	print(var_to_str(PackedFloat64Array([vec.x, vec.y])))

In master, this is printed:

Vector2(0.1, 0.2)
PackedFloat64Array(0.10000000149011612, 0.20000000298023224)

With this PR, this is printed:

Vector2(0.1, 0.2)
PackedFloat64Array(0.1, 0.2)

@aaronfranke aaronfranke added this to the 4.6 milestone Sep 17, 2025
@aaronfranke aaronfranke requested a review from a team as a code owner September 17, 2025 14:20
@aaronfranke aaronfranke added regression cherrypick:4.5 Considered for cherry-picking into a future 4.5.x release labels Sep 17, 2025
@cridenour
Copy link
Copy Markdown
Contributor

Tested and working as described. A huge QoL upgrade for those on precision=double. Thank you @aaronfranke

Copy link
Copy Markdown
Member

@Ivorforce Ivorforce left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense to me.

@clayjohn clayjohn removed the cherrypick:4.5 Considered for cherry-picking into a future 4.5.x release label Sep 17, 2025
Copy link
Copy Markdown
Member

@Calinou Calinou left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tested locally, it works as expected. Code looks good to me.

When using Tools > Upgrade Project Files on the 3D platformer demo, this is the only change:

 [node name="Circle" type="MeshInstance3D" parent="."]
-transform = Transform3D(1, 0, 0, 0, -3.61999e-06, -1, 0, 1, -3.61999e-06, 0.00550658, 0.532125, 0.000651598)
+transform = Transform3D(1, 0, 0, 0, -3.6199901e-06, -1, 0, 1, -3.6199901e-06, 0.00550658, 0.532125, 0.000651598)

I've tried various other demos and changes are similarly minimal, so this change should be safe in terms of VCS diffs.

@Repiteo Repiteo merged commit 79d0eea into godotengine:master Sep 30, 2025
20 checks passed
@Repiteo
Copy link
Copy Markdown
Contributor

Repiteo commented Sep 30, 2025

Thanks!

@aaronfranke aaronfranke deleted the fix-rtos-fix-32bit branch September 30, 2025 16:44
@akien-mga akien-mga changed the title Apply rtos_fix hack for handling 32-bit floats on all calls to rtos_fix Apply rtos_fix hack for handling 32-bit floats on all calls to rtos_fix Jan 25, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants