-
Notifications
You must be signed in to change notification settings - Fork 177
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
Track additional characteristics in Scenario #3024
Track additional characteristics in Scenario #3024
Conversation
This required adding a scenario variable to the basic GameThread and changing constructors to include it.
…ap settings I would prefer to handle this by generating an actual MapSettings object in Scenario.java but that would require some XML input and output functions on MapSettings itself.
BotForces are now in basic scenario so this works in all cases
Forgot this in a previous commit
I also want to add EMI and temperature to base Scenario but I will do that in a subsequent commit
This object allows for a simpler method of random generation of bot forces for scenarios. It can be added to any BotForce object and is tracked via XML I/O. It includes variables that parameterize the random generation process to find opfor. These additional random forces are generated and added to the game in GameThread. Currently, I just have a non-interesting test case in the generateForce method, but it should be straightforward to build in the more complex logic needed in subsequent commits.
Instead of BV, this technique tries to balance the weight of units after applying some modifiers based on unit type. So tank weight only counts for 60% of mech weight and so on. These multipliers are currently hard-coded into the static getSimplePointScore method, but could be made customizable at some point.
…Randomizer If the unit type is set to Mek or Aero and percentConventional is greater than zero then there is some probability that the Mek or Aero will be replaced by a Tank/VTOL or Conventional Fighter, respectively.
Units will be generated in groups of size equal to the variable lanceSize which will help units be a little more consistent. It can however lead to going over the maxPoints pretty substantially when small numbers of units are deployed so may need to tweak how that works.
I also added the apache common math library to build.gradle so that I can use their GammaDistribution function to create variation. The center of this distribution is either a focal weight class provided by the object or the mean weight class of the player units. The gamma distribution then samples around this value and the results are trimmed to plausible values and then rounded to an integer.
…nitialize method in AtBScenario I am not sure why these variables need to be set in the AtBScenario#initialize method rather than the constructor, but I am not going to mess with it.
This allows both the trees to expand into space without problems
This allows them all to be expanded to their correct size
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In general this looks good. However, there's a bunch of comments with changes of varying severity, with the largest and most significant being issues in MekHqXmlUtil usage and File I/O in general. Outside of that the comments are largely related to missing brackets, spacing, other text accessibility, and some light code enhancements.
Also, there's a lot of places in BotForceRandomizer and ScenarioDeploymentLimit that could be converted to use streams to improve their readability, but that's just a personal opinion.
Co-authored-by: Justin Bowen <39067288+Windchild292@users.noreply.github.com>
…/mekhq into better_scenarios
Thanks for the very detailed review @Windchild292. I have made all of the requested changes except the two cases of modernizing the XML file I/O. Can you tell me a class that is fully modernized so I can use it as an example? |
Never mind I think I fixed this in the latest commit. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just a few remaining spacing/brackets issues, then this will be good to merge
MekHqXmlUtil.writeSimpleXMLTag(pw1, indent, "destinationEdge", behaviorSettings.getDestinationEdge().ordinal()); | ||
MekHqXmlUtil.writeSimpleXMLTag(pw1, indent, "retreatEdge", behaviorSettings.getRetreatEdge().ordinal()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just realized these are enums being parsed through their ordinals instead of names...
I've added a note to fix this, as it can cause migration issues, and to move the file I/O for behaviour settings to that file.
(Nothing to do, just commenting on something I noticed and how I'm planning on fixing it)
MekHqXmlUtil.writeSimpleXMLOpenTag(pw1, indent++, "allowedUnitTypes"); | ||
for(int type : allowedUnitTypes) { | ||
pw1.println(MekHqXmlUtil.indentStr(indent+2) | ||
+"<allowedUnitType>" | ||
+type | ||
+"</allowedUnitType>"); | ||
MekHqXmlUtil.writeSimpleXMLTag(pw1, indent, "allowedUnitType", type); | ||
} | ||
pw1.println(MekHqXmlUtil.indentStr(indent+1) + "</allowedUnitTypes>"); | ||
MekHqXmlUtil.writeSimpleXMLCloseTag(pw1, --indent, "allowedUnitTypes"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd normally suggest using the new array writing methods instead of this.
However, this is a magic number we'll need to convert to an enum... and this method is so much easier to convert. Just a comment for future implementations, please don't do it here.
Co-authored-by: Justin Bowen <39067288+Windchild292@users.noreply.github.com>
…/mekhq into better_scenarios
Ok @Windchild292. Think I got all of them. |
Approved pending CI (just for safety) |
This PR refactors some features out of AtBScenario into Scenario and adds some additional features to Scenario. This PR is tied to the Story Arc PR #2997, and should allow creators to create pre-made scenarios for story arcs. However, it is generalizable enough that it could have other potential uses as well.
Current State
I believe this PR is ready for review. I am going to look and see what I can clean up based on the automated reports, but feel free to give feedback at this point.
Refactoring
The following variables and related methods were re-factored out of AtBScenario to Scenario:
botForces
andbotForcesStubs
. This allows basic scenarios to include pre-loaded OpFor and Allied units. I also borrowed code from AtBGameThread and inserted it into GameThread so that these botForces are actually loaded. At a basic level, this feature can include a fixed set of entities listed in the BotForce object, but I also added an additional class described below that can do randomization of botForces. There is another variable in AtBScenario for allies (alliesPlayer) but I did not refactor this variable because allies can be created in BotForce simply enough by assigning them to team 1 (always the player's team).terrainType
,mapSizeX
,mapSizeY
,map
, andusingFixedMap
. These function identically as they did in AtBScenario.start
variable that gives the starting deployment position of the player's units.I don't believe any of these changes will affect AtB functioning at all because AtBScenario inherits from Scenario and I made sure to keep methods the same. I did have to give some of the variables protected rather than private access because the initialize method in AtBScenario assigns some of these variables directly.
I also did not need to do anything to ScenarioObjectives. These were already a part of the basic Scenario object and they can be used more or less directly, although I did need to make a few changes to make sure they were checked for in basic scenarios and not just AtB games.
GUI changes
I made a variety of changes to
ScenarioViewPanel
so that all of these new features in scenario will actually show up to the player. I borrowed quite a bit fromAtBScenarioViewPanel
butScenarioViewPanel
involves no dynamic buttons just information. I also did a lot of cleanup on the code there to make it more compact and produce a more pleasing display. Here is an example of the new look:New Features
BotForceRandomizer
I wanted people to be able to create randomized BotForces as well as fixed ones. I also wanted these to be able to scaled to variable player deployments. I originally thought I could just use or rework the code from
ScenarioForceTemplate
andAtBDynamicScenarioFactory
. However the logic of these objects is quite complex and difficult to separate from the expectations of AtB game play.So, instead, I created a new class called
BotForceRandomizer
that can be added to aBotForce
as a variable. It is a lightweight object that just tracks some parameters for random generation such as faction, quality, unit type, and skill level. The code for generating units borrows substantially from code inAtBDynamicScenarioFactory
but is much, much simpler. Part of the reason for this is that, players/creators can mix fixed unit lists and random forces in BotForces. So rather than try to consider all the very specific cases that AtB needs to consider like artillery, aeros with bombs, dropship support, etc., this class is set up so that creators can specify special stuff like that in fixed units and then just roll for the remaining units.I currently have two scaling techniques which are specified in a private enum. The first is just BV. The second is an "adjusted weight" scaling. This is basically just the total weight of units, but those weights are "weighted" by unit type. So tank weight only counts for 60% of mech weight and so forth. This is loosely based on some old point based systems used in Battletech products. The idea is that this balances forces based on rough unit type and weight parity but does not adjust for skill level, tech level, etc. Right now the unit type weights used are hard coded but this could be made user editable in the future. It should also be easy based on the way I have this set up to add other scaling methods in the future.
Right now the generator works pretty decently, but there is definitely room for improvement. My initial goal here is just to get the architecture set up and then tinker with the details later based on how it plays.
ScenarioDeploymentLimit
This feature enables limits on what units the player can deploy to a scenario. All of the parameters for this leave in the ScenarioDeploymentLimit class and an instance of this class can optionally be added to Scenario. If it is not present, then limits are not enforced. Limits are enforced in the following way.
Most of these limits are enforced by the
canDeployForces
andcanDeployUnits
methods in Scenario, which I refactored from AtBScenario. The methods in AtBScenario are unchanged and just override the super methods. I also added a new Scenario#canStartScenario method that is checked in the GUI to see if all of the scenario buttons should be enabled, which helped to clean up some real messy code. Again AtBScenario has an override method for this that adds one additional condition.