alkurbatov/suvorov-bot

Strategy Settings for plugins

Opened this issue · 9 comments

Strategy should pass settings into plugins during plugins creation.

alkurbatov:
"a. We definitely need to know which strategy to use in advance. As a result, the strategy should always be created before any other plugins.
b. The strategy could provide a kind of requirements (another struct) with some settings. Those settings could include different hints for different subsystems (in or case for the miner). The things like worker type (i.e. race specific) could be included into the settings, too.
c. Dispatcher takes a const reference to the settings from the strategy.
d. Dispatcher passes the settings by reference into each plugin. A plugin in its turn can put the hints it needs into member variables (also constants).

Such approach allows to pass hints not only to the miner, but to any other plugin and keeps cache role on the hub, not game brain :)"

This is needed for useful settings for these other issues:

  1. #16 "Retaliate to early scout's (worker's) attack": how many workers to attack/follow enemy-worker-scout
  2. #27 "Repair terran buildings": max repair workers total, how many per damaged building
  3. #34 "Fix gas saturation": desired gas-worker per geyser, total desired gas-workers (or total gas-income-rate desired)
  4. #37 "Reserve resources in the slow queue": desired ratio of army-spend-rate to econ-spend-rate
  5. #42 "Support build of macro hatchery": whether next TownHall built should be Macro or at Expansion
  6. #51 "Strategy IdealArmyComposition": what units should be considered for future Supply need

Preliminary StrategySettings struct:

enum EconStrat {
    STANDARD = 0,  // expand when near ideal workers (16) per base, up to maxBases
    GREEDY = 1,  // expand whenever minerals allow, up to maxBases
    NO_EXPAND = 2,  // no expanding, unless specified in BuildOrder
    NO_ECON = 3,  // don't build workers (or expand), unless specified in BuildOrder
    CONSERVATIVE = 4,  // only expand after maxing workers per base, up to maxBases
        // (3x mineral, 3x geyser: 3x8=24 + 3x2=6, =30)
};

struct StrategySettings {
    explicit StrategySettings(const sc2::Point3D& town_hall_location_);

    size_t minMineralWorkersPerTownHall = 6;  // transfer enough for close_minerals
    size_t maxMineralWorkersPerTownHall = 16;  // can set to 24
    size_t maxBases = 0;  // don't expand past this number. 0 = no limit

    size_t minimumGasWorkerPerGeyser = 2;
    size_t totalDesiredGasWorkers = 0;
    
    bool makeNextTownHallMacro = false;
    
    size_t maxRepairersTotal = 6;
    size_t repairersPerDamagedBuilding = 2;
    
    bool attackEnemyWorkerScout = false;  // attack immediately, or wait for attack
    size_t attackersPerWorkerScout = 1;  // can set to 2 or 3 for worker/cannon rushes
    
    float buildingVsTrainingRatio;  // construction queue vs training military units
    
    EconStrat econStrat = EconStrat::STANDARD;
};

What do you think about using mineral income instead of max workers per town hall? I think checking income looks closer to what human players do as usually we don't want to expand unconditionally (except zergs :) ).

Eventually, mineral-income may be better. But first we need good income-estimation (both current and future-prediction), which I plan to do after a couple other military-focused PRs.

I think for simplicity for now, we include maxBases. So maxWorkersPerBase x maxBases (with maxWorkersTotal) equals a certain income roughly, until we have better information. And player could set maxBases=3, but have a trigger in lategame if floating minerals to set to 4 or 5, etc. You can set it to 1 for all-in.

For early game, you can specify when to expand, and MINER plugin won't attempt to expand if you have one in the queue.

Max bases is harder to calculate and balance, especially if one wants to occupy e.g. rich minerals spot.
I would leave this task to bot authors as particular numbers of values/bases depends on play style.
Or we could support both, but it could be harder.

As you said "usually we don't want to expand unconditionally", the idea for maxBases is the author would have a condition within the Strategy they make that would decide when expansion is allowable. So this task would still be with the bot authors, controllable through the Settings (via maxBases), which would be modified during play. The idea is that the Miner (once maxBases > currentBases), would make the decision of exactly 'when' to expand, based on the current mineral workers (informed by the EconStrat and other Strat variables), and the fast/slow queue ratio.

I still think that it is much simpler to drop decision making from the miner. Imagine that you are going to use a kind of ML here which will tell exactly when bot need's to build a town hall or we are going to push first and if it failed, create several town halls. Of course miner has to distribute workers and set rally points, but this is mostly 'worker' subsystem, not decision making.

What you say is still possible by using the ALL_IN / NO_EXPAND EconStrat, which removes any auto-expand behavior from Miner. For 95% of new authors, I think they will care more about Opening Build, Army Unit Composition, and Unit Micro Behavior. ML bots are very small percentage currently, and these Settings would still accommodate them. Having auto-expand logic in Miner for midgame and lategame would make everything easier.

Strategies are still classes so can inherit from e.g. EconStrategy and apply some tweaks from it. The idea here is to keep game style/plan related stings in dedicated place. As a result, the product stays modular (as it is now) without rigid dependences and it is relatively simple to rewrite particular subsystem without breaking whole bot.