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

AI Toy - Piracy, new behaviors, and a new test platform to build upon #6486

Merged
merged 9 commits into from
Feb 6, 2025

Conversation

Scoppio
Copy link
Collaborator

@Scoppio Scoppio commented Feb 2, 2025

What is it about?

A couple of experimental features added for the AI, those can be enabled or disabled at will by the player who owns the server.

New feature - Piracy!

As it was requested many times, a button for the bot behavior settings that makes it disregard concepts like "honor", or "not targeting civilians"

Experimental AI

Two new sliders (Anti Crowding, Favor High TMM)

Enabling the experimental features will expose two new sliders in the bot, the anti-crowding slider and the Favor High TMM slider. Anti Crowding will lower the points of movements that takes it in places where there are too many units inside a specific radius. Favor High TMM is just that, it score higher moves that gives better TMM.

New Utility Path Ranker

An experimental utility path ranker was added, it uses many features that we dont see in the bot today, they are exploratory and are being added with the intent to allow people to test and give their impressions. This is planned to be used as a stepping stone for more deep and complex AIs.

This one has the following capabilities (theoretically)

  • Move in formation
  • Keep enemy ar range
  • Army scale maneuver planning
  • Threath assesment
  • Threath awareness
  • Unit Role based scoring for movements
  • Self Preservation also helps with deciding defense strategies.

Smoke test

A simple "run a game with an observer and two bots" integration test, it initializes the game, rolls a single turn and finishes it. Unfortunatelly it does not run on our CI, so it is only enabled if it sees a specific Env Var flag.

QuickGameRunner

Utility that allows to quick iterate when building and editing AIs for the bot, you can run the "testAi" task and just see its results immediatelly.
It can run with Commanders GUI, ClientGUI or no GUI at all.

@Scoppio Scoppio self-assigned this Feb 2, 2025
@Scoppio Scoppio marked this pull request as ready for review February 4, 2025 00:29
);
}

private static class EnemyProfile implements Comparable<Double> {

Check warning

Code scanning / CodeQL

Inconsistent compareTo Warning

This class declares
compareTo
but inherits equals; the two could be inconsistent.


// Worry about how badly we can damage ourselves on this path!
double expectedDamageTaken = calculateMovePathPSRDamage(movingUnit, pathCopy);

Check notice

Code scanning / CodeQL

Unread local variable Note

Variable 'double expectedDamageTaken' is never read.
int timeout = 5;
GUIType guiType1 = GUIType.DEFAULT;
if (args.length > 1) {
guiType1 = GUIType.values()[Integer.parseInt(args[1])];

Check notice

Code scanning / CodeQL

Missing catch of NumberFormatException Note

Potential uncaught 'java.lang.NumberFormatException'.
guiType1 = GUIType.values()[Integer.parseInt(args[1])];
}
if (args.length > 2) {
rounds = Integer.parseInt(args[2]);

Check notice

Code scanning / CodeQL

Missing catch of NumberFormatException Note

Potential uncaught 'java.lang.NumberFormatException'.
rounds = Integer.parseInt(args[2]);
}
if (args.length > 3) {
timeout = Integer.parseInt(args[3]);

Check notice

Code scanning / CodeQL

Missing catch of NumberFormatException Note

Potential uncaught 'java.lang.NumberFormatException'.
@Scoppio Scoppio force-pushed the feat/princess-new-sliders branch from f48969a to 47ddb4e Compare February 4, 2025 01:04
@Scoppio Scoppio force-pushed the feat/princess-new-sliders branch from 47ddb4e to a0c40a3 Compare February 4, 2025 01:16
Copy link

codecov bot commented Feb 4, 2025

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 28.55%. Comparing base (6567ce1) to head (2220f96).
Report is 40 commits behind head on master.

Additional details and impacted files
@@             Coverage Diff              @@
##             master    #6486      +/-   ##
============================================
- Coverage     28.56%   28.55%   -0.02%     
- Complexity    14420    14464      +44     
============================================
  Files          2801     2815      +14     
  Lines        275369   277309    +1940     
  Branches      48716    48973     +257     
============================================
+ Hits          78669    79173     +504     
- Misses       192023   193435    +1412     
- Partials       4677     4701      +24     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@Scoppio Scoppio changed the title Feat/princess new sliders (WIP) Feat/princess Experimental features Feb 4, 2025
@Scoppio Scoppio changed the title Feat/princess Experimental features AI Toy - Piracy, new behaviors, and a new test platform to build upon Feb 4, 2025
Copy link
Collaborator

@rjhancock rjhancock left a comment

Choose a reason for hiding this comment

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

Overall looks good but a few small questions and changes.

Comment on lines 530 to 536
protected @Nullable Coords calculateAlliesCenter(int myId, @Nullable List<Entity> friends, Game game) {
return calcAllyCenter(myId, friends, game);
}

public static @Nullable Coords calcAllyCenter(int myId, @Nullable List<Entity> friends, Game game) {
if ((friends == null) || friends.size() <= 1) {
return null;
Copy link
Collaborator

Choose a reason for hiding this comment

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

What is the purpose of duplicating a public method as protected?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

none really, just old habit of trying to keep access privilege as closed as possible on classes, but you are right, its just proxying a call to a static function the original one, no need to hide it behind protected.

* @param enemyId The enemy id
*/
public void recordEnemyTarget(int enemyId) {
enemyTargetCounts.put(enemyId, enemyTargetCounts.getOrDefault(enemyId, 0) + 1);
Copy link
Collaborator

Choose a reason for hiding this comment

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

Why the +1?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

its increasing the number of "units targeting this enemy", thats what it means by "record enemy target", I am improving the javadoc on this

* @param coords The coordinates to record
*/
public void recordPlannedPosition(Coords coords) {
positionDensity.put(coords, positionDensity.getOrDefault(coords, 0) + 1);
Copy link
Collaborator

Choose a reason for hiding this comment

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

Same here...

Terrains.SNOW,
Terrains.SWAMP,
Terrains.MUD,
Terrains.TUNDRA));
Copy link
Collaborator

Choose a reason for hiding this comment

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

This would need to be adjusted as other Terrains are added.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

indeed, I plan to remove this class soon

Comment on lines 4870 to 4872
if (attacker instanceof Aero) {
Aero aero = (Aero) attacker;
// Account for sensor damage
Copy link
Collaborator

Choose a reason for hiding this comment

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

(attacker instance Aero aero) ... and remove the cast on 4871.

run(gameFile, roundsLimit, timeoutMinutes);
}
} catch (Exception e) {
Sentry.captureException(e);
Copy link
Collaborator

Choose a reason for hiding this comment

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

This being a utility method, do you really want to have it send the errors to Sentry vs just deal with them locally when you run them?

Or is the intention for when others run this for those same said errors to be reported?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I added sentry by mistake here, but looking at the code inside error, there is no way to log error without calling sentry, I would expect any error to be reported, independent of where it was generated, however I could see it being too noisy if someone is using this in an automated manner.

@HammerGS
Copy link
Member

HammerGS commented Feb 6, 2025

@Scoppio This has conflicts now.

@Scoppio Scoppio requested a review from rjhancock February 6, 2025 01:04
@HammerGS HammerGS merged commit dd7dd68 into MegaMek:master Feb 6, 2025
6 checks passed
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.

3 participants