Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve BotModule performance. #21360

Merged
merged 1 commit into from Mar 12, 2024
Merged

Improve BotModule performance. #21360

merged 1 commit into from Mar 12, 2024

Conversation

RoosterDragon
Copy link
Member

@RoosterDragon RoosterDragon commented Mar 9, 2024

Several parts of bot module logic, often through the AIUtils helper class, will query or count over all actors in the world. This is not a fast operation and the AI tends to repeat it often.

Introduce some ActorIndex classes that can maintain an index of actors in the world that match a query based on a mix of actor name, owner or trait. These indexes introduce some overhead to maintain, but allow the queries or counts that bot modules needs to perform to be greatly sped up, as the index means there is a much smaller starting set of actors to consider. This is beneficial to the bot logic as the TraitDictionary index maintained by the world works only in terms of traits and doesn't allow the bot logic to perform a sufficiently selective lookup. This is because the bot logic is usually defined in terms of actor names rather than traits.

Copy link
Member

@pchote pchote left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks reasonable overall, but not tested ingame.

OpenRA.Mods.Common/ActorIndex.cs Outdated Show resolved Hide resolved
Several parts of bot module logic, often through the AIUtils helper class, will query or count over all actors in the world. This is not a fast operation and the AI tends to repeat it often.

Introduce some ActorIndex classes that can maintain an index of actors in the world that match a query based on a mix of actor name, owner or trait. These indexes introduce some overhead to maintain, but allow the queries or counts that bot modules needs to perform to be greatly sped up, as the index means there is a much smaller starting set of actors to consider. This is beneficial to the bot logic as the TraitDictionary index maintained by the world works only in terms of traits and doesn't allow the bot logic to perform a sufficiently selective lookup. This is because the bot logic is usually defined in terms of actor names rather than traits.
Copy link
Member

@pchote pchote left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code changes LGTM, but not tested.

@@ -102,7 +106,6 @@ void IBotTick.BotTick(IBot bot)
scanForIdleHarvestersTicks = Info.ScanForIdleHarvestersInterval;

// Find new harvesters
// TODO: Look for a more performance-friendly way to update this list
var newHarvesters = world.ActorsHavingTrait<Harvester>().Where(a => !unitCannotBeOrdered(a) && !harvesters.ContainsKey(a));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so why aren't we using the actor index to get these harvesters?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this whole system is meant for tracking existing harvesters and can be replaced

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment here explains it - a index on player alone might not pay for itself. https://github.com/OpenRA/OpenRA/pull/21360/files#diff-35fc4a2486ac8f0e2c2e1f2cefc1906401fd30c12d47e5b3395400e3541272f6R65-R67

I spotted some slowness in a few bot methods which motivated this PR, but this line wasn't a problem. I suspect the Harvester trait is selective enough that it isn't actually all that bad to have this as-is.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

but we already have harvestersIndex in the class?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That one also filters on Info.HarvesterTypes whereas this one doesn't. And given the desc on that of Leave empty to disable harvester replacement. Currently only needed by harvester replacement system. I don't want to apply it here, as that sounds like it could break any configs that were relying on being able to not specify the HarvesterTypes.

Copy link
Member

@PunkPun PunkPun left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Otherwise LGTM. Ran large RA and D2K AI games and didn't notice regresions

@dnqbob
Copy link
Contributor

dnqbob commented Mar 12, 2024

Although this PR should not have problem on multiplayer, I think some multiplayer AI tests (2 player ob 2 AI in game) can be necessary to confirm its stability.

Copy link
Member

@PunkPun PunkPun left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@PunkPun PunkPun merged commit dc0f26a into OpenRA:bleed Mar 12, 2024
3 checks passed
@PunkPun
Copy link
Member

PunkPun commented Mar 12, 2024

changelog

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants