ID:2094461
 
Code:
/dmm_suite/proc/parse_grid(model as text,xcrd as num,ycrd as num,zcrd as num)
/*Method parse_grid()
- Accepts a text string containing a comma separated list of type paths of the
same construction as those contained in a .dmm file, and instantiates them.
*/


var/list/members //will contain all members (paths) in model (in our example : /turf/unsimulated/wall and /area/mine/explored)
var/list/members_attributes //will contain lists filled with corresponding variables, if any (in our example : list(icon_state = "rock") and list())
var/list/cached = modelCache[model]
var/index

if(cached)
members = cached[1]
members_attributes = cached[2]
else

/////////////////////////////////////////////////////////
//Constructing members and corresponding variables lists
////////////////////////////////////////////////////////

members = list()
members_attributes = list()
index = 1

var/old_position = 1
var/dpos

do
//finding next member (e.g /turf/unsimulated/wall{icon_state = "rock"} or /area/mine/explored)
dpos = find_next_delimiter_position(model, old_position, ",", "{", "}") //find next delimiter (comma here) that's not within {...}

var/full_def = trim_text(copytext(model, old_position, dpos)) //full definition, e.g : /obj/foo/bar{variables=derp}
var/variables_start = findtext(full_def, "{")
var/atom_def = text2path(trim_text(copytext(full_def, 1, variables_start))) //path definition, e.g /obj/foo/bar
old_position = dpos + 1

if(!atom_def) // Skip the item if the path does not exist. Fix your crap, mappers!
continue
members.Add(atom_def)

//transform the variables in text format into a list (e.g {var1="derp"; var2; var3=7} => list(var1="derp", var2, var3=7))
var/list/fields = list()

if(variables_start)//if there's any variable
full_def = copytext(full_def,variables_start+1,length(full_def))//removing the last '}'
fields = readlist(full_def, ";")

//then fill the members_attributes list with the corresponding variables
members_attributes.len++
members_attributes[index++] = fields

CHECK_TICK
while(dpos != 0)

modelCache[model] = list(members, members_attributes)


////////////////
//Instanciation
////////////////

//The next part of the code assumes there's ALWAYS an /area AND a /turf on a given tile

//first instance the /area and remove it from the members list
index = members.len
if(members[index] != /area/template_noop)
var/atom/instance
_preloader.setup(members_attributes[index])//preloader for assigning set variables on atom creation

instance = locate(members[index])
var/turf/crds = locate(xcrd,ycrd,zcrd)
if(crds)
instance.contents.Add(crds)

if(use_preloader && instance)
_preloader.load(instance)

//then instance the /turf and, if multiple tiles are presents, simulates the DMM underlays piling effect

var/first_turf_index = 1
while(!ispath(members[first_turf_index],/turf)) //find first /turf object in members
first_turf_index++

//instanciate the first /turf
var/turf/T
if(members[first_turf_index] != /turf/template_noop)
T = instance_atom(members[first_turf_index],members_attributes[first_turf_index],xcrd,ycrd,zcrd)

if(T)
//if others /turf are presents, simulates the underlays piling effect
index = first_turf_index + 1
while(index <= members.len - 1) // Last item is an /area
var/underlay = T.appearance
T = instance_atom(members[index],members_attributes[index],xcrd,ycrd,zcrd)//instance new turf
T.underlays += underlay
index++

//finally instance all remainings objects/mobs
for(index in 1 to first_turf_index-1)
instance_atom(members[index],members_attributes[index],xcrd,ycrd,zcrd)
CHECK_TICK


Problem description:
So, the grid parser of the map loader runtimes when I pass it a map to load. I get at least a hundred runtimes, called on different turfs that need to be placed.
Base runtime:
runtime error: list index out of bounds
proc name: parse grid (/dmm_suite/proc/parse_grid)
source file: reader.dm,242
usr: Unknown (/mob/living/carbon/human)
src: /dmm_suite (/dmm_suite)
usr.loc: space (175,65,7) (/turf/space)
call stack:
/dmm_suite (/dmm_suite): parse grid("/turf/open/space,/area/space", 171, 69, 7)
/dmm_suite (/dmm_suite): load map(_maps/map_files/templates/smal..., 171, 59, 7, null, null)
small_shuttle_1.dmm (/datum/map_template): load(space (172,60,7) (/turf/space), 1)
CrAzYPiLoT (/client): Map Template - Place()

Code in question is above. Any help is appreciated.
Which line is 242?
These three lines seem to be the problem, specifically the last one (which is 242):
  var/first_turf_index = 1
while(!ispath(members[first_turf_index],/turf)) //find first /turf object in members
first_turf_index++
If that's going out of bounds, that means it can't find any turfs in the members list. Looking a few lines above that in the parser, this line might explain why:
            if(!atom_def) // Skip the item if the path does not exist.  Fix your crap, mappers!
continue
members.Add(atom_def)


Are you sure /turf/open/space is still a valid path in your game? You could try adding some debug output above that continue to see if it's discarding paths.
In response to DarkCampainger
DarkCampainger wrote:
Are you sure /turf/open/space is still a valid path in your game? You could try adding some debug output above that continue to see if it's discarding paths.

There's your issue, the codebase CrAzYPiLoT is porting this too (from the one I'm from, /tg/) doesn't have a refactor we did for /turfs, tl;dr of it is that they have no /turf/open/space, they have /turf/space, and since they ported the new maps over too, they're porting invalid paths.

Still the real issue is that the maploader simply ignores these paths (only to runtime later on) instead of recording them to a log and loading what best it can.
Yeah, that was it. Thank you so much!