Describe the project you are working on: This applies to any project.
Describe the problem or limitation you are having in your project:
The way data structures are printed out is currently a bit inconsistent, and it could be improved.
Explanation in bullets below each set of outputs. Test code:
func _ready():
print("Vector2")
print(Vector2())
print("Vector3")
print(Vector3())
print("Color")
print(Color())
print("Quat")
print(Quat())
print("Plane")
print(Plane())
print("AABB")
print(AABB())
print("Rect2")
print(Rect2())
var t = Transform2D()
t.x = Vector2(1, 5)
print("Transform2D")
print(t)
var b = Basis()
b.x = Vector3(1, 5, 0)
print("Basis")
print(b)
print("Transform")
print(Transform(b))
Output with current master:
(0, 0)
Vector3
(0, 0, 0)
Color
0,0,0,1
Quat
(0, 0, 0, 1)
Plane
0, 0, 0, 0
AABB
0, 0, 0 - 0, 0, 0
Rect2
(0, 0, 0, 0)
Transform2D
((1, 5), (0, 1), (0, 0))
Basis
((1, 0, 0), (5, 1, 0), (0, 0, 1))
Transform
1, 0, 0, 5, 1, 0, 0, 0, 1 - 0, 0, 0
The current output is a bit confusing and inconsistent:
Color is lacking spaces after the commas.
AABB and Transform both contain a dash, which can be mistaken for a minus sign.
Some things have parenthesis, some don't, and Basis/Transform2D have nested parenthesis.
Transform2D prints out column-major, while Basis prints out row-major, and Transform is row major except the origin is last.
Describe the feature / enhancement and how it helps to overcome the problem or limitation:
The proposal is to change the behavior of the above code so that the output looks like this:
(0, 0)
Vector3
(0, 0, 0)
Color
(0, 0, 0, 1)
Quat
(0, 0, 0, 1)
Plane
(0, 0, 0), 0
AABB
(0, 0, 0), (0, 0, 0)
Rect2
(0, 0), (0, 0)
Transform2D
[X: (1, 5), Y: (0, 1), O: (0, 0)]
Basis
[X: (1, 5, 0), Y: (0, 1, 0), Z: (0, 0, 1)]
Transform
[X: (1, 5, 0), Y: (0, 1, 0), Z: (0, 0, 1), O: (0, 0, 0)]
No dashes anywhere, parenthesis used for grouping with commas for separation.
Transforms and Basis are now printed consistently and with explicit labels to avoid any confusion.
Describe how your proposal will work, with code, pseudocode, mockups, and/or diagrams:
Branch: https://github.com/aaronfranke/godot/tree/to-string
PR: https://github.com/godotengine/godot/pull/34668
One remaining question is whether or not we want to show trailing decimals, since these are floats (real_t). Currently they are omitted, but it could be argued that it would be better to show them. This could also be done in a follow-up proposal or PR.
If this enhancement will not be used often, can it be worked around with a few lines of script?:
This will be used often, and yes it can be worked around, but this should be in core.
Is there a reason why this should be core and not an add-on in the asset library?:
This is about changing how core data types work, so it's already in core.
I dont like having some of them print multiple lines. Often times, you want to coalesce the string representation into another string. Also it makes it unusable in log lines (for instance in server logs that are consumed by a log consumer such as fluentd)
@jonbonazza Do you have an idea for another format that would be the highly readable and not confusing?
I think the color is better output in hex: #000000 instead of (0, 0, 0, 1).
@dalexeev I don't think this is a good idea for two reasons:
0.002 which would be rounded inaccurately.@jonbonazza Do you have an idea for another format that would be the highly readable and not confusing?
I think that something like [(1, 0, 0), (0, 1, 0)] for Transform2D makes sense and something similar for the others.
@jonbonazza The thing with that suggestion is that it gives the impression that the first row is a Vector3, when it's not really a vector in the world, it's just the first component from each of the three column vectors in the matrix. Transform2D is composed of X, Y, and origin Vector2 vectors, each of which is a column in the matrix. So with that format (using the example code with t.x.y = 5), the bold items would be for the X vector: [(1, 0, 0), (5, 1, 0)]. But also, if we put all of the components of each vector together, like in the current output for Transform2D, it might be confusing because then the column vectors are displayed horizontally. Furthermore, I'm wondering if using [] could be confusing because it would look like an array, but it's not an array.
I am wondering if maybe we could do something very explicit, like either [X: (1, 5), Y: (0, 1), O: (0, 0)] or maybe instead something like [Row0: (1, 0, 0), Row1: (5, 1, 0)]. Either of these formats should be clear and hard to confuse with arrays (since arrays wouldn't have named elements with colons).
@aaronfranke i dont think it suggests that at all. It just suggest a 2d array. Nothing about x y or z. But id also be okay your explicit suggestion. In the end i think you are thinking too hard about something that isnt really a problem. It doesnt really matter what the format respresents as long as users know how to read it. Thats what docs are for.
Also, in the case of transform, i dont know why the x y and z vectors are so important. The axes dont matter much in the context of transform matricies.
@jonbonazza I updated this proposal and the PR with feedback from here, let me know what you think.
My goal is to be explicit to avoid confusion, so I decided to have labels for everything. Keep in mind that the current behavior was inconsistent with column/row between 2D/3D, so this confused the person who implemented these operators in the first place.
@aaronfranke my only real remaining qualm is that the ones that don't have a distinct start/end token (i.e. () or []) will be hard to parse mentally whe coalesced with other strings, for example, in logs. I think they are fine when printed on their own, but this is rarely thr case in practice.
Most helpful comment
@aaronfranke i dont think it suggests that at all. It just suggest a 2d array. Nothing about x y or z. But id also be okay your explicit suggestion. In the end i think you are thinking too hard about something that isnt really a problem. It doesnt really matter what the format respresents as long as users know how to read it. Thats what docs are for.
Also, in the case of transform, i dont know why the x y and z vectors are so important. The axes dont matter much in the context of transform matricies.