Just when I thought I was out...

Discussion and information relevant to creating special missions, new ships, skins etc.

Moderators: another_commander, winston

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 added sendScriptMessage: to the AI methods wiki page this morning. It calls a method on the same ship as the AI belong to. “Send” was probably a bad choice of name; it comes from an implementation perspective, where the ship, the AI and the script are three different objects, sending messages to each other.
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 »

Roberto wrote:
After destroying the Frigate, the defence ship I was monitoring switched to the docking AI as intended, but promptly got stuck in "AWAIT_COORDS". Here's the AI in full (apologies for length of code):
I just looked beter at your code. In "GLOBAL" you don't define a target (like the station) before you request the docking coordinates. So no coordinates are transmitted to the "AWAIT_COORDS" state and it will wait forever.
User avatar
Roberto
---- E L I T E ----
---- E L I T E ----
Posts: 318
Joined: Sun Jun 11, 2006 1:16 pm
Location: London, UK

Post by Roberto »

Thanks guys - I'll give this stuff a try later on tonight.
User avatar
Roberto
---- E L I T E ----
---- E L I T E ----
Posts: 318
Joined: Sun Jun 11, 2006 1:16 pm
Location: London, UK

Post by Roberto »

OK, after two months away from this (my connection went for a few days, and by the time it was back up, I was on to other things!), I'm ready to resume trying to figure out how to get ships docking at my station :)

Eric, your last suggestion was to define the target - I did this and it did seem to help, as I then witnessed a ship docking correctly (it was wondrous to behold!). However, none of the other escort ships managed to follow suit - I remember seeing one circling round and round the station, but not achieving anything.

*EDIT* Just ran another test - and this time I saw two ships docking correctly (after getting in each other's way for a bit!), but there was another that just sat there, stuck in the ABORT state. Not sure why.

Here's the code as it now stands (apologies for the length) - basically, can any of you AI experts see where I'm going wrong?

Code: Select all

{
    GLOBAL = {
        ENTER = (setTargetToStation, "setDesiredRangeTo: 6000.0", checkForMotherStation, performIntercept); 
        EXIT = (); 
        "DESIRED_RANGE_ACHIEVED" = ("setSpeedTo: 0.0", requestDockingCoordinates, "setStateTo: AWAIT_COORDS"); 
        "NOTHING_FOUND" = ("setStateTo: RECALL"); 
        "MOTHER_LOST" = ("setStateTo: RECALL"); 
        "STATION_FOUND" = ("setSpeedTo: 0.0", requestDockingCoordinates, "setStateTo: AWAIT_COORDS"); 
        ATTACKED = (setTargetToPrimaryAggressor, "setAITo: taranisDefenderAI.plist"); 
        "INCOMING_MISSILE" = (fightOrFleeMissile, setTargetToPrimaryAggressor, "setAITo: taranisDefenderAI.plist"); 
        "GROUP_ATTACK_TARGET" = (setTargetToFoundTarget, "setAITo: taranisDefenderAI.plist"); 
        UPDATE = (checkForMotherStation); 
    }; 
    "AWAIT_COORDS" = {
        "APPROACH" = ("setStateTo: APPROACH"); 
        "APPROACH_COORDINATES" = ("setStateTo: GO_TO_COORDS"); 
        "BACK_OFF" = ("setStateTo: RETREAT"); 
        "HOLD_POSITION" = ("setStateTo: RETREAT"); 
        "DOCKING_ABORTED" = ("setStateTo: ABORT"); 
        "TRY_AGAIN_LATER" = ("pauseAI: 30.0", "setStateTo: ABORT"); 
        "COLLISION" = ("setStateTo: ABORT"); 
        "RESTART_DOCKING" = ("setStateTo: GLOBAL"); 
        DOCKED = ("setStateTo: EXIT_SYSTEM"); 
        ATTACKED = (setTargetToPrimaryAggressor, "setAITo: taranisDefenderAI.plist"); 
        "INCOMING_MISSILE" = (fightOrFleeMissile, setTargetToPrimaryAggressor, "setAITo: taranisDefenderAI.plist"); 
        "GROUP_ATTACK_TARGET" = (setTargetToFoundTarget, "setAITo: taranisDefenderAI.plist"); 
        ENTER = (); 
        EXIT = (); 
        UPDATE = (); 
    }; 
    APPROACH = {
        ENTER = (recallDockingInstructions, "setSpeedFactorTo: 1.0", performFlyToRangeFromDestination); 
        "DESIRED_RANGE_ACHIEVED" = (requestDockingCoordinates, "setStateTo: AWAIT_COORDS"); 
        "DOCKING_ABORTED" = ("setStateTo: ABORT"); 
        "COLLISION" = ("setStateTo: ABORT"); 
        "RESTART_DOCKING" = ("setStateTo: GLOBAL"); 
        ATTACKED = (setTargetToPrimaryAggressor, "setAITo: taranisDefenderAI.plist"); 
        "INCOMING_MISSILE" = (fightOrFleeMissile, setTargetToPrimaryAggressor, "setAITo: taranisDefenderAI.plist"); 
        "GROUP_ATTACK_TARGET" = (setTargetToFoundTarget, "setAITo: taranisDefenderAI.plist"); 
        EXIT = (); 
        UPDATE = (); 
    }; 
    RETREAT = {
        ENTER = (recallDockingInstructions, "setSpeedTo: 0.0", setDestinationToDockingAbort, performFaceDestination); 
        "FACING_DESTINATION" =  ("setSpeedFactorTo: 1.0", "setDesiredRangeTo: 500.0", performFlyToRangeFromDestination); 
        "DESIRED_RANGE_ACHIEVED" = ("setSpeedTo: 0.0", requestDockingCoordinates, "setStateTo: AWAIT_COORDS"); 
        "DOCKING_ABORTED" = ("setStateTo: ABORT"); 
        "COLLISION" = ("setStateTo: ABORT"); 
        "RESTART_DOCKING" = ("setStateTo: GLOBAL"); 
        ATTACKED = (setTargetToPrimaryAggressor, "setAITo: taranisDefenderAI.plist"); 
        "INCOMING_MISSILE" = (fightOrFleeMissile, setTargetToPrimaryAggressor, "setAITo: taranisDefenderAI.plist"); 
        "GROUP_ATTACK_TARGET" = (setTargetToFoundTarget, "setAITo: taranisDefenderAI.plist"); 
        EXIT = (); 
        UPDATE = (); 
    }; 
    "GO_TO_COORDS" = {
        ENTER = (performFaceDestination);
        FRUSTRATED = ("setSpeedTo: 0.0", performFaceDestination); 
        "FACING_DESTINATION" = (recallDockingInstructions, performFlyToRangeFromDestination); 
        "DESIRED_RANGE_ACHIEVED" = (requestDockingCoordinates, "setStateTo: AWAIT_COORDS"); 
        "DOCKING_ABORTED" = ("setStateTo: ABORT"); 
        "COLLISION" = ("setStateTo: ABORT"); 
        "RESTART_DOCKING" = ("setStateTo: GLOBAL"); 
        ATTACKED = (setTargetToPrimaryAggressor, "setAITo: taranisDefenderAI.plist"); 
        "INCOMING_MISSILE" = (fightOrFleeMissile, setTargetToPrimaryAggressor, "setAITo: taranisDefenderAI.plist"); 
        "GROUP_ATTACK_TARGET" = (setTargetToFoundTarget, "setAITo: taranisDefenderAI.plist"); 
        EXIT = (); 
        UPDATE = ();
    };
    ABORT = {
        ENTER = (abortDocking, "setSpeedTo: 0.0", setDestinationToDockingAbort, "setDesiredRangeTo: 500.0", performFaceDestination); 
        "FACING_DESTINATION" = ("setSpeedFactorTo: 1.0", "setDesiredRangeTo: 500.0", performFlyToRangeFromDestination); 
        "RESTART_DOCKING" = ("setStateTo: GLOBAL"); 
        "REACHED_SAFETY" = (performIdle, "setStateTo: GLOBAL"); 
        "DESIRED_RANGE_ACHIEVED" = (performIdle, "setStateTo: GLOBAL"); 
        ATTACKED = (setTargetToPrimaryAggressor, "setAITo: taranisDefenderAI.plist"); 
        "INCOMING_MISSILE" = (fightOrFleeMissile, setTargetToPrimaryAggressor, "setAITo: taranisDefenderAI.plist"); 
        "GROUP_ATTACK_TARGET" = (setTargetToFoundTarget, "setAITo: taranisDefenderAI.plist"); 
        UPDATE = (); 
        EXIT = (); 
    }; 
    RECALL = {
	ENTER = ("setCoordinates: pwm 145000 -29000 60500", setDestinationFromCoordinates, "setDesiredRangeTo: 50.0", checkCourseToDestination);
	"COURSE_OK" = ("setSpeedFactorTo: 1.0", performFlyToRangeFromDestination);
	"WAYPOINT_SET" = ("setAITo: gotoWaypointAI.plist");
	"DESIRED_RANGE_ACHIEVED" = ("setStateTo: GLOBAL");
        ATTACKED = (setTargetToPrimaryAggressor, "setAITo: taranisDefenderAI.plist"); 
        "INCOMING_MISSILE" = (fightOrFleeMissile, setTargetToPrimaryAggressor, "setAITo: taranisDefenderAI.plist"); 
        "GROUP_ATTACK_TARGET" = (setTargetToFoundTarget, "setAITo: taranisDefenderAI.plist"); 
	UPDATE = (setDestinationFromCoordinates, checkCourseToDestination);
        EXIT = (); 
    }; 
    "EXIT_SYSTEM" = {ENTER = (performDocking, exitAI); EXIT = (); UPDATE = (); }; 
} 
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 »

Roberto wrote:
Eric, your last suggestion was to define the target - I did this and it did seem to help, as I then witnessed a ship docking correctly (it was wondrous to behold!). However, none of the other escort ships managed to follow suit - I remember seeing one circling round and round the station, but not achieving anything.
When the ship has escorts you must explicit order them to also dock. You do it with the command: dockEscorts. When the ship has no escorts, this command does not do any harm, so just use it always when there is a possibility for escorts. I added it to your global state:

Code: Select all

    GLOBAL = { 
        ENTER = (setTargetToStation, "setDesiredRangeTo: 6000.0", checkForMotherStation, performIntercept); 
        EXIT = (); 
        "DESIRED_RANGE_ACHIEVED" = ("setSpeedTo: 0.0", requestDockingCoordinates, "setStateTo: AWAIT_COORDS"); 
        "NOTHING_FOUND" = ("setStateTo: RECALL"); 
        "MOTHER_LOST" = ("setStateTo: RECALL"); 
        "STATION_FOUND" = (dockEscorts,"setSpeedTo: 0.0", requestDockingCoordinates, "setStateTo: AWAIT_COORDS"); 
        ATTACKED = (setTargetToPrimaryAggressor, "setAITo: taranisDefenderAI.plist"); 
        "INCOMING_MISSILE" = (fightOrFleeMissile, setTargetToPrimaryAggressor, "setAITo: taranisDefenderAI.plist"); 
        "GROUP_ATTACK_TARGET" = (setTargetToFoundTarget, "setAITo: taranisDefenderAI.plist"); 
        UPDATE = (checkForMotherStation); 
    }; 

The system will now give all your escorts a "dockingAI.plist" and the mother has now lost control of the escorts. They dock by themselves. But when the mother breaks the docking procedure to engage an attack it can not summon the escorts anymore. You can also decide to place the "dockEscorts" later in the code, just before docking.
User avatar
Roberto
---- E L I T E ----
---- E L I T E ----
Posts: 318
Joined: Sun Jun 11, 2006 1:16 pm
Location: London, UK

Post by Roberto »

Cheers, Eric. I think I expressed myself badly, though - this is the AI for the escort ships themselves (the Mother being the Taranis station). I assume dockEscorts would only work in the station's AI. In any case, I'd rather the escorts remained "under control" at all times if possible.

The thing is, the AI as it stands does work - just not in every instance. Could there be some reason why ships might sometimes have difficulty doing a performFaceDestination (in ABORT)? The station is pretty large - might increasing the setDesiredRangeTo figure make a difference somehow? Could the billboard I've added opposite the station entrance (pretty far out, though) somehow be causing confusion?
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 »

Roberto wrote:
Could there be some reason why ships might sometimes have difficulty doing a performFaceDestination (in ABORT)? The station is pretty large
No, docking abort sends the ship co-ordinates on 8000 meters from the station. Your script is telling to go in that direction until 500 meters from that point (= 7500 meters away from the station). Should be enough, even for a very large station.

Two other bugs:
In AWAIT_COORDINATES you write:

Code: Select all

"HOLD_POSITION" = ("setStateTo: RETREAT"); 
?? The ship should wait, not retreat.

In several states you use "setAI". I assume you return from that AI with an exitAI. Than it falls back in this previous state. However a lot have no update event and will do nothing. Without an update the states need a "RESTARTED" message. This is triggered when returning from an other AI. You can than jump to the first GLOBAL state:

Code: Select all

"RESTARTED" = ("setStateTo: GLOBAL")
User avatar
Roberto
---- E L I T E ----
---- E L I T E ----
Posts: 318
Joined: Sun Jun 11, 2006 1:16 pm
Location: London, UK

Post by Roberto »

I'll have a look at AWAIT_COORDINATES tonight (I believe I copied that "HOLD_POSITION" line from somewhere - is it even necessary?).

I'm using setAI in this to return the ships to their "fighting" AI (if faced with a new aggressor); when the fighting is over, setAI should (I hope) switch them back to docking again (am I right in assuming I don't *have* to use exitAI?). Since they'll likely end up somewhere else entirely as a result of the fighting, it makes sense to me that they should restart docking from the beginning (i.e. GLOBAL) every time.

