Join us at the Oolite Anniversary Party -- London, 7th July 2024, 1pm
More details in this thread.

Old AI bugs

For test results, bug reports, announcements of new builds etc.

Moderators: winston, another_commander, Getafix

User avatar
JensAyton
Grand Admiral Emeritus
Grand Admiral Emeritus
Posts: 6657
Joined: Sat Apr 02, 2005 2:43 pm
Location: Sweden
Contact:

Post by JensAyton »

I very definitely can’t guarantee that messageMother: will continue to work for non-escorts.
User avatar
Kaks
Quite Grand Sub-Admiral
Quite Grand Sub-Admiral
Posts: 3009
Joined: Mon Jan 21, 2008 11:41 pm
Location: The Big Smoke

Post by Kaks »

Uh-oh. Maybe it's worth requesting a new messageSelf: method for 1.73...
Hey, free OXPs: farsun v1.05 & tty v0.5! :0)
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 »

Kaks wrote:
Uh-oh. Maybe it's worth requesting a new messageSelf: method for 1.73...
I already suggested this in my earlier message: "exitAIWithMessage:". But maybe a messageSelf: would be mode universal and easier to implement as it could be almost the same as the current messageMother:
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 »

from the two choices, messageSelf: would be the most flexible. It could also be put in use elsewhere. e.g. to shrink code like:

Code: Select all

	CRITICAL = {
		ENTER = ("pauseAI: 10");
		COLLISION = ("setStateTo: EXPLODE");
		ECM = ("commsMessage: WARNING: Quirium Cascade imminent!", "setStateTo: TIMER5");
		EXIT = ();
		UPDATE = ("pauseAI: 30", performTumble, "commsMessage: -Beep!- ");
	};
	TIMER5 = {
		ENTER = ("pauseAI: 2.0");
		EXIT = ();
		UPDATE = ("commsMessage: 5", "setStateTo: TIMER4");
	};
	TIMER4 = {
		ENTER = ("pauseAI: 2.0");
		EXIT = ();
		UPDATE = ("commsMessage: 4", "setStateTo: TIMER3");
	}; 
	TIMER3 = {
		ENTER = ("pauseAI: 2.0");
		EXIT = ();
		UPDATE = ("commsMessage: 3", "setStateTo: TIMER2");
	};
	TIMER2 = {
		ENTER = ("pauseAI: 2.0");
		EXIT = ();
		UPDATE = ("commsMessage: 2", "setStateTo: TIMER1");
	};
	TIMER1 = {
		ENTER = ("pauseAI: 2.0");
		EXIT = ();
		UPDATE = ("commsMessage: [bomb-last-words]", "setStateTo: DEFUSE_CHANCE");
	};
down to

Code: Select all

	CRITICAL = {
		ENTER = ("pauseAI: 10");
		COLLISION = ("setStateTo: EXPLODE");
		ECM = ("commsMessage: WARNING: Quirium Cascade imminent!", "setStateTo: TIMER");
		UPDATE = ("pauseAI: 30", performTumble, "commsMessage: -Beep!- ");
	};
	TIMER = {
		ENTER = ("pauseAI: 2.0", "messageSelf: MESSAGE_5");
		MESSAGE_5 = ("commsMessage: 5", "messageSelf: MESSAGE_4");
		MESSAGE_4 = ("commsMessage: 4", "messageSelf: MESSAGE_3");
		MESSAGE_3 = ("commsMessage: 3", "messageSelf: MESSAGE_2");
		MESSAGE_2 = ("commsMessage: 2", "messageSelf: MESSAGE_1");
		MESSAGE_1 = ("commsMessage: [bomb-last-words]", "setStateTo: DEFUSE_CHANCE");
		UPDATE = ("pauseAI: 2.0");
	};
as long as is is no reactToMessage but a plain message
User avatar
JensAyton
Grand Admiral Emeritus
Grand Admiral Emeritus
Posts: 6657
Joined: Sat Apr 02, 2005 2:43 pm
Location: Sweden
Contact:

Post by JensAyton »

But that messes with the purity of the state machine model! (Not that it’s very pure as it stands.)

Seriously, though, I’m thinking exitAIWithMessage:, with exitAI being an alias for exitAIWithMessage: RESTARTED, and messageSelf: as well as icing.
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 »

Ahruman wrote:
and messageSelf: as well as icing.
Very nice icing indeed. I now realise it is a command I was already searching for. It would allow for all kinds of delayed actions without the need of switching states, like:

Code: Select all

        "INCOMING_MISSILE" = ("messageSelf: FIGHT_MISSILE", "pauseAI:2.0"); 
        "FIGHT_MISSILE" = (fightOrFleeMissile, "setStateTo: FLEE"); 
It works as long as you stay aware that other actions, like an attack, could have switched the state before a next update. So an attack state should also be able to act on that FIGHT_MISSILE message.

