ID:145474
 
Problem description:

While I haven't had time to look into the problem myself, I noticed Swapmap produces a runtime error when you have multiable turfs in one location, and assumes that the turf is in the other turf which stops the loading process of that map. I did alittle searching and only saw one other person complain about the problem here: http://developer.byond.com/forum/ index.cgi?action=message_read&id=397052&forum=3&view=0 Althougth they did not know what the problem was at the time. I did a test case using Swapmap itself to show the problem: Simply create a turf that does not cover the entire tile, or it would merely get rid of the previous tile (I used his Fence.dmi as a /turf rather than an /obj)
turf
ground/icon='ground.dmi'
dirt/icon='dirt.dmi'
fen/icon='fence.dmi'

Place it on demo.dmp so that it has two turfs in one tile, then Convert the Demo.dmp into a swapmap format, and attempt to load it, you should get:

runtime error: bad loc
proc name: Read (/atom/Read)
usr: /swapmap (/swapmap)
src: the fen (6,8,3) (/turf/fen)
call stack:
the fen (6,8,3) (/turf/fen): Read(C:\\Program Files\\BYOND\\user... (/savefile))
/swapmap (/swapmap): Read(C:\\Program Files\\BYOND\\user... (/savefile), null, null)
SwapMaps Load("demo")
Dark (/mob): LoadMap("demo")
runtime error: Cannot create objects of type null.
proc name: Read (/swapmap/Read)
usr: /swapmap (/swapmap)
src: /swapmap (/swapmap)
call stack:
/swapmap (/swapmap): Read(C:\\Program Files\\BYOND\\user... (/savefile), null, null)
SwapMaps Load("demo")
Dark (/mob): LoadMap("demo")

I don't have time right now to look into it, but if anyone wants to try and see where the code goes south, feel free to post it here. Well back to lurking and too much school work.. I'd guess that it's something to do with adom/Read() or swapmap/Read(), I have too much homework right now, but I'll post anything I get when I don't.
swapmap
Read(savefile/S,_id,turf/locorner)
var
x;y;z;n
list/areas
area/defarea=locate(world.area)
id=_id
world << "obj/map/M[S["id"]]"
if(locorner)
ischunk=1
x1=locorner.x
y1=locorner.y
z1=locorner.z
if(!defarea) defarea=new world.area
if(!_id)
S["id"] >> id
else
var/dummy
S["id"] >> dummy
S["z"] >> z2 // these are depth,
S["y"] >> y2 // height,
S["x"] >> x2 // width
S["areas"] >> areas
locked=1
AllocateSwapMap() // adjust x1,y1,z1 - x2,y2,z2 coords
var/oldcd=S.cd
for(z=z1,z<=z2,++z)
S.cd="[z-z1+1]"
for(y=y1,y<=y2,++y)
S.cd="[y-y1+1]"
for(x=x1,x<=x2,++x)
S.cd="[x-x1+1]"
var/tp
S["type"]>>tp
var/turf/T=locate(x,y,z)
T.loc.contents-=T
T=new tp(locate(x,y,z))
if("AREA" in S.dir)
S["AREA"]>>n
var/area/A=areas[n]
A.contents+=T
else defarea.contents+=T
// clear the turf
for(var/obj/O in T) del(O)
for(var/mob/M in T)
if(!M.key) del(M)
else M.loc=null
// finish the read
T.Read(S)
S.cd=".."
S.cd=".."
sleep()
S.cd=oldcd
locked=0
del(areas)

adom
Read(savefile/S)
var/list/l
if(contents.len) l=contents
..()
// if the icon was a text string, it would not have loaded properly
// replace it from the cache list
if(!icon && ("icon" in S.dir))
var/ic
S["icon"]>>ic
if(istext(ic)) icon=swapmaps_iconcache[ic]
if(l && contents!=l)
contents+=l
del(l)
Well, I've looked into it, and I found a few things: The problem occurs when you attempt to convert from a dmp for a load, with BYOND's current setup, its not possible to make what is needed for the error to occur at runtime, that being, making a turf on a location where a turf exists, it merely erases the previous turf. This is however possible in the dmp editor which is provided to us in the IDE. Since it is only possible in that, I've found that the runtime error had to before any code actually ran in Read(), that point which I tracked to the converter itself which LummoxJr kindly provided. Now, the convert merely pharses the text a dmp gives when open in a notepad, (which is essentially what BYOND itself does) And tries to replicate it to a save file format, this however causes a problem, as, only BYOND can create a turf in a turf, we can't,.. lets take a closer look at the dmp:
<font size = 1>
"a" = (/obj/fence,/obj/fence,/turf/ground,/area)
"b" = (/obj/fence,/turf/ground,/area)
"c" = (/turf/ground,/area)
"d" = (/obj/gold,/turf/ground,/area)
"e" = (/turf/ground,/turf/fen,/area)

(1,1,1) = {"
abbbbbbbbb
bccccccccb
bcdccecdcb
bccccccccb
bccccccccb
bccccccccb
bccccccccb
bcdccccdcb
bccccccccb
bbbbbbbbbb
"}

</font size>
This is what the demo.dmp, with my added tile; looks like, as you can see,..

"e" = (/turf/ground,/turf/fen,/area)

It contains a turf, in a turf, when BYOND read it, it puts it right, when Lummox's converter reads it, it treats it as it does the object in the line before it:

"d" = (/obj/gold,/turf/ground,/area)

Saying that, /turf/ground/, is within /turf/fen, when it isn't in reality. So when it goes to read it, it gives a bad loc for the turf, and ceases the read, which causes the rest of the map, during loading, past that tile, to be blank. I can't seem to figure a way around this either, as there is no way on our end to make a turf in a tile a turf exists, which out just taking the turf, and making it's icon an underlay of the previous turf, but since this conversion is happening before the game is ever done, externally, there is no way to change anything before it is in save file form. This is rather inconvenient on my end, as I'd rather not have to make all tiles I put over turfs as objects instead, as that gives a significantly less amount of objects left to work with for other systems within a game. One thing I did think of, was editing Lummox's conversion code, which could prevent the error, but since there is no way to alter the way in which BYOND read's a file, I have no way to save what the other tile was, unless there is a way I could hold that data on the side, then just edit the pharsing to exclude the extra tile, and add it as an underlay after the load, if anyone knows a way to do that, it'd be a great help.