ID:1560937
 
Keywords: hud
Applies to:DM Language
Status: Open

Issue hasn't been assigned a status value.
Currently you cannot have screen objects (a subtype of atom/movable at the very least) which do not contain procs, verbs, and vars common to map objects. (I have tried arcane pacts with the parent_type demons, but no amount of blood sacrifice appears to allow this.)

If, for example, you want an administrator verb to apply to all map objects, you might create an atom proc and add it to the client verb list of administrators. However, screen objects such as hud buttons would receive this verb as a side effect of their inheritance, and the only way to remove it is to override the proc, changing its hidden and/or src settings. This is possible, but difficult to maintain, as it must be hardcoded on a proc by proc basis.

Screen objects belong somewhere between atoms and movable atoms; all movable atoms want to be screen objects, but dedicated screen objects (GUI/HUD) should in most cases never be allowed on the map, meaning they have no use for loc/locs, Move(), etc.

Alternately, this could be done by moving screen_loc to atoms, at which point you could conceivably make a screen object subtype that does not share code with anything else. I assume the reason this was not done was due to some sort of engine optimization or requirement.

Admittedly this is a minor improvement; there are not enough hud elements in most games for this to be a substantial optimization of memory, CPU, etc. However, I think it's fair to say that in most cases dedicated hud objects (as opposed to screen-based inventory, etc) are a dedicated side branch of atoms that share little if anything in common with the rest of the code.
As far as I know, this is why /image was created.
It has screen_loc and shares quite a bit of other functionality with /atom/movable, but it's substantially faster since it doesn't have any movement/etc overhead.

My guess is that both /image and /atom/movable inherit their functionality from an internal class (or it's just copy-pasted). I've considered making a request to externalize it, but the current graphics classes have enough problems already...

As far as I know, this is why /image was created.
It has screen_loc and shares quite a bit of other functionality with /atom/movable, but it's substantially faster since it doesn't have any movement/etc overhead

Can you expound upon this thought?

Images are only faster than atoms to initialize because generally speaking, there are less movable atoms in the world than image objects.

The memory overhead is minimal at best, and frankly, the majority of the overhead is going to come in the form of the way that objects are polled for updates. Images and movable atoms would be polled the exact same way, and as such, would not have any difference to performance.

Images are a special branch of atom that serve the function of per-user visual effects.

Movable atoms are physical objects. Screen objects no longer being tied to physical objects Largely speaking, what we're interested in are appearances anyway, and not the physical atoms.

This feature request is kind of a non-starter, and only complicates things for the sake of complication.
In response to Ter13
Ter13 wrote:
Can you expound upon this thought?

My guess is that /atom/movable has more vars to initialize (built-in or otherwise), so right off the bat I'd expect it to take a little longer (this version of SS13 shows 50 on /image and 96 on /atom/movable). Not sure how procs factor in, but I don't think they make a big difference.

Also, the recent betas (currently using 506.1244) did something to widen the gap, since i'm seeing images initialize many times faster (they're only twice as fast on 504).

Ter13 wrote:
The memory overhead is minimal at best, and frankly, the majority of the overhead is going to come in the form of the way that objects are polled for updates. Images and movable atoms would be polled the exact same way, and as such, would not have any difference to performance.

Maybe not exact. Made a thread on this yesterday.

The change made to images is pretty much identical to the one made for objs and mobs, which was to search for IDs in a different way and also avoid holding onto them for 1-4 ticks.

I believe the time gap is proportionally wider mainly because the percentage of creation time needed for that O(N) loop was higher for images. As you say, movables have more vars and may need to do more in initialization, so I think that's the difference. With the mechanical parts much improved, the difference between the other parts is much more apparent.
In response to Wild Bill Bartok
As far as I know, this is why /image was created.
It has screen_loc and shares quite a bit of other functionality with /atom/movable, but it's substantially faster since it doesn't have any movement/etc overhead.

To my knowledge /image cannot be inherited or reprogrammed and does not have native click events. Both of those are desirable attributes for making an interactive HUD/GUI, eg, /hud/button/inventory.
In response to SuperSayu
SuperSayu wrote:
To my knowledge /image cannot be inherited or reprogrammed and does not have native click events. Both of those are desirable attributes for making an interactive HUD/GUI, eg, /hud/button/inventory.

Yeah, this is a problem. Like the other dedicated graphics classes, it's partially internal (for lack of a better term) and some functions are inaccessible and/or buggy.
But it can do clicks, so that's not a problem. In fact, if you tie it to an object, any clicks on it are sent to the object (so it can represent it on the HUD). It can also be set to override the object's graphics completely.
I'm not sure if it would be beneficial enough to add, but I would be interested in seeing a variation of /images that is nearly identical, except it can run clicks of its own. Images tend to be the fastest, most efficient method for purely visual things in HUD/GUI related stuff, and if it could support clicks of its own without needing an object then it could be used for buttons instead of just backgrounds and such.

If it gained maptext support, there's even more use there. Objects work fine for this, but when it comes to using them for this we really don't need a lot of their vars or procs, like bump, move, etc; which means if we could use images that don't need to initialize all of that it might be more effective.

The question would be whether the performance increase would even be high enough to matter, though. Especially if this isn't something that can be added to BYOND really quickly and easily, since we don't want any development time going to waste for too small of a benefit.

Hm, I really don't know. Don't mind me too much. I'm rambling on a bit, and just theorizing really. I haven't gotten into testing this type of thing enough to speak confidently.
Honestly I don't see a dedicated screen object type improving performance in any way. The places performance are ever lost tend to be on things like ill-designed loops, or defining too many vars in the base type. With good choices of subtypes, like for instance /obj/item vs. /obj/hud, performance losses just shouldn't come up.

Furthermore I don't see it as useful for screen objects to have no support for procs or verbs. There are legitimate reasons to have one or both. Lack of proc support would be relatively useless--even images can be subtyped and given procs. Also this wouldn't make sense if the object was a click target, as Click() is itself a proc.
Well, that answers the question I had. Good to know for sure that it wouldn't be of much use. Subtypes are definitely a major influence, but I didn't know they could be used on images so that's good to know.

@OP: You've brought up an interesting discussion, but I must admit your point about an administration verb didn't hold up very strongly. I can't think of many similar cases, and in terms of the example its self, I can't think of many games that would need to do something like that with administration.

All in all, given what Lummox Jr and Ter13 said, I think you might be better off experimenting a bit further and just optimizing your systems with things as they already are now.

I really can't see this feature doing much good now that things have been explained clearer.
I will not be surprised if the idea is ultimately rejected, it is a minor quibble compared to the work that would be done to add it, both in the language and for existing projects.

The reason I want it is more architectural than a matter of optimization--screen objects don't *belong* as a subtype of /obj or /atom/movable, because in most cases there is no reason to share code, and there are often side effects of sharing code.

A simple example is normal click code--if in general you have a click mode "Do X to the clicked atom" you have to make excuses for HUD objects appearing to be sane children of the /obj tree. For example, I would expect tool use or hand interactions or gun attacks to work on all turfs and all movable atoms, but not that particular subtype of objects used for the hud. You could make an atom proc to distinguish between them without typechecking, but unless there are other and various types of exceptions, that proc only exists to get around the inheritance issue... the more different cases where you have to solve the same problem, the more redundant code you may end up creating to get around it.

Again nothing that can't be gotten around it's just inelegant.
In response to SuperSayu
You can just redefine the path tree to give yourself another ancestor between obj/mob and atom/movable which allows you to use inheritance in the above mentioned example, but not the turf/obj/mob example.

//breakable behavior in here
/atom/movable/breakable
HUD/parent_type = /atom/movable/

//redefine the path tree a little
obj/parent_type = /atom/movable/breakable
mob/parent_type = /atom/movable/breakable



//this is an /atom/movable
HUD
icon = 'a.dmi'
New(location)
. = ..(null)
if(location)
screen_loc = location

client/verb/addHud() //sorry lummox, we're defying the cardinal rule of /atom/movable :)
var/HUD/h = new("1,1")
var/HUD/c = new("2,1")

screen += h
screen += c

sleep(100)
In response to SuperSayu
SuperSayu wrote:
A simple example is normal click code--if in general you have a click mode "Do X to the clicked atom" you have to make excuses for HUD objects appearing to be sane children of the /obj tree. For example, I would expect tool use or hand interactions or gun attacks to work on all turfs and all movable atoms, but not that particular subtype of objects used for the hud. You could make an atom proc to distinguish between them without typechecking, but unless there are other and various types of exceptions, that proc only exists to get around the inheritance issue... the more different cases where you have to solve the same problem, the more redundant code you may end up creating to get around it.

That depends entirely on the type of game, though. It's not unreasonable to want a HUD click on an obj to be the same as clicking the obj when it's on the map. (Plus, the click verb passes along where you clicked it.) It's usually more flexible and more desirable for the HUD object to simply be linked to the original, but there is sometimes a point to simply reusing the same object.