Relationship between 'Role' and AI

General discussion for players of Oolite.

Moderators: winston, another_commander

User avatar
Smivs
Retired Assassin
Retired Assassin
Posts: 8408
Joined: Tue Feb 09, 2010 11:31 am
Location: Lost in space
Contact:

Relationship between 'Role' and AI

Post by Smivs »

Can someone satisfy my curiosity?
As I understand things, when a ship is spawned it has a specific role, pirate, hunter, trader etc. Indeed it was spawned because the game decided to add a ship of this specific role. Reading the Wikiwe are told the role has a bearing on the behaviour of the ship.
But the AIs also clearly have a bearing on ship's behaviour as well. But sometimes you find ships with the same Role, but using different AIs. So what is the relationship?
An example:-
From the wiki page
HUNTER: These ships cruse the space lanes and attack offenders and ships with bounties (including the player of cause). They are pretty brave in combat only fleeing if really badly hurt and sometimes fight to the death.....
Yet when you look at the Hunters from the core ships they seem to use either the Route1trader.AI or the Pirate.AI, which are clearly very different. So what gives the Hunter (or any other Role) its particular behaviour pattern?
Commander Smivs, the friendliest Gourd this side of Riedquat.
User avatar
Eric Walch
Slightly Grand Rear Admiral
Slightly Grand Rear Admiral
Posts: 5536
Joined: Sat Jun 16, 2007 3:48 pm
Location: Netherlands

Re: Relationship between 'Role' and AI

Post by Eric Walch »

Smivs wrote:
Can someone satisfy my curiosity?......Yet when you look at the Hunters from the core ships they seem to use either the Route1trader.AI or the Pirate.AI, which are clearly very different. So what gives the Hunter (or any other Role) its particular behaviour pattern?
Normally there is no relationship. Only for some special roles an AI switch is used. When spawned in those roles, the AI defined in shipdata than is never used but is changed, based on the role. That allows defining a single ship with both trader, pirate, scavenger or other roles.
User avatar
Smivs
Retired Assassin
Retired Assassin
Posts: 8408
Joined: Tue Feb 09, 2010 11:31 am
Location: Lost in space
Contact:

Post by Smivs »

Ah, that makes sense.
So say a Hunter/Trader with a trader AI specified in the shipdata.plist would switch to, what, a Police AI if it was spawned as a Hunter?
Commander Smivs, the friendliest Gourd this side of Riedquat.
User avatar
Eric Walch
Slightly Grand Rear Admiral
Slightly Grand Rear Admiral
Posts: 5536
Joined: Sat Jun 16, 2007 3:48 pm
Location: Netherlands

Post by Eric Walch »

Smivs wrote:
Ah, that makes sense.
So say a Hunter/Trader with a trader AI specified in the shipdata.plist would switch to, what, a Police AI if it was spawned as a Hunter?
Yes. The complete role/AI mapping list is in Oolites Config folder as "autoAIMap.plist"
User avatar
Commander McLane
---- E L I T E ----
---- E L I T E ----
Posts: 9520
Joined: Thu Dec 14, 2006 9:08 am
Location: a Hacker Outpost in a moderately remote area
Contact:

Post by Commander McLane »

Smivs wrote:
So say a Hunter/Trader with a trader AI specified in the shipdata.plist would switch to, what, a Police AI if it was spawned as a Hunter?
Yes, only that it's called "route1patrolAI", and is used by both police and hunters.

Oolite knows the following generic ship roles, "generic" meaning that the engine itself uses these roles (and only these) to populate the Ooniverse:

