ID:2065656
 
Applies to:DM Language
Status: Open

Issue hasn't been assigned a status value.
This might actually be a DM feature rather than a DS one, but I'm not sure how exactly they are distinguished?

Basically, could we have some sort of method to draw basic lines to the screen or game world? E.g., something like, DrawLine(x0,y0 , x1,y1) would drawn a line from the coordinates (x0, y0) to (x1, y1) while maybe a chained notation like DrawLine(x0,y0, ...., xN,yN) would mean drawing a line from the coordinates (x0, y0) to (x1, y1), then from (x1, y1) to (x2, y2), then ..., and then from (xN-1, yN-1) to (xN, yN).

Lines are a fairly-common, fairly-basic primitive that are difficult to do in DM since we can't really write to the screen buffer in any way. After consulting with someone, it seems like the only available methods are more like hacks rather than proper solutions, and I'd guess a built-in line drawing method would be faster. It's not like it's a one-use features, either, since lines can readily be used to build up more complex shapes and figures such as arbitrary polygons and Bézier curves.
This might actually be a DM feature rather than a DS one, but I'm not sure how exactly they are distinguished?

Seeker is the client specifically.
This would be classified as a DM Language feature.

Being able to draw graphics primitives is actually something Tom and I discussed waaaaaayyy back, and maptext was one of the things that grew out of those discussions.

I'm not sure how I'd draw a line in our renderer, but I do know it'd be pretty doable in the webclient. The bigger issue IMO is one of syntax. I think for consistency this shouldn't be done as a proc call, but rather as some sort of special object--preferably one that does not interlayer with atoms, which complicates things enormously.

Basically, I'd like to have a concept together where certain drawing primitives are supported, with limited style info, and it'd be easy to interact with those primitives like you would atoms. (Ideally, they would be atoms of some kind, shown in client.screen.) I have no desire to go for anything as in-depth as full SVG support, but being able to specify some simple shapes, stroke width, stroke and fill colors, maybe gradients, and maybe a dashed line style, would have its uses.

This is a great time to hammer out those details, because 510 isn't finalized yet and I'm still gathering ideas for 511.
In response to Lummox JR
The bigger issue IMO is one of syntax. I think for consistency this shouldn't be done as a proc call, but rather as some sort of special object

In that case, I could easily see something like,
var/line/L = new(x0,y0 , x1,y1) // Base points.
L.Stroke(x2,y2 , x3,y3) // Now draws a line from (x1,y1) to (x2,y2), and then
// from (x2,y2) to (x3,y3).
L = new (x0,y0 , x1,y1 , x2,y2 , x0,y0) // A quadrilateral.

or something like that, and presumably it could be transformed like other objects with MapColors() or Transform().

What exactly do you mean by interlayering, though? If it's the sense I'm getting, I could see situations where a line would make sense to appear above some atoms and below others (e.g., a spell cast from one player to another, and appears below tree tops but over top the players).
Well, I guess there's an inherent question of whether it's important to allow these things to be drawn in among map elements, or as part of HUD.

Drawing among map elements gets super tricky, because layering algorithms have to be setup to handle those cases. In topdown that's usually not a problem, but in isometric/side formats it'd be an issue for sure.
To be honest, for side/isometric, it makes sense for the shapes to use plane-only layering.

For topdown, plane/layer doesn't seem to be an issue because the line/polygon sequence would wind up just being able to be treated as an atom with visible bounds calculable to the largest rectangle that would fully enclose the shape.

For isometry, it's pretty much an unsolvable problem unless you restrict them to just layer onto a plane similarly to how the SNES handled moded layers.
In response to Lummox JR
Lummox JR wrote:
I have no desire to go for anything as in-depth as full SVG support, but being able to specify some simple shapes, stroke width, stroke and fill colors, maybe gradients, and maybe a dashed line style, would have its uses.

Convex quadrilaterals? :D
In response to D4RK3 54B3R
Those can be trivially built up from lines, though, and relatively efficiently too.
In response to Lummox JR
Lummox JR wrote:
The bigger issue IMO is one of syntax. I think for consistency this shouldn't be done as a proc call, but rather as some sort of special object--preferably one that does not interlayer with atoms, which complicates things enormously.

Why not draw inspiration from other frameworks?

/paint_device
-> A non-atomic but renderable (e.g. client.screen, overlays, ...) type. Could provide procs for, say, scaling, rotating, clearing, etc as well as vars pertaining to its width, layer, etc.

/painter
-> New(/paint_device/p)"
-> Initialized on a /paint_device, provides methods for drawing to it. See QPainter for ideas, but procs like SetPen() and DrawLine() would be fundamental.

So then I'd add some object derived from /paint_device to my screen, and if I wanted to draw to it I would create a new /painter for it.
Bump. I already have my own in-engine solution to this but it'd be nice for it to be some kind of native feature, could reduce overhead.

Really though this request is about primitives as a whole!