Author Topic: Outpost 2 Coding 101: Week 11  (Read 16783 times)

Offline Sirbomber

  • Hero Member
  • *****
  • Posts: 3238
Outpost 2 Coding 101: Week 11
« on: April 01, 2010, 11:53:15 PM »
Week 11 (Final Week)
Your First Multiplayer Game with an AI - Man Versus Machine

Okay, this is it.  Your final test of Outpost 2 coding aptitude.  Can you make an AI that can handle itself in multiplayer against multiple human opponents?  Probably not, but not through any fault of your own.  Let's get started, shall we?

...Well, I'd like to, but I really don't know what to write for this tutorial.  I've taught you pretty much everything there is to know about AI.

I might still have a few tricks up my sleeve.  A few final tidbits of information to share with you before I wrap this up.  So let's finish what we started three months ago.

IMPORTANT NOTE: Making a Land Rush-capable AI is not recommended at this time.

AI Setup
There are a few key difference between setting up an AI in single player and setting one up in multiplayer.  There are also some things you need to know when designing multiplayer games with an AI.  Let's start from the top.

1) Initializing the AI
So in single player you just set the number of players to 2 instead of 1.  So in multiplayer, you just set it to 5 instead of 4, right?  Wrong.  The DescBlock should only hold the maximum number of human players.  But if we do this our AI doesn't work properly.  What are we to do?!
Why, we do this, of course!
Code: [Select]
// Add this immediately after your DescBlock:
struct SDescBlockEx {
    int unk0;
    int unk1;
    int unk2;
    int unk3;
    int unk4;
    int unk5;
    int unk6;
    int unk7;
};

SCRIPT_API SDescBlockEx DescBlockEx = { 1, 0, 0, 0, 0, 0, 0, 0 };

2) Determining AI player number
Unlike in single player, we don't know which player number the AI will get assigned as it will be one more than the number of human players.  Here's how we find it:
Code: [Select]
short numAI;	// AI player number.

int InitProc()
{
// Determine AI player number
for (numAI = 0; numAI < 7; numAI++)
{
     if (!Player[numAI].IsHuman())
     break;
}
...
}

This loop runs through each player (1 through 7) and checks if the current player is human.  If not, the loop stops and the current player is set to the AI.

3) Building your AI
From here, it's just like the earlier tutorials involving AI.  Check those if you need help.

4) Making a good AI
Quote
There is no help available on that topic.  You're on your own.
If you've come this far, you can figure this out yourself.  I'll give you a few hints though:
A. You'll probably need gratuitous amounts of cheating.  Deal with it.
B. Don't try to make your AI "general purpose".  Keep things specific to the current map you're working on, and try to keep variations between gameplay to a minimum.
C. Let your AI grow over time.  This includes base building, research, mining, and using more, larger unit groups with different types of units.
D. Experiment!  Learn for yourself what works and what doesn't, and modify your AI as such.
E. For bonus points, try to make your AI adapt to what the player is doing.  If a Plymouth human player is building a Spaceport, have your AI build some Meteor Defenses!
F. For more bonus points, make the AI cheat a bit less.  Have it actually perform research instead of just giving it free tech, and only let it build vehicles if it has the research for it.
G. SUPER-DUPER BONUS POINT OPPORTUNITY: Have your AI output the results of the game to a file.  List what was and wasn't effective.  Each time the AI plays, read in this file.  This will allow your AI to learn how to play OP2 better as it plays the game more!  'Course, it's a lot of hard work, but...

Well, that's it for Outpost 2 Coding 101.  It's been a blast, and I really hope you guys learned something from this.  I expect to see a lot of new, high-quality stuff coming from you guys!

For those interested in further programming endeavors outside of Outpost 2, I advise you to check out these two sites:
C++ Language Tutorial
C++ Reference

You may also want to pick up a book, but you should ask someone more knowledgeable than I about that.

Stay tuned, I might work on Outpost 2 Coding 202, where we'll pursue more advanced topics like campaign creation, advanced AI, and possibly delve into the Holy Grail of Outpost 2 Programming: a general-purpose AI.

Until then, feel free to post comments, questions, complaints, criticisms, or whatever here.
« Last Edit: April 02, 2010, 07:55:58 AM by Sirbomber »
"As usual, colonist opinion is split between those who think the plague is a good idea, and those who are dying from it." - Outpost Evening Star

Outpost 2 Coding 101 Tutorials

Offline Moley

  • Jr. Member
  • **
  • Posts: 95
Outpost 2 Coding 101: Week 11
« Reply #1 on: April 02, 2010, 06:17:30 AM »
one question... in the general purpose AI, are "we" as a forum make the AI one piece at a time?
as in, someone starts the code and we improve on it as we test and change the code?
I HATE SPELLING!!!!!!
if i spell something or screw up grammer,
ignore it or tell me if you dont understand what i typed.

Offline Sirbomber

  • Hero Member
  • *****
  • Posts: 3238
Outpost 2 Coding 101: Week 11
« Reply #2 on: April 02, 2010, 06:25:08 AM »
Don't ask about 202 stuff.  I haven't put much thought into it yet, so I can't answer any questions about it.
"As usual, colonist opinion is split between those who think the plague is a good idea, and those who are dying from it." - Outpost Evening Star

Outpost 2 Coding 101 Tutorials

Offline Simpsonboy77

  • Full Member
  • ***
  • Posts: 168
Outpost 2 Coding 101: Week 11
« Reply #3 on: April 08, 2010, 08:06:26 AM »
How would we query tethysgame for the map size, (height and width)? Additionally is there a bit we could query to see it the map is a world map (wraps around)?

Also could we query each tile and get the movement speeds for say a robo surveyor? I have an idea I want to try out this weekend.
My tutorials
Part 1
Part 2
Part 3

Offline Sirbomber

  • Hero Member
  • *****
  • Posts: 3238
Outpost 2 Coding 101: Week 11
« Reply #4 on: April 08, 2010, 08:30:32 AM »
This should work, but I didn't actually test it...

Code: [Select]
// Adapted from volcanoes code

// Create a location off the map
LOCATION mapSize(1024, 1024);

// Clip it to the actual map size, repositioning it to the bottom-right corner of the map
mapSize.clip();

// Use the location's x/y coordinates to determine map width/height
short mapHeight = mapSize.y;
short mapWidth  = mapSize.x;

// If the width is 512, we know this is a world map
if (mapWidth == 512)
 ...
"As usual, colonist opinion is split between those who think the plague is a good idea, and those who are dying from it." - Outpost Evening Star

Outpost 2 Coding 101 Tutorials

Offline jcj94

  • Sr. Member
  • ****
  • Posts: 407
    • http://techfusion-279.com
Outpost 2 Coding 101: Week 11
« Reply #5 on: March 17, 2011, 01:36:14 PM »
I would enjoy a 202...

 

Offline Hooman

  • Administrator
  • Hero Member
  • *****
  • Posts: 4955
Re: Outpost 2 Coding 101: Week 11
« Reply #6 on: March 15, 2019, 02:09:54 AM »
Update: The newer version of the SDK is using "Export" rather than "SCRIPT_API". Combining that with a more compact definition for DescBlockEx, I'd recommend using:
Code: [Select]
struct SDescBlockEx {
    int numAiPlayers;
    int unused[7];
};

Export SDescBlockEx DescBlockEx = { 1 };

The compiler will auto 0 fill the remaining fields.

For details, see:
https://forum.outpost2.net/index.php/topic,2633.0.html