Anti stall algorithm

Anti stall algorithm

Here is where ideas can be collected for the skirmish AI in development

Moderators: hoijui, Moderators

User avatar
AF
AI Developer
Posts: 20687
Joined: 14 Sep 2004, 11:32

Anti stall algorithm

Post by AF »

Ok XE8 ahs 2 antistall algorithms taken from OTAI, however the later one is not right, it works for some accosaions and not for others:

Code: Select all

	if(cant get definition of units) canbuild
	BuildTime = targets_buildTime / builders_buildSpeed;
	// Energy Cost/Second
	EPerS = (energyCost*0.8f) / BuildTime;
	if (EnergyStored + BuildTime * (EnergyIncome - (EnergyUsage + EPerS)) < 0.0f){
		//insufficient energy to build  a stall is anticipated if construction is started
		cant build
	}
	MPerS = (metalCost*0.8f) / BuildTime;
	if (metalstored + BuildTime * (MetalIncome - (MetalUsage + MPerS)) < 0){
		// insufficient metal
		//insufficient metal to build, a stall is anticipated if construction is started
		cant build
	}
	canbuild
The *0.8f is there because it changes how it works, e.g. 0.8 works better with XTA but messes up gundam and EE support but 0.9 has the opposite affect.

Now I know that soemtimes you build anyways knowing there's gonna be a stall because ti's important but I need foundations, a general algorithm before I starta dding special exceptions.
Sheekel
Posts: 1391
Joined: 19 Apr 2005, 19:23

Post by Sheekel »

Nice! But uhh....move to AI forum?
User avatar
Dragon45
Posts: 2883
Joined: 16 Aug 2004, 04:36

Post by Dragon45 »

Anti Stall will need to take into a few things:

1) Energy used by weapons when firing. Very important to make sure laser defenses and Berthas etc actually work. :P

2) Energy used by construction- seems you've already taken this into account.

3) Energy used by motion.

4) Energy used by standard unit on/off (This includes metal makers and radar towers/jammers, the latter of which are very important also.)


Basically you need to break down *everywhere* that uinits cna use energy, and then rate them in priority to what weightage the "importance" of any particular usage possibilty is at any given time.

F.ex, if the enemy is attacking, then defense energy usage gets highest priority. If no attack is in sight, then construction/Metal Maker/Jammers get highest priority, with less being accounted for in lasers.

Also, might wanna keep some things as always-on or "always have enrgy available for this"; like jammers. ^_^
User avatar
Guessmyname
Posts: 3301
Joined: 28 Apr 2005, 21:07

Post by Guessmyname »

Don't forget repairing and ressurecting and capturing
User avatar
Lindir The Green
Posts: 815
Joined: 04 May 2005, 15:09

Post by Lindir The Green »

Dragon45 wrote:Anti Stall will need to take into a few things:

1) Energy used by weapons when firing. Very important to make sure laser defenses and Berthas etc actually work. :P

2) Energy used by construction- seems you've already taken this into account.

3) Energy used by motion.

4) Energy used by standard unit on/off (This includes metal makers and radar towers/jammers, the latter of which are very important also.)
Making sure that there is enough energy for 1, 2, and 4 is the buildtree maker's job.

In XTA, I make NTAI build extra energy, and then metal makers that are usually on but in big battles NTAI will automatically turn them off using the metal maker group AI.

NTAI's job is just to make sure there are CURRENTLY enough resources to support the building.

btw, why is this in the mod forum?
User avatar
AF
AI Developer
Posts: 20687
Joined: 14 Sep 2004, 11:32

Post by AF »

The problem I face si that I want a ne algorithm, just 2 equations even a single equation and a simple true/false statement based on the value returned. Such as above see the if witht he big equationa dn the ==0.0 at the end? And if it's smaller than 0 then you're gonna stall?


When i post these things in the AI forum i dotn get what i wante dinstead I get conjecture and speculation, whereas past experience shwos that the people who know more about this are the modders because they're the people who balanced the damned things, and because more players/modders watch this forumt han the AI forum and they're more likely to gage a general relationship.

Several times I've asked this to several people and instead of getting raw foundations I get top floor requests, which is pointless as I need a good solid foundation ro what you say is totally useless.

Energy In
Metal in
Metal out
Energy out
Metalcost
Energy cost
Buildtime
builder buildspeed