ABORT seems to be the state the ships get stuck in, if they get stuck at all. I hope they're not taking performIdle too literally! I can see how jumping straight to that state from another AI might possible cause a problem (they might not be able to define where DockingAbort is?) - but I don't see how that could happen, given that I'm not using exitAI.

Are you certain there isn't any issue with ships being assigned a DockingAbort position that's (depending on where they are) the other side of the floating billboard?
User avatar
Roberto
---- E L I T E ----
---- E L I T E ----
Posts: 318
Joined: Sun Jun 11, 2006 1:16 pm
Location: London, UK

Post by Roberto »

A thought: if there's no way of preventing some of the ships from getting "stuck" in ABORT, is there some way I could get the AI to recognise a long delay (and thereby get it to switch states in such cases?).
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 »

Roberto wrote:
A thought: if there's no way of preventing some of the ships from getting "stuck" in ABORT, is there some way I could get the AI to recognise a long delay (and thereby get it to switch states in such cases?).
It should always have an outcome.It is turning to the coordinates and than flying to that destination. It should never been waiting for something.

Code: Select all

    ABORT = { 
        ENTER = (abortDocking, "setSpeedTo: 0.0", setDestinationToDockingAbort, "setDesiredRangeTo: 500.0", performFaceDestination); 
        "FACING_DESTINATION" = ("setSpeedFactorTo: 1.0", "setDesiredRangeTo: 500.0", performFlyToRangeFromDestination); 
        "DESIRED_RANGE_ACHIEVED" = (performIdle, "setStateTo: GLOBAL");
        "FRUSTRATED" = (performIdle, "setStateTo: GLOBAL");
You could add the line "FRUSTRATED" to the above conditions. When the ship for some reason is not able to turn in the "FACING_DESTINATION" within a certain time it will issue a "FRUSTRATED" message.
User avatar
Roberto
---- E L I T E ----
---- E L I T E ----
Posts: 318
Joined: Sun Jun 11, 2006 1:16 pm
Location: London, UK

Post by Roberto »

OK, I've added a FRUSTRATED line to ABORT, and it seemed to work (I counted them all out, and I counted them all back!). However, I then tested it again to be sure, and annoyingly, two of the five ships got "stuck" again.

On the second occasion, the aggressor ship was destroyed before all of them had launched... but I don't think that can be a factor, as it's not the "attack" AI they're getting stuck in, but the docking AI (which they all switch to when there's no viable target, as it were).

