Page 2 of 2

Posted: 29 Mar 2006, 18:56
by Spectre
hmm SAI is instable ( eh... changed something but forgot where... ) and I cant find the crashbug... could someone help me with getting Windbg to run? When I try to compile SAI with debug symbols the linker reports that "libcpmtd.lib" is missing... :|

edit: eh.. those files are only missing in the free Toolkit 2003.... :( ( I use codeblocks)

Posted: 29 Mar 2006, 19:22
by submarine
BvDorp wrote:how's AAI development anyways?
today was my final exam in theoretical physics (luckily everything went pretty well :) ) so i continued development this afternooon

im still busy fixing bugs, balancing the economy and improving water support

Posted: 29 Mar 2006, 20:30
by AF
Try using the VS express 2005 c edition + platform sdk, that way you can sue the debugger included with it and follow the same instructions as used in vs 2003.

compile as debug and go into project settings and set the workign directory as your spring folder, and the command as the path tot he spring executable, add script.txt as the arguement (to make it load the last game done in the lobby/sprign sp), then debug->start and when it encounters an error it'll break and show you the code in vs..

Also having looked at SAI code I have several suggestions

you used delete value; where value is an array, instead you should sue delete [] value otherwise all you're doing is deleting the first item in the array adn the rest is lost creating a memory leak.

Try using vector<int> rather than int* for an array also, you seem to hold lots of data in a large nubme rof arrays each cross idnexed, so say int* a int* b, a[unitid] b[unitid], try instead to have a single array using a single data structure such as

struct data {
int a;
int b;
};

also your function for comparing strings is actually slow and unneeded, it's faster to do
string udname;
if(udname == string("ARMMEX")){

than string udname
if(sa->cmpname(udname,"ARMMEX")){

also you have objects with functions where nearly every single one takes a callback itnerface as its last parameter, instead try adding an initialization function and using that to pass over the callabck so yuo can elinminate the last parameter.

Also look at NTAI and JCAI source for the handleevent() functions to deal with captured untis given untis etc....

Posted: 29 Mar 2006, 21:36
by Spectre
thanks for your help af.. I´ll try VS2005.
I started cleaning up the source.. 0.1 uses structs and the c++ strings already ;) but thanks for pointing out the mem leak..

Posted: 30 Mar 2006, 13:47
by Spectre
uh.. VS2005 works but as soon as I compile any AI in debug mode it crashes everytime GiveOrder() gets called plus on some very strange occasions...

Code: Select all

void CGlobalAI::Update()
{
	int frame=cb->GetCurrentFrame();	
	if (frame==100) {
		 string name="CORMEX";
		 const UnitDef *hallo=cb->GetUnitDef(name.c_str());
		 float3 cpos=cb->GetUnitPos(comID);
		 float3 pos=cb->ClosestBuildSite(hallo,cpos,30000,0);   
		   
	   
		Command c;
		c.id =-cb->GetUnitDef (name.c_str())->id;
		c.params.push_back (pos.x);
		c.params.push_back(pos.y);
		c.params.push_back (pos.z);
	    
		callback->GetAICallback()->GiveOrder (comID, &c);
	}
}
crashes in debug but not in release .. :(

edit: I had to remove odbc32.lib and odbccp32.lip from the linker input.. do I need this lib to get a working debug version?

edit2: got it working.. had to change form Multithreaded Debug DLL /Mtd to /MT
and line debugging works Oo strange...

Posted: 30 Mar 2006, 20:34
by AF
There are errors in that code, one or two I learnt ages ago, one or two I learnt recently (0.7 specific)

Code: Select all

string name="CORMEX";
const UnitDef *hallo=cb->GetUnitDef(name.c_str());
is better off for now as

Code: Select all

const UnitDef *hallo=cb->GetUnitDef("CORMEX");
however then a problem occurs:

Code: Select all

float3 cpos=cb->GetUnitPos(comID);
float3 pos=cb->ClosestBuildSite(hallo,cpos,30000,0); 
2 problems, what if the engine cannot give you a position say the unti is out of LOS or has bene destroyed ro any other random reason? You'd end up passing a ZeroVector or UpVector itno the closestbuildsite and building in the corner

secondly, sometimes the engine will return a null pointer on GetUnitDef() so you need to check for ti else it'll cause a crash when you feed ti into closestbuildsite()

Also 30k is a bit much to pass in? Are you sure ti isnt slowing SAI down doing so? Brazillian battlefields is only 8kx8k in those units and closestbuildsite will still search the empty sectors past the edges...

Code: Select all

      Command c;
      c.id =-cb->GetUnitDef (name.c_str())->id;
      c.params.push_back (pos.x);
      c.params.push_back(pos.y);
      c.params.push_back (pos.z);
      
      callback->GetAICallback()->GiveOrder (comID, &c);
That looks bad, I wouldnt reccomend doing tit hat way anyways. You're also neglecting to check fi the command succeeded, it'll return -1 if it failed.

Also check that commands.params.empty() == false for commands that use parameters otherwise the engine will crash trying to access them (0.7 specific bug, never crashed in 0.67 etc), and I've found that even though I push_back() parameters in code it doesnt always mean it isnt empty (this causes the infrequent crashes in XE7.5 for which I'm gonna release a fixed version for).......

Code: Select all

void CGlobalAI::Update()
{
   if (cb->GetCurrentFrame()==100) {
       const UnitDef* hallo=cb->GetUnitDef("CORMEX");
       if(hallo == 0) return;
       float3 cpos=cb->GetUnitPos(comID);
       if(cpos == ZeroVector) return;
       if(cpos == UpVector) return;
       float3 pos=cb->ClosestBuildSite(hallo,cpos,3000,1);

      Command c;

      c.id = -hallo->id;
      c.params.push_back(pos.x);
      c.params.push_back(pos.y);
      c.params.push_back(pos.z);

      int i=0;
      if(c.params.empty() == false) i = cb->GiveOrder (comID, &c);
      if(i == -1)
      {
       // do stuff here if ti fails
      }
   }
}

Posted: 30 Mar 2006, 22:18
by QMan
AF wrote:Also 30k is a bit much to pass in? Are you sure ti isnt slowing SAI down doing so? Brazillian battlefields is only 8kx8k in those units and closestbuildsite will still search the empty sectors past the edges...
Found a bug with this particular thing last night. The closest build site radius command actually scales down the radius value by SQUARE_SIZE*2, so 30k is really just less than 2k.

I was trying to figure out why my builders kept building in the sector centers, and then saying no more room existed and moved to another sector. Turns out I had to scale my radius value up, and it works perfectly.

Posted: 31 Mar 2006, 00:15
by krogothe
30k will still be bigger than brazilian battlefields, its just the resolution of the search will be SQ2, so it will only do 2k checks. However if you add even a small separation your computer will explode. KAI used 1k and it was still slow as hell, though zaphod said he optimized it, so i gotta test it out!
My VS2005 doesnt allow for debug mode either, but you get used to it very quickly, since 99% of the time it is very easy to see whats crashing it, and the other 1% just requires a bit of logging!

Posted: 31 Mar 2006, 10:54
by Bobris
I already written here Relese STL replacement (not totaly complete, but you get idea) which allows to use debug version of AI (compiled by VS2005) and release version of Spring (compiled by VS2003).
http://taspring.clan-sy.com/phpbb/viewt ... c&start=19

Posted: 31 Mar 2006, 20:25
by AF
I found that closestbuildsite wasnt exactly useful as it always gave the closestbuildsite tot he spot given and giving the unitpos isnt always the best idea. So I offseted the unitsposition by say 100 or 200 points in the x axis then rotated the new position about the original position by a random angle, checking afterwards if the new pos was offmap and making the necessary transformation.

Beforehand in nanoblobz untis never made use of their build distance and always walked straight to their destination then nanolathed, but now they nanolathe at a distance and they're less likely to get congested as they're more willing to spread out....

Posted: 02 Apr 2006, 21:25
by Spectre
update: http://fileuniverse.com/?p=showitem&ID=2818

first debugged build under VS2005 :-)
Im too lazy for changelogs but it builds a nice fusion economy now :wink:

Posted: 03 Apr 2006, 00:37
by jcnossen
Found a bug with this particular thing last night. The closest build site radius command actually scales down the radius value by SQUARE_SIZE*2, so 30k is really just less than 2k.
IIRC that is because it is specified in world space units, and it needs to be scaled down because the bitmap that marks the occupied areas in spring is half the size of the heightmap. (Well it's dimensions are half of that of the heightmap, so the number of squares is actually one 4th of that of the heightmap.... ;))

As krogothe said, I optimized it so it returns directly when the closest spot is found, instead of checking all possible spots and then returning.
So usually, it is much faster than it was when KAI was released, it will only take a lot of time when there actually isn't any building space nearby.

Posted: 03 Apr 2006, 08:50
by krogothe
Zaphod wrote: As krogothe said, I optimized it so it returns directly when the closest spot is found, instead of checking all possible spots and then returning.
So usually, it is much faster than it was when KAI was released, it will only take a lot of time when there actually isn't any building space nearby.
<3

Posted: 03 Apr 2006, 10:44
by Suprano
hm i compiled this using MSVC, and it crashed right after starting.

Then i compiled it using mingw [had to change the abs() calls to abs((int) blabla) ]and my own compiled mingw ta spring, but it crashed too... :/

No idea what to do now

--Ano

Posted: 03 Apr 2006, 11:24
by submarine
using the correct calling convention *hint*

Posted: 03 Apr 2006, 11:39
by Tobi
mingw compiled AI dlls in MSVC spring won't ever work, same for the MSVC dlls in mingw compiled spring. The C++ ABI is significantly different.

E: also, when compiling a certain AI in MSVC or mingw and running it in spring compiled by the same compiler, it should actually work because the calling convention ought to be the same (unless it's manually changed).