Experiment: NPC Non-AI ship
Moderators: winston, another_commander
- hiran
- Theorethicist
- Posts: 2403
- Joined: Fri Mar 26, 2021 1:39 pm
- Location: a parallel world I created for myself. Some call it a singularity...
Experiment: NPC Non-AI ship
I'd like to run another experiment on Oolite.
Since I have control over the debug console, I am wondering whether I can spawn a ship at some position, then give it speed and turns to have it fly towards another position. Ideally I could see that ship flying by from my own ship.
So this ship would be a non player character (NPC), but at the same time not controlled by AI like so many other ships in Oolite.
Or would it make sense to have a minimal AI that could bring the ship to a given position/direction in given time so it would fly it's own bezier curve?
Any help here appreciated...
Since I have control over the debug console, I am wondering whether I can spawn a ship at some position, then give it speed and turns to have it fly towards another position. Ideally I could see that ship flying by from my own ship.
So this ship would be a non player character (NPC), but at the same time not controlled by AI like so many other ships in Oolite.
Or would it make sense to have a minimal AI that could bring the ship to a given position/direction in given time so it would fly it's own bezier curve?
Any help here appreciated...
Sunshine - Moonlight - Good Times - Oolite
- hiran
- Theorethicist
- Posts: 2403
- Joined: Fri Mar 26, 2021 1:39 pm
- Location: a parallel world I created for myself. Some call it a singularity...
Re: Experiment: NPC Non-AI ship
It seems noone knows how this could be achieved.
That given, I will never be able to send events from a player controlling his local ship to some other Ooniverse to also move an avatar ship. Which means players will never see one another passing by.
So I will give up investigating in that direction.
That given, I will never be able to send events from a player controlling his local ship to some other Ooniverse to also move an avatar ship. Which means players will never see one another passing by.
So I will give up investigating in that direction.
Sunshine - Moonlight - Good Times - Oolite
- phkb
- Impressively Grand Sub-Admiral
- Posts: 4830
- Joined: Tue Jan 21, 2014 10:37 pm
- Location: Writing more OXPs, because the world needs more OXPs.
Re: Experiment: NPC Non-AI ship
Giving a ship the null AI (oolite-nullAI.js) would make it unresponsive, allowing you to then do whatever you want with the ship programmatically. Although I haven't tested every function, so it might not work.
- hiran
- Theorethicist
- Posts: 2403
- Joined: Fri Mar 26, 2021 1:39 pm
- Location: a parallel world I created for myself. Some call it a singularity...
Re: Experiment: NPC Non-AI ship
That is half a solution, after all.
But how would one control the ship then? Especially via the debug console?
Or could it be feasible to have some AI that just beziers the ship to a given coordinate/heading/speed, and the cordinate/heading/speed triple would be injected via the debug console?
Sunshine - Moonlight - Good Times - Oolite
-
- Quite Grand Sub-Admiral
- Posts: 6682
- Joined: Wed Feb 28, 2007 7:54 am
Re: Experiment: NPC Non-AI ship
Check ship.destination and ship.desiredSpeed JS properties, also PriorityAIController.prototype.behaviourApproachDestination in Resources/Scripts/oolite-priorityai.js.
- hiran
- Theorethicist
- Posts: 2403
- Joined: Fri Mar 26, 2021 1:39 pm
- Location: a parallel world I created for myself. Some call it a singularity...
Re: Experiment: NPC Non-AI ship
So how would this look as a complete example using the Debug Console?another_commander wrote: ↑Fri Dec 17, 2021 2:24 pmCheck ship.destination and ship.desiredSpeed JS properties, also PriorityAIController.prototype.behaviourApproachDestination in Resources/Scripts/oolite-priorityai.js.
How can a ship be spawned with the right controller?
How can the ship's position be set? How can direction, speed and destination coordinates be set?
Depending on the Oolite Debug Console communication performance we could estimate how many ships can be controlled this way in parallel.
Sunshine - Moonlight - Good Times - Oolite
Re: Experiment: NPC Non-AI ship
All ships have to have an AI - but it is possible for that AI to avoid using any of the in-built flight code whatsoever. You just have to combine a bunch of obscure features ... but then, you were going to have to do that anyway.
Start with https://wiki.alioth.net/index.php/Oolit ... ScriptedAI (and the neighbouring ScriptedAttack if you want it to be able to shoot too). A very basic JS AI can set that AI mode off (you probably don't even need the priority AI library) - or you can also call it from a simple plist AI if you prefer.
That lets you then control a ship's flight model and laser fire directly with a callback function as described at https://wiki.alioth.net/index.php/OXP_Scripted_AI - that callback can as well as returning the future flight parameters, also do all the usual things like setting position, firing ECM, etc. And of course the Debug Console can update suitable shipscript variables to tell the callback function what it should be doing.
Note: if you're using this for multiplayer, there'll be a discrepancy:
- the player will fire the laser when they think they're going to hit
- the ship under ScriptedAttack will fire when its AI thinks it's going to hit (based on its accuracy parameter)
So if you want to fire if and only if the player does, you may need to make use of a huge virtual invisible target in the right direction, so it always thinks it's going to hit, and then only use ScriptedAttack on the frames it should actually fire.
As far as a basic example (untested, but you can probably figure out the bugs) goes:
Ship script (just use a null AI script with this one):
Debug console:
Ship starts off stationary, when you enter the debug console code it should start doing slow pitch loops.
Start with https://wiki.alioth.net/index.php/Oolit ... ScriptedAI (and the neighbouring ScriptedAttack if you want it to be able to shoot too). A very basic JS AI can set that AI mode off (you probably don't even need the priority AI library) - or you can also call it from a simple plist AI if you prefer.
That lets you then control a ship's flight model and laser fire directly with a callback function as described at https://wiki.alioth.net/index.php/OXP_Scripted_AI - that callback can as well as returning the future flight parameters, also do all the usual things like setting position, firing ECM, etc. And of course the Debug Console can update suitable shipscript variables to tell the callback function what it should be doing.
Note: if you're using this for multiplayer, there'll be a discrepancy:
- the player will fire the laser when they think they're going to hit
- the ship under ScriptedAttack will fire when its AI thinks it's going to hit (based on its accuracy parameter)
So if you want to fire if and only if the player does, you may need to make use of a huge virtual invisible target in the right direction, so it always thinks it's going to hit, and then only use ScriptedAttack on the frames it should actually fire.
As far as a basic example (untested, but you can probably figure out the bugs) goes:
Ship script (just use a null AI script with this one):
Code: Select all
this.flightParameters = {};
this.shipSpawned = function()
{
this.performScriptedAI();
}
this.scriptedAI = function(delta)
{
return this.flightParameters;
}
Code: Select all
ship.script.flightParameters = { stickPitch: -0.2; desiredSpeed: this.ship.maxSpeed / 3; }
- hiran
- Theorethicist
- Posts: 2403
- Joined: Fri Mar 26, 2021 1:39 pm
- Location: a parallel world I created for myself. Some call it a singularity...
Re: Experiment: NPC Non-AI ship
Thank you for that response, but I may not yet be up to speed.cim wrote: ↑Mon Feb 28, 2022 9:17 pmAll ships have to have an AI - but it is possible for that AI to avoid using any of the in-built flight code whatsoever. You just have to combine a bunch of obscure features ... but then, you were going to have to do that anyway.
Start with https://wiki.alioth.net/index.php/Oolit ... ScriptedAI (and the neighbouring ScriptedAttack if you want it to be able to shoot too). A very basic JS AI can set that AI mode off (you probably don't even need the priority AI library) - or you can also call it from a simple plist AI if you prefer.
That lets you then control a ship's flight model and laser fire directly with a callback function as described at https://wiki.alioth.net/index.php/OXP_Scripted_AI - that callback can as well as returning the future flight parameters, also do all the usual things like setting position, firing ECM, etc. And of course the Debug Console can update suitable shipscript variables to tell the callback function what it should be doing.
Note: if you're using this for multiplayer, there'll be a discrepancy:
- the player will fire the laser when they think they're going to hit
- the ship under ScriptedAttack will fire when its AI thinks it's going to hit (based on its accuracy parameter)
So if you want to fire if and only if the player does, you may need to make use of a huge virtual invisible target in the right direction, so it always thinks it's going to hit, and then only use ScriptedAttack on the frames it should actually fire.
As far as a basic example (untested, but you can probably figure out the bugs) goes:
Ship script (just use a null AI script with this one):Debug console:Code: Select all
this.flightParameters = {}; this.shipSpawned = function() { this.performScriptedAI(); } this.scriptedAI = function(delta) { return this.flightParameters; }
Ship starts off stationary, when you enter the debug console code it should start doing slow pitch loops.Code: Select all
ship.script.flightParameters = { stickPitch: -0.2; desiredSpeed: this.ship.maxSpeed / 3; }
What I understand so far is I should create my own scripted AI. This is probably a file that goes into some OXP. I am wondering why your description sounds just so much different from https://wiki.alioth.net/index.php/OXP_howto_AI, which talks about state machines.
Next, how would I spawn a ship that makes use of this AI? I suspect this command would have to come via the Debug Console. I could try to make use of Ship::spawnOne, and then I'd need a handle on that ship for further instructions, such as setting the AI.
After that, I'd like to use the Debug Console to set position, rotation, speed etc. but these seem to be Ship variables
velocity, pitch, roll, yaw, position, orientation.
Could we create a working list of commands to be used on the Debug Console?
Sunshine - Moonlight - Good Times - Oolite
Re: Experiment: NPC Non-AI ship
There are a few ways to write AIs. The original way involves the state machines described there.I am wondering why your description sounds just so much different from https://wiki.alioth.net/index.php/OXP_howto_AI, which talks about state machines.
You can also use a Javascript file as the ship's AI. There's a library called "Priority AI" shipped with the core game which provides one way to set up these AIs - https://wiki.alioth.net/index.php/Oolit ... I_Tutorial - but that's not the only option: any JS can be used in the AI script.
Yes, if your intent is to then control the ship from the debug console, that makes sense.I suspect this command would have to come via the Debug Console.
System.addShips()
would be the most straightforward way to add it, and returns a reference to the added ships which you can then access as a variable in the debug console.https://wiki.alioth.net/index.php/Oolit ... m#addShips
Here you go - https://wiki.alioth.net/index.php/Oolit ... ject_modelCould we create a working list of commands to be used on the Debug Console?
Any JS method can be called from the debug console, and it has local variable storage to get the results back, and access to the standard Oolite worldscript globals like system. So you can do things like this to spawn a ship, get it into a local variable in the debug console, and then call Ship methods on that ship instance
Code: Select all
ships = system.addShips("trader", 1, [2000, 2000, 2000]); // near the witchpoint
ship = ships[0];
ship.commsMessage("Hello");
At least just for early testing, I'd set up a new shipdata.plist entry, based on an existing ship but then overriding a few propertieshow would I spawn a ship that makes use of this AI
Code: Select all
"aitest_adder" = {
like_ship = "adder";
is_external_dependency = yes;
roles = "aitest";
script = "my-ship-script.js"; // or whatever you called the file from my previous post
ai_type = "nullAI.plist";
};
aitest
for trader
in the system.addShips call above and you've got one ready to use.- hiran
- Theorethicist
- Posts: 2403
- Joined: Fri Mar 26, 2021 1:39 pm
- Location: a parallel world I created for myself. Some call it a singularity...
Re: Experiment: NPC Non-AI ship
My application, the Nexus is from Oolite perspective just a Debug Console. The fact that this debug console does not just allow to send low level commands into Oolite but adds to the gameplay is not known by Oolite. So it is ok to assume I am just controlling a ship from the Debug Console.
Finally, one step ahead! I am able to spawn a ship, close to the witchpoint. And I can see the ship appearing out of a singularity, then wheezing off towards the planet. It will send whatever messages I inject with the commsMessage.cim wrote: ↑Wed Mar 02, 2022 12:40 pmSystem.addShips()
would be the most straightforward way to add it, and returns a reference to the added ships which you can then access as a variable in the debug console.
https://wiki.alioth.net/index.php/Oolit ... m#addShips
Here you go - https://wiki.alioth.net/index.php/Oolit ... ject_modelCould we create a working list of commands to be used on the Debug Console?
Any JS method can be called from the debug console, and it has local variable storage to get the results back, and access to the standard Oolite worldscript globals like system. So you can do things like this to spawn a ship, get it into a local variable in the debug console, and then call Ship methods on that ship instanceCode: Select all
ships = system.addShips("trader", 1, [2000, 2000, 2000]); // near the witchpoint ship = ships[0]; ship.commsMessage("Hello");
After running the system.addShips command, Oolite responds back with e.g.
Code: Select all
[[Ship "Boa Class Cruiser Leader" position: (3456.26, 1553.22, 10340.5) scanClass: CLASS_NEUTRAL status: STATUS_IN_FLIGHT]]
I never created an OXP so I am struggling with the next bits.
So what I did is this:cim wrote: ↑Wed Mar 02, 2022 12:40 pmAt least just for early testing, I'd set up a new shipdata.plist entry, based on an existing ship but then overriding a few propertieshow would I spawn a ship that makes use of this AIThen you can swapCode: Select all
"aitest_adder" = { like_ship = "adder"; is_external_dependency = yes; roles = "aitest"; script = "my-ship-script.js"; // or whatever you called the file from my previous post ai_type = "nullAI.plist"; };
aitest
fortrader
in the system.addShips call above and you've got one ready to use.
- I created a folder underneath addons named ~/GNUstep/Applications/Oolite/Addons/Crossplay.oxp
- Inside that, I created the files
manifest.plist
AIs/RemoteControlled.js
Config/shipdata.plist
Here is the content of RemoteControlled.js:
Code: Select all
this.flightParameters = {};
this.shipSpawned = function()
{
this.performScriptedAI();
}
this.scriptedAI = function(delta)
{
return this.flightParameters;
}
Code: Select all
"aitest_adder" = {
like_ship = "adder";
is_external_dependency = yes;
roles = "aitest";
script = "RemoteControlled.js"; // or whatever you called the file from my previous post
ai_type = "nullAI.plist";
};
Code: Select all
...
AddOns/Crossplay.oxp
AddOns/Basic-debug.oxp
...
When I now issue the command
Code: Select all
ships = system.addShips("aitest", 1, [2000, 2000, 2000],1);
Code: Select all
null
Sunshine - Moonlight - Good Times - Oolite
Re: Experiment: NPC Non-AI ship
Bearing in mind that it's been several years since I did any serious OXP coding, so others might be more able to help with this bit...
- your RemoteControlled.js file should go in Scripts/ not AIs/
- your shipdata.plist needs enclosing { and } to hold the aitest_adder entry
(More generally, your Debug Console emulating app is going to need an accompanying OXP, so it's probably worth taking some time out to just write a couple of simple ones - or at least have a good look through existing ones - to see what comes up.)
- your RemoteControlled.js file should go in Scripts/ not AIs/
- your shipdata.plist needs enclosing { and } to hold the aitest_adder entry
(More generally, your Debug Console emulating app is going to need an accompanying OXP, so it's probably worth taking some time out to just write a couple of simple ones - or at least have a good look through existing ones - to see what comes up.)
- hiran
- Theorethicist
- Posts: 2403
- Joined: Fri Mar 26, 2021 1:39 pm
- Location: a parallel world I created for myself. Some call it a singularity...
Re: Experiment: NPC Non-AI ship
Much better! I can flood the space now with adders that act like sitting ducks!cim wrote: ↑Thu Mar 03, 2022 9:08 amBearing in mind that it's been several years since I did any serious OXP coding, so others might be more able to help with this bit...
- your RemoteControlled.js file should go in Scripts/ not AIs/
- your shipdata.plist needs enclosing { and } to hold the aitest_adder entry
The next step is to make them fly.
I tried
Code: Select all
ship.script.flightParameters = { stickPitch: -0.2; desiredSpeed: this.ship.maxSpeed / 3; }
Sunshine - Moonlight - Good Times - Oolite
Re: Experiment: NPC Non-AI ship
Try giving it a kick with
If that doesn't work, to make sure it's getting the right AI attached, try replacing the function with this.
If the AI mode is being set properly, that should force the movement pattern, and also fill your logfile with time fractions. If the AI mode isn't being set properly nothing happens - but doing
ship.performScriptedAI()
in the console.If that doesn't work, to make sure it's getting the right AI attached, try replacing the function with this.
Code: Select all
this.scriptedAI = function(delta)
{
log(ship.name, delta);
return { stickPitch: -0.2; desiredSpeed: this.ship.maxSpeed / 3; }
}
ship.performScriptedAI()
in the console should then set it off.- hiran
- Theorethicist
- Posts: 2403
- Joined: Fri Mar 26, 2021 1:39 pm
- Location: a parallel world I created for myself. Some call it a singularity...
Re: Experiment: NPC Non-AI ship
Meanwhile I believe the problem is the nullAI. I switched to dumbAI and now at least the ships are rotating.cim wrote: ↑Thu Mar 03, 2022 10:50 pmTry giving it a kick withship.performScriptedAI()
in the console.
If that doesn't work, to make sure it's getting the right AI attached, try replacing the function with this.If the AI mode is being set properly, that should force the movement pattern, and also fill your logfile with time fractions. If the AI mode isn't being set properly nothing happens - but doingCode: Select all
this.scriptedAI = function(delta) { log(ship.name, delta); return { stickPitch: -0.2; desiredSpeed: this.ship.maxSpeed / 3; } }
ship.performScriptedAI()
in the console should then set it off.
I am wondering which AI would be best to choose, as I just want to define position, orientation and speed.
Is there an AI that would just hold the course? Not worrying about what to do next (or, in state machines an AI with only one state)?
Sunshine - Moonlight - Good Times - Oolite
Re: Experiment: NPC Non-AI ship
You basically just need an AI that isn't going to do anything to interfere with ship behaviour once it's initialised - nullAI should be fine for that.
If the code isn't working it'll be because something in the script initialisation isn't working. Possibly shipSpawned() is too early to be calling ship.performScriptedAI() - as I said, it's been a while since I worked on any of this.
Try the following as an AI: call it "DebugControl.js" or something (yes, js not plist - but this one does go in the AI folder)
(DumbAI will indeed cause the ship to rotate in place - but that's just because that's what it does)
If the code isn't working it'll be because something in the script initialisation isn't working. Possibly shipSpawned() is too early to be calling ship.performScriptedAI() - as I said, it's been a while since I worked on any of this.
Try the following as an AI: call it "DebugControl.js" or something (yes, js not plist - but this one does go in the AI folder)
That should be sufficient for now to permanently hand-off control to the ship script and debug console, and stop any other AI behaviour interfering.this.name = "Debug Control AI";
this.aiStarted = function()
{
this.ship.performScriptedAI()
}
(DumbAI will indeed cause the ship to rotate in place - but that's just because that's what it does)