- trader
- hunter
- police
- pirate
- scavenger
- miner
- escort
- thargoid
- thargon
- sunskim-trader (is this a generic role? I'm not sure)

The first four make the bulk of ships, and are spread randomly over the space lanes whenever you enter a new system. Scavengers and miners are only launched by stations under certain circumstances. Escorts are accompanying some traders. Thargoids and thargons come into the mix occasionally.

Each of these generic roles has one standard AI assigned to it:

- trader: route1traderAI
- hunter and police: route1patrolAI
- pirate: pirateAI
- scavenger: scavengerAI
- miner: minerAI
- thargoid: thargoidAI
- thargon: thargletAI
- sunskim-trader: route2sunskimAI

Whenever the engine populates a system from the generic roles, it gives each ship its generic AI, regardless of the AI assigned to it in its shipdata.plist-entry.

However, you can assign a different AI to each ship in its shipdata.plist-entry. This will be used, if the ship is not spawned automatically by the populator, but via a script. For script-spawned ships you're also not limited to the generic role, but are completely free to assign any string you want as a role. If you want a certain ship to only be spawned by your own script, you should make sure to use a sufficiently unique role, or somebody else may have used the same string before.
User avatar
Smivs
Retired Assassin
Retired Assassin
Posts: 8408
Joined: Tue Feb 09, 2010 11:31 am
Location: Lost in space
Contact:

Post by Smivs »

Thanks, Guys, Curiosity satisfied. :)
Commander Smivs, the friendliest Gourd this side of Riedquat.
Switeck
---- E L I T E ----
---- E L I T E ----
Posts: 2411
Joined: Mon May 31, 2010 11:11 pm

Post by Switeck »

Escort ai changes escorts with a bounty to pirates (if they have a cargo bay) because they are automatically ejected from being an escort of a clean mothership.
User avatar
Commander McLane
---- E L I T E ----
---- E L I T E ----
Posts: 9520
Joined: Thu Dec 14, 2006 9:08 am
Location: a Hacker Outpost in a moderately remote area
Contact:

Post by Commander McLane »

Switeck wrote:
Escort ai changes escorts with a bounty to pirates (if they have a cargo bay) because they are automatically ejected from being an escort of a clean mothership.
Pirates can have escorts, too. :wink:

The thing to remember is that, while the populator adjusts the AI for generic roles, it doesn't necessarily adjust a pre-defined bounty. Which means that, if you want to give your ship the generic "escort" role, you mustn't set a bounty in its shipdata.
User avatar
Smivs
Retired Assassin
Retired Assassin
Posts: 8408
Joined: Tue Feb 09, 2010 11:31 am
Location: Lost in space
Contact:

Post by Smivs »

More curiosity! Two more questions...
Looking on the AI page of the Wiki, I noticed this description of the 'Scan for Offenders' AI method
Locates all the ships in range, multiplies the legal status with a government factor, subtracts a random value between 0 and 255 from this result and compares the remaining value. It chooses the worst remaining offender. Because of the random value not all ships are found in every scan and the lower the bounty and lower the government, the longer it takes to detect a ship as offender. Returns: "TARGET_FOUND" or "NOTHING_FOUND".

Government factor = 0 in an anarchy and increases with 0.4 for every government till it reaches 2.8 for a corporate state. Result is that it never finds a ship in an anarchy, that is needs 637 points to always find an offender in a feudal state and only needs 91 points to always find a offender in a corporate state.
If I understand this correctly it means that a scan for offenders will never find an offender in an Anarchy, and is unlikely to in a feudal state as well. Now as this is where you'd most expect to find offenders this struck me as odd. Is this right? Perhaps it's to stop any Police/Hunters cleaning up the System before you (the player) arrive. :?:

Also on the AI page I found the role scanning methods at the bottom of the page, which I would like to use. Specifically
scanForNearestShipWithPrimaryRole:(NSString*) role
I'm not an expert with this language, so could some kind soul tell me how to incorporate this into an AI?
I tried

Code: Select all

