Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make floating-point values in the inspector more permissive #10068

Open
MrEgggga opened this issue Jun 28, 2024 · 4 comments
Open

Make floating-point values in the inspector more permissive #10068

MrEgggga opened this issue Jun 28, 2024 · 4 comments

Comments

@MrEgggga
Copy link

MrEgggga commented Jun 28, 2024

Describe the project you are working on

A 2D physics-based puzzle platformer

Describe the problem or limitation you are having in your project

I constantly run into issues when changing floating-point values in the inspector:

I mention the actual bugs to point out that these sort of stem from the over-restrictiveness of the Range class and the Godot inspector. However, they should probably be handled separately from this proposal.

Disallowing NaN and Infinity (godotengine/godot#81076) fixed a number of issues where the editor or games crashed when certain fields were set to infinite values, but in my opinion this was a stopgap solution and doesn't really do anything for cases when these fields could be set to NaN via script. In general, I don't see any reason for editing floating points to be this restrictive by default; generally the developer of a game knows what they're trying to do more than the editor does (they might be using NaN in one of their scripts as a special value because Godot currently has no easily-editable way of making optional types in the inspector; they might need a number to be accurate to more than a thousandth; etc.), and making things less restrictive by default in the editor doesn't make things worse for use cases which need the more restrictive behavior; the fields which cause huge problems when set to non-finite values can keep the behavior from godotengine/godot#81076.

Describe the feature / enhancement and how it helps to overcome the problem or limitation

Add options in the Range class which can remove some of these restrictions, and enable these by default for exported variables (but not for Range nodes in games).

Describe how your proposal will work, with code, pseudo-code, mock-ups, and/or diagrams

  • Add a boolean field allow_infinite with default value false to the Range class that allows for non-finite values.
  • Add a boolean field allow_finer with default value false to the Range class that prevents rounding of values entered by typing into the field (using the slider in SpinBox or the up/down arrows would still round things to the step value).
  • Set both of these to true for float properties with no hint, and false by default with properties with hints, similar to allow_greater and allow_lesser. Add hints or_infinite, or_finer and ideally add these to existing properties as appropriate (but that can be done separately, after the features needed are implemented).

If this enhancement will not be used often, can it be worked around with a few lines of script?

If a specific floating point value is needed that cannot be entered in the inspector (e.g. NaN, 0.12345, pi, 0), it is possible to edit the scene in an external editor and write the exact value in there; however, if the field is touched in the inspector (e.g. by selecting it and pressing Enter) it'll often be rounded again. Exact values can also be set in scripts or as the default export value, but these are kind of inflexible and cumbersome.

Is there a reason why this should be core and not an add-on in the asset library?

This is about changing some core behavior in the editor and is less of a "new feature" than a "fix."

@Calinou
Copy link
Member

Calinou commented Jun 28, 2024

  • everything entered into a floating point field in the inspector is rounded to the nearest thousandth -- I have had cases where I need more precision and had to either set the value via a script or edit the scene with a text editor

There's already a proposal tracking this: #3524

@Calinou Calinou changed the title make floating-point values in inspector more permissive Make floating-point values in the inspector more permissive Jun 28, 2024
@Mickeon
Copy link

Mickeon commented Jun 29, 2024

  • Add a boolean field allow_infinite with default value false to the Range class that allows for non-finite values.

There's a PR for this but it's not been taken a look at for a bit, maybe by next minor release?
godotengine/godot#88354

@MrEgggga
Copy link
Author

MrEgggga commented Jun 29, 2024

One thing I'm not sure about for allow_finer: how should unrounded values be shown in the inspector?

If nothing about SpinBox and EditorSpinSlider is changed, the value displayed is rounded, and hovering over the field shows the actual value -- the problem with this is that if you click on the field to edit it, there is no way to get back to the actual value. In my opinion, selecting the text of a field, changing nothing, and pressing Enter to confirm should not change the value of a field.

I can see two ways about this:

  • Keep the current behavior, but when the text of the field is selected for editing, change the text to the actual value. The main problem with this is that it obscures the actual value a bit, and since SpinBox doesn't show the actual value when hovered (as far as I can tell) there would be no way to see the actual value except by editing it -- not the end of the world, but maybe a little unintuitive.
  • If an input allows for finer input, don't show the rounded value at all. (Alternatively, never show the rounded value -- even if a float field doesn't allow for finer values, it shouldn't hide when an unrounded value is in the field.) This solution would probably cause problems for Ranges with non-power-of-ten step sizes, and before Parallax2D: Repeat size is getting value 2.08165e-12 instead 0 godot#91631 is fixed it would make rounded fields affected by rounding errors extremely ugly.

For infinite values, I think the solution is much clearer: show their actual values unconditionally rather than showing them as 0 (the current behavior godotengine/godot#88006). I would also say that instead of inf and nan (the behavior if nothing else is changed) they should show as INF and NAN since they must be typed in all caps when editing, but this is less important.


I'm currently working on implementing this proposal for personal use (so far I've implemented the fields described, added hints, and poorly updated SpinBox and EditorSpinSlider according to the second (worse) bullet point above), so if this or one of the many similar issues and proposals linked gets approved I might be able to make a pull request. I could also probably rewrite everything to fit with the pull request godotengine/godot#88354 linked above.

@MrEgggga
Copy link
Author

MrEgggga commented Jul 1, 2024

I'm mostly done with the interesting part of implementing this proposal; currently I have the following things left:

  • fixing a small issue with SpinBoxes with allow_finer set to true where the cursor is put in the middle of the number when clicked
  • making sure non-finite values are displayed properly regardless of whether allow_infinite is true
  • splitting allow_infinite into allow_infinite and allow_nan & similar for range hints, to align closer with Add toggle to Range for allowing non finite numbers godot#88354
  • splitting real_t_value for EditorSpinSlider into real_t_value and float_value; renaming the fields (see below -- I haven't committed the code which this relates to as of this post)

I would also have to update the range hint of every single float field in Godot's codebase (around 875 fields) for these features to be of any use. I plan on doing this, but I'm not sure whether it should be in the same pull request or separate.

What I have so far is available at https://github.com/MrEgggga/godot/tree/permissive-range. (So far I've been making most of my commits fairly small, but according to the contributing guidelines in the documentation it seems like it would be best to squish everything into one commit.)


One issue I ran into when implementing this was that fields which are stored as real_t or float rather than double looked terrible when not rounded properly (e.g. if you typed 0.12345 into one of the components of a Vector3 and pressed Enter, it would change to 0.12345000356436). My solution for this (not yet committed as of this post) is a bit hacky:

  • I added a boolean field to EditorSpinSlider called real_t_value (tentative) which should be set to true when the field displayed is stored as a real_t (there's no specific thing for float (as in 32-bit float) fields because I somehow only saw that those existed after doing all this).
  • When not rounding, the EditorSpinSlider stringifies numbers using String::num_real instead of String::num when real_t_value is true. This means the values are displayed cleanly.
  • For EditorProperty subclasses whose float fields are known to be real_t (e.g. EditorPropertyVectorN), every spinbox has real_t_value set to true by default. For EditorPropertyFloat, I added a new range hint real_t (tentative) which enables real_t_value when included.

I'll probably have to rewrite pretty much all of this if I want to account for single-precision float fields as well as real_t fields seeing as real_t isn't necessarily single-precision, and this all just feels kind of ugly in general (although I can't think of any better solution). One thing I'm unsure of is how much of this should be exposed -- right now it's possible to use the real_t hint with export_range in GDScript, but it's not in the autocomplete and there's very little point in it as GDScript floats are always double-precision.


One issue that wasn't a problem before (because it was covered up by a bigger problem) but might come up in the future is that values that are too small (around 5e-15 for double-precision fields and 5e-7 for single-precision) will be rounded to zero (see godotengine/godot#93768). This probably isn't that big a deal (for quite a while it's been impossible to input float values less than 5e-4 and have them stick), but I personally think that the inspector should use scientific notation for large and small values, both for readability and to ensure that information is not lost when EditorSpinSlider converts floats to strings back and forth. However, this probably belongs in a separate proposal.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants