ID:137607
 
A HUD has been discussed before, but there are several problems with implementing it as an image on the map, most notably when you move to the edge of the map. A HUD is excellently suited to giving players a lot of information in a small area, yet directly in the playfield where it is easily accessed.

I realise this will take a great deal of work and will probably be a BYOND 3 feature if it ever makes it in, but I would like to be able to send specific graphics (perhaps even atoms) to a client at absolute coordinates on thier map display. You could use this for borders and HUDs without worrying about updating the location of the display objects or having them run off the map.

That way if I send an icon of a health display object, with several overlays to shade each body part to show damage to hit locations, to the client's display at 1,1; I would know it is always in the lower left corner of the client map, even if the player moves so that that area is off the map.
Shadowdarke wrote:
A HUD has been discussed before, but there are several problems with implementing it as an image on the map, most notably when you move to the edge of the map. A HUD is excellently suited to giving players a lot of information in a small area, yet directly in the playfield where it is easily accessed.

Dantom has said that allowing for non-map turfs (perhaps in a ring around the map) is on the future list.


I realise this will take a great deal of work and will probably be a BYOND 3 feature if it ever makes it in, but I would like to be able to send specific graphics (perhaps even atoms) to a client at absolute coordinates on thier map display.

Even with the above, this could certainly be interesting. However, given how complicated it might be, the above solution would probably be enough.
Shadowdarke wrote:

I realise this will take a great deal of work and will probably be a BYOND 3 feature if it ever makes it in, but I would like to be able to send specific graphics (perhaps even atoms) to a client at absolute coordinates on thier map display. You could use this for borders and HUDs without worrying about updating the location of the display objects or having them run off the map.
map.

Interestingly enough, this is something that I have been thinking about in just the last few weeks, after essentially abandoning the idea last year.

I noticed that many of the puzzle games-- Backgammon, Cribbage, Dragonsnot, and ShapeShifter, to name a few-- use this kind of HUD display to avoid the statpanels entirely. In Dragonsnot, for instance, you select your pieces from a neat little column on the left-side of the map. It occurred to me when playing Tanks, that many, many other games could benefit from this approach as well. But since they use maps larger than the screen, they really can't, because, barring huge hacks, there's no way of keeping the display fixed with the map. But if we had some way of setting absolute coordinates, this wouldn't be an issue and then games that really wanted full control over the stats could just handle them on the map.

Ideally the HUD would work like Stat() and be updatable on a per-client basis, to avert the need for image(), but in our first run we could simplify and not do anything special at all. The key, for now, is simplicity. I don't suspect that this is actually a major problem to implement, if we can come up with a flexible notation. The client already has to re-map the map data sent from the server, so it doesn't really care which coordinates things are at.

Unfortunately, it is not quite as simple as merely setting the absolute coordinates. While that might work for a brief amount of time, once the player moves on the map, the display will become messed up. What we really want is a way of making a particular coordinate immobile, so that when the map shifts it gets drawn in place of the layer normally there, if it were using the server-coordinates.

I have thought through a number of possible notations for this, but haven't come up with anything too satisfactory just yet. One idea would be to have client.dx,dy vars that would simply offset the client map by some fixed width such that anything drawn in the layers [1-dx],[1-dy] would always be displayed; a similar notation could be used from the other two borders. However, this strikes me as somewhat clunky. The more powerful idea would be the ability to isolate each tile as being immobile or not, perhaps by making a special kind of "client-side map" in the map-editor and having that always overlay the server-side map. It wouldn't be so hard to do if we could just treat it like this, where each client-side coordinate replaced its server-side counterpart, but it's not quite that simple, since you really want the server-side coordinate to be used for the purposes of the game (locations, view() checking, etc). It is almost as if the client-map is on a different level, and perhaps we should treat it as such. It just has to be _displayed_ on the current level.

I think this would be a great addition to the system, so we'll continue to think about it and consider implementing it if it turns out to be feasible.
In response to Tom
I meant absolute screen coordinates, rather than map coordinates. For example:

hud(x,y,atom)

would display the icon of atom at screen coordinates x,y. The max x and y values would be limited by world.view.


If you only do border edges, you could use a similar notation.

hud(direction,coordinate,atom)

direction could indicate which edge (NORTH,SOUTH,EAST,WEST) and coordinate would indicate how far along that edge.

A possible extension would be to automatically increment the location if direction and coordinate are ommitted. For example:

hud (NORTH,1,healthmeter)
hud (magicmeter)
hud (weapon)
hud (spell)

would make the first four spaces contain those icons.
In response to Shadowdarke
Shadowdarke wrote:
I meant absolute screen coordinates, rather than map coordinates.

