ID:165625
 
Basically, what I want to do is every so often have a map empty it's self of all mobs/objs, then have it randomly spawn some new mobs/objs.
I can kind of do that. The problem is, every single way I have tried worked well with 1 map... But after 5+ maps, that were only 30x30 it got pretty laggy. So you can imaging what it would be like on a much larger scale.

From what I have worked out, the lag is coming from the game having to check which objects need to be deleted.

What I am doing is having a turf that every so often runs a proc.
When the server is started this turf creates a list of all turfs with the same z level as it.
When the proc is ran it will try to delete every object off the map first, then it will use pick to pick several turfs on the map then create objects at that location.
I am pretty sure this causes little to no noticeable lag at all. I've tried it without deleting other mobs/objs on the map and I didn't notice any real lag (until it had ran a few times and had created a ton of stuff).

Anyway, the problem I am having is with coming up with a decent method to delete the objects.
I've tried using...
for(var/obj/O in range(Range,T))
del O

But it doesn't seem to work properly, for some reason no matter what range I set it to, it just wont delete objects that are at the edge of the map.

I've tried using...
for(var/obj/O in world)
if(O.z==T.z)
del O

This works, but it is just way to laggy to actually use.

And I've tried...
for(var/obj/O in block(locate(1,1,T.z),locate(Range,Range,T.z)))
del O

This just refused to work all together, I have no idea why. Maybe because it is a turf calling the proc?

I even tried giving every mob/item an inactive timer, where after not seeing a player for so long they would delete themselves. But even that caused lag :[

So, is there anyway of clearing an inactive map of all mobs and objs and then having it respawn random mobs and objs in random locations on the map WITHOUT it causing to much lag :[?
And just so you know, I am talking about doing this on a scale of... 50-100 maps, starting off at 30x30 in size and gradually increasing up until around 50x50/100x100 (depending on how many map there is).
Instead of using Range, check out world.maxx and world.maxy.
In response to Android Data
Tried that too :[ And it is still no good.

It really is starting to look like there is no way of doing this without it making some seriously noticeable lag :[ I tried having the host run a proc that would delete all objs/mobs in the world that are not on the same z level as a player just before the map is respawned, but even that caused lag.

:[ I'm running out of ideas now.
Yuugi wrote:
I've tried using...
for(var/obj/O in range(Range,T))
> del O

But it doesn't seem to work properly, for some reason no matter what range I set it to, it just wont delete objects that are at the edge of the map.

range() is limited to a range of 12.

And I've tried...
for(var/obj/O in block(locate(1,1,T.z),locate(Range,Range,T.z)))
> del O

This just refused to work all together, I have no idea why. Maybe because it is a turf calling the proc?

This is a subtle problem, but basically the issue is that block() returns a list of turfs, not including their contents like range() would do. (Incidentally, you should definitely use maxx and maxy in there if you want to get the whole Z level.) So you have to loop through each turf, then delete the items in its contents.

I even tried giving every mob/item an inactive timer, where after not seeing a player for so long they would delete themselves. But even that caused lag :[

That's actually a better solution, but if not implemented right it can cause problems. The easiest way is to use some sort of event list.
var/list/deletable = new

proc/DeleteLoop()
while(1)
while(deletable.Remove(null)) // do nothing in this loop
var/i,j,time
for(i=1, i<=deletable.len, ++i)
time = deletable[deletable[1]] - world.time
if(time > 0) break
for(j=1, j<i, ++j) del(deletable[j])
if(i>1) deletable.Cut(1,i)
if(!deletable.len) time=9000
sleep(time)

proc/AddToDeleteLoop(item, time=9000)
time += world.time
deletable -= item
while(deletable.Remove(null)) // do nothing in this loop
// do a simple binary search to find where to put this in the list
var/first=1,last=deleteloop.len,i
while(first<=last)
i=round((first+last)/2)
var/t = deletable[deletable[i]]
if(time < t) last = i-1
else if(time > t) first = i+1
else break
deletable.Insert(first, item)
deletable[item]=time


Each item, when a player enters an area and signals their presence (or periodically until the player leaves) can use AddToDeleteLoop() to specify when it should be deleted. (You could use a similar loop to check on player presence.) The DeleteLoop() proc is spawned at the beginning of the game and keeps track of items that need to be removed.

Lummox JR