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

Allow some non-integer built-in constants in gdscript #14704

Merged
merged 1 commit into from
Aug 10, 2018

Conversation

poke1024
Copy link
Contributor

I'm always missing named compile-time color constants for Colors in the editor. This adds them:

demo

Since adding full fledged static constants to gdscript (I started) might entail some longer discussions due to various side effects (time of initialization, change of byte code for singletons, etc.), this PR's implementaiton is just adding some syntactic sugar by expanding Color.xyz into Color(r, g, b, a) in the gdscript parser.

@akien-mga
Copy link
Member

That feature is already implemented as ColorN("red"), I don't think we should add another way to do the same thing: http://docs.godotengine.org/en/latest/classes/[email protected]#class-gdscript-colorn

@poke1024
Copy link
Contributor Author

ColorN doesn't have code completion.

@Calinou
Copy link
Member

Calinou commented Dec 15, 2017

Considering that you might not want to use "pure" color values (which look unpleasant to the human eye), is this worth implementing? You could define constants using the const keyword in a script instead.

@leoddd
Copy link
Contributor

leoddd commented Dec 16, 2017

Is there a way to add custom entries to ColorN in-game?
If not, then I'd say that this PR could be used instead of ColorN, just because it's actually more intuitive to access different built-in colors from the Color class, rather than a built-in function; and the code-completion is helpful as well, because I would've looked for "lime" instead of "yellowgreen".
If adding custom entries to ColorN is a thing that could be considered then I'd rather go that route though. Would make consistent color scheming across the game easier, at least.

@akien-mga akien-mga added this to the 3.0 milestone Dec 16, 2017
@poke1024
Copy link
Contributor Author

@leoddd That's my stance, basically. If there's a static, curated list of colors Godot ships with, I'd like to have it as editor hint in some way.

@bojidar-bg
Copy link
Contributor

What about adding code completion to ColorN instead?
Also, I doubt such constants' resolution should be put in GDScript, it would be better if they are accessed similar to the numeric constants (to allow for, e.g. Vector3.up and the list as well).

@poke1024
Copy link
Contributor Author

How would you add code completion to ColorN? It takes a string parameter - you'd need to add a completely different kind of code completion not available yet.

I agree Vector3.up (and others) would be nice. But that does suggest adding full static non-integer constants to gdscript, which I originally started but then stopped as it's a change I'm probably not fit to do in a way that will match Godot's compiler design; it probably involves changing Godot's byte code as it needs access to some sort of globals/singleton management, the only global being self AFAIK. One relatively simple approach would be having static x = 3 internally rewrite into static x = func return 3 and then internally rewrite abc.x into abc.x(); but that would not be a constant. It might be ok if we use this only internally and do not open definition of static constants to gdscript users.

On the other hand, if we do not expose this feature (definition on non-numeric static constants), one could generalize the approach of this PR to add Vector.up and similar builtin constants - I actually think that this approach wouldn't be so bad, as it's a small change and would allow for a set of non-integer static constants for some built-in classes.

@poke1024
Copy link
Contributor Author

PR is now cleaned up and much generalized (changed PR title to reflect this).

To sum up this new PR: instead of making all static built-in constants integers (as in current master), built-in constants may now be other types (basically any Variant types that do not bloat the constant table, see below).

As an example, this implements Vector3.UP, Vector3.DOWN, and so on (besides Color names).

All non-color constants show in the docs just as integer constants do:

docs

Internally, in GDScriptParser, all constants are represented by a ConstantNode which AFAIK embeds the Variant in a constant table in the byte code - if this PR is followed, then there should be a guard to not allow any Variant but only some basic types like Vector2, Vector3, String that are ok to embed in this way.

What this is not: a full-fledged static constants solution for having any expression or object type as a static constant or that lets users define their own static constants.

@poke1024 poke1024 changed the title Static color constants for gdscript Allow some non-integer built-in constants in gdscript Dec 17, 2017
core/variant.h Outdated
static void get_numeric_constants_for_type(Variant::Type p_type, List<StringName> *p_constants);
static bool has_numeric_constant(Variant::Type p_type, const StringName &p_value);
static int get_numeric_constant_value(Variant::Type p_type, const StringName &p_value, bool *r_valid = NULL);
static void get_constants_for_type(Variant::Type p_type, List<StringName> *p_constants);
Copy link
Contributor