Right-- I was talking about screen coordinates as well. I think we are basically talking about different approaches to the same task. The problem as I see it, is this: when you send a graphic to something at a client (screen) coordinate, what happens to the stuff already there at the corresponding server (map) coordinate? As the user scrolls along the map, the HUD must stay fixed, which means that the existing map elements it sits upon must either be replaced or shifted. And since you still want users to be able to interact with the HUD, those absolute screen coordinates must themselves be translated into server coordinates so that they are clickable, locateable, etc; in other words, they are just like every other element on the map.

Now personally-- and I think this is what you are getting at-- I don't want to mess with the server coordinates at all. The HUD itself should simply restrict the view(), and by creating it when the map is first loaded we can do this without much trouble. I think that this idea might work:
  • Create a special map that you will use for the HUD.
  • The objects on this map will set the client view, so if you make a 10x10 map with non-null objects around the border (and an empty area in the interior), the view will effectively be 4.
  • Designate the HUD map within the world, ie world.view = 'myhud.dmp'. Perhaps the map will have a z-level of -1.
  • This map will always be drawn on the screen. The client will then remap the server coordinates to fit inside the smaller view() by simply applying the border offsets.
  • Users can interact with the HUD elements just as if they were on the normal map, for the purpose of clicking; the z coordinate will simply come in as the aforementioned -1. Ditto for locate(), so you can grab and replace certain HUD elements.

    That's about the easiest system I could think of that doesn't require an excessive amount of work on our end. It is pretty flexible, but would still require the use of image() to handle statpanels and such. The more advanced HUD-- something like Stat() -- would be more challenging and might actually be less efficient, although it would probably be easier for the designer to use.
In response to Tom
Ahh! I understand now. Yes, I was looking for the easy way out on the designer's end ;)

I had assumed it would just float over the map, but that would cause the same sort of trouble for you when it hits the edge that it would now for a designer.
In response to Tom
i hope you plan to implement this, and i also hope that you make it have the ability to have a right click menu for each HUD item, such as an obj does. This would make it easy to execute commands very quickly. Actually if it is at all possible, just make the HUD items obj atoms, then that would give us the full ability to do whatever we wanted, a click, double click, or right click, and what so have ya.

I think this could be the single most coolest thing that byond would ever have, excluding the skins idea, which would be even cooler.

If this does ever get made, i will be sure to be one of the first people who uses it.

FIREking
In response to Shadowdarke
Shadowdarke wrote:
I meant absolute screen coordinates, rather than map coordinates. For example:

hud(x,y,atom)

would display the icon of atom at screen coordinates x,y. The max x and y values would be limited by world.view.


If you only do border edges, you could use a similar notation.

hud(direction,coordinate,atom)

direction could indicate which edge (NORTH,SOUTH,EAST,WEST) and coordinate would indicate how far along that edge.

A possible extension would be to automatically increment the location if direction and coordinate are ommitted. For example:

hud (NORTH,1,healthmeter)
hud (magicmeter)
hud (weapon)
hud (spell)

would make the first four spaces contain those icons.

better yet, as for syntax or whatever, Hud() could be a proc like Stat()

mob
Stat()
statpanel("inventory",contents)
Hud()
hudblock(1, 1, src)
hudblock(2, 1, /obj/HealthDisplay)
hudblock(3, 1, /obj/ManaDisplay)
hudblock(4, 1, /obj/StaminaDisplay)

where hudblock() is as follows
hudblock(x coordinate, y coordinate, atom path to display)

in the example above, the first block would show your self, and what your body looked like, the second block would show the obj that would automatically either update its self or whatever, showing your health

when we give it the ability to have these types of arguments, it would be possible to do all types of things

hopefully these would act sort of like overlays, so that you could see the turf underneath the hud block.
In response to Tom
Tom wrote:
- Create a special map that you will use for the HUD.
- The objects on this map will set the client view, so if you make a 10x10 map with non-null objects around the border (and an empty area in the interior), the view will effectively be 4.

Would this support just taking up a block at the bottom or side of the screen? In other words, doing the buttons in DragonSnot shouldn't cause the loss of turf all the way around.

My real reason for asking is not DragonSnot (which actually uses the full border anyway, and which, because it is a fixed space, doesn't need the hub functionality) but because of that future Civilization-based game that the DDT game will get to someday (I've really been getting itchy about that lately!)