With a variable pause you than even could randomise the response time. That would be better than en external state for a delayed missile response because on switching AI you could loose other pending messages to react upon.
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 »

I notice a problem with traders and their escorts. I have "new 1.72 only AI.oxp" installed.

If I attack one escort of a trader, the mother turns red and sends out distress messages. However, the other escorts stay yellow and just continue escorting their mother. They don't get me as a target at all. Therefore I can very conveniently slaughter the escorts one after the other, without anybody firing any shot at me, and finally kill the mother.

In some other cases about half of the escorts go after me (but notably the one I am attacking in most cases does not defend itself). Still as an attacker I can feel quite safe.
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 »

Commander McLane wrote:
If I attack one escort of a trader, the mother turns red and sends out distress messages. However, the other escorts stay yellow and just continue escorting their mother.
This behaviour has not changed with this new AI, it is hard coded in the function deployEscorts. This function is also called when using fightOrFleeHostiles. deployEscorts sends a random number between 1 and max escorts after the attacker. When called a second time and the target has not changed it does nothing.

Problem is that defending against a player needs a different approach than defending against a npc pirate. Against a pirate it is a good strategy to let some of the escorts close to the ship for a later meeting with an other pirate. At the end the deployed escorts will draw all pirate attention and the mother can flee.
Against a player it should deploy anything it has to make a change at all. Escorts are programmed to not react themselves when performing escort. I don't want to change that.

---
In the meantime I found the reason why pirate ships sometimes start fighting against a non-existing target when the player stays cloaked. First it finds the cloaked player and immediately looses it. The TARGET_FOUND and the TARGET_LOST are both set for the next update event. TARGET_FOUND triggers the checkGroupOddsVersusTarget command while the TARGET_LOST sends it to the TRAVEL_TO_LURK_AREA state. Some fast ships travel the 1500m in this state before an update happens (Next update was set at 5 seconds in LURK). Than it returns back to LURK and only than receives the ODDS_GOOD message that sent him in an attack against the long lost target. I now set the pause very low so the ODDS_GOOD message arrives during the TRAVEL_TO_LURK_AREA update were it will be ignored.

Code: Select all

    LURK = {
        ENTER = ("setSpeedTo: 0.0", performIdle); 
        ATTACKED = (setTargetToPrimaryAggressor, "setStateTo: ATTACK_SHIP"); 
       "ATTACKED_BY_CLOAKED" = ("setStateTo: FLEE_FOR_CLOAKED"); 
	"TARGET_LOST" = ("setStateTo: TRAVEL_TO_LURK_AREA", "pauseAI: 0.5"); <---
        "INCOMING_MISSILE" = (fightOrFleeMissile, "setStateTo: FLEE"); 
        "NOTHING_FOUND" = ("setStateTo: COLLECT_LOOT"); 
        "TARGET_FOUND" = (setTargetToFoundTarget, checkGroupOddsVersusTarget); 
        "CARGO_SCOOPED" = ("setStateTo: CHECK_CARGO"); 
        "ODDS_GOOD" = (groupAttackTarget); 
        "ODDS_LEVEL" = (groupAttackTarget); 
        "GROUP_ATTACK_TARGET" = (setTargetToFoundTarget, "setStateTo: ATTACK_SHIP"); 
		"ENTER WORMHOLE" = ("setStateTo: ENTER_WORMHOLE");
        UPDATE = (scanForRandomMerchantmen, "pauseAI: 5.0"); 
    }; 
User avatar
LittleBear
---- E L I T E ----
---- E L I T E ----
Posts: 2869
Joined: Tue Apr 04, 2006 7:02 pm
Location: On a survey mission for GalCop. Ship: Cobra Corvette: Hidden Dragon Rated: Deadly.

Post by LittleBear »

On the subject of AI bugs, I don't think the docking AI is working quite right. Its meant to exit the AI when attacked, but when attacking docking ships they keep docking whilst I attack them ignoring the attack and continuing to try to dock.
OXPS : The Assassins Guild, Asteroid Storm, The Bank of the Black Monks, Random Hits, The Galactic Almanac, Renegade Pirates can be downloaded from the Elite Wiki here.
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 »

LittleBear wrote:
On the subject of AI bugs, I don't think the docking AI is working quite right. Its meant to exit the AI when attacked, but when attacking docking ships they keep docking whilst I attack them ignoring the attack and continuing to try to dock.
Since 1.72 docking ships do start to react on an attack in some stages of their AI. But only in a few. When you have installed my newAI it should react in most of the cases. I still have not added it in all the final docking stages. In the final approach it switches between two states. I added the attack response only in one of both to get a kind of random factor. It will only stay 2 seconds in that state were attacks are ignored and than will jump to a state were it will react.

It is still a gamble. An AI cant' take dedicate decisions. e.g. continue those last meters to dock safely or respond to the attack. And this attack reactions will also put ships without lasers in an attack state.

