Page 1 of 2

Drones OXP

Posted: Mon Aug 25, 2008 6:01 pm
by Thargoid
This OXP contains 3 versions of the drones:
  • Combat Drone - basic model, with laser only. Fired as a missile, should chase target and then let rip with its lasers.
  • Kamikaze Drone - upgrade on the Combat Drone to include a light warhead. At energy low or on a 1in10 chance, goes Banzai and becomes a missile.
  • Anti-Thargoid Drone - dropped as a mine, seeks out Thargoid targets and goes for the kill.
All have a limited range, after which they go inactive and can be scooped. Usually they are re-usable, but sometimes they break (that part is working).

This OXP is now part of Armoury OXP, which can be downloaded here.

[/color]

Posted: Mon Aug 25, 2008 8:26 pm
by Eric Walch
drones_kamikazeDroneAI.plist: in "BANZAI" state a missing "}" at the end. This will result in going nothing for this AI!


Your combat drone seems to work fine. It followed its target and went dead after it ran out of fuel as planned by AI. Last part of AI logfile:

Code: Select all

Oolite [ai.takeAction.takeAction] -[AI takeAction:] (AI.m:411): Combat Drone 242 to take action setDesiredRangeTo: 35000.0
Oolite [ai.takeAction.takeAction] -[AI takeAction:] (AI.m:411): Combat Drone 242 to take action checkDistanceTravelled
Oolite [ai.takeAction.takeAction] -[AI takeAction:] (AI.m:411): Combat Drone 242 to take action setSpeedFactorTo: 0.5
Oolite [ai.takeAction.takeAction] -[AI takeAction:] (AI.m:411): Combat Drone 242 to take action setDesiredRangeTo: 35000.0
Oolite [ai.takeAction.takeAction] -[AI takeAction:] (AI.m:411): Combat Drone 242 to take action checkDistanceTravelled
Oolite [ai.takeAction.takeAction] -[AI takeAction:] (AI.m:411): Combat Drone 242 to take action setSpeedFactorTo: 0.5
Oolite [ai.takeAction.takeAction] -[AI takeAction:] (AI.m:411): Combat Drone 242 to take action setDesiredRangeTo: 35000.0
Oolite [ai.takeAction.takeAction] -[AI takeAction:] (AI.m:411): Combat Drone 242 to take action checkDistanceTravelled
Oolite [ai.takeAction.takeAction] -[AI takeAction:] (AI.m:411): Combat Drone 242 to take action setSpeedFactorTo: 0.5
Oolite [ai.message.receive] -[AI reactToMessage:] (AI.m:353): AI drones_combatDroneAI.plist for Combat Drone 242 in state 'ATTACK_SHIP' receives message 'GONE_BEYOND_RANGE'
Oolite [ai.takeAction.takeAction] -[AI takeAction:] (AI.m:411): Combat Drone 242 to take action setStateTo: OUT_OF_GAS
  Oolite [ai.message.receive] -[AI reactToMessage:] (AI.m:353): AI drones_combatDroneAI.plist for Combat Drone 242 in state 'ATTACK_SHIP' receives message 'EXIT'
  Oolite [ai.message.receive] -[AI reactToMessage:] (AI.m:353): AI drones_combatDroneAI.plist for Combat Drone 242 in state 'OUT_OF_GAS' receives message 'ENTER'
  Oolite [ai.takeAction.takeAction] -[AI takeAction:] (AI.m:411): Combat Drone 242 to take action commsMessage: Combat drone ready for pick-up - out of fuel.
  Oolite [ai.takeAction.takeAction] -[AI takeAction:] (AI.m:411): Combat Drone 242 to take action switchLightsOff
  Oolite [ai.takeAction.takeAction] -[AI takeAction:] (AI.m:411): Combat Drone 242 to take action performIdle
  Oolite [ai.takeAction.takeAction] -[AI takeAction:] (AI.m:411): Combat Drone 242 to take action becomeUncontrolledThargon
