How to make an AI build a structure?

How to make an AI build a structure?

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

Moderators: hoijui, Moderators

Post Reply
Morloth
Posts: 3
Joined: 19 Jan 2008, 14:38

How to make an AI build a structure?

Post by Morloth »

Hi everyone,

I just started out buildin my own AI and I have some nice ideas for
it, but for the moment I'm stuck with an AI that can't build
anything... I'm able to make a commander move, but I'm not able to
make him build something.

Here is the code I'm using at the moment:

Code: Select all

void TestGlobalAI::UnitFinished(int unit)
{
    const UnitDef *unitdef = aicallback->GetUnitDef(unit);
    if (unitdef->isCommander) {
       char buf[1024];
       sprintf(buf, "Command id is %d\n", unit);
       aicallback->SendTextMsg(buf, 0);

       const int unitnumber = aicallback->GetNumUnitDefs();
       const UnitDef* unitList[unitnumber];
       aicallback->GetUnitDefList(unitList);

       const UnitDef* solarDef;

       // Search for the solar collector we want to build.
       for (int i = 0; i < unitnumber; i++) {
           if (unitList[i]->energyMake > 0) {
              solarDef = unitList[i];
              sprintf(buf, "Solar unit ID is: %d\n", solarDef->id);
              aicallback->SendTextMsg(buf, 0);
              break;
           }
       }

       if (solarDef == 0) {
           aicallback->SendTextMsg("No solar unit found :(", 0);
       } else {

           float3 commanderpos = aicallback->GetUnitPos(unit);
           float3 buildSite = aicallback->ClosestBuildSite(solarDef,
commanderpos, 1400.0, true);
           buildSite.x += 200;
           aicallback->CreateLineFigure(commanderpos, buildSite,
(float)10, 10, 10000, 0);
           sprintf(buf, "Location: %f, %f, %f\n", buildSite.x,
buildSite.y, buildSite.z);

           aicallback->SendTextMsg(buf, 0);
           aicallback->SendTextMsg("Lets build some shite!", 0);

           Command c;
           c.id = -solarDef->id;
           c.params.resize(3);
           c.params[0] = buildSite.x;
           c.params[1] = aicallback->GetElevation(buildSite.x, buildSite.z);
           c.params[2] = buildSite.z;
           if (aicallback->GiveOrder(unit, &c) == -1)
              aicallback->SendTextMsg("Build action failed :(", 0);
       }
    }
}
I do get to see an arrow which points right of the commander to an
empty plane with more then enough space to build something, but the
commander simply won't move. In the Infolog the following information
is shown:

[ 0] Spring 0.78.2.1
[ 0] Build date/time: Jan 18 2009 20:20:06
[ 0] Player Player connected with number 0 (client version 0.78.2.1)
[ 0] Player Player finished loading and is now ingame
[ 0] GameID: 15e67949dc2f3621fd6b0c81fa320045
[ 0] /home/u0/apas2008/bridder/Spring/AI/Bot-libs/TestAI.so has a C++ interface
[ 0] GlobalAI1: Hello world v2
[ 0] GlobalAI1: Command id is 6372
[ 0] GlobalAI1: Solar unit ID is: 1
[ 0] GlobalAI1: Location: 5296.000000, 91.718750, 440.000000
[ 0] GlobalAI1: Lets build some shite!

There are some messages about a LUA widget called Lups which fails, but I don't think it's relevant.

This is the picture in game with the arrow designating where the commander should build:

Image

If someone could give me some pointers I'd be very very happy! Also is there a description for the API used by AIs? I have a hard time to skip through the code of TA Spring and other AIs to figure out which parameters I should pass to commands, etc.

Thanks!
Bram
Kloot
Spring Developer
Posts: 1867
Joined: 08 Oct 2006, 16:58

Re: How to make an AI build a structure?

Post by Kloot »

Some tips:
  • You don't need to retrieve all the UnitDef pointers every time a UnitFinished() event triggers. It's better to move that code to your AI's initialization function (InitAI()).

    When handling UnitDef pointers, always test that they are not NULL before dereferencing them.

    You search for a UnitDef that has energyMake > 0, but you don't check if it's part of the Commander's build options. IOW, unitList might not be the solar collector at all, but some other unit that happens to produce energy. In that case the build order will fail (silently).
User avatar
AF
AI Developer
Posts: 20687
Joined: 14 Sep 2004, 11:32

Re: How to make an AI build a structure?

Post by AF »

Just a note:

Code: Select all

float3 buildSite = aicallback->ClosestBuildSite(solarDef, commanderpos, 1400.0, true);
buildSite.x += 200;
In the first line buildSite is given a valid position.

In the second line you shift that position to a new position 300 points away, but this new position may not be a valid buildsite, and there are no checks. I assume this is to prevent the commander attempting to build directly underneath it? It might be best then to shift commanderpos by 300 not buildSite.

Also be aware that energymake > 0 isn't the only check you need. You also need EnergyUsage < 0. In OTA the solar collectors used up -20 energy as a kludge for opening and closing and not generating power when closed.
Morloth
Posts: 3
Joined: 19 Jan 2008, 14:38

Re: How to make an AI build a structure?

Post by Morloth »

Kloot wrote:Some tips:
  • You don't need to retrieve all the UnitDef pointers every time a UnitFinished() event triggers. It's better to move that code to your AI's initialization function (InitAI()).
Thanks for the tip, I do that in my code now. The above snippet was just to show the complete code to my problem without being bogged down by separate methods, etc.
Kloot wrote:Some tips:
You search for a UnitDef that has energyMake > 0, but you don't check if it's part of the Commander's build options. IOW, unitList might not be the solar collector at all, but some other unit that happens to produce energy. In that case the build order will fail (silently).
[/list]

Ah yes! That was the problem, thank you very much :). But regarding my question to an API or documentation is there any? Because it would be nice to have a complete overview of what parameters need to be passed to all the Command calls.

AF wrote:Just a note:

Code: Select all

float3 buildSite = aicallback->ClosestBuildSite(solarDef, commanderpos, 1400.0, true);
buildSite.x += 200;
In the first line buildSite is given a valid position.

In the second line you shift that position to a new position 300 points away, but this new position may not be a valid buildsite, and there are no checks. I assume this is to prevent the commander attempting to build directly underneath it? It might be best then to shift commanderpos by 300 not buildSite.
True, but I wanted to make sure that the command didn't fail because the commander was standing on top of it. As can be shown in the picture there is plenty of space at the new location.
AF wrote:Also be aware that energymake > 0 isn't the only check you need. You also need EnergyUsage < 0. In OTA the solar collectors used up -20 energy as a kludge for opening and closing and not generating power when closed.
Thanks for telling me, I wasn't aware of this.

At this point I'm not so much interested in the details of each mod. I just want to do some experiments with integrating planners in an AI and later fine tune for specific mods. This is my first go at building an AI for an RTS game so I want to get a good grasp on the API before starting on a full featured AI bot. I'll explain the detail when I'm a little further with this project 8).

Thanks for your help!
Bram
imbaczek
Posts: 3629
Joined: 22 Aug 2006, 16:19

Re: How to make an AI build a structure?

Post by imbaczek »

API is quite fluid atm, there'll be a major AI interface update in not so far future, hopefully before the next release. The current C++ API should be still available, but changes are to be expected.

If you're feeling adventurous, investigate caiinterface branch.
Post Reply

Return to “AI”