Choose a reason for hiding this comment

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

Wrong indentation here, BTW.

@ghost
Copy link

ghost commented Dec 18, 2017

This is just nitpicking, but shouldn't Vector3.BACK and Vector3.FORWARD be swapped around? I got the impression that in a right-handed coordinate system, from a perspective where x-positive would be "right" and y-positive "up", z-negative would be "forward". Here's a reference that I guess supports this.

@ghost
Copy link

ghost commented Dec 18, 2017

Your Vector2 constants also seem to have this problem; in the 2D view, Vector2(0, -1) is "up" and Vector2(0, 1) is "down".

@akien-mga
Copy link
Member

This is just nitpicking, but shouldn't Vector3.BACK and Vector3.FORWARD be swapped around? [...] Your Vector2 constants also seem to have this problem; in the 2D view, Vector2(0, -1) is "up" and Vector2(0, 1) is "down".

Proved the point I made every time such constants were asked for that they're not improving code quality. If people don't understand how the coordinate system works, having such helpers just makes code less readable and more error prone; whatever is Vector3.RIGHT when you're looking towards (5.24, -12.13, -2.0)?

Still, if people really want those, why not, they've been requested enough times to show that some people think differently from me ;) But I wouldn't extend GDScript features like non-integer built-in constants just for those.

@poke1024
Copy link
Contributor Author

poke1024 commented Dec 18, 2017

@Homer666 Not an expert on this one, but here's some thoughts on this confusing topic.

If you'd pick a right-handed coordinate system and you'd define forward in a negative numeric direction, then forward is not a good name for decreasing in z IMHO.

The reason is, I believe, that most people tend to think in left-handed systems; and even though OpenGL is right-handed in object space, you often find camera views in OpenGL that are configured to left-handed systems (https://stackoverflow.com/questions/4124041/is-opengl-coordinate-system-left-handed-or-right-handed).

I agree with @akien-mga: all these terms lose their meaning if you're not in a standard camera frame. Only if you're in a standard camera in OpenGL object space, forward is -z.

I think you wantright, up and forward to correspond to numerically increasing values in the respective axes, because that is what most people intuitively think. And that's left-handed.

Unity also follows this convention:
https://docs.unity3d.com/ScriptReference/Vector2.html
https://docs.unity3d.com/ScriptReference/Vector3.html

EDIT To substantiate that claim a bit, think of a person knowing no math in front of a paper with a point. Now tell that person to go - from that point - one step right, one step up, and one step forward, and see where the person ends up. This will always be left-handed.

@poke1024
Copy link
Contributor Author

Added a few more constants for illustration of what might make sense.

@ghost
Copy link

ghost commented Dec 18, 2017

@poke1024 I do agree that left-handed would come naturally to most people, but I don't know if deviating from the way Godot works is really a good idea.

From what I can tell, Unity follows this convention because it actually uses a left-handed coordinate system for everything, so having forward be +z makes perfect sense there. Its 2D view also seems to just be the 3D world with the z-axis flattened, so +y is still up as it was in 3D.

Godot's two different coordinate spaces don't adhere to these two things. Identifying and understanding these little coordinate quirks have always been a requirement to using Godot beyond just plopping down Control nodes, so this won't really change anything beyond having to remember that some of the Vector constants are backwards...

@poke1024
Copy link
Contributor Author

I understand, and indeed Unity seems to be consistenty left-handed. So, Vector2.UP should be what Godot uses as "up" in the standard 2d view, i.e. (0, -1, 0). But then I also really get @akien-mga's point now.

I guess I should change the constants to the Godot way and users could be informed that these constants only make sense if they consistently set up their local transformation frames in a way that adheres to these convention.

The main question remains though if this PR will ever see the light of day :-)

@ghost
Copy link

ghost commented Dec 18, 2017

I hope it does! It's a good PR!!!

Anyway, regarding Vector3 specifically.... wrapping your head around the coordinate space is a bump that people will probably run into even without the constants; when I started playing around with 3D, my characters were facing z+ which caused them to move "left" when x+ increased, which tripped me up a little. I think that having this explicitly stated as a constant or something would help more than it would hinder honestly.

