-
-
Notifications
You must be signed in to change notification settings - Fork 260
Description
The confusion around the use of different floating-point types keeps coming up. A lot of people lose time and wonder why they need to convert the delta: f64 parameter when working with Vector2, which is f32 based. Even our Hello World tutorial needs to deal with this, distracting from more important topics. At the same time, it is arguable whether people typically need the 8-byte precision in games (although it's definitely nice to have it when truly needed).
In C++ and GDScript, this is less of a problem. GDScript only has one type float (which is 8 bytes except in vectors etc. if single precision builds are used). C++ has both but allows implicit conversions, so multiplying double with float is not such a ceremony as in Rust.
I see multiple options here.
-
Make all API types
f32by default.- Allow people to opt-in to
f64. Either we couple this to the existingdouble-precisionfeature, which is technically slightly different, but it could make sense that people who care about this enough would also wantdouble-precision. - Alternatively, a separate feature. I would need to have very good reasons here; we already have lots of Cargo features and I want to avoid their proliferation -- to keep usage simple and since it's impossible to test all combinations properly. I'd almost say we should try combining it with the existing feature first, and then wait for concrete user feedback.
- Allow people to opt-in to
-
Magic on the API boundary.
- For
enginemethods, we could acceptimpl Into<f64>parameters. However, return types would still need to bef64orf32. - For user-defined
#[func]methods, proc-macros could silently translatef32in parameter and return-type position tof64. This would however be a departure from "use pure Rust with attributes" and could also confuse static analysis tools, as well as users that encounter signatures different from the trait methods.
- For
-
Keep using both
f32andf64, but integrate them wherever possible.- Vector operators would accept both parameter types.
- This falls short since vector fields still have one type, and return types also have one type. We will still need conversions, just in some places not. Not sure if this truly makes code clearer.
-
Use custom types.
- Either a generic
Floatthat can be converted to bothf32andf64. It could have some integrations like multiplications with vectors etc. But in practice, it won't simplify that much -- you'll usedelta.as_f32()instead ofdelta as f32, so ergonomics are questionable. - Use specialized types like
Duration,Angleetc. While very interesting by itself, we might not be ready to add those, as we'd need to manually annotate the entire Godot API surface. - In general, I'm not sure we win that much here. Rust doesn't have implicit conversions (apart from the
impl Intoparameter trick), so having a new type means mostly that you now even need to convert tof64. - Also, it makes the type system more complex -- there is
f32,f64,realand now this.
- Either a generic
-
Don't care.
- We say that the current solution is the best possible one. This would be the rusty approach, saying "things are maximally explicit, your problem if the code is verbose".
- Not sure if I particularly like this approach, especially in gamedev where pragmatic approaches and productivity are often preferred. See also Ergonomics and Panics for a similar discussion.
- There is clear indication from Discord help requests that the status quo brings some confusion. We don't have a good explanation why
f32andf64are mixed apart from "that's what Godot does". And maybe that's enough of an explanation, but to some extent it's a cop-out.