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

Scripting requests

An area for discussing new ideas and additions to Oolite.

Moderators: another_commander, winston

User avatar
cim
Quite Grand Sub-Admiral
Quite Grand Sub-Admiral
Posts: 4072
Joined: Fri Nov 11, 2011 6:19 pm

Re: Scripting requests

Post by cim »

phkb wrote:
I have this code:

Code: Select all

var shipdata = Ship.shipDataForKey(my_shipkey);
Now, shipdata has a condition_script set for it. I want to run the "allowSpawnShip" function to check whether it's OK to create a ship with this key. But how to I execute the function?
I can't think of any way you could do that at the moment. The shipdata entry just tells you the name of the condition script source file - it doesn't give you a reference to the running script created from that source.
User avatar
phkb
Impressively Grand Sub-Admiral
Impressively Grand Sub-Admiral
Posts: 4666
Joined: Tue Jan 21, 2014 10:37 pm
Location: Writing more OXPs, because the world needs more OXPs.

Re: Scripting requests

Post by phkb »

Ah. Oh well. Thanks for the prompt response!
User avatar
phkb
Impressively Grand Sub-Admiral
Impressively Grand Sub-Admiral
Posts: 4666
Joined: Tue Jan 21, 2014 10:37 pm
Location: Writing more OXPs, because the world needs more OXPs.

Re: Scripting requests

Post by phkb »

Could I use "setScript" on some ship in the system (say, the main station) to briefly set the script, run the function and then reset it?
User avatar
cim
Quite Grand Sub-Admiral
Quite Grand Sub-Admiral
Posts: 4072
Joined: Fri Nov 11, 2011 6:19 pm

Re: Scripting requests

Post by cim »

phkb wrote:
Could I use "setScript" on some ship in the system (say, the main station) to briefly set the script, run the function and then reset it?
I would strongly advise using a disposable entity - hide an alloy plate at 10^13 metres from the sun, or something - rather than anything which might have a meaningful script on it, for that sort of trick. Resetting the script afterwards won't reset the values of any variables (which can include event handlers, of course) changed since load, and nor will it re-run shipSpawned or similar events if that's needed to set up other parts of the script.

Anyway, that would work in terms of granting access to the condition script's initial method definitions, and in many cases that's enough, but won't work in the general case because the condition script might have its own internal state, and creating a copy of it won't copy that internal state.

Condition scripts could also have conditions based on external environment - time, mission variables, state variables in other scripts, who else is currently in-system - so if you're doing this for the traffic reports, you might find that the condition script reports one value when you try to schedule a launch for a few days time, and another value when you actually get around to launching it.
User avatar
phkb
Impressively Grand Sub-Admiral
Impressively Grand Sub-Admiral
Posts: 4666
Joined: Tue Jan 21, 2014 10:37 pm
Location: Writing more OXPs, because the world needs more OXPs.

Re: Scripting requests

Post by phkb »

I'm running this code in order to get a list of ships currently docking with a station:

Code: Select all

//-------------------------------------------------------------------------------------------------------------
// returns an array of ships currently attempting to dock at the station
this.$getShipsDocking = function(station) {
    function $isDocking(entity)
    {
        return entity.isShip && entity.isPiloted && !entity.isStation && entity.dockingInstructions && entity.dockingInstructions.station == station;
    }
    return system.filteredEntities(this, $isDocking, station, 25600); // <<-- this is line 3369
}
But I'm starting to see this error:

Code: Select all

14:01:07.381 [gnustep]: 2015-05-22 14:01:07.381 oolite[1632] src/Core/Scripting/OOJavaScriptEngine.m:2176  Assertion failed in OOJSObjectGetterImplPRIVATE.  Invalid parameter not satisfying: context != NULL && object != NULL && requiredJSClass != NULL && outObject != NULL

14:01:07.474 [script.javaScript.exception.ooliteDefined]: ***** JavaScript exception (StationDockControl 0.3.0): Error: Native exception: src/Core/Scripting/OOJavaScriptEngine.m:2176  Assertion failed in OOJSObjectGetterImplPRIVATE.  Invalid parameter not satisfying: context != NULL && object != NULL && requiredJSClass != NULL && outObject != NULL
14:01:07.474 [script.javaScript.exception.ooliteDefined]:       ../AddOns/StationDockControl.oxp/Scripts/stationdockcontrol.js, line 3369.
Any ideas on what I'm doing wrong here? I don't get the error all the time, only sometimes.
User avatar
cim
Quite Grand Sub-Admiral
Quite Grand Sub-Admiral
Posts: 4072
Joined: Fri Nov 11, 2011 6:19 pm

Re: Scripting requests

Post by cim »

phkb wrote:
I'm running this code in order to get a list of ships currently docking with a station:Any ideas on what I'm doing wrong here? I don't get the error all the time, only sometimes.
It should fail with a more helpful error than that (and will, in tonight's build), but doing a quick bit of experimentation I would guess that you are sometimes calling that function with station = null. If you log the value of station shortly before the call, that should tell if that's what's happening or not.
User avatar
Phasted
Competent
Competent
Posts: 51
Joined: Wed Jun 09, 2010 3:56 pm

Re: Scripting requests

Post by Phasted »

Here's one out of left field (and maybe I'm not the first to suggest it)...

What are the odds of getting system.ID and player.ship.galaxyCoordinatesInLY made read/write?
User avatar
cim
Quite Grand Sub-Admiral
Quite Grand Sub-Admiral
Posts: 4072
Joined: Fri Nov 11, 2011 6:19 pm

