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

ACS-Like autoresolve [WIP] #5271

Draft
wants to merge 25 commits into
base: master
Choose a base branch
from
Draft

Conversation

Scoppio
Copy link
Collaborator

@Scoppio Scoppio commented Dec 2, 2024

ACS-like autoresolve

This autoresolve implements a mechanism that is inspired in the Abstract Combat System to play out the result of combats instantaneously.

How it works

It uses alot of the work created by @SJuliez for SBF, like the action handlers, phase managers, mostly "dumb" units (so only handlers and services can do things), it also implements a fairly generic memory to units, so they can remember actions they took in their turn, attacks they suffered, etc.

It first redistributes all the forces into ACS Valid force formations, then it creates each formation and links up the AlphaStrike representation of each Entity with its original entity counterpart.

It also reloads every entity as new references, and recreates all crews as new references, otherwise they will stay attached to the original units on the Campaign, which will cause damage and other changes to propagate to the units even if you cancel the resolution.

After all formations are set, a game starts, it uses the initiative, deployment, movement, firing and end phases. Movement phase is used for Engagement and Control which currently is kind of a "thermometer", it mostly change the balance of the game betwen rounds so you dont have a single formation steamrolling everything always.

During firing phase the units hit random units inside enemy formations, as in the quick/simple ACS rules for damage designation.

During the endphase units have their morale tested as per SBF rules (maybe I should change for ACS rules here), they are also checked for withdraw (there is a low chance for a formation to withdraw).
All units that leave the game take some amount of damage.

How to use it

There is a toggle implemented in the campaign options, where you can select if you want your autoresolve to be played by bots (selected as default) or not. With the option unchecked it will use the ACS-like autoresolve instead of opening MM with bots. Now just click in the Autoresolve

Copy link

@github-advanced-security github-advanced-security bot left a comment

Choose a reason for hiding this comment

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

CodeQL found more than 20 potential problems in the proposed changes. Check the Files changed tab for more details.

@Scoppio Scoppio self-assigned this Dec 2, 2024
@Scoppio Scoppio requested a review from IllianiCBT December 2, 2024 02:46
@IllianiCBT
Copy link
Collaborator

I am eager to take a look at this, but it might not be until the end of the week as I really need to maximize my CO IIC time once thanksgiving guests leave, tomorrow.

Is there anything specific you want me to take a look at?

@codecov-commenter
Copy link

codecov-commenter commented Dec 2, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 10.26%. Comparing base (7ddb24c) to head (ffff8b2).
Report is 3 commits behind head on master.

Additional details and impacted files
@@             Coverage Diff              @@
##             master    #5271      +/-   ##
============================================
- Coverage     10.47%   10.26%   -0.21%     
  Complexity     6069     6069              
============================================
  Files           959     1031      +72     
  Lines        135559   138417    +2858     
  Branches      19750    20111     +361     
============================================
+ Hits          14204    14213       +9     
- Misses       119997   122849    +2852     
+ Partials       1358     1355       -3     

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

@Scoppio
Copy link
Collaborator Author

Scoppio commented Dec 2, 2024

I am eager to take a look at this, but it might not be until the end of the week as I really need to maximize my CO IIC time once thanksgiving guests leave, tomorrow.

Is there anything specific you want me to take a look at?

Yes, the force creation/setup process, if there is anything that I should take into consideration but isnt, then the post game resole too. The Damage handlers so you can see if it lacks anything you wanted.

@Scoppio
Copy link
Collaborator Author

Scoppio commented Dec 2, 2024

CodeQL is pointing false positives for errors that are not errors.

<modifier>0</modifier>
<isRepeatable>0</isRepeatable>
</KeyBind>
xsi:noNamespaceSchemaLocation="keyBindingSchema.xsl">
Copy link
Collaborator

Choose a reason for hiding this comment

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

I know xml can sometimes get grumpy when we change whitespaces. Just wanting to verify the changes here won't cause any issues?

}