Here are a few lines from the log file, or whatever it's called, relating to one of the ships:

Code: Select all

[dumpState.shipEntity]: Name: Outrider
  [dumpState.shipEntity]: Roles: <OORoleSet 0x14f8b010>{taranis_defender}
  [dumpState.shipEntity]: Primary role: defense_ship
  [dumpState.shipEntity]: Script: <OOJSScript 0x271bf940>{"oolite-default-ship-script" version 1.70}
  [dumpState.shipEntity]: Subentity count: 2
  [dumpState.shipEntity]: Behaviour: BEHAVIOUR_FACE_DESTINATION
  [dumpState.shipEntity]: Target: <StationEntity 0x310f2000>{"Taranis Corporation HQ" "Taranis Corporation HQ" ID: 301 position: (-45162.5, 144264, 414078) scanClass: CLASS_STATION status: STATUS_IN_FLIGHT}
  [dumpState.shipEntity]: Destination: (-40906.5, 138047, 416767)
  [dumpState.shipEntity]: Other destination: (-40906.5, 138047, 416767)
  [dumpState.shipEntity]: Waypoint count: 0
  [dumpState.shipEntity]: Desired speed: 0
  [dumpState.shipEntity]: Fuel: 70
  [dumpState.shipEntity]: Fuel accumulator: 1
  [dumpState.shipEntity]: Missile count: 2
  [dumpState.shipEntity.ai]: AI:
    [dumpState.ai]: State machine name: taranisDockingAI.plist
    [dumpState.ai]: Current state: ABORT
    [dumpState.ai]: Next think time: 1288.2
    [dumpState.ai]: Next think interval: 1288.2
  [dumpState.shipEntity]: Frustration: 0
  [dumpState.shipEntity]: Success factor: 500.133
  [dumpState.shipEntity]: Shots fired: 0
  [dumpState.shipEntity]: Time since shot: 101101
  [dumpState.shipEntity]: Spawn time: 181.212 (1106.88 seconds ago)
  [dumpState.shipEntity]: Hull temperature: 60
  [dumpState.shipEntity]: Heat insulation: 1
  [dumpState.shipEntity]: Flags: has_ecm, has_fuel_injection, escortsAreSetUp, pitching_over, isFrangible
