I don't mean the basics, I can add/remove/manipulate overlays just fine.
I mean the internals. Here's a proc I used to get some info on them:
/mob/verb/analyze_appearance()
var/T = null
T = pick(usr.overlays)
if(!T)
world << "pick(usr.overlays) didn't get anything"
return
world << "\blue Basic info on appearance:"
world << "Parent type: [T:parent_type]"
world << "Type: [T:type]"
world << "Tag: [T:tag]"
world << "Vars: [T:vars.len]"
world << "viz:"
for(var/V in T:vars)
world << "[V]"
world << "-----------------------------------------"
return
It gives the following results:
Basic info on overlay thing
Parent type: /datum
Type: /image
Tag:
runtime error: undefined variable /var/vars
proc name: analyze overlay thing (/mob/verb/analyze_overlay_thing)
source file: test.dm,125
usr: Jose Riker (/mob/living/carbon/human)
src: Jose Riker (/mob/living/carbon/human)
call stack:
Jose Riker (/mob/living/carbon/human): analyze overlay thing()
Feeding an /image, /obj, etc (even an /icon) to that proc gets sane results and no runtimes.
I'm mainly interested in this because I'd like to understand BYOND's internal graphics handling better.
Right now, my best guess is that /images and /"appearances" exist because /atom/movable has too much overhead to function as a lightweight graphics object.
/"appearances" are the more extreme class, since apparently they're stripped down to the point where they don't even have a vars list.
Then there's another problem.
To quote the DM reference:
In general, people who do not like reference counting garbage collection should be happy that DM provides a del instruction, allowing you to take charge and delete things whether they are referenced or not.
This is what happens upon attempting to del() an /"appearance":
runtime error: bad del
It seems appearances are an exception to the above principle.
Why aren't they bound by the same rules that govern most other classes?
It's natural that graphic objects should be as minimal as possible, to increase performance and allow freer manipulation.
Is that the goal here, or is there something i'm missing?
Calling DarkCampaigner, SuperSaiyanX, KaioChao, and Stephen001! These guys probably understand these internal types the best, but I have a pretty solid grasp on them, and their use.
Alright, so basically, BYOND, as a server-side driven online game client, needs a way to communicate visual data to clients.
It works through a sort of appearance registry. Whenever you change these variables of any atom:
alpha
blend_mode
color
icon
icon_state
text
dir
layer
transform
You start manipulating information regarding their appearance.
Essentially, these variables act as a sort of unique hash that identifies each visual appearance generated by the world. These appearances are then communicated upon need to the client for reference by a 3 or 4-byte index.
In other words, whenever I change the visual appearance of any atom in the world, the server hunts for an exact match within the global appearance dictionary. If no exact match is found, it creates a new appearance and provides it with either an abandoned, or new reference number. (When objects are deleted or garbage collected, their reference number is vacated, and each time a new object is created, it has to search the dictionary for the first empty reference.)
Anyway, once this appearance is registered by an internal identifer, it can be communicated to the client.
So the server needs to send a message to the client that is lexically something like this:
ID: APPEARANCE_REGISTER
0: [icon]
1: [icon_state]
2: [text]
3: [alpha]
4: [color]
5: etc
The client receives this information, digs that relevant data out of the rsc if it's not already loaded (/icon objects are actually serialized references to RSC data), then it gets the information ready for rendering in a texture within the graphics context.
Appearances are internally referenced by their ID number by every type of atom. Atoms are defined by what you can see. The client doesn't actually care about any non-visual information regarding atoms, so what the client sees, when it sees something like a turf look like this:
The rest of the variables are pretty much all server-side, stuff the client doesn't really care about.
Anyway, the point is, that appearances reference a unique visual state, and as such, only store information to specific virtual data. They aren't intended to be accessible, but you can abuse casting and the look-up operator to manipulate them.
They also can't be forcibly deleted, because ostensibly, if you are using BYOND from the front-end, you really shouldn't be manipulating back-end stuff like that.
Although, it would be nice to be able to grab an appearance object by id and globally forcibly update appearance data, rather than having to loop through every object using that appearance.