I noticed the "commsMessage:" is not displayed. That's new in 1.71. Only objects with pilots can use this command. Through a bug in all previous versions a missile had a pilot, stange but true. In 1.72 you now need the command: "commsMessageByUnpiloted:". I recently updated the wiki for that. however, no messages in 1.71 unless you explicit put a pilot in the missile but that needs the creation of an character.plist Just setting "unpilotted" to "NO" didn't work for me, adding a character did. (for an other oxp. To be precise: the fuelpods from AH's CargoWreck that was uploaded yesterday).

Basically the AI works, It comes in an attackTarget state and the target is right. That it is not firing a laser has an other cause that has nothing to do with the AI. Maybe scanclass missile never fires lasers? Does the drone attack ships when you add it with a pirateAI.plist?

Posted: Mon Aug 25, 2008 9:08 pm
by Thargoid
Thanks. I'll upload a minor tweak to add the }; I was playing with the file just before I uploaded, must have accidentally removed it.

In fact the comms messages were working here. It seems if I put them as the first command in the action, then they work, but if they're after another one then they don't. Plus if there is an urgent command in the line then they also don't work (hence why the Banzai state came back). I saw the new comms for unpiloted's in the wiki, but as it's listed as 1.72 I can't try it yet (I'm still on 1.71.2).

I'll try the pirateAI test tomorrow and see what results I get.

Thanks for the testing for me, good to know the AI is doing as I thought, even if it's not quite doing what I hoped. At least my AI coding skills are improving (braces notwithstanding).

Posted: Mon Aug 25, 2008 9:16 pm
by Eric Walch
Your kamakaze drone AI is basically working. However, rolling dices is going to fast. Without a pause it runs 8 times a second. This way you get much to fast in the BANZAY state. And setting speed when in a "performAttack" is useless. I changed setSpeed: into a pauseAI: 3 and got following dump. (I deleted the repeating parts, replaced it with: "[deletions]"). Studying such a log carefully also gives also more insight how the AI actually does its work.

Code: Select all

[deletions]
Oolite [ai.takeAction.takeAction] -[AI takeAction:] (AI.m:411): Kamikaze Drone 205 to take action setDesiredRangeTo: 35000.0
Oolite [ai.takeAction.takeAction] -[AI takeAction:] (AI.m:411): Kamikaze Drone 205 to take action checkDistanceTravelled
Oolite [ai.takeAction.takeAction] -[AI takeAction:] (AI.m:411): Kamikaze Drone 205 to take action setDesiredRangeTo: 5000.0
Oolite [ai.takeAction.takeAction] -[AI takeAction:] (AI.m:411): Kamikaze Drone 205 to take action pauseAI: 3.0
Oolite [ai.message.receive] -[AI reactToMessage:] (AI.m:353): AI drones_kamikazeDroneAI.plist for Kamikaze Drone 205 in state 'INTERCEPT_TARGET' receives message 'DESIRED_RANGE_ACHIEVED'
Oolite [ai.takeAction.takeAction] -[AI takeAction:] (AI.m:411): Kamikaze Drone 205 to take action setStateTo: ATTACK_SHIP
  Oolite [ai.message.receive] -[AI reactToMessage:] (AI.m:353): AI drones_kamikazeDroneAI.plist for Kamikaze Drone 205 in state 'INTERCEPT_TARGET' receives message 'EXIT'
  Oolite [ai.message.receive] -[AI reactToMessage:] (AI.m:353): AI drones_kamikazeDroneAI.plist for Kamikaze Drone 205 in state 'ATTACK_SHIP' receives message 'ENTER'
  Oolite [ai.takeAction.takeAction] -[AI takeAction:] (AI.m:411): Kamikaze Drone 205 to take action performAttack
Oolite [ai.takeAction.takeAction] -[AI takeAction:] (AI.m:411): Kamikaze Drone 205 to take action setDesiredRangeTo: 35000.0
Oolite [ai.takeAction.takeAction] -[AI takeAction:] (AI.m:411): Kamikaze Drone 205 to take action checkDistanceTravelled
Oolite [ai.takeAction.takeAction] -[AI takeAction:] (AI.m:411): Kamikaze Drone 205 to take action pauseAI: 3.0
Oolite [ai.takeAction.takeAction] -[AI takeAction:] (AI.m:411): Kamikaze Drone 205 to take action rollD: 10
  Oolite [ai.message.receive] -[AI reactToMessage:] (AI.m:353): AI drones_kamikazeDroneAI.plist for Kamikaze Drone 205 in state 'ATTACK_SHIP' receives message 'ROLL_6'
Oolite [ai.takeAction.takeAction] -[AI takeAction:] (AI.m:411): Kamikaze Drone 205 to take action setDesiredRangeTo: 35000.0
Oolite [ai.takeAction.takeAction] -[AI takeAction:] (AI.m:411): Kamikaze Drone 205 to take action checkDistanceTravelled
Oolite [ai.takeAction.takeAction] -[AI takeAction:] (AI.m:411): Kamikaze Drone 205 to take action pauseAI: 3.0
Oolite [ai.takeAction.takeAction] -[AI takeAction:] (AI.m:411): Kamikaze Drone 205 to take action rollD: 10
  Oolite [ai.message.receive] -[AI reactToMessage:] (AI.m:353): AI drones_kamikazeDroneAI.plist for Kamikaze Drone 205 in state 'ATTACK_SHIP' receives message 'ROLL_2'
[deletions]
Oolite [ai.takeAction.takeAction] -[AI takeAction:] (AI.m:411): Kamikaze Drone 205 to take action setDesiredRangeTo: 35000.0
Oolite [ai.takeAction.takeAction] -[AI takeAction:] (AI.m:411): Kamikaze Drone 205 to take action checkDistanceTravelled
Oolite [ai.takeAction.takeAction] -[AI takeAction:] (AI.m:411): Kamikaze Drone 205 to take action pauseAI: 3.0
Oolite [ai.takeAction.takeAction] -[AI takeAction:] (AI.m:411): Kamikaze Drone 205 to take action rollD: 10
  Oolite [ai.message.receive] -[AI reactToMessage:] (AI.m:353): AI drones_kamikazeDroneAI.plist for Kamikaze Drone 205 in state 'ATTACK_SHIP' receives message 'ROLL_1'
  Oolite [ai.takeAction.takeAction] -[AI takeAction:] (AI.m:411): Kamikaze Drone 205 to take action setStateTo: BANZAI
    Oolite [ai.message.receive] -[AI reactToMessage:] (AI.m:353): AI drones_kamikazeDroneAI.plist for Kamikaze Drone 205 in state 'ATTACK_SHIP' receives message 'EXIT'
    Oolite [ai.message.receive] -[AI reactToMessage:] (AI.m:353): AI drones_kamikazeDroneAI.plist for Kamikaze Drone 205 in state 'BANZAI' receives message 'ENTER'
    Oolite [ai.takeAction.takeAction] -[AI takeAction:] (AI.m:411): Kamikaze Drone 205 to take action commsMessage: Banzai!!
    Oolite [ai.takeAction.takeAction] -[AI takeAction:] (AI.m:411): Kamikaze Drone 205 to take action switchLightsOff
Oolite [ai.takeAction.takeAction] -[AI takeAction:] (AI.m:411): Kamikaze Drone 205 to take action switchAITo: hardMissileAI.plist
  Oolite [ai.stack.push] -[AI preserveCurrentStateMachine] (AI.m:188): Pushing state machine for <AI 0x502c270>{"drones_kamikazeDroneAI.plist" in state: "BANZAI" for Kamikaze Drone 205}
  Oolite [ai.message.receive] -[AI reactToMessage:] (AI.m:353): AI drones_kamikazeDroneAI.plist for Kamikaze Drone 205 in state 'GLOBAL' receives message 'ENTER'
  Oolite [ai.takeAction.takeAction] -[AI takeAction:] (AI.m:411): Kamikaze Drone 205 to take action setSpeedFactorTo: 1.0
  Oolite [ai.takeAction.takeAction] -[AI takeAction:] (AI.m:411): Kamikaze Drone 205 to take action setStateTo: ATTACK_SHIP
    Oolite [ai.message.receive] -[AI reactToMessage:] (AI.m:353): AI drones_kamikazeDroneAI.plist for Kamikaze Drone 205 in state 'GLOBAL' receives message 'EXIT'
    Oolite [ai.message.receive] -[AI reactToMessage:] (AI.m:353): AI drones_kamikazeDroneAI.plist for Kamikaze Drone 205 in state 'ATTACK_SHIP' receives message 'ENTER'
    Oolite [ai.takeAction.takeAction] -[AI takeAction:] (AI.m:411): Kamikaze Drone 205 to take action setDesiredRangeTo: 25.0
    Oolite [ai.takeAction.takeAction] -[AI takeAction:] (AI.m:411): Kamikaze Drone 205 to take action performIntercept
Oolite [ai.takeAction.takeAction] -[AI takeAction:] (AI.m:411): Kamikaze Drone 205 to take action setDesiredRangeTo: 30000.0
Oolite [ai.takeAction.takeAction] -[AI takeAction:] (AI.m:411): Kamikaze Drone 205 to take action checkDistanceTravelled
Oolite [ai.takeAction.takeAction] -[AI takeAction:] (AI.m:411): Kamikaze Drone 205 to take action setDesiredRangeTo: 25.0
Oolite [ai.takeAction.takeAction] -[AI takeAction:] (AI.m:411): Kamikaze Drone 205 to take action pauseAI: 5.0
[deletions]
Oolite [ai.message.receive] -[AI reactToMessage:] (AI.m:353): AI hardMissileAI.plist for Kamikaze Drone 205 in state 'ATTACK_SHIP' receives message 'GONE_BEYOND_RANGE'
Oolite [ai.takeAction.takeAction] -[AI takeAction:] (AI.m:411): Kamikaze Drone 205 to take action setStateTo: EXPLODE
  Oolite [ai.message.receive] -[AI reactToMessage:] (AI.m:353): AI hardMissileAI.plist for Kamikaze Drone 205 in state 'ATTACK_SHIP' receives message 'EXIT'
  Oolite [ai.message.receive] -[AI reactToMessage:] (AI.m:353): AI hardMissileAI.plist for Kamikaze Drone 205 in state 'EXPLODE' receives message 'ENTER'
  Oolite [ai.takeAction.takeAction] -[AI takeAction:] (AI.m:411): Kamikaze Drone 205 to take action becomeExplosion

Posted: Mon Aug 25, 2008 9:37 pm
by JensAyton
To clarify, you can enable this type of debug spew using the Javascript console with the following command:

Code: Select all

someShip.reportAIMessages = true
Under Mac OS X, the debug OXP provides a convenient checkbox which does the same thing.

Posted: Mon Aug 25, 2008 9:40 pm
by Thargoid
Originally the speed change was in the ENTER branch, but I was wondering if that was screwing up the performAttack somehow so temporarily shifted it down to the UPDATE.

The logic of it being there is the Kami Drone has a much higher top speed than the other two for it's missile mode (the scenario being when it goes Kami it switches it's engine to short-life overdrive and gets the extra speed boost). Hence why the intercept part is only at 0.6 and the attack at 0.3 (I thought also perhaps trying attack at 0.6 might be what was screwing the laser up). I'll shift the speed drop to the EXIT of the intercept state I think.

Anyway I tried a pirateAI on a combat drone, and it didn't seem to fire either. So it may be something inherent about being missile class (or not having a pilot?). More playing tomorrow perhaps, unless there are any more thoughts around?

Posted: Mon Aug 25, 2008 9:42 pm
by Thargoid
Ahruman wrote:
To clarify, you can enable this type of debug spew using the Javascript console with the following command:

Code: Select all

someShip.reportAIMessages = true
Under Mac OS X, the debug OXP provides a convenient checkbox which does the same thing.
And there's my useful thing to learn for today ;)

Eric's dump-out shows the AI is actually working along more or less the route I thought it was (and planned it to), but it's a useful tool for the future to know how to do the trace on a PC.

Posted: Tue Aug 26, 2008 8:10 am
by Eric Walch
Thargoid wrote:
Originally the speed change was in the ENTER branch, but I was wondering if that was screwing up the performAttack somehow so temporarily shifted it down to the UPDATE.
For attack or intercept it is useless to set a speed as it is constantly overruled by the code.
"performIntercept" always uses max_flightspeed (and never uses afterburners when present)
"performAttack" constant calculates and sets its own speed.

Only "performFlyToRangeFromDestination" uses the given speed an will use afterburners when the set speed is higher than max. But even than it will cut down the speed when it reaches the destination. Then you set the range very close to the destination, it will start fast but end up with a very low speed and it will not approach the endpoint at the original asked higher speed.

Posted: Tue Aug 26, 2008 8:36 am
by Thargoid
Ah ok, makes sense.

Anyway, just done some testing, and it's scan-class CLASS_MISSILE that's screwing up the laser firing. If I use an anti-Thargoid drone (as that's mine-spawned and uses a scanfor to get it's target rather than the players target on missile launch) with a class of CLASS_NEUTRAL then they fire away merrily against a spawned Thargoid Warship. Do same but with scanclass set to CLASS_MISSILE and the lasers go off again.

So I can fix the ATD by that adjustment (and having them appear as ships on the scanner) but I guess I'll need to reconsider the other drones targetting/launching to something similar and probably scanForHostiles when they're spawned. As of course the missiles scanclass gets set by their launch method and equipment status being _MISSILE... :roll:

Now the question is how to do the scanning. For the ATD it's easy (scan for CLASS_THARGOID), but as scanForHostiles doesn't seem to work (presumably as what's hostile to the player may well not be hostile to the drone) things are a little more limited. Time to go dive into the wiki for inspiration!

Posted: Tue Aug 26, 2008 3:20 pm
by Thargoid
Alright, now with those items resolved and the things are actually aggressive, I think we're ready for a beta-test version (available here).

All three drone types now launch and find their own targets independently rather than relying on the player (they're independent ships, not missiles now).

  • Anti-Thargoid drone - armed with a military laser, and seeks out anything with scanclass CLASS_THARGOID (as scanForThargoid sometimes didn't seem to work?).
  • Combat drone - armed with a beam laser, and seeks for (in this order) hostiles (in relation to the drone itself), pirates, thargoids (via scanclass again) and fugitives.
  • Kamikaze drone - as combat drone, except also armed with a light yield (3000 weapon_energy) warhead, which it sometimes uses.
As before, in all cases if they survive combat and can't find additional targets they go offline and can be scooped and possibly re-used.

I'd be interested to know what people think of them, if there are any bugs or glitches, if tweaks are needed (speed, accuracy, strength etc) and also how much they should cost and what tech level. Those last two are giving me headaches, especially in relation to some of the kit in Ramirez's Missiles & Bombs.

Download link - Drones v0.30 beta test.

Editted to add - should have said, but needs Oolite v1.70 or above.[/color]

Posted: Tue Aug 26, 2008 4:23 pm
by JensAyton
Thargoid wrote:
  • Anti-Thargoid drone - armed with a military laser, and seeks out anything with scanclass CLASS_THARGOID (as scanForThargoid sometimes didn't seem to work?).
[/color]
scanForThargoid specifically scans for Thargoid motherships (it’s exactly equivalent to scanForNearestShipWithPrimaryRole: thargoid). It can be considered deprecated; thargletAI.plist now uses scanForNearestShipHavingRole: thargoid-mothership instead.

Posted: Tue Aug 26, 2008 4:42 pm
by Thargoid
It managed to miss one that was right in front of me (literally about 20m or so, having just been player.spawned).

But this information is useful to know for my next planned ship/mission OXP, where this will be important.

Also any chance of a definitive decision as to whether they're called tharglets or thargons? Just so I know what to call the kids :lol:

Posted: Tue Aug 26, 2008 9:48 pm
by Eric Walch
Just to inform: any ship that has a script defined will no longer use the launch-actions, death_actions and so on. The three places were this happens with your oxp the launch_actions can be completely removed. (setting Ai at this point is not necessary)

But maybe also replace the other occasions with a script.js. Not spawning a ship in a death_action but with a script like:

Code: Select all

this.shipDied = function()
{
    let drone = this.ship.spawnOne("role")
    if(this.ship.target)
    {
        drone.target = this.ship.target
	drone.setPosition(this.ship.position)
    }
}
Advantage of a js script is that when you spawn the thing you can store the entity in a variable and do some additional settings. e.g. transfer the target to the spawned ship and put the drone exactly on the position of the launcher. That way the drone needs not looking for a target itself but still goes for the target the player aimed at. That way you can use the missiles you started with.

That way you you must of cause create a different script for each launcher. But a bunch of almost identical scripts ask for a more intelligent approach. In shipdata.plist you can define a "script_info" that is a directory of variables that are accessible by the script:

Code: Select all

script = "droneLauncher.js"; 
"script_info" = {"launch_name" = "antithargoid_drone"; }; 
The script now becomes:

Code: Select all

this.shipDied = function()
{
    let drone = this.ship.spawnOne(this.ship.scriptInfo.launch_name)
    if(this.ship.target)
    {
        drone.target = this.ship.target
    }
}
Now you have an universal script that works with all your launchers. You only define in the different launch_names in shipdata.plist

On testing I just noticed that the "shipDied" event never happens when a ship is exploded by AI script. So in the AI you must help a little by explicit call this event after exploding:

Code: Select all

	ENTER = (becomeExplosion, "sendScriptMessage: shipDied"); 
You can do the same thing with your 3 current, almost identical, scripts. Put the two differences in a script_info and use this from within the script.

Sounds difficult? By what I see from your scripts I think you get it quick and you'll publish the first oxp that uses the script_info.

Posted: Tue Aug 26, 2008 10:19 pm
by JensAyton
Thargoid wrote:
Also any chance of a definitive decision as to whether they're called tharglets or thargons? Just so I know what to call the kids :lol:
They are Thargoid Robot Fighterletgons.

Seriously, I’m not in a position to make decisions about canonicity.

Posted: Wed Aug 27, 2008 6:13 am
by Thargoid
I'm going away for the rest of the week, but I can see a version 0.40 coming on with a script.js next week. The concept seems clear enough, but then I've thought that before ;)

I quite like the fire and forget mine-based drones, but I may make both versions (missile and mine) available for full choice to the player (plus I guess NPCs could use the missile ones too).