@poke1024 poke1024 force-pushed the colorconstants branch 2 times, most recently from 148cac2 to 9a25997 Compare December 19, 2017 19:01
@poke1024
Copy link
Contributor Author

Apart from experimenting with a few other constants (more like a brainstorm for anyone evaluating this PR) I've turned the color constants to upper case for consistency with other constants and made them appear in the docs:

color-docs

@akien-mga
Copy link
Member

Thanks a lot for your contribution!
We are now entering a strict release freeze for Godot 3.0 and will only consider major bug fixes. We won't merge new features and enhancements anymore until 3.0 is released.

Moving this PR to the 3.1 milestone, to be reviewed once the release freeze is lifted. It could eventually be cherry-picked for a future 3.0.1 maintenance release if it doesn't change the user-facing APIs and doesn't compromise the engine's stability.

@akien-mga akien-mga removed this from the 3.0 milestone Jan 4, 2018
_VariantCall::add_variant_constant(Variant::VECTOR3, "UP", Vector3(0, 1, 0));
_VariantCall::add_variant_constant(Variant::VECTOR3, "DOWN", Vector3(0, -1, 0));
_VariantCall::add_variant_constant(Variant::VECTOR3, "FORWARD", Vector3(0, 0, -1));
_VariantCall::add_variant_constant(Variant::VECTOR3, "BACK", Vector3(0, 0, 1));
Copy link
Member

@aaronfranke aaronfranke Jun 16, 2018

Choose a reason for hiding this comment

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

Great work, although I'd also like to suggest adding "ONE" and maybe "NEGONE" for feature parity with the C# built-ins I added: https://github.com/godotengine/godot/blob/master/modules/mono/glue/Managed/Files/Vector3.cs#L280

@akien-mga
Copy link
Member

akien-mga commented Jul 25, 2018

This needs a rebase after #19264, but we should likely decide whether we want the feature or not. WDYT @vnen @reduz?

Edit: We should also decide about the conflicting PR #15435.

core/color.h Outdated
@@ -187,6 +188,7 @@ struct Color {
static Color hex(uint32_t p_hex);
static Color html(const String &p_color);
static bool html_is_valid(const String &p_color);
static const Map<String, Color> &names();
Copy link
Member

Choose a reason for hiding this comment

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

I would simply not add this here, its not going to be used anyway, just put them together with the other constants inside Variant

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

@reduz
Copy link
Member

reduz commented Jul 27, 2018

This is very cool, if you can change what mentioned in the review, we can merge it

cn->datatype = _type_from_variant(cn->value);
expr = cn;
cn->value = Variant::get_constant_value(bi_type, identifier);
cn->datatype = _type_from_variant(cn->value);expr = cn;
Copy link
Member

Choose a reason for hiding this comment

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

Slight nitpick: there shouldn't be 2 statements in the same line.

@karroffel
Copy link
Contributor

Bump, there is a very small formatting issue, but I would love to see this merged! 💙

@akien-mga
Copy link
Member

I agree with the feature itself, but I think the list of constants that was added is way overkill, this should be reviewed before 3.1 is out. Things like BLACK_CIRCLE seem hardly useful, quite arbitrary (I don't think we want to add constants for all of Unicode), and risky (they break generating RST documentation from XML currently).

akien-mga added a commit to akien-mga/godot that referenced this pull request Aug 20, 2018
They were introduced in godotengine#14704 but need more discussion IMO,
they don't strike me as core features that would have to be
registered in Variant directly.

Moreover, they currently break the documentation XML as string
constants end up encoded as e.g. `value=""..""`.
@poke1024
Copy link
Contributor Author

@akien-mga You're right, some constants are a pure demo thing "look what you can do with constants", I forgot about them.

@aaronfranke
Copy link
Member

Why aren't the Color constants UPPERCASE?

Also, in C# they are in a Colors static class, so that they are separate from the Color struct's other static members (like the Color8 constructor). While there are no other static members in GDScript's Color to warrant this change, it's worth considering Colors.RED etc for consistency.

@bojidar-bg
Copy link
Contributor

(Note that changing the case of the constants might warrant a change in ColorN's documentation, due to #35581)

@Vivraan
Copy link
Contributor

Vivraan commented Aug 4, 2020

I can do some of these changes, I'm already invested in this.
#41019

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.