Describe the project you are working on:

A side scrolling fighting game.
The game logic is in 2D, but visuals may be changed to 3D at some point.
I frequently wish to draw points or vectors in space to visualize and debug my logic, e.g. distances, directions, targeting, velocity, grids, touch-input bounds, etc.
At first I intuitively tried to call the public draw_*()methods of a CanvasItem derived Singleton, but this results in the error:
Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.
Describe how this feature / enhancement will help your project:
The goal is to conveniently draw debugging visualizations from anywhere in your code without cluttering the actual logic with glue code.
Further, any debug drawing code shall be clearly separated from drawing that is intended to end up in the final product.
Currently I see two workarounds to draw debug visualizations, both have drawbacks:
You either embed the entire debug drawing logic into your class e.g. if its Node2D or Control, but this clutters your logic with debug code for drawing. It does not distinguish between drawing that is supposed to end up in the shipped game and debug visualizations.
Or you have to implement a Singleton that provides various helpful shapes like point, line, box, etc. and make it work with the transforms of 2D, Control and 3D.
Similar to this: https://github.com/klaykree/Godot-3D-Lines/blob/master/DrawLine3D.gd
In the spirit of "The Godot editor is a Godot Game" we may argue that "any drawing is drawing" and we should not have an engine-side differentiation between debug and release drawing. In this case we may discuss what changes, if any, would be needed to facilitate the implementation of an Add-On with the desired capabilities.
Show a mock up screenshots/video or a flow diagram explaining how your proposal will work:
An API example may be of more use here:
func _targetEnemy():
# have some math or gameplay logic here..
var selfPos: Vector3 = ...
var targetPos: Vector3 = ...
# params: from, to, color, duration, view space transform
Debug.draw_line(selfPos, targetPos, Color.red, 0.0, maincamera3D)
Considering the performance impact it would be preferable to have the option to toggle all Debug calls at runtime additionally to compiling them out.
Describe implementation detail for your proposal (in code), if possible:
https://github.com/klaykree/Godot-3D-Lines/blob/master/DrawLine3D.gd seems like a good start. Possibly attention needs to be paid to handling multiple viewports and offscreen rendering.
If this enhancement will not be used often, can it be worked around with a few lines of script?:
I assume it will be used often. It is likely more than a few lines of code to provide a generic class with a rich set of shapes like CanvasItem to draw in both 2D and 3D.
Is there a reason why this should be core and not an add-on in the asset library?:
A DebugDraw class like this may well be an add-on.
Implementing it on the native side may benefit performance though.
However more important may be to not hide such a debug feature behind an add-on.
Misc:
A more advanced version (or a add-on implemented on top of this core functionality) may offer the possibility to add Tags. This would allow to toggle the drawing of only certain tags at run time.
Debug.draw_line("Targeting", selfPos, targetPos, Color.red, 0.0, maincamera3D)
I would use this often. Like all the time, everyday all day, in all my projects. It would save me an tremendous amount of dev time.
For vectors, I would really need something akin to the print statement, but with an optional visual cue for the vector direction (think arrow head)
debug_vector(Vector vector, optional Color color, optional int thickness, optional bool arrow_head)
With this all I'd need to do would be debug_vector(myvector) and immediately get a visual representation of my vector on screen.
Alternatively there could be a DebugVector Node, similar of the Line2D:
$DebugVector(Vector vector, Vector vector,Vector vector,Vector vector, ...)
By default, each vector is drawn on top of everything else, in a different color and with arrow head and outline.
All properties are are accessed like this if the user want to change defaults:
$DebugVector(optional vector).thickness = 3
$DebugVector(optional vector).arrow_head= false
$DebugVector(optional vector).outline= false
$DebugVector(optional vector).color= RED
The weeks and months time I spend learning to understand various nested positional vectors could all be saved instantly for newcomers with something like this and allow easy and fast debugging for experienced users.
(EDIT: differentiated between print-like functionality and a Node functionality)
I agree that this sounds like something that would be used in a massive variety of projects, all the time.
The performance benefit of keeping it in the engine would be good. I also like how, if it were in the engine, then you could just wrap the methods in #ifdef TOOLS_ENABLED and completely filter out all the functionality in release builds while still maintaining general availability for all users while in the editor context.
Personally, I favor the Debug singleton route. It just keeps everything simpler and would allow you to consolidate the implementation under a single class by having nodes call to it and have it submit requests to the VisualServer when appropriate (abstracting away the glue code complexity).
I added further considerations to the opening post. You may wish to re-read it.
I am actually trending to an Add-on solution meanwhile, because:
An engine-side differentiation in debug drawing vs "real" drawing is not really appealing to me. Both is drawing. In Unity you can not have your Debug.draw*() code in release builds due to this distinction. Any drawing should be drawing and make no hard distinction. And if the drawing API is there, we don't need any engine side modification.
Considering my "Tag" Use-Case I added above I came to realize that users may want to adapt their particular Debug.draw*() methods to their project's scope and goals. Though you could just wrap the native ones in a custom singleton.
However I am unsure if an Add-on like this could be implemented with the current API.
I am currently trying to get a grasp of the VisualServer.immediate_*() methods to see where I can get with it.
People need to realize that anything that is not part of the official download will not be used by users who first come into contact with Godot for a while.
How would a new Godot user know they need addon xyz (debug draw in this case) to properly learn how Godot works? If vector debug draw is there, why is it not available from the get-go?
The AssetLib is clunky, yes, and the one embedded into the editor seems to not work for me at all.
But that is an issue of the AssetLib and not really a valid point for pushing a feature into the engine core.
I prefer Godot's lean API over the bloated bag of redundant features you get with other Engines.
Three physics back-ends, four ways to handle input, eight animation systems.
A philosophy like this would escalate quickly and end up more confusing than helpful.
If people are presented with an abundance of redundant options they might face a endless quest to research "the best one", not getting anything done in the process.
At least I tend to do that ;)
If people have a specific problem they intuitively search for a solution and will likely find the AssetLib.
The existence of this new proposal repository underlines the importance of having a specific problem before trying to find a solution.
However, that is not to say that I am still unsure where to have this debug feature.
I made a utility script for this exact purpose some weeks ago, as I was also in need of drawing debug geometry. While it does work, it has at least 2 issues: it requires placing a node in the scene (usually a direct child of the root node), and ImmediateGeometry has some performance issues when drawing and deleting multiple objects every frame.
Given these limitations, I would support the addition of a dedicated or easier way to draw debug geometry. Visual debugging can be extremely useful, especially in the early prototyping stage or when you are manipulating vectors in various ways and want to visualize them.
Most helpful comment
The AssetLib is clunky, yes, and the one embedded into the editor seems to not work for me at all.
But that is an issue of the AssetLib and not really a valid point for pushing a feature into the engine core.
I prefer Godot's lean API over the bloated bag of redundant features you get with other Engines.
Three physics back-ends, four ways to handle input, eight animation systems.
A philosophy like this would escalate quickly and end up more confusing than helpful.
If people are presented with an abundance of redundant options they might face a endless quest to research "the best one", not getting anything done in the process.
At least I tend to do that ;)
If people have a specific problem they intuitively search for a solution and will likely find the AssetLib.
The existence of this new proposal repository underlines the importance of having a specific problem before trying to find a solution.
However, that is not to say that I am still unsure where to have this debug feature.