ID:2908507
 
(See the best response by Kozuma3.)
Code:
Temp_Update()
spawn(1) for(var/area/Level_one/L1 in world)
for(var/atom/A in L1)
A.temperature = temp

spawn(1) for(var/area/Level_two/L2 in world)
for(var/atom/A in L2)
A.temperature = temp
A.temperature -= L2.coolness

spawn(1) for(var/area/Level_three/L3 in world)
for(var/atom/A in L3)
A.temperature = temp
A.temperature -= L3.coolness

spawn(1) for(var/area/Level_four/L4 in world)
for(var/atom/A in L4)
A.temperature = temp
A.temperature -= L4.coolness

spawn(1) for(var/area/Level_five/L5 in world)
for(var/atom/A in L5)
A.temperature = temp
A.temperature -= L5.coolness


Problem description:

I have a sidescroller game, with "levels" going horizontally across the map to tell the game how deep you are into the ground.
I.E LEVEL ONE IS THE SURFACE

My Issue... I wanted the UPDATE TEMPERATURE proc to update all the atoms on the map without causing little freezes every time it does it!!! The game is still playable, but the CPU jump IS noticeable.

Therefore I decided to update the atoms on the map one LAYER at a time. I was wondering if putting spawn(0.1) would do this properly, handling the update of each layer one at a time instead of all in one go.

Is spawn(0.1) the right thing to put there? Should I use sleep(0.1)?? Do I need to use spawn(0.1) for the first layer and spawn(0.2) for the second?? The aim is that the CPU is not doing all this work in one go. Fairly simple

Love and thanks if you can get back to me,
Johnny
Just to clarify, I believe my code is fine for what I want to do. I was just wondering if any of you geniuses could correct me
Best response
Using in world is most likely the cause of the issue, if you were to cache the areas you're wanting to modify in their own list it would be much quicker.
In response to Kozuma3
Kozuma3 wrote:
Using in world is most likely the cause of the issue, if you were to cache the areas you're wanting to modify in their own list it would be much quicker.

Ok Kozuma this is new territory for me for sure. Could you elaborate for me how to cache those areas into a list?
Essentially any time you're looping through an unholy number of atoms, you're going to be incurring a large amount of overhead. It's just the way it is.

I hate to not really address your direct question about sleep/spawn, but... All of my suggestions are going to involve rethinking this process, because looping through this many objects is unsustainable unless you only really need to do it once.

First, for what reason do all of these atoms need their temperatures adjusted? What bearing does temperature have on the world? Does it only affect mobs? If that's the case, why not make temperature an area variable, adjust that variable when the temperature changes, and apply that change to all mobs within that area? That'd significantly cut down on the number of things you're looping through.
I'm gonna keep it the way I've got it brother, because the game I'm making is temperature orientated and I really do need everything tracked. Trust me I've thought about this a few times.

However, the way I'm doing it now (layer by layer) has significantly sped up the CPU and I think it will work fine. I was only asking incase somebody could teach me a way to do it faster

But hey--- Thanks for responding!! :D
var list/areas = new

area/New()
areas += src

//for(var/area/A in areas)
If a redesign isn't an option, what Kozuma's recommending is the next-best thing here. Add the layer areas that need temperature adjusting to a list and then loop through those instead of looping through the world.

Think about it this way: Looking for a needle in a haystack is a hell of a lot easier when the haystack is tiny, right? Or better yet, in this case, if the haystack has no hay and only has needles.
A few things that you can do to clean this up and make it easier on the server.

1) Caching the atoms, like koz said. Looping over world so much is going to bog you down, so you can either simply slap these guys inn their own list, or better yet have a temperature manager datum that tracks them and handles these updates.

2) Regarding your spawns and sleeps. If you have a hot proc like this, you can relieve the strain by checking how much CPU you have available with world.tick_usage and sleeping if it's over a certain amount. I would not recommend spawn here, as you can muck things up with so many atoms at play, so sleep is your friend here, not spawn. For example:

proc/DoBigThing()
for(var/atom/a)
if(world.tick_usage <= 50) // if we have used 50% or less of the available cpu this tick
a.DoLittleThing()
else
sleep(world.tick_lag)


3) The best alternative here is to update the temperature on things as needed. Rarely will you need to update the temperature on everything all at once, as most of those things likely won't be a part of the active gameplay loop or your simulation. Managing data effectively like this is integral to game development, and necessary when you're running large procs like this.
Oooooh this looks like juicy stuff Folak. I'm reading now
Ok I'm definitely seeing how using lists instead of checking the whole world is applicable in a lot of the stuff I've done, already made a file called LISTS.dm and updating a few things.

Also Folak I will check to see where I can apply world.tick_usage! I have a large PROC called "Time of Day" and a few other beefy ones where I could use this nifty little trick.

All in all, VERY glad I made this thread and have definitely learnt something I can apply to all my projects in the future!! Thanks for the responses, guys
This is the wrong approach. Even if you are actively simulating temperature on every atom in the world, updating each atom's temperature outside of simulation is a waste of time.

Instead, create an object that represents each level, and then update the temperature on that object, and then during simulation of the atoms in those levels, reference the level object's temperature in order to help determine the atom's temperature.

Ideally, you should only be simulating atoms that could impact actions that shape play, rather than maintaining a graph of every object in the world regardless of whether the space has active play going on.
Ah yes thankyou Ter that is a good idea indeed. I will probably do that eventually.

For now however I'll just do what Kozuma said and put it in a list. Can't believe I've never used lists before!! But yeah I'm gonna keep it the way I've got it for the moment and I'll probably do what you suggested once the FPS drops