scanForNearestShipWithPrimaryRole:pirate,
with upper and lower case Ps on the pirate, a space and no space after the colon and pretty much every other permutation, and it gets rejected. Each time the log shows
[ai.unpermittedMethod]: Handler "UPDATE" for state "HEAD_FOR_WITCHPOINT" in AI "cbhAI.plist" uses "scanForNearestShipWithPrimaryRole:pirate", which is not a permitted AI method.
I've also tried the old 'scanForNearestShipWithRole' with the same result. I am using this in the 'Update's which currently have a scanForOffenders method. I am adding a scanForHostiles which it seems happy with, and the scanForNearestShipWithPrimaryRole, which it's not happy with.
I expect my syntax is wrong. Can anyone point me in the right direction?
To put all this in context I'm trying to adapt the Route1Patrol AI to make the detection of offenders and pirates more efficient for a Hunter role ship.
In fact no harm being truthful, the original AI for my NPC Contractor isn't working as well as I'd like and I'm trying to improve it ready for the next update/release.
Commander Smivs, the friendliest Gourd this side of Riedquat.
User avatar
Eric Walch
Slightly Grand Rear Admiral
Slightly Grand Rear Admiral
Posts: 5536
Joined: Sat Jun 16, 2007 3:48 pm
Location: Netherlands

Post by Eric Walch »

Smivs wrote:
Government factor = 0 in an anarchy and increases with 0.4 for every government till it reaches 2.8 for a corporate state. Result is that it never finds a ship in an anarchy, that is needs 637 points to always find an offender in a feudal state and only needs 91 points to always find a offender in a corporate state.
If I understand this correctly it means that a scan for offenders will never find an offender in an Anarchy, and is unlikely to in a feudal state as well. Now as this is where you'd most expect to find offenders this struck me as odd. Is this right? Perhaps it's to stop any Police/Hunters cleaning up the System before you (the player) arrive. :?:
Correct. That is also one of the reasons there are no police added to anarchies. Or those systems became anarchies because galcop never could find and kill those hostiles? This way of treating bounties makes also that a ship with small bounty is often left alone in the lower governments, but will attact police attention soon in the higher governments.

Also are in anarchies more hunters added than in other systems. They have the same intentional search "problem" as police. But hunters and police still react on broadcasts for help and police will still react when they witness a crime.
Smivs wrote:
I tried

Code: Select all

scanForNearestShipWithPrimaryRole:pirate
with upper and lower case Ps on the pirate, a space and no space after the colon and pretty much every other permutation, and it gets rejected.
Should be

Code: Select all

scanForNearestShipWithPrimaryRole: pirate
All the commands with a semicolon have a space after it. I just used that specific command yesterday without any problem:

Code: Select all

ENTER = ("scanForNearestShipWithPrimaryRole: buoyForCollisionTesting", "setSpeedFactorTo: 1"); 
User avatar
Smivs
Retired Assassin
Retired Assassin
Posts: 8408
Joined: Tue Feb 09, 2010 11:31 am
Location: Lost in space
Contact:

Post by Smivs »

Thanks for that Eric. Unfortunately it's still not working. I've tried :-

Code: Select all

scanForNearestShipWithPrimaryRole: pirate
(which I'm sure I'd tried before), and now I'm getting this error message in the log
[plist.parse.failed]: Failed to parse /home/smivses/.Oolite/AddOns/Contractor_v4.0.oxp/AIs/cbhAI.plist as a property list.
Parse failed at line 22 (char 1242) - unexpected character (wanted ',' or ')')
I've added the comma (,) after the code thus

Code: Select all

scanForNearestShipWithPrimaryRole: pirate,
but am still getting the same error message.

Below is the first section of the AI (with the comma) to put this in context.

Code: Select all

{
	GLOBAL =
	{
		ENTER = ("setStateTo: HEAD_FOR_WITCHPOINT");
	};
	"HEAD_FOR_PLANET" =
	{
		ENTER = (setCourseToPlanet, "setDesiredRangeTo: 50000.0", checkCourseToDestination);
		"COURSE_OK" = (setSpeedToCruiseSpeed, performFlyToRangeFromDestination);
		"WAYPOINT_SET" = ("setAITo: cbhgotoWaypointAI.plist");
		"DOCKING_REQUESTED" = ("setAITo: receiveDockingAI.plist");
		"DESIRED_RANGE_ACHIEVED" = ("setStateTo: HEAD_FOR_WITCHPOINT");
		"ACCEPT_DISTRESS_CALL" = (setTargetToFoundTarget, "setAITo: cbhinterceptAI.plist");
		"OFFENCE_COMMITTED" = (setTargetToFoundTarget, "setAITo: cbhinterceptAI.plist");
           "TARGET_FOUND" = (setTargetToFoundTarget, checkTargetLegalStatus);
	        "TARGET_MINOR_OFFENDER" = ("setAITo: cbhinterceptAI.plist");
	        "TARGET_OFFENDER" = ("setAITo: cbhinterceptAI.plist");
	        "TARGET_FUGITIVE" = ("setAITo: cbhinterceptAI.plist");
		"INCOMING_MISSILE" = (setTargetToFoundTarget, "setAITo: cbhdelayedReactToAttackAI.plist");
		ATTACKED = (setTargetToPrimaryAggressor, "setAITo: cbhinterceptAI.plist");
		RESTARTED = (checkAegis);
		UPDATE = (setCourseToPlanet, "setDesiredRangeTo: 50000.0", checkCourseToDestination, scanForOffenders, scanForHostiles, scanForNearestShipWithPrimaryRole: pirate, "pauseAI: 10.0");
	};
As you'll see it's an adapted version of the Route1patrol AI. My intention is to ensure that the Bounty Hunter (Contractor) locates and attacks any offender of any status where-ever they may be, independent of System type. As these are very rare this should not interfere with the normal dynamics of the game.
This all came about a couple of weeks ago when I came across a Contractor, the first one I'd seen since July (that's how rare they are!), and noticed it was just cruising around doing nothing even though there were two or three offenders on the scanner. These NPC Contractors (Bounty Hunters) should be ruthless and unforgiving, and at the moment, they're not.
Commander Smivs, the friendliest Gourd this side of Riedquat.
another_commander
Quite Grand Sub-Admiral
Quite Grand Sub-Admiral
Posts: 6645
Joined: Wed Feb 28, 2007 7:54 am

Post by another_commander »

AI methods taking a parameter should be enclosed in quotes. Try changing

Code: Select all

scanForNearestShipWithPrimaryRole: pirate
to

Code: Select all

"scanForNearestShipWithPrimaryRole: pirate"
and it should work. At least it works like this for the built-in Constrictor, which is using this AI method to locate the player.
User avatar
Smivs
Retired Assassin
Retired Assassin
Posts: 8408
Joined: Tue Feb 09, 2010 11:31 am
Location: Lost in space
Contact:

Post by Smivs »

Ah, that's worth a try, thanks. I'll report back.
Commander Smivs, the friendliest Gourd this side of Riedquat.
User avatar
Eric Walch
Slightly Grand Rear Admiral
Slightly Grand Rear Admiral
Posts: 5536
Joined: Sat Jun 16, 2007 3:48 pm
Location: Netherlands

Post by Eric Walch »

Smivs wrote:
Thanks for that Eric. Unfortunately it's still not working. I've tried :-
A_C already gave the solution but I noticed another bug:

Code: Select all

UPDATE = (setCourseToPlanet, "setDesiredRangeTo: 50000.0", checkCourseToDestination, scanForOffenders, scanForHostiles, scanForNearestShipWithPrimaryRole: pirate, "pauseAI: 10.0");
	};
You do several scans in one line. However, every scan first clears any previous found target. So, scanForOffenders and scanForHostiles have no effect in your code as anything they find get lost by the last scanForNearestShipWithPrimaryRole command. (As mentioned in locating entities)

Even worse: they can set the flag NOTHING_FOUND and than the last command can set the TARGET_FOUND flag. Than at update time the flags are analyzed in random order so there is a 50% change it reacts to the NOTHING_FOUND first.

So generally one should never use more than one search request per UPDATE
User avatar
Smivs
Retired Assassin
Retired Assassin
Posts: 8408
Joined: Tue Feb 09, 2010 11:31 am
Location: Lost in space
Contact:

Post by Smivs »

I've obviously still got a lot to learn!
I had a quick look at the wiki section you referenced. Should I be adding pauses between the scans, or are multiple updates the best way to go?
Commander Smivs, the friendliest Gourd this side of Riedquat.
Post Reply