true false, will I stall if I build?

Now I know there are all these things it 'should' do, but thats not what i'm asking and I have planned for those but they cannot be done if I dont have the core basic fundamental equation I am asking for.
Egarwaen
Posts: 1207
Joined: 27 Feb 2006, 21:19

Post by Egarwaen »

Hm. If I understand what you're asking... It's a fairly simple rate problem. So here's a simple algorithm:

Code: Select all

Am I spending more metal/energy than I'm making?
    If not, then I will never stall, unless an unexpected expenditure crops up.
    If so, do I have enough unallocated metal/energy in storage to complete the current project AND will I be making more metal/energy than I'm spending once I've completed the current project?
        If not, then I will stall.
        If so, then I will not stall.
Of course, this is very conservative. The second condition (line 3) in particular is bad. A more accurate one would be "Do I have enough unallocated metal/energy in storage to keep constructing without stalling until enough other projects finish to make my net metal/energy rate positive again?", but that could be hard to estimate. Basically, your storage is irrelevant unless you have a metal/energy "debt".

This also requires a concept of "allocated" metal/energy storage, as once a project's laid claim to some metal/energy in storage, other projects can't lay claim to it, or a stall will occur. You can also use this to allocate, say, 250 energy for defensive weapons fire, and cancel projects if more energy's needed for that.
User avatar
AF
AI Developer
Posts: 20687
Joined: 14 Sep 2004, 11:32

Post by AF »

The problem is there is no way fo distributing energy between different cons, and it's that latter part you mentioend whcih is what i was asking for. Otherwise I already ahd the extreme conditions checked for, such as having no metal/energy in storage.

The problem witht hat sort fo chekc si what if you have a stable income once building of 1 in and 1 out and 1 stored? Or if your stored metal/energy is yoyo'ing because of turning on and off mohos and metal makers...
Egarwaen
Posts: 1207
Joined: 27 Feb 2006, 21:19

Post by Egarwaen »

AF wrote:The problem is there is no way fo distributing energy between different cons, and it's that latter part you mentioend whcih is what i was asking for. Otherwise I already ahd the extreme conditions checked for, such as having no metal/energy in storage.
There's not going to be a simple algorithm for that. That's a data structures problem - you're going to want some kind of data structure that tracks a construction project's status, including the resources allocated to it. This could also be used to answer question 2, I think. ("Do I have enough unallocated metal/energy in storage to keep constructing without stalling until enough other projects finish to make my net metal/energy rate positive again?") It wouldn't have to be very complicated: metal allocated to project, energy allocated to project, expected completion time of project, metal consumption of project, energy consumption of project. That tells you everything you need.
The problem witht hat sort fo chekc si what if you have a stable income once building of 1 in and 1 out and 1 stored? Or if your stored metal/energy is yoyo'ing because of turning on and off mohos and metal makers...
A stable income like that seems like a pathological case, though you could add some "If storage is below X%, create a dummy 'recharge' build task to recover."

As for the Metal Makers thing, the Metal Maker Group AI handles that. As long as you aren't e-stalling anyway, you'll never e-stall with the MMGAI on. Though you might still want to be more conservative with energy, and never drop below 70% of storage or something, to get the most out of your MMs?
User avatar
AF
AI Developer
Posts: 20687
Joined: 14 Sep 2004, 11:32

Post by AF »

But the metal maker AI doesnt determine wether you're going to nstall ti simply starting switching on after 1 threshold adn turning off at another , and I cant do any of the stuff without a core fundamental equation which tells me in a very simplistic way

given these values if the environment and the values dont change will i stall or can I build this.

