On 04/12/2017 at 1:59 PM, frob said:How many units have you got in order for this to be repeated tens of thousands of times? Each unit doing the scan should only scan the four neighboring cells for a list, and choose one from the list if the list is not empty.
It's a 2D game with a very basic art style because I want to push a maximum number of units. As of now, I'm only picking the first target and ignoring the others to save on CPU cycles.
On 04/12/2017 at 1:59 PM, frob said:If you're doing those things already and still have "tens of thousands of times" every second, it would mean you've got 20,000+ units out there all looking for actions.
Yes. The initial prototype of the game with nothing but unit movement would have 500 000 units at ~20fps (only a fraction are on screen, but they're all moving). As I started to add combat and collision, it quickly started going down. Right now, I'm trying to find the balance between simulation accuracy and unit number.
On 04/12/2017 at 1:59 PM, frob said:Why is every unit constantly scanning? Shouldn't they only scan when their current action is complete, which typically means once every 1-2 seconds?
That's gonna sound ridiculous, but my game stutters if my units aren't scanning constantly. I think it has to do with my threaded code because it stops stuttering with multi thread disabled, but my framerate drops by a lot. Right now, I'd rather keep the constant scanning + multi thread because it gives me both higher framerate and no stuttering which can be improved by reducing the scanning time without reducing its occurrence.
21 hours ago, JoeJ said:Maybe bad memory layout or too much indirection. Maybe you should sort entities so they match grid memory order to improve caching.
My grid contains cells that own lists of pointers to entities that are in the cell. Cells are packed in the grid, but I can't pack entities in cells because they're can be many entities in one cell.
9 hours ago, Kylotan said:How do you determine which the 8 surrounding grid squares are? These should be O(1) operations but it's possible to get this wrong.
I dynamically calculate the bounding box coordinates around the unit and iterate through these as indexes inside the grid. I did it that way so that if I want units to have a longer range than 1 cell, I can just give it a radius in cells and it gives the bounding box around the unit which can be scanned for enemies.
9 hours ago, Kylotan said:How is cell.get_entity implemented? If there's only one entity possible there, this too should be O(1), but again, maybe this is wrong.
Many enemies can be in a cell, but you'll always only see one. The collision guarantees that if there's an enemy in the cell, then there can be no friendly.
Entity cell.get_entity()
{
return this->entities.first(); // entities being a list of pointers
}
9 hours ago, Kylotan said:How is isEnemy implemented?
By team id comparison.
bool Entity.is_enemy(Entity other) {
return this.team_id != other.team_id;
}