It would be wonderful to provide the kind of command-bar along the bottom that Civ, Age of Empires, and the like have. It might have a minimap so you could click to jump to an area (in some fashion...we couldn't do the real thing most likely), and stats for your selected unit and the like.

Or, equally possible, we might want to carve out a non-symmetric HUD like so (= is a hud turf, map not drawn to scale...):

==============
= =
= =
= =
==============
==============


I'm guessing your proposed approach would handle all this, but just wanting to check!
In response to Tom
The other thing, besides the edge of the map (I usually build padding equal to world.view around the playable edges of the map, just because there's so many possibilities for bugs/errors/unforseen effects there), is that images still obey the rules of luminosity and opacity for line-of-sight. I can make an image appear in the lower left corner of the screen... I just can't make it remain visible if there's darkness or walls down there.
In response to LexyBitch
Another idea, that I just thought of reading through the rest of this post, and that would be usefull in a couple of locations.

It prolly sounds liek about the same thing, but oh well, if its been said, then Im an idiot, and Im too tired to say anything >:P

Basicaly, why not set 2 new built in vars/procs. Make one, a var on every obj/turf/overlay/whatever, just like density, and luminosity, perhaps make it 'sight' or some such thing. A simple toggle will do. sight=1 and -everyone- can see that turf, sight=0, and only the client can see that whatever. Build it in so sight=0 also makes whatever its refering to non dense, so theres no miss-communication between the server and the clients over density issues.


Second, would be the ability to display whatever your displaying, in -reference- to a mob. So instead of the good ol 'in the door and up the stairs' method, you could simply say... wait a min here.. doesnt it already exist? >:P Im fairly certain that that part at least is do-able currently... so really, all wed need would be the first part.

Other then a HUD system, this could also be used for player only graphics. Say you want a single player to have the ability to see specialty tiles on the map, this would be a fairly good way to go about doing it.

Anyways, Ive prolly said whats been said before, so Ill shut up ^^;

Elorien
In response to Elorien
Other then a HUD system, this could also be used for player only graphics. Say you want a single player to have the ability to see specialty tiles on the map, this would be a fairly good way to go about doing it.

Anyways, Ive prolly said whats been said before, so Ill shut up ^^;

Elorien

well that isnt what i would be striving for, i would want the HUD to be interactive, allowing you to put any atom in a "hudblock" using the HUD() proc, just like the stat proc, you can read my HUD Syntax post for more info on what i mean.

Giving up the ability to point where we want the hudblock to be displayed, and telling it a type path (any declared atoms within the code, or any thing existing, such as src in one case) for what to display gives us much more power, but this would have to be implemented of course.
In response to LexyBitch
LexyBitch wrote:
The other thing, besides the edge of the map (I usually build padding equal to world.view around the playable edges of the map, just because there's so many possibilities for bugs/errors/unforseen effects there), is that images still obey the rules of luminosity and opacity for line-of-sight. I can make an image appear in the lower left corner of the screen... I just can't make it remain visible if there's darkness or walls down there.

Good point. The client map will be computed independent of the view() though, so lighting shouldn't be an issue.
In response to Deadron
Deadron wrote:

Would this support just taking up a block at the bottom or side of the screen? In other words, doing the buttons in DragonSnot shouldn't cause the loss of turf all the way around.

Yes and no. This system will allow you to effectively have a "window" into the viewport. Since the view must be square, you won't be able to have a row of fixed buttons that take up half of the bottom row and, at the same time, make the other half part of the map itself. It's either a part of the window-frame (the border) or a part of the interior (the view).

That said, after brainstorming this a bit we've come up with a slightly augmented system that might make your suggestion plausible. The idea would be to extend the window analogy to not only cover the window-frame, but the glass part as well. Dense parts of your client map will determine the viewport of your server map. Non-dense parts will be overlayed onto the viewport at every square. This means that you could set a background image for your entire client (in place of the default black) and possibly make irregularly shaped views if you are willing to handle the edge-detection. It's a pretty flexible system.
In response to Tom
Tom wrote:
Deadron wrote:

Would this support just taking up a block at the bottom or side of the screen? In other words, doing the buttons in DragonSnot shouldn't cause the loss of turf all the way around.

Yes and no. This system will allow you to effectively have a "window" into the viewport. Since the view must be square, you won't be able to have a row of fixed buttons that take up half of the bottom row and, at the same time, make the other half part of the map itself. It's either a part of the window-frame (the border) or a part of the interior (the view).

That said, after brainstorming this a bit we've come up with a slightly augmented system that might make your suggestion plausible. The idea would be to extend the window analogy to not only cover the window-frame, but the glass part as well. Dense parts of your client map will determine the viewport of your server map. Non-dense parts will be overlayed onto the viewport at every square. This means that you could set a background image for your entire client (in place of the default black) and possibly make irregularly shaped views if you are willing to handle the edge-detection. It's a pretty flexible system.

Sweet!! and spiffy as well!!
So is that a yes or a no on the whole thing?
can we expect it after the next release(two releases from now)

or is a "future" thing?

Thanks, I would really appreciate it

--FIREking

ps. Will the HUD display blocks be atoms? for interactive obj's and such?
In response to Tom
That's good... I figured anything you built especially to handle HUD functionality would be independent of such things. I was just talking about the problems with implementing a soft-coded HUD in DM.

To jump down to the lower part of this thread, where you describe the system as it will work, I have to say: kick ass! This will also have the side-effect of adding lots of view functionality.

Say I want to have a thermoimager in my game. This will make all hot/living things show up as indistinct red blurs... even if there's darkness/walls between you and them. Can't do this with image, because of the opacity/luminosity thing. If I understand this HUD pane business, though, I could put red heat signature objects in the HUD, over the locations of all "hot" objects in orange() when the imager is used. Granted, it would be hard to make these blurs move... unless you're using a system that already tracks all mobs in orange for some reason... but if it's an instant scan effect, it would work.
In response to Tom
I think this would be most easily done if you tied in some of the ideas discussed on Deadron's Map Musings thread.

I think it would be beneficial to begin to separate maps, so that multiple maps of disparate sizes could exist at any given time. Essentially this would move some variables out of /world and into /map to begin with. Then dynamic loading and unloading of maps could be thrown in.

Anyway, I bring this up because the best way to do the HUD would probably be to create a new built-in object: world.view. The world.view property would be treated as a special map, one that doesn't move with an eye but rather simply overlays the displayed maps. You could then add turfs and objs to this (with a default turf being null or a special blank turf, for obvious reasons), with their locations corresponding to their location on the viewport. Then the code to set up a HUD would look something like this:

spells_icon.loc=world.view.locate(1,1,1)

Of course there is one drawback to that system: It'd be nice to be able to draw text directly onto the HUD, too. Maybe later.

If you moved to a multi-map system from the current system, you could still maintain backward compatibility. If the "main map" is in /world, then additional maps can be created independently of that. The advantages of a multi-map system are many, including possible dynamic loading and saving of maps as sections, special maps for RPG combat arenas, and so on.

Lummox JR
In response to FIREking
Im confuzzled.. This would already be interactive O.o;

As it stands now you can make pretty much anything interactive, just use click() and dblclick() O.o; actually a rightclick() would be nice too ^_~

Actually, the map way that was mentioned could work for this too. To be -really- usefull itd need a couple of add-ons..

First off, and again sorry if it was already said, make it user only. So only a specific user can see it, that way you can have multiple map overlays for different users...

Second, make it so you can set the map so it will scroll, or not.

I think thatd be a fairly usefull way of doing things..

And actually, now that I think of it, itd be neat if we could map output to turfs... maybe be able to define something that would normally go to the text box, to a defined location, or to the location of a mob.. Itd be gread for damage displays among other things ^^;;

Oh well, Ill stop rambling on
In response to Lummox JR
Lummox JR wrote:

Anyway, I bring this up because the best way to do the HUD would probably be to create a new built-in object: world.view. The world.view property would be treated as a special map, one that doesn't move with an eye but rather simply overlays the displayed maps. You could then add turfs and objs to this (with a default turf being null or a special blank turf, for obvious reasons), with their locations corresponding to their location on the viewport.

Yes, this is the approach we have in mind. My earlier post in this thread ([link]) discusses it in a bit more detail.

Then the code to set up a HUD would look something like this:
spells_icon.loc=world.view.locate(1,1,1)

Well, that's doesn't quite fit in with the current notation, but it's the same basic idea. Here's how it will tentively work:
spells_icon.loc=locate(1,1,ID)
where ID will be some reference to the hud map, which will be assigned with client.map = 'hud.dmp'. Perhaps it could even just take that as an argument: locate(1,1,client.map). This will allow you to have multiple client maps and even be able to change them at runtime as needed (eg: when you get in a tank you get a gunner map, when you exit, you get a solider map, and so forth). For now, you'll have to use these in tandem with image() if you want to toggle stats on a per-user basis since, just like the normal maps, the hud maps will be shared between users. Clearly this just begs for dynamic map support, but that's a considerably more difficult feature that will probably have to wait for a while. But it's not so bad-- Deadron has shown, in DragonSnot, that images can make excellent control elements.

The problem with introducing nifty new features like this is that they begin to spawn feature creep, since obviously so much more can be done. We have to be careful!
In response to Elorien
Elorien wrote:

First off, and again sorry if it was already said, make it user only. So only a specific user can see it, that way you can have multiple map overlays for different users...

Yes, that's a valid point, but it makes the problem more difficult, and in some cases might not be desired. Currently you can use image() to broadcast stuff on the map/HUD to individuals.

Second, make it so you can set the map so it will scroll, or not.

That's one of the main purposes of the HUD-- it will not scroll, while the underlaying main map will.

And actually, now that I think of it, itd be neat if we could map output to turfs... maybe be able to define something that would normally go to the text box, to a defined location, or to the location of a mob.. Itd be gread for damage displays among other things ^^;;

Yes, hopefully we can add image("text") in the future to handle map text.
Page: 1 2