Re: Scripting requests

Post by cim »

Phasted wrote:
What are the odds of getting system.ID and player.ship.galaxyCoordinatesInLY made read/write?
Virtually zero in that sense - they're essentially derived values that can't meaningfully be written to.

There might be a more practical way to do what you're trying to achieve by writing to them, though.
popsch
Above Average
Above Average
Posts: 27
Joined: Sun Jan 01, 2006 3:50 pm

Re: Scripting requests

Post by popsch »

Hi,

I was looking into OXP programming again and am still missing this functionality:

Code: Select all

setShipProximityAlertForPlayer( distance )
setShipProximityAlertForRole(distance, primaryRole)
event handler:

Code: Select all

shipProximityAlert = function(who)
The first two functions would setup when the event handler would be called. The event handler would be called whenever a ship gets closer than a certain distance.

This would enable a lot of nice extensions: AI that doesn't let you in close range, ships won't let you sneak up behind them and kill them in one salvo, proximity infractions near the station when hindering another ship, playing tag in space, having races near pylons in space, etc.

Is anything like this achievable right now?
User avatar
cim
Quite Grand Sub-Admiral
Quite Grand Sub-Admiral
Posts: 4072
Joined: Fri Nov 11, 2011 6:19 pm

Re: Scripting requests

Post by cim »

popsch wrote:
The event handler would be called whenever a ship gets closer than a certain distance.
For this to be an event handler it would need to every frame check the distance to every other ship: that's quite expensive especially if there's a lot of objects in system and many of them are carrying out these checks.

What the core game does to do the same sort of thing is in the priority AI:
- the AI calls ship.checkScanner() (generally as a preconfiguration after all "urgent" priorities like "currently in a fight" have been rejected)
- the AI checks the results for ships meeting certain criteria (they have to be in the ship's scanner range by definition, but you could require them to be even closer in the criteria check) and acts accordingly if any are found.

Something which would probably be reasonably quick if you did need very frequent checks:
- in a timer every ten seconds use ship.checkScanner() to get a list of nearby ships: this shouldn't generally need running faster
- in a faster timer (every 0.25 seconds should be enough for most checks, which is the fastest repeat a timer can have), check the distances to the ships in the list
popsch
Above Average
Above Average
Posts: 27
Joined: Sun Jan 01, 2006 3:50 pm

Re: Scripting requests

Post by popsch »

cim wrote:
popsch wrote:
The event handler would be called whenever a ship gets closer than a certain distance.
For this to be an event handler it would need to every frame check the distance to every other ship: that's quite expensive especially if there's a lot of objects in system and many of them are carrying out these checks.
As you stated, it wouldn't have to be processed every frame, but only every 300 frames (5 seconds) or every 600 frames (10 seconds) by the main loop. Furthermore, if it's done in Objective C with a callback, it'll be more efficient than in Javascript with a timer. That's why I was hoping for a callback function instead of coding a timer and check in javascript.
User avatar
cim
Quite Grand Sub-Admiral
Quite Grand Sub-Admiral
Posts: 4072
Joined: Fri Nov 11, 2011 6:19 pm

Re: Scripting requests

Post by cim »

popsch wrote:
Furthermore, if it's done in Objective C with a callback, it'll be more efficient than in Javascript with a timer.
A timer is a callback, and checkScanner makes the really slow bit (finding entities roughly nearby another entity) happen in Obj-C reasonably quickly, so it should be efficient enough. (Using the JS AI "wake time" event - as the core AIs do - is marginally more efficient than a timer, but I doubt by enough to matter)

The flexibility of the JS approach is also another consideration - you've suggested event handlers restricted by distance and primary role, but there are plenty of other potential filters (legal status, ship armament, cargo carried - to name three used by core AIs) which might be needed. Similarly, some OXP applications might need proximity checks against all objects carried out every 10 seconds while others might want proximity checks against a relatively short list of objects but need them to be done in every frame - or at least considerably more regularly than 5-10 seconds, since a ship on injectors can go 10-20km in that time, and a ship on torus could go 50km or more.
popsch
Above Average
Above Average
Posts: 27
Joined: Sun Jan 01, 2006 3:50 pm

Re: Scripting requests

Post by popsch »

Is it possible to force a ship start firing a weapon (e.g., the forward laser)? It seems that ship only as performAttach() which requires a set target. I just want to turn on and off lasers though without a given target.
User avatar
cim
Quite Grand Sub-Admiral
Quite Grand Sub-Admiral
Posts: 4072
Joined: Fri Nov 11, 2011 6:19 pm

Re: Scripting requests

Post by cim »

Not easily. You can use performScriptedAttackAI and [wiki]OXP_Scripted_AI[/wiki] to put it into a more controlled attack mode, including specifying firing of a particular weapon mount - but it still won't fire if its target isn't roughly in its sights.

It's technically fairly easy to add an option to the scripted AI to force firing even if there's no target in sights, but there are a huge pile of AI interaction implications from allowing a ship to (intentionally!) fire at an object it doesn't have targeted so it would have to be used carefully.
Switeck
---- E L I T E ----
---- E L I T E ----
Posts: 2412
Joined: Mon May 31, 2010 11:11 pm

Re: Scripting requests

Post by Switeck »

Firing a missile though isn't as hard. BUT you better give the missile a custom script or it'll instantly go boom from lack-of-target.
Post Reply