If I do this
for(var/turf/T in range(10,src))

Will it still check all turfs in the game? Is what comes after 'in' relevant at all? If so, is there a way to use the Find() proc to achieve the same result without using a for loop?
In response to Kenryuto1
Find() might not be what you think it is. It's simply a function that returns the index of the specified item in the specified list. It's the same as this:
// list.Find(item, start, end)
proc/list_find(list/list, item, start = 1, end = list.len + 1)
for(var/index in start to end - 1)
if(list[index] == item)
return index
return 0

It's an alternative to "item in list" which only returns true or false, instead of the index, like this:
// item in list
proc/list_in(list/list, item)
for(var/check in list)
if(check == item)
return TRUE
return FALSE

Neither are alternatives to looping over a list to actually do something to each item.
Here's my source:

In response to Kaiochao
Kaiochao wrote:
Here's my source:


Okay, I stand corrected. What the user that shared this info with me explained was actually correct... Kind of...

@kenryuto, forget everything I just posted. I made a bad call.
In response to Kaiochao
Kaiochao wrote:
             while(Duration > 0)
Duration -= 5
sleep(10)
This is what's causing the lag over time. Every turf in the aoe is running this loop. Every second, every turf in the aoe does something and then sleeps for another second. It might not seem like much, but multiplied by the number of turfs you have, it is apparently enough to cause lag that "lasts for the remainder of the server's runtime" (but in theory should only last as long as the while() lasts).

If you do the math, the actual sleep duration is 10 * Duration / 5.
In other words, you sleep by 10 for every time you can remove 5 from Duration, so you can just sleep once by that amount.

One large optimization you can make is to only sleep once. The thing to notice is that the duration of the sleep doesn't differ between the turfs, so you don't need each turf to sleep separately (each call to sleep has its own overhead, so it's best to minimize the calls). There's actually a lot of work being done in Transform per turf that all of the turfs are repeating exactly.

Assuming there aren't any overrides of Transform() that drastically change what's being done.

For the most part, this has drastically reduced the overhead. At the time, I had forgotten that there are overrides for Transform(). The primary process that overrides Transform() is another Transform() proc. How can I make it so that the latest sleep gets followed through with?

For example, right now if grass Transforms into dirt and initiates a 20 second sleep. If 15 seconds later, the dirt is Transformed into water and a sleep of 100 seconds is initiated, the tile will still return to grass after just 5 seconds. Is there a way to make sure that Transform() procs cut eachother off?
This is a common problem you are going to run into with naively scheduled state machines.

Let's look at a simplified example:

mob
var
status_bleeding = 0
proc
gameTick()
if(status_bleeding)
takeDamage(5)

Bleed(time)
status_bleeding = 1
sleep(time)
status_bleeding = 0


The problem here is the same problem you have. You are setting a boolean state, and then assuming naively that at the end of the time, the state has ended.

There's a few other issues with this example, but let's fix the naive problem by modifying Bleed()

        Bleed(time)
++status_bleeding
sleep(time)
--status_bleeding


This approach won't suffer from the same problem and it's a minimal change. But it exposes another problem that the last one had too: If we save the mob and load it back into the world, the proc delays won't save with it, so you'll just have an infinitely bleeding mob. Normally that's not an issue, we just mark bleeding status as tmp, but sometimes we might have a state we actually want to resume on load as though nothing happened. Let's look at how we'd fix that.

mob
var/tmp
status_bleed_time
proc
gameTick()
if(world.time<status_bleed_time)
takeDamage(5)

Bleed(time)
status_bleed_time = max(status_bleed_time,world.time + time)

Write(savefile/F)
..()
F["status_bleed_time"] << (status_bleed_time-world.time)

Read(savefile/F)
..()
F["status_bleed_time"] >> status_bleed_time
status_bleed_time += world.time


Now we've actually got all the relevant information for tracking bleeds reliably over time and it saves.


Now, your specific example doesn't actually need to save, so it's the easy one to fix. Let's just stash the old appearance, and the number of transformations, and only restore the old appearance when we hit zero.

turf
var/tmp
transform_status = 0
transform_appearance = 0


When we change the turf:
if(!(turf.transform_status++))
turf.transform_appearance = turf.appearance


When we go to change the turf back:
if(!(--turf.transform_status))
turf.appearance = turf.transform_appearance
turf.transform_appearance = null


Those two if statements there help ensure that everybody knows their transform order and waits their turn to properly change the turf's appearance.

Easy, low tech, maybe a little brittle, but you'll know when you screw it up.
In response to Ter13
This is amazing! I've had this probably with countless naively coded booleans of mine and this will help with all of them! My problem has been beyond solved at this point. Thanks to everyone who responded!
Page: 1 2