ID:1472894
 
Applies to:DM Language
Status: Open

Issue hasn't been assigned a status value.
Would it be possible to handle image objects slightly differently when applied to the world?

Currently when you render the image objects to the world and someone logs in after they have been rendered to the world, they won't see them.

var/image/i=image(icon,loc,icon_state)
world<<i


Image objects could be used to render particles on certain objects.

Personally I'd like to render certain elements as image objects because I can set it's locations as other /atom and it appears above the location, it is convenient.

For example I wish to create a torch, which has image objects as the flame particles and they are rendered to the world at the moment you create the torch. At this point of time, it would mean that only the people who were in the world at the creation time will be able to see the flame particles.
I do find this to be a bit strange. I understand why the current behavior is the way it is, but I think once a mob becomes a part of world's contents, it should be able to see the images shown to world.

I believe this behavior is because the VM simplifies this to showing the image to all connected clients. Change this behavior would require the back-end to be looking at when mobs enter or exit world's contents and checking to see which images they can or can't see (or just blatantly showing them images regardless of previous state).

This will be something lummox or tom will have to review and tell us if this idea makes sense on the back-end. I can see the possibility of this idea being a bad one due to how complicated its implementation might be, and how it could negatively affect older games (in keeping the spirit of backwards compatibility). I of course do not care about backwards compatibility, and to me it would be fine if this only worked for complications made with versions 504+.

For your temporary workaround, keep track of when mobs login and logout, and create a list. Each time this list changes, traverse through it and show your current list of world images to them (keep track of world images too).

var/list/world_images = list()
var/list/world_mobs = list()

proc/show_world_image(image/i)
world << i
world_images += i

proc/remove_world_image(image/i)
world_images -= i
for(var/mob/m in world_mobs)
if(m.client) m.client.images -= i
del i

mob/Login()
..()
world_mobs += src
for(var/mob/m in world_mobs)
for(var/image/i world_images)
m << i

mob/Logout()
world_mobs -= src
..()
I am aware of the possible work around, I currently use a similar method. I myself personally do not care about the backwards compatibility as much either.

In my opinion the images shown to the world could be stored in the world instead of the every single client to whom it was shown to.
In response to Taitz
It isn't that simple.

When you do this:
world << image


Inside, its doing this:
for(each connected client as c)
c << image


So what you're requesting isn't a concept that exists in the backend, which is why I was telling you it most likely will not change. This is because they would have to write a whole new system to make this work. The system would have to track who has seen and hasn't seen images.
Figured I'd pop some information in here gleaned from Lummox for future reference.

Information regarding appearance changes is communicated to clients regardless of the position of the image object if it's deliberately exposed to the client via adding it to the images list.

This means that you will incur slight additional network overhead for appearance changes related to objects that are not in the client's viewable area, however, the images will not be displayed unless the image object is connected to an object within that client's viewable area.

world << i

Is basically just shorthand notation for perform output operation on all valid clients currently connected.
FIREking, I am aware of how it works in terms of inside workings due to it being client based. Regarding simplicity, is there anything, which is simple anyways?

The current method to show image objects to clients is good, but as an additional feature to allow showing it to the world, where as adding it into the world contents would be good as well, since it is about the only visual effect you can exactly tie up to other /atom and has the same location, where as other ones would require constant location change ie. /movable ,since setting their loc typically means to place it inside some other object.
While it would be kind of nice if it did work this way, isn't it easy enough to just keep track of what images you want displayed to the world and just display those to new clients as they connect? Don't even really have to track who has seen it then, since new clients would probably want to see it anyways.

If you're doing stuff like removing it from connected clients at some point and whatnot you'd have to do a little more work keeping track of things, but I can't imagine it being all that much work to handle it yourself.
var/list/globalimgs = list()

proc/globalimage(image/i)
while(globalimages.Remove(null)) //clean up null refs
globalimgs += i //add to global list
world << i //expose to world

client/New()
. = ..()
if(.)
//if we've just logged in successfully, add the global image list to our images list
src.images.Add(globalimgs)


It's like, not even ten lines of code.
You forgot the 'if(!i) return', now the code is useless! =P, but seriously, really not that hard at all like I figured.
In response to Nadrew
Nadrew wrote:
You forgot the 'if(!i) return', now the code is useless! =P, but seriously, really not that hard at all like I figured.

I only include sanity checks in my code where I know that the values can reasonably enter domains where they are no longer valuable to the computation.

The way I look at it, if you are stupid enough to feed a null value into a proc, you deserve every last runtime.