ID:1821346
 
1279

This is stumping me a little bit and I'm wondering if I'm running into memory/heap corruption or something from SwapMaps. I've got a list of "hero" objects and when adding the second hero, the first one in the list is becoming null. I've tracked it down to the following line.

    g_listOfActiveZLevels.Add(M.z1);


That line has nothing to do with the hero list but when I remove it, the first hero doesn't get nulled.

This code.
   ...
var/mob/Hero/h = new();
m_listOfHeroes.Add(h)
...


calls this code.
mob/Hero/New()
...
m_Map = Proc_CreateNewMapFromTemplate("CustomMap")
...


which calls this code.
proc/Proc_CreateNewMapFromTemplate(templateName)
var/swapmap/M = SwapMaps_CreateFromTemplate(templateName)
M.SetID("Map_[g_iMapCounter++]")
g_listOfActiveZLevels.Add(M.z1);
...


Which in turn is nulling out the first hero in m_listOfHeroes.

Ah, I just found an map_CustomMap.txt file in my maps directory with the following:
//Orphan savefile buffer '' found on Mon Mar 30 17:09:24 2015

//End of exported data.


Not sure how important that find is.

Anyway, stuck at this point.
Lummox, I posted the DungeonDominus source in my usual location if you're the one that looks at this.

Realizing the slowness is due to initializing static maps for the purposes of creating templates which is fine. I only need to call it once if it doesn't exist.

Repro Steps.
1. Start
2. Click on "Buy Hero" button.
3. Click on "Fight" arrow and wait for hero to enter dungeon.
4. When the hero gets into the dungeon, Click "Buy Hero" again.

Expecting:
3: Hero
1: Hero
9: Hero
10: Hero
11: Hero
12: Hero
13: Hero
14: Hero
14: Hero
4: Hero
5: Hero
6: Hero
7: Hero
8: Hero
2: Hero
3: Hero


Actual:
1: Hero
9: Hero
10: Hero
11: Hero
12: Hero
13:
14:
14:
...


Also, if I remove this call from world/New() the issue goes away. It touches the same list.
    Proc_InitializeStaticMaps()


    Proc_InitializeStaticMaps()
for (var/i = 1; i <= world.maxz; i++)
g_listOfActiveZLevels.Add(i);


    list/g_listOfActiveZLevels = new();
I may have just solved it. I had filed an issue a long while back on something similar and I'm pretty sure it got fixed. Regression?

Changing the variable declaration from = new() to = list() and the problem went away.

*EDIT* - No, that didn't solve the problem. Almost like a buffer overrun where moving lines of code around will move the problem around. *sigh*

     list/g_listOfActiveZLevels = list();

I'll take a look at this soon. If there's a buffer overrun it may well show up in the debugger.
Gah, I spent quite a while chasing this and it turns out not to be a bug at all. SwapMaps is deleting the mob because it's standing on one of the turfs being loaded. SwapMaps always clears the loading region of mobs.
Sorry if you wasted time on something that is my own fault. I spent two days trying to make sense of it myself and while I suspected it had to do with SwapMaps, I couldn't pinpoint the issue and I still can't actually.

My expectation is that swapmaps looks for space to load the map and if it can't find it, it increases maxz and Reads the map into that location.

you said; "Always clears the loading region of mobs"

I get that statement if I'm overwriting an existing map via chunk. In this case, I don't even control where the map loads. It automatically loads into the next available space that it can find and fit in. That could be on any z level with space. In my case, it's always maxz+1 so how is my hero standing on empty space?






ah crap, found it. villa overwriting dungeon.
... although, why is it overwriting my dungeon? Still expecting it to create the new map on the next zLevel.
maybe you can help me understand this.

The first map I create from template starts with maxz being 3 and swapmaps_compiled_maxz being 3. Swapmaps increments z1 to 4 as expected.

I add the dungeon which moves maxz to 5.

I add the second map from template and as expected, world.maxz is 5 but then we get into ConsiderRegion(...) which is somewhat mind blowing and it returns a list where z1 ends up a 5 and not a 6 as I would expect. I assume it's looking for a chunk of space large enough to load the map starting at compiled_maxz+1 and working our way up. Might actually be a nice option to skip ConsiderRegion in favor of always doing maxz+1. Anyway,

Then it does this: z2 += z1-1

which is 1 + 5 -1 which is 5 again.

and then this
world.maxz = max(z2, world.maxz)

which is 5,5 so we get 5 back but maxz was already 5 so I don't get it.

I was already managing my own zLevels with the dungeons so I did a quick rewrite to populate the map manually instead of from template. Problem solved although I'm not convinced there isn't something screwy going on. Maybe you'll set me straight. I use swapmaps in most of my projects so it would be useful to know where I went wrong.