// should I do something here? Maybe do the trigger?
// MekHQ.triggerEvent(new ScenarioResolvedEvent(currentScenario));
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think we want the trigger here, so it can be picked up by subscribers - though I don't know any that listen for this event, it's unlikely to hurt anything.

// MekHQ.triggerEvent(new ScenarioResolvedEvent(currentScenario));
return;
}

Copy link
Collaborator

Choose a reason for hiding this comment

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

There seems to be a lot of duplicated code here, is there value in grabbing the original code and partitioning them into discrete methods and calling those, instead?

Copy link
Collaborator

@IllianiCBT IllianiCBT left a comment

Choose a reason for hiding this comment

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

Everything I've seen has me very excited to see this implemented. This is only a partial review as this is hardily a small PR and I need sleep. :D

@@ -706,6 +805,64 @@ public static void updateGuiScaling() {
setLookAndFeel(GUIPreferences.getInstance().getUITheme());
}

public void startAutoResolve(AtBScenario scenario, List<Unit> units) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Let's have a JavaDoc here, when you get round to it. The method is fairly well laid out, so it probably doesn't need to be super verbose.

String message = "This will auto resolve the battle. Do you want to proceed?";
var autoResolveMethod = getCampaign().getCampaignOptions().getAutoResolveMethod();
if (getCampaign().getCampaignOptions().isAutoResolveVictoryChanceEnabled()
// unfortunately UNITS MATTER force creating has a bug that makes it impossible to calculate victory chance without causing
Copy link
Collaborator

Choose a reason for hiding this comment

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

Is this still the case? I know you did some work on erasing the bugs earlier in the week

@@ -0,0 +1,7 @@
package mekhq.campaign.ai.utility;
Copy link
Collaborator

Choose a reason for hiding this comment

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

Do we need an interface if we've only got one implementing class?

import java.util.*;
import java.util.function.Function;

public class Memory {
Copy link
Collaborator

Choose a reason for hiding this comment

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

We definitely need a JavaDoc on this class as it's not immediately obvious what it does.

@@ -0,0 +1,7 @@
package mekhq.campaign.ai.utility;
Copy link
Collaborator

Choose a reason for hiding this comment

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

Don't forget the legal notice on your new classes. You're missing them in a couple of places. I know this is still WIP, so you might not have got around to them yet, but figured it was worth mentioning just in case.

@@ -0,0 +1,6 @@
package mekhq.campaign.autoResolve.damageHandler;
Copy link
Collaborator

Choose a reason for hiding this comment

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

Similar to my last comment, does this need to be a separate class? Can we merge the two enums, seeing that they have the same entries with identical ords

import java.util.stream.Collectors;
import java.util.stream.Stream;

public class RandomUtils {
Copy link
Collaborator

Choose a reason for hiding this comment

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

We could do with some JavaDocs for this class, and/or methods. It might also be worth taking a look at ObjectUtility to see whether there is value in merging the two classes. I would have mentioned this back when you first suggested a random workhorse method, but I only discovered it existed earlier today.


@Nullable
public static Entity breakEntityRef(Unit unit) {
var entity = ASConverter.getUndamagedEntity(unit.getEntity());
Copy link
Collaborator

Choose a reason for hiding this comment

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

While it's not marked as such getEntity() can return null. Something to be aware of as I believe if that occurs here it will result in an NPE.

static public UnitStrength getUnitStrength(Entity entity) {
// The values here are completely arbitrary and should be adjusted as needed, probably should be in a config file.
if (entity instanceof Mek) {
return new UnitStrength(entity.calculateBattleValue(), +1, entity);
Copy link
Collaborator

Choose a reason for hiding this comment

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

It might be worth taking a look at entity.getGenericBattleValue() - GBV is static per unit type & weight, so you might be able to do some math to derive inter-unit type power modifier from that. I don't think the arbitrary values are inherently wrong, mind, just wanted to give you options. :)

@@ -0,0 +1,90 @@
/*
Copy link
Collaborator

Choose a reason for hiding this comment

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

It's 02:30 local, so I'm going to call it here. Leaving this message so I know where I was up to.

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

Successfully merging this pull request may close these issues.

3 participants