ID:2382229
 
(See the best response by Lummox JR.)
Descriptive Problem Summary:

When attempting to follow http://www.byond.com/forum/?post=1613721 guide on dealing with immutability/mutability with overlays, a code snippet is utilized to remove overlays and underlays from a mob. While working perfectly well for underlays, the snippet working on overlays bugs out returning an index out of bound error.

Numbered Steps to Reproduce Problem:

1. Code copied and adjusted from linked thread.
2. Successful compile.
3. Utilizing the verb in the game.

Code Snippet (if applicable) to Reproduce Problem:
Overlays_Remove()
set category="Other"
appearanceO = overlays[overlays.len]
appearanceU = underlays[underlays.len]
usr.overlays-= appearanceO
usr.underlays-= appearanceU


Variables appearanceO and U defined before.

Expected Results:

Both overlays and underlays are stored in the appearance vars, then removed and can be rather restored with Overlay Restore.

Overlays_Restore()
set category="Other"
usr.overlays+= appearanceO
usr.underlays+= appearanceU


Actual Results:

Works fine with underlays but overlays return an error:

runtime error: list index out of bounds
proc name: Overlays Remove (/mob/Players/verb/Overlays_Remove)
usr: (src)
src: Test(/mob/Players)
src.loc: CustomTurf (130,190,5) (/turf/CustomTurf)
call stack:
Test(/mob/Players): Overlays Remove()

Does the problem occur:
Every time? Or how often? 100% of the time
In other games? N/A
In other user accounts? Yes
On other computers? Yes

When does the problem NOT occur?

N/A

Did the problem NOT occur in any earlier versions? If so, what was the last version that worked? (Visit http://www.byond.com/download/build to download old versions for testing.)

N/A

Workarounds:

None
Does the object in question even have any overlays?

/world/New()
var/obj/A = new
var/obj/B = new
A.overlays += B

world.log << isnull(A.overlays[A.overlays.len]) // 0
world.log << isnull(B.overlays[B.overlays.len]) // runtime error: list index out of bounds
Yeah, multiple ones. Also using an older version of the verb:

Overlays()
set category="Other"
usr.overlays-=usr.overlays
usr.underlays-=usr.underlays


Gets rid of both properly.

Could the error come up a result if some of the overlays are icons and some of them are images?
Best response
The object has no overlays. If it did, this error would not happen, period. You're assuming it has overlays but it definitely does not.
Tested it out a bit more thoroughly, specifically manipulating it in a way where I could operate on a set number of overlays and figured out what is the exact bit [also cleaning up the code a bit in the manner of defining the variables and targetting the src. rather than usr.]

Results: Mixed

The error print no longer occurs, but figured out what was the real fault that wasn't immediatelly noted:

I was using multi-overlay effects, but the provided code only removed the last one added. Since there was usually only a singular underlay used, the same problem was barely noticable for them.

Overall, code works but only on the last element added of said lists.

Any advice on how a proper one going through the whole list of each and then readding them back would be structured?
Reread my section about the FLOAT_LAYER in that tutorial. You'll quickly discover that there is no need to go through an overlays list to reorder them.
It's not exactly about reordering - I found the tutorial snippet quite useful regarding the potential of dealing with issues of certain overlays getting stuck on relogs or disappearing when contained in other object and after some testing, the utility worked out nicely.
overlays getting stuck on relogs

You shouldn't be saving overlays. You should be regenerating them on login using your equipment system. The objects you have equipped on your character should be enough information to rebuild the overlays list. After mob.Write(), simply remove the overlays and underlays list from the savefile.
We already use that and I just found this method promising for specific instances but I guess that's the extent of what can be expected.