But everyone is adding stuff and bloating the thign without me getting anywhere =(
User avatar
Lindir The Green
Posts: 815
Joined: 04 May 2005, 15:09

Post by Lindir The Green »

X and Y are defined in the mod.tdf

Code: Select all

bool stall = 0
if ((energy_in * X) < (energycost * buildtime / buildspeed))
{
   stall=1
}
if ((metal_in * Y) < (metalcost * buildtime / buildspeed))
{
   stall=1
}
It's that simple.
User avatar
AF
AI Developer
Posts: 20687
Joined: 14 Sep 2004, 11:32

Post by AF »

but that doesnt fit with the universal build routines which ahve no mod.tdf, adn that this doesnt fit all situation within a single faction either...
User avatar
Lindir The Green
Posts: 815
Joined: 04 May 2005, 15:09

Post by Lindir The Green »

Well, you could experiment with different values in the universal build routine, but I think that almost every mod would work with a single X and a single Y.
User avatar
AF
AI Developer
Posts: 20687
Joined: 14 Sep 2004, 11:32

Post by AF »

I disagree, tests show that a single value works for XTA sometimes, and othertimes it's totally wrong.

That adn I dont have time todo lots of playtests, i have exams coming up soon and I've got my construction system rewrite to get going, once thats done I'm handing it over to you then I'll release when you and bamb are happy your buildtrees are ready to release.
Egarwaen
Posts: 1207
Joined: 27 Feb 2006, 21:19

Post by Egarwaen »

Wait, what're the X and Y factors for? Are energy_in and metal_in the displayed-to-user energy/metal income?
User avatar
AF
AI Developer
Posts: 20687
Joined: 14 Sep 2004, 11:32

Post by AF »

Ok let me redefine:

Lindir is referring to X and Y multipliers which i currently have set at 0.8f
He is suggested that I bidn them to tags in the mod.tdf and let modders define them, but that doesnt work as he thinks it does because the algorithm itself is flawed, and while 0.8 seems to be the best value for XTA, it doesnt fit every scenario in XTA like ti should do.

Code: Select all

   if(cant get definition of units) canbuild
   BuildTime = targets_buildTime / builders_buildSpeed;
   // Energy Cost/Second
   EPerS = (energyCost*X) / BuildTime;
   if (EnergyStored + BuildTime * (EnergyIncome - (EnergyUsage + EPerS)) < 0.0f){
      //insufficient energy to build  a stall is anticipated if construction is started
      cant build
   }
   MPerS = (metalCost*Y) / BuildTime;
   if (metalstored + BuildTime * (MetalIncome - (MetalUsage + MPerS)) < 0){
      // insufficient metal
      //insufficient metal to build, a stall is anticipated if construction is started
      cant build
   }
   canbuild 
User avatar
Veylon
AI Developer
Posts: 174
Joined: 21 Sep 2005, 19:45

Post by Veylon »

It shouldn't have to be up to the modder to tell that AI makers how to make AIs!

The formula for calculating stall is fairly simple:
[/code]
Stall=False
if(Resource + (Income - Usage) * BuildTime < 0)
Stall = true

Code: Select all


If you want to factor in the costs of future projects, all you have to do is figure out how much usage they will use and add it into the Usage variable. In fact, that's how you factor in anything that's not being used [i]right now[/i].

If you have your own custom system that doesn't use the GetEnergy(), function, it's a lot easier to figure things because it doesn't spike so much.

I really think that this is all you need. Just as in real life, if you keep some energy in the bank for emergencies, everything should work out. If you stall, you can pull builders off and send them somewhere else. If the stall is not so bad, just don't start new projects.
User avatar
ILMTitan
Spring Developer
Posts: 410
Joined: 13 Nov 2004, 08:35

Post by ILMTitan »

It's not optimized or even runnable, but this is what I always though a construction handler should look like.

Code: Select all

class ConHandler{
private:
  //all current projects
  
  list<ConProjects> projects;
  
  //list of metal makers/extracters
    list<Unit> mMakers;
  
  //list of energy makers.
  list<Unit> eMakers;

  /*list of units that draw energy, like targeting sensors, radar/jammers,
    not including cons or weapons*/
  list<Unit> eSpenders;
  
  //same as above, should be 0 for a normal game of XTA
  list<Unit> mSpenders;
  
  //how much energy you want to have in excess for weapons etc.
  int eBuffer;

  //how much exess energy exsists at the lowest point
  int eMargin;
  
  //how much metal you want to have in excess in case of lost mexes
  int mBuffer;

  //how much excess metal exsists at the lowest point
  int mMargin;

  //list of all points of interest to the ConHandler, in temporal order
  //the first element is always the most recently computed state
  list<ConPoint> conPoints;

public:
  //removes unit from any/all of the lists, and recalculates conPoints
  void unitLost(Unit unit,int time);

  //likely simply removes a ComPoint from comPoints
  void unitComplete(Unit unit,int time);

  /*checks to see if construction of unit by con at this moment will cause a 
    stall, true if it will, false if it won't*/
  bool willStall(Unit unit, Unit con, int time);

  //scheduals a construction job to start as soon as stalling will be avoided.
  void schedual(Unit unit, Unit con, int time);

  //adjusts state for one time uses of energy (weapons)
  void eSpent(int amount, int time);

  //adjusts state for one time uses of metal (???)
  void mSpent(int amount, int time);
}

struct ConPoint{
public:
  int time;
  int metalIncome;
  int changeMetalIncome;
  int energyIncome;
  int changeEnergyIncome;
  int totalMetal;
  int totalEnergy;
}

bool ConHandler::willStall(Unit unit, Unit con, int time){
  if(unit.metalCost<this.mMargin && unit.energyCost<this.eMargin){
    return false;
  }
  ConPoint old = this.conPoints.pop();
  int delT = time-old.time;
  ConPoint cur(old);
  cur.time = time;
  cur.totalMetal = old.totalMetal+old.metalIncome*delT;
  cur.totalEnergy = old.totalEnergy+old.energyIncome*delT;
  cur.changeMetalIncome = 0;
  cur.changeEnergyIncome = 0;
  this.conPoints.push_front(cur);
  ConPoint startCon(cur);
  int buildTime = unit.buildTime/con.buildSpeed;
  // Energy Cost/Frame
  int ePF = unit.energyCost/buildTime; 
  int mPF = unit.metalCost/buildTime;
  startCon.changeMetalIncome = -mPF;
  startCon.changeEnergyIncome = -ePF;
  startCon.metalIncome = startCon.metalIncome
    + startCon.changeMetalIncome;  
  startCon.energyIncome = startCon.energyIncome
    + startCon.changeEnergyIncome;
  ConPoint endCon;
  endCon.time = buildTime + startCon.time;
  endCon.changeMetalIncome = mPF + unit.metalIncome - unit.metalUse;
  endCon.changeEnergyIncome = ePF + unit.energyIncome - unit.energyUse;
  ConPoint mod;
  ConPoint modOld;
  for(list<ConPoint>::iterator i = this.conPoints.iterator();
      i.hasNext(); i++){
    mod = *i;
    if(mod.time > startCon.time){
      if(mod.time > endCon.time && modOld.time =< endCon.time){
	delT = endCon.time - modOld.time;
	endCon.totalMetal = modOld.totalMetal - modOld.metalIncome*delT;
	endCon.totalEnergy = modOld.totalEnergy - modOld.energyIncome*delT;
	endCon.metalIncome = modOld.metalIncome + endCon.changeMetalIncome;
	endCon.energyIncome = modOld.energyIncome + endCon.changeEnergyIncome;
	modOld = endCon;
      }
      delT = endCon.time - modOld.time;
      mod.totalMetal = modOld.totalMetal - modOld.metalIncome*delT;
      mod.totalEnergy = modOld.totalEnergy - modOld.energyIncome*delT;
      mod.metalIncome = modOld.metalIncome + mod.changeMetalIncome;
      mod.energyIncome = modOld.energyIncome + mod.changeEnergyIncome;
      if(mod.totalMetal < this.metalBuffer
	 || mod.totalEnergy < this.energyBuffer){
	return true;
      }
    }
    modOld = mod;
  }
  return false;
}
User avatar
AF
AI Developer
Posts: 20687
Joined: 14 Sep 2004, 11:32

Post by AF »

Veylon, that equation failed me when I shoved NTai in EE, GD started building a nuke reactor and stalled when ti should have built the mexes first giving ti the energy to push forward with a reactor. Whatsmore in XTA it delayed a kbot factory so it wouldnt build even though the reosurces where there....

XTA:: said thigns would make the AI stall that didnt in the end, and let through thgins that made the AI stall too

EE:: made decisions that where guaranteed to stall

both mods couldnt handle startup with that equation, unless I added a modifier to make it apepar they didnt cost as much as they did.


As to why ILMTitan hasnt started an AI yet is beyond me....
User avatar
ILMTitan
Spring Developer
Posts: 410
Joined: 13 Nov 2004, 08:35

Post by ILMTitan »

Because I am trying to graduate, and any distraction cripples my productivity. Just 1 more month, then find a job, then maybe have some fun (build an AI).
Post Reply

Return to “AI”