Currently in DM your options for handling visibility of objects are mostly limited to being on or off. Some situations call for more fine grain control where you only want some players to be able to see an object.
This gets a little more tricky as well when players enter and leave the game so you have to remember what's visible to who.
My idea was to standardize how we deal with these problems by extending our notion of visibility with a few helpful methods which handle it all for you.
Basic Example
var/obj/Apple/A = new/Apple()
A.HideFrom(usr) // Everyone can see the apple except the usr
sleep(5) // Delay
A.ShowTo(usr) // Now the usr can see the apple again
Healthbar Example
var/obj/HealthBar/HB = new/obj/HealthBar()
HB.HideFromAllOnline(usr) // Anyone currently online won't be able to see it
HB.HideFromAllOffline(usr) // Even offline players won't see it when they come back online
HB.ShowTo(usr) // The current user can see it now
usr.overlays += HB
Source Code
You might only need a few of these methods but all are included for completeness.
/*
Author: http://www.byond.com/members/Zecronious
Date: 7 Jan 2017
Description: Control what players can see what objects.
*/
atom
var
image/cover
hideFromNewClients = FALSE
New()
..()
cover = image(null,src)
cover.override = TRUE
// Ensure that if this object is saved and recreated that it will
// be added back to the global list so no information is lost.
if(hideFromNewClients)
hiddenFromNewClients += src
proc
// Specify one person to show this to
ShowTo(target)
if(istype(target,/mob))
var/mob/M = target
M.client.images -= src.cover
else if(istype(target,/client))
var/client/C = target
C.images -= src.cover
// Specify one person to hide this from
HideFrom(target)
target << src.cover
// All players currently online will be able to see this
ShowToAllOnline()
for(var/client/C in clients)
ShowTo(C)
// All players currently online won't be able to see this
HideFromAllOnline()
for(var/client/C in clients)
HideFrom(C)
// Players who are offline will be able to see this when they come back online
ShowToAllOffline()
hiddenFromNewClients -= src
// Players who are offline won't be able to see this when they come back online
HideFromAllOffline()
hiddenFromNewClients += src
var/list
hiddenFromNewClients = list()
clients = list()
client
New()
..()
clients += src
for(var/atom/A in hiddenFromNewClients) A.HideFrom(src.mob)
Final Note
I've done the best I can do justify all my additions performance wise. This code leans more towards using a tiny bit more memory to save time on the CPU later on. Memory is cheap and people have lots of it but CPUs are expensive so I hold back as much as possible on that.
Also thanks to Gooobai for inspiring me to write this after I saw his cool idea for blind spots (http://www.byond.com/forum/?post=2186744)
You should be initializing it as needed and nulling it back out when it's empty. You can also save a bit more overhead by using += (or |=) and -= instead of Add() and Remove().
You could save a bit of overhead on the loops by not doing a containerless loop (which defaults to world + special lists) by storing online clients in a list and removing them when they exit the game, and looping over that list.
Other than that, using image.override for this is a great technique.