Is there anything there that would suggest why it's not moving? (Would that I had a frustration of zero on this matter!)

I haven't done anything about the "HOLD_POSITION" line in AWAIT_COORDINATES yet, because I don't know what I'm meant to do (delete it?), and in any case, I don't think that's the problem.
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 »

Roberto wrote:
Is there anything there that would suggest why it's not moving? (Would that I had a frustration of zero on this matter!)
The target dump clearly shows it is hanging in the Behaviour: BEHAVIOUR_FACE_DESTINATION

My comment about frustration was wrong I think. I looked in the code. Although it sets frustration to zero, it is not raising it. (maybe this should be added to the code). Most behaviour routines raise the frustration to a level that normally never triggers the "FRUSTRATED" message. It is a good way to get out of a routine it is stuck in.

But the question is why it is not turning to the destination. Maybe they are to close to something (I don't know what pitching_over means but is is not a normal message)

I know that when you are very close to a ship and his AI is telling him to move, it also does not move. But than there is an collision_alert message at the end.

The only answer I can give is, not wait for the "FACING_DESTINATION" if it takes too long.

copy the content of FACING_DESTINATION to UPDATE = ("setSpeedFactorTo: 1.0", "setDesiredRangeTo: 500.0", performFlyToRangeFromDestination, "pauseAI: 10");
And set an "pauseAI: 10" in ENTER. The only reason not directly fly away is not to ram anything but first letting the ship turn in the right direction. But on putting the performFlyToRangeFromDestination also in update is will only wait 10 seconds for the turn and than fly off.
User avatar
Roberto
---- E L I T E ----
---- E L I T E ----
Posts: 318
Joined: Sun Jun 11, 2006 1:16 pm
Location: London, UK

Post by Roberto »

Thanks Eric. I made that change and a similar one in RETREAT, and also lowered some of the speeds to reduce the (slight) risk of collision. I tried compensating for possible performFaceDestination issues in "GO_TO_COORDS", but sticking performFlyToRangeFromDestination in UPDATE seemed to make the ships too reckless, and adding pauses destroyed the elegance of the final approach! So, unless there's something clever I haven't thought of, I think I've pushed this AI as far as I can. Which is probably far enough, given that I've only witnessed one ship getting stuck in "GO_TO_COORDS" so far, and overall the ships are behaving with more "intelligence" than I've seen before in Oolite.

I've no idea why performFaceDestination doesn't always seem to work. I can understand why it wouldn't if the ship were very close to another object, but a FRUSTRATED line should take care of that - and in the one instance I had of a ship getting stuck in "GO_TO_COORDS", it didn't. Oh well - it's beyond my control, as the Vicomte de Valmont would say. :)

Here's the revised code for RETREAT, "GO_TO_COORDS" and ABORT anyway:

Code: Select all

 RETREAT = {
        ENTER = (recallDockingInstructions, "setSpeedTo: 0.0", setDestinationToDockingAbort, performFaceDestination, "pauseAI: 10"); 
        "FACING_DESTINATION" =  ("setSpeedFactorTo: 0.5", "setDesiredRangeTo: 500.0", performFlyToRangeFromDestination); 
        "DESIRED_RANGE_ACHIEVED" = ("setSpeedTo: 0.0", requestDockingCoordinates, "setStateTo: AWAIT_COORDS"); 
        "DOCKING_ABORTED" = ("setStateTo: ABORT"); 
        "COLLISION" = ("setStateTo: ABORT"); 
        "RESTART_DOCKING" = ("setStateTo: GLOBAL"); 
        ATTACKED = (setTargetToPrimaryAggressor, "setAITo: taranisDefenderAI.plist"); 
        "INCOMING_MISSILE" = (fightOrFleeMissile, setTargetToPrimaryAggressor, "setAITo: taranisDefenderAI.plist"); 
        "GROUP_ATTACK_TARGET" = (setTargetToFoundTarget, "setAITo: taranisDefenderAI.plist"); 
        EXIT = (); 
        UPDATE = ("setSpeedFactorTo: 1.0", "setDesiredRangeTo: 500.0", performFlyToRangeFromDestination, "pauseAI: 10"); 
    }; 
    "GO_TO_COORDS" = {
        ENTER = (performFaceDestination);
        FRUSTRATED = ("setSpeedTo: 0.0", performFaceDestination); 
        "FACING_DESTINATION" = (recallDockingInstructions, performFlyToRangeFromDestination); 
        "DESIRED_RANGE_ACHIEVED" = (requestDockingCoordinates, "setStateTo: AWAIT_COORDS"); 
        "DOCKING_ABORTED" = ("setStateTo: ABORT"); 
        "COLLISION" = ("setStateTo: ABORT"); 
        "RESTART_DOCKING" = ("setStateTo: GLOBAL"); 
        ATTACKED = (setTargetToPrimaryAggressor, "setAITo: taranisDefenderAI.plist"); 
        "INCOMING_MISSILE" = (fightOrFleeMissile, setTargetToPrimaryAggressor, "setAITo: taranisDefenderAI.plist"); 
        "GROUP_ATTACK_TARGET" = (setTargetToFoundTarget, "setAITo: taranisDefenderAI.plist"); 
        EXIT = (); 
        UPDATE = ();
    };
    ABORT = {
        ENTER = (abortDocking, "setSpeedTo: 0.0", setDestinationToDockingAbort, "setDesiredRangeTo: 500.0", performFaceDestination, "pauseAI: 10"); 
        FRUSTRATED = ("setSpeedTo: 0.0", performFaceDestination); 
        "FACING_DESTINATION" = ("setSpeedFactorTo: 0.5", "setDesiredRangeTo: 500.0", performFlyToRangeFromDestination); 
        "RESTART_DOCKING" = ("setStateTo: GLOBAL"); 
        "REACHED_SAFETY" = (performIdle, "setStateTo: GLOBAL"); 
        "DESIRED_RANGE_ACHIEVED" = (performIdle, "setStateTo: GLOBAL"); 
        ATTACKED = (setTargetToPrimaryAggressor, "setAITo: taranisDefenderAI.plist"); 
        "INCOMING_MISSILE" = (fightOrFleeMissile, setTargetToPrimaryAggressor, "setAITo: taranisDefenderAI.plist"); 
        "GROUP_ATTACK_TARGET" = (setTargetToFoundTarget, "setAITo: taranisDefenderAI.plist"); 
        UPDATE = ("setSpeedFactorTo: 1.0", "setDesiredRangeTo: 500.0", performFlyToRangeFromDestination, "pauseAI: 10"); 
        EXIT = (); 
    }; 

With that more or less sorted, I've already run into my next AI problem, but hopefully this one will be easier to solve! I've modified the station's AI so it occasionally launches various types of "traffic":

Code: Select all

        "ROLL_1" = ("launchShipWithRole: taranis_traffic");
	"ROLL_2" = ("launchShipWithRole: taranis_traffic_nohyp"); 
	"ROLL_3" = ("addShips: taranis_traffic3 1"); 
	UPDATE = ("rollD: 15000", decreaseAlertLevel, "scanForNearestShipWithPrimaryRole: player"); 
Previously I had a "rollD: 5000" to launch just the one type of traffic, and ships were emerging at reasonable intervals, so you can see why I went up to 15000 (as I want the overall amount of traffic to remain about the same). However, when I went to the witchpoint to check that "ROLL_3" ships were emerging there... I saw no ships. I increased the probability and tried again, but still no joy.

I'm not sure whether I've made a mistake with addShips (I think it was LittleBear who said this can be used in an AI), or whether I've experienced that "random seed" thing inherent to the dice-rolling. If it's the latter, then how can I get around this? Should I perhaps use the JavaScript timer Ahruman suggested on page 3 of this thread, in conjunction with a lower rollD number? How low should this number be to avoid the "random seeding" problem?
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'm not sure whether I've made a mistake with addShips (I think it was LittleBear who said this can be used in an AI), or whether I've experienced that "random seed" thing inherent to the dice-rolling.
It can not be used. It is a player script command. Player script commands can only be used from within AI scripting with a "scriptActionOnTarget:" command. But that use should be discouraged as it had bad implications on overall performance. Only when used very occasionally you can use that command .
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 »

As of 1.71, scriptActionOnTarget: is deprecated in favour of using sendScriptMessage: and doing the work in the ship script. However, this has the disadvantage that it won’t work with 1.65, so I’ll forgive people for using scriptActionOnTarget: until the MNSR. :-)
Post Reply