RTS resource calculation with tons of objects

  • Hey there. So most of the time, my game looks a little like this:

    Only thing is, it needs to calculate resource production for every one of these floating islands (cells). The way it does this at the moment is one step away from being the laggiest system out there.

    First, it takes care of the resources that can be calculated by just adding stuff they produce. These are things like grain fields, windmills and lumberjacks:

    i.imgur.com/SfAhXY8.png

    Then it calculates the ones which have requirements. In other words you need a certain amount of another resource to produce something:

    i.imgur.com/dFEpSAx.png

    The for each is not the greatest, especially since this is running on 300+ objects once every second. Not the greatest.

    I've thought about a few different solutions.. Two things are certain that need to be possible. It needs to know to disable things which don't meet requirements, and it needs to be 100% accurate every time.

    Er, anyone got ideas? I'm going crazy here.

  • It should be cake walk to do that kind of calculations for any CPU at all.

    Care to share a bit more of your event sheet ?

  • "For Each" is a system loop meaning the process has to finish before the rest of the rest of the tick can complete.

    For occasions that require iterating over a large number of instances it would be better to do so per tick on each, or a small group of objects, rather than choking the cpu.

    A variable compare is a decent method to do so.

    global myindex < object.count

    ->object.variable= global myindex, do foo

    ->add 1 to global myindex

  • It should be cake walk to do that kind of calculations for any CPU at all.

    Care to share a bit more of your event sheet ?

    Sure

    This is the whole function, which runs once every second.

    global myindex < object.count

    ->object.variable= global myindex, do foo

    ->add 1 to global myindex

    Yeah I had hoped to do that, but if one in the middle is destroyed it will fail to do anything on that tick. This is run every second, so at 60fps I would max out at 60 objects (when there are 300 on screen). It also needs to do the calculations in order - farms first, then houses. I could do:

    every 0.1 seconds

    repeat cell.count / 10 times

    ...But I don't know, it seems like bad design.

    Here's a solution I have thought of which I really want to avoid:

    keep a record of how many of each type exist in the world and add/subtract on create and destroy. Then make this go through each of the 6 resources (instead of cells) and calculate the max it can get from that. If disabling resource deficient cells, find the n top cells of that type and disable them. When a new thing is made, recalculate only the disabled ones

    In theory this would always only be as laggy as 6 cells being calculated. Trouble is it's a massive pain in the butt to implement. It would mean making it completely, 100% airtight.

  • You have multiple "for each" running in a single function.

    Use variables, use functions sparingly.

    You can use the object index if you have objects being destroyed.

  • Try Construct 3

    Develop games in your browser. Powerful, performant & highly capable.

    Try Now Construct 3 users don't see these ads
  • Do it all in one go, not in multiple pass / loop.

    Add a "priority" number instance variable to your cell family and do something like :

    For each cell order by cell.priority

    Then according to the type of cell, do the correct calculation. This way you'd loop over your cell collection only once.

  • Do it all in one go, not in multiple pass / loop.

    Add a "priority" number instance variable to your cell family and do something like :

    For each cell order by cell.priority

    Then according to the type of cell, do the correct calculation. This way you'd loop over your cell collection only once.

    Ah, it works as is, it's just that doing a complicated for each on 300+ objects makes for a laggy game. It hangs for 100ms or so every second with just 200 on screen.

    I think I'll have to just use that solution I don't like. I'm pretty sure it will work, it's just a pain to implement.

    Thanks for the help you guys!

  • It might work as is, but there are a lot of implicit "for each". Doing a single explicit one will reduce the amount of iterations and thus, diminish the perceivable lag you have each second.

Jump to:
Active Users
There are 1 visitors browsing this topic (0 users and 1 guests)