When attacked by a npc ship it is often more wise to continue the docking. Still in my believe ships should break off the docking because the game is about the player and when he attack a ship should react. (Whit JS you could instruct to only react on player attacks while docking but not in AI scripting)
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 »

Eric Walch wrote:
Commander McLane wrote:
If I attack one escort of a trader, the mother turns red and sends out distress messages. However, the other escorts stay yellow and just continue escorting their mother.
This behaviour has not changed with this new AI, it is hard coded in the function deployEscorts. This function is also called when using fightOrFleeHostiles. deployEscorts sends a random number between 1 and max escorts after the attacker. When called a second time and the target has not changed it does nothing.
No, the problem is a little different (at least with your revised AIs OXP). When attacking an escort the mother receives the ATTACKED message and goes into traderInterceptAI. However, it does not get a target. Therefore it gets stuck in the GLOBAL state of traderInterceptAI. It can't perform fightOrFleeHostiles if it doesn't see any hostiles.

Inserting a setTargetToPrimaryAggressor in front of the fightOrFleeHostiles solved the problem for me, but unfortunately not consistently. Still sometimes the mother gets stuck in the GLOBAL state with no target. Probably the target should be set in the ATTACKED states of route1traderAI instead?

I think you have to do some more trials. But at least now you have a starting point.
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 »

Commander McLane wrote:
No, the problem is a little different (at least with your revised AIs OXP). When attacking an escort the mother receives the ATTACKED message and goes into traderInterceptAI. However, it does not get a target. Therefore it gets stuck in the GLOBAL state of traderInterceptAI. It can't perform fightOrFleeHostiles if it doesn't see any hostiles....I think you have to do some more trials. But at least now you have a starting point.
Yes, I noticed yesterday for the first time such a trader stuck in global. It only starts traderInterceptAI when it has found a target. And fightOrFleeHostiles always returns one of the three options when called when there is a target. Somehow the target got lost during the switch. In that state I didn't check for a TARGET_LOST or TARGET_DESTROYED. I now added both to the global state.
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 »

I re-looked the code of fightOrFleeHostiles. It contains:

Code: Select all

- (void) fightOrFleeHostiles
{
	if ([self hasEscorts])
	{
		if (found_target == last_escort_target)  return; <----
		
		primaryAggressor = found_target;
		primaryTarget = found_target;
		[self deployEscorts];
		[shipAI message:@"DEPLOYING_ESCORTS"];
		[shipAI message:@"FLEEING"];
		return;
	}
There is a condition that lets it returns without issuing a message and my code hangs. This condition can happen when fightOrFleeHostiles is called a second time for the same hostile target.
Using a setTargetToPrimaryAggressor will do nothing in this case.

I look if I can do something with the update event. In the other case I will request that also a message is sent on returning. e.g. KNOWN_HOSTILE

EDIT: Probably only a FLEEING message would also do.
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 »

Commander McLane wrote:
No, the problem is a little different (at least with your revised AIs OXP). When attacking an escort the mother receives the ATTACKED message and goes into traderInterceptAI. However, it does not get a target. Therefore it gets stuck in the GLOBAL state of traderInterceptAI. It can't perform fightOrFleeHostiles if it doesn't see any hostiles.
I added a new state to the traderInterceptAI that now catches the messages from fightOrFleeHostiles. In case fightOrFleeHostiles gives no answer the UPDATE of this state will execute. When fightOrFleeHostiles does give an answer it never executes the UPDATE. This way is will not hang in 1.72. I updated the oxp on the box.new 1.72 AI's

For 1.73 the addition can be removed again and fightOrFleeHostiles itself should be changed to always give an answer.
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 »

I updated my new AI file. I added an update to the ABORT state. For some reason docking ships sometimes hang in the "performFaceDestination" behaviour. Ship does not move at all and the "FACING_DESTINATION" message is never send. According to the C-code this could never happen, but it does. Probably the ship is facing exact in the right direction or exact in the opposite direction when starting. And maybe it only happens with low FPS counts. Anyhow, with an update we have a backup mechanism. When not turned by itself within 10 seconds it always starts flying to its destination.

This is a behaviour I only noticed since 1.72 but maybe it did happen with earlier versions. It is most noticeable when I leave the computer on its own for longer times. There are often several ships hanging in this state. When I fly very close to such a ship, they jump into the "avoidCollision" behaviour. When it than falls back to "performFaceDestination", the AI proceeds as it should had in the first place.
Those ship are extra noticeable when launching. A launch takes 10 minutes game time. To simulate this past time further, Oolite docks simultaneously all ships on-approach and all ships waiting to approach. Ships in the abort state are on none of those lists thus stay around the station.

Am I the only one with this problem? Anyhow the backup mechanism in this new dockingAI works on my computer.

New 1.72 AI's
Post Reply