- Home /
How to best call performance intensive game logic functions?
Hello,
I'm programming a grid based game. One of my game logic functions goes through every single element of that grid to do things.
private void GoThroughMap(Action<int,int,int> action)
{
for (x = 0; x < mapX; x++)
{
for (y = 0; y < mapY; y++)
{
for (z = 0; z < mapZ; z++)
{
action(x, y, z);
}
}
}
}
Now I had this in void FixedUpdate
initially and it worked well enough. Until I decided to actually test this with a 1000 by 1000 grid (x and z, y was 1) instead of the 100 by 100 grid I used before. Game performance crashed.
I only need that function every second or so, which I assume would massively reduce the load on my game. But I'm not sure what's the best way to implement this. Keep it in void update with a float timer to check against? Use InvokeRepeating(string methodName, float time, float repeatRate);
? Some coroutine? Or something else?
it depends what it is it's doing. does it need to execute reliably every said amount of seconds? is it ok, like pathfinding, to execute whenever ready? does it have to be a function call for every iteration? could there be checks that reduce the execution by avoiding cells under certain conditions?
It's basically meant to go through the buildings in my game and do things like calculating inhabitants, taxes, status etc.
I've been thinking it might be smarter to just use a list of buildings so it doesn't have to go through loads of empty fields and just iterate through the list. But it'd still be smarter to just update everything every few seconds.
That said, I don't think it really matters if it's a fraction of a second earlier or later. At least for this.
For another purpose I'd need a function where I can change the intervals it is invoked so I can have a game-speed setting.
"I've been thinking it might be smarter to just use a list of buildings so it doesn't have to go through loads of empty fields..."
Yes, very likely. The 1000 x 1000 is making 1 million calls, doing whatever the action method requires, so the question is how many buildings are there?
Personally, I'd use threads, but then I'm an old hand at this and I'm quite familiar with the issues that implies.
Answer by BitMax · Oct 06, 2018 at 04:08 PM
That's a start. What you can also do is differ it so you calculate 10% every 0.1 seconds so it's not doing one massive recalc every second or so.
Good idea. How would I do this? Use a coroutine that waits for .1 second when it's through 10% of the data? Or some other way?
uncompiled, untested- example only
private int lastX=0;
private float lastTime=0;
public float processTimeInterval =1;
public float processFractionOf$$anonymous$$ap = 0.1f;
private void GoThrough$$anonymous$$ap(Action<int,int,int> action)
{
//check timer
if(lastTime+processTimeInterval < Time.realtimeSinceStartup)
return;
lastTime=Time.realtimeSinceStartup
//compute how much of the map to process
maxX= lastX + mapX * processFractionOf$$anonymous$$ap;
if(maxX>=mapX) maxX=mapX;
for (x = lastX; x < maxX; x++) //loops only those in our selected range
{
for (y = 0; y < mapY; y++)
{
for (z = 0; z < mapZ; z++)
{
action(x, y, z);
}
}
}
//update lastX for next call to his function
lastX=maxX;
if(maxX>=mapX) lastX=0;
Answer by MonoFlauta · Oct 06, 2018 at 06:34 PM
Is it neccesary that you check everything every frame? Wouldn't it better to use some kind of EventManager? I guess it depends on the game, but probably an EventManager should do the trick in most of cases. I made one here: https://github.com/MonoFlauta/Framework-Goat/tree/master/Framework%20Goat/Assets/Framework%20Goat/EventManager And if not, did you consider trying out ECS? https://unity3d.com/es/learn/tutorials/topics/scripting/introduction-ecs
Your answer
Follow this Question
Related Questions
How and when to use a JS Array over BuiltIn Array 2 Answers
How to optimize game performance in this code? 1 Answer
Reactivating prefab instances upon becoming visible 2 Answers
Make a stand alone exe file with no graphic 1 Answer
Extreme performance impact of Transform.set_localRotation() 0 Answers