System.addShips

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

Moderators: winston, another_commander, Getafix

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:

System.addShips

Post by Commander McLane »

One of the major new features in Oolite 1.74 is the family of addShips (and addGroup) methods. When I started to update my OXPs for 1.74, I only replaced the deprecated properties and methods in the first go, and tried to become friends with the new mission screen handling, but then I realized that there is yet another completely overhauled aspect of the game which I should try to befriend: the way of adding entities.

Only that this turns out to be a little harder than expected. Gladly, the legacy_addShips family is not deprecated and will continue to work, but still I would like to switch to cutting edge scripting. But here's the caveat: I am not yet completely happy with the new methods.

So this is not strictly a bug report, but some musings after testing and reflecting upon a new feature.
addShips

This method was added in Oolite test release 1.74.

function addShips(role : String, count : Number [, position: vectorExpression] [, radius: Number]) : Array

Adds ships to the system and returns the added ships in an array. Position is in absolute coordinates. When no position is given, the witchpoint is assumed. When no radius is given, the maximum scanner range is used. Ships added in range of the witchpoint automatically create a witchpoint entry cloud.
First: I am as happy as I could be about the methods returning the added ships. :D That was seriously missing from the legacy_ methods and will make scripting easier. If you want to do something to your freshly added ships you won't have to search for them first and put them in an array, but the array is already there. Yes!

I am not quite so happy about the ships-added-at-the-witchpoint-automatically-create-a-cloud thing. Way back, when we discussed the ship adding methods, I asked for a seperate parameter which would determine the creation of a witch cloud. My reason is simple: In many cases you want to give the impression that another ship is waiting for the player at the witchpoint in order to assault him/her. That makes sense in-game: the attacker could have used a series of smaller jumps to "overtake" the player, and would have been lurking somewhere near the witchpoint for hours. But of course we can't spawn the NPC hours before the player enters the system. We have to do it exactly when the player enters. But what we explicitely do not want is to give the impression that the NPC has entered the system at the same time as or even after the player. In other words: we don't want it to pop up with a witch cloud. Now, in most cases this won't matter, as the NPC will very likely not be created in the player's field of view. But there is of course no guarantee for that, so in the few remaining cases the optical impression will spoil the intended effect. Therefore I still vote for explicit control of the cloud through the script, in other words: the addition of another parameter to the methods.

Then there is the small drawback that this method only accepts absolute coordinates. It is more an itching than a pain, but I thought I'd mention it anyway. Having other optional coordinate systems would make things sometimes easier. But as the new framerate-display also displays the abs coordinate you can always position your ship at the point you want to spawn something at and read the coordinates (and could anyway with the debug console), therefore just an itching.
addShipsToRoute

This method was added in Oolite test release 1.74.

function addShipsToRoute(role : String, count : Number [, fraction: Number] [, route: String]) : Array

Adds ships to the system on certain common routes and returns the added ships as an array. The routes are the two character codes wp, pw, ws, sw, sp, and ps, where w stands for the witchpoint, p for the planet and s for the sun.

When no route is defined, the route witchpoint → main station is assumed.

The position is a fraction of the route and must be between 0 and 1. Unlike the legacy commands the fraction takes planetary radii in account, so it does not start counting in the centre of sun/planet but from its surface. When no fraction is defined, a random fraction is chosen. Ships are added within scanner range of this position. Ships added in range of the witchpoint automatically create a witchpoint entry cloud.
Now here the itching gets more painful, because this method is a lot less powerful than the legacy_ methods. I have two points of pain:

First, instead of three coordinates for x, y, and z direction there is only one parameter left. This means that this method cannot place anything outside the corridor. In many cases, however, we want to place something outside the corridor. An example from Anarchies.oxp: The Hacker Outpost is spawned at one of four random locations, depending on the system setup. The points of reference are always two of the three anchoring objects (witchpoint, planet, sun), but the Outpost is supposed to be difficult to find, so it cannot be placed directly in-between these points. Instead it is spawned somewhere in-between and a good distance perpendicular to the direct line. Very easily achievable with

Code: Select all

system.legacy_addShipsAtPrecisely("anarchies_hacker_outpost", 1, "psu", [0, 0.6, 0.5]);
which adds an Outpost which is in z-direction exactly halfway between planet and sun, but 60% of this distance off in y-direction. This is not achievable with the new methods, because only the "[0.5]" out of the "[0, 0.6, 0.5]" is left, so to speak. Another example: It won't be possible with the new methods to add a station orbiting the sun perpendicular to the ps-line, or it will only be possible via trial and error with abs coordinates. This is a complication I don't really like.

My second pain point is the "and must be between 0 and 1". Why this unnecessary restriction? It didn't exist with the legacy_ methods. Again, a solar station cannot be added on the exact opposite side of the planet, which would be easy with route "ps" and a factor >1.

I guess this fell victim to the "takes planetary radii in account", which means that now a factor of 1.1 might be inside the planet (or sun), and only an unknown and ever differing value > 1 will put the object behind the planet. But personally speaking, I would rather not have this new feature and take care of not placing objects inside the planet or sun myself, than lose the ability to place objects behind the planet, witchpoint, or sun.

As I said, these are my personal musings as a scripter about a new functionality. Feel free to object, and: discuss.
User avatar
Thargoid
Thargoid
Thargoid
Posts: 5528
Joined: Thu Jun 12, 2008 6:55 pm

Post by Thargoid »

To my understanding from past discussions the new methods aren't a replacement of the old legacy ones, but in parallel with them - at least for the moment. There are certain cases (some of which you mention) where the new stuff won't work and you need to use the legacy version. Hence the lack of depreciation, as it's not a replacement.

As to the witchpoint and the clouds - you could always spawn them somewhere else then move them to the witchpoint area? A workaround of sorts I know, but would do what you want. And would be quite trivial as you've got a ready-made array of ships to perform the position adjustment on, so they would even keep their formation if the same adjustment was used for each.
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 »

You are right that "addShipsToRoute" has many drawbacks when trying to use in special situations. But there is nothing in addShipsToRoute that you can also do with the more generic "addShips".

"addShipsToRoute" is only a convenience method for adding ships without further thinking. e.g. with the legacy method you had to subtract planetary diameters from the route yourself or you could end up adding ships inside the planet. The current "addShipsToRoute" is just mend for a very easy way of adding ships to the four main routes without thinking about endponts. 0 and 1 is always a safe endpoint. It even takes the radius of the ship into account:

Code: Select all

Planet <-> Withchpoint
Planet <-> Sun
Sun <-> Withchpoint
Station <-> Withchpoint
For everything else, just use the "addShips" that allows for any possible addition coordinate.
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 »

Thargoid wrote:
As to the witchpoint and the clouds - you could always spawn them somewhere else then move them to the witchpoint area? A workaround of sorts I know, but would do what you want. And would be quite trivial as you've got a ready-made array of ships to perform the position adjustment on, so they would even keep their formation if the same adjustment was used for each.
Its not that straight forward when ships also have escorts. :wink: But doable as I do in Dredgers.oxp. There I wanted to add general trader ships as derelicts and also needed an array of the added ships. As it is 1.73 code, I could only use the spawn() function. So there I let the mainStation spawn() all the derelicts and than relocate them to were I want them. And when they were spawned with escorts, I remove the escorts (But I could relocate them also when I wanted)
That part would have been much simpler with the new 1.74 code :lol:
User avatar
Thargoid
Thargoid
Thargoid
Posts: 5528
Joined: Thu Jun 12, 2008 6:55 pm

Post by Thargoid »

Isn't it? Pre-define your moving offset, then step through the array of added ships, check each for escorts. If present move those and then the mother, if not then just move the ship. Repeat for all entries in the array.

Seems simple to me, or am I missing something? Granted it needs to be considered and done, but it's not that much more work.
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 »

Thargoid wrote:
As to the witchpoint and the clouds - you could always spawn them somewhere else then move them to the witchpoint area?
Point of interest: ships will not interact with their environment while your script is running, so you don’t need to worry about them colliding with things and so forth. It’s entirely safe to spawn them inside the sun and then move them into place.

Escorts do make this approach unpleasantly complex, though. A flag (or parameter object, for future expansion) seems in order.

(Side note: escorts aren’t a good plan for the lying-in-wait scenario, since they’ll start trying to form up after they’re spawned.)
Commander McLane wrote:
Then there is the small drawback that this method only accepts absolute coordinates.
This isn’t going to change, but now that you mention it, I did intend to add utilities for converting to and from the “classic” coordinate systems.

(Note that you can position an entity between any two arbitrary points using Vector3D.interpolate(), e.g. Vector3D.interpolate([0, 0, 0], system.mainStation, 0.5) is halfway between the witchpoint and the main station.)
Now here the itching gets more painful, because this method is a lot less powerful than the legacy_ methods. I have two points of pain:
As Eric said, comparing the special-case convenience wrapper for the new version to the most general of the old functions is a bit unfair. In any case, I demonstrated putting-x-parallel-to-y here. In short: if you don’t have a particular direction in mind, construct one by taking the cross product of your normalized direction with a random unit vector (which gives you a vector perpendicular to the direction), multiply by the intended distance, and add to your position on the reference line (e.g. the interpolated vector generated above). If you need it with less gobbledegook, describe your precise requirements.
Commander McLane wrote:
It won't be possible with the new methods to add a station orbiting the sun perpendicular to the ps-line, or it will only be possible via trial and error with abs coordinates. This is a complication I don't really like.
Or by doing the maths. I realise that having an out-of-the-box solution for the particular case you want is convenient, but the generalized approach is strictly more powerful, not less.

The difference is that you can calculate any position relative to anything else in a script, even if you need help with the details, whereas the legacy model only allowed certain hard-coded calculations (although the combination of JavaScript, legacy_addShipsAtPrecisely and abs coordinates made this possible before the new functions). In fact, you can perform almost all the geometry calculations Oolite can (the only limitation I’m aware of is that scripts don’t know a ship’s bounding box or docking slot parameters).
Commander McLane wrote:
My second pain point is the "and must be between 0 and 1". Why this unnecessary restriction?
Looks like over-enthusiasm in the parameter checking to me. Kaks?
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 »

Hi! :)

The 'must be between 0 and 1' bit:

in the case of the 'ps' route, where we've got an imaginary line between the centre of the planet and the centre of the sun, 0 corresponds to the point closest to the planet where it's safe for a ship to pop into existence, and 1 to the point closest to the sun where it's theoretically safe for a ship to pop into existence.

As Eric said, addShipToRoute is meant to just be a convenience method, specifically to add ships to 'known routes'! :)

If you want to add ships outside them routes, it seems to make more sense to use the genric addShips function, rather than extend addShipsToRoute in order to add ships outside routes...

PS: for a more direct comparison, the ToRoute functions were directly inspired by the legacy_addSystemShips function, though I must admit it never occurred to me to try that legacy function with numbers outside the 0-1 range!
Hey, free OXPs: farsun v1.05 & tty v0.5! :0)
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 »

In other words: addFooToRoute is only a convenience method for placing ships exactly on the vertices of the pws-triangle. I understand that and I can live with that. It is just that I find the convenience of an automagical collision protection by taking into account the radii less useful than the convenience of being able to place an entity in any relation to two of the three fixed objects. So from my point of view this convenience method isn't really convenient.

Of course with the right geometry and algebra all necessary calculations can be done in the scripts, and then the resulting abs-coordinates be used with addShips, but to have this as the general approach to ship spawning strikes me as, well, inconvenient. It puts the burden on the scripter which until now rested upon the code. That is like forcing us scripters into a state of having to re-invent a wheel which previously had been a natural part of our vehicle. I would then at least ask for a set of convenience functions which can be used to calculate coordinates relative to the three fixed points (and not just on the exact lines between those points).

As far as spawning and re-positioning is concerned, yes, of course it can be done, but again it is not very convenient. It is a workaround for something that is missing as a proper method. And for things that may expected to be done routinely I would prefer a proper method over being pointed to a workaround.

IIRC the objective of re-designing the ship spawning methods was to have an addShips method which would supersede the existing legacy_foo methods. With the addShips method as introduced in 1.74 this is clearly not the case. It can't do (or only with a lot of footwork by the individual scripter) what the legacy methods can. Therefore it can't supersede them, and they have to continue to exist alongside it. Personally I find that unsatisfying, and therefore my feedback musings.
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:
Of course with the right geometry and algebra all necessary calculations can be done in the scripts, and then the resulting abs-coordinates be used with addShips, but to have this as the general approach to ship spawning strikes me as, well, inconvenient. It puts the burden on the scripter which until now rested upon the code. That is like forcing us scripters into a state of having to re-invent a wheel which previously had been a natural part of our vehicle. I would then at least ask for a set of convenience functions which can be used to calculate coordinates relative to the three fixed points (and not just on the exact lines between those points).
When adding ships relative to other ships, the new method is much simpler. When adding it in relation to system objects, it will involve a bit more calculation. Therefor it was decided to let the old methods in place.
Somehow it was thought that those scripters that really need the return array also love the freedom of doing the position calculations themselves.

There probably should have been a conversion tool available, as you and Ahruman writes. Probably easy to implement as the math is already in the code.

e.g.

Code: Select all

system.legacyToCoordinate("pwr", [0, 0.6, 0.5]) 
returning the absolute coordinates
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:
e.g.

Code: Select all

system.legacyToCoordinate("pwr", [0, 0.6, 0.5]) 
returning the absolute coordinates
Good to know. Please amend the Wiki. :D
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 »

OK, as of this morning,
system.legacyToCoordinates("pwr", [0, 0.6, 0.5]);
is implemented in trunk!
Of course, it accepts all coordinate systems, not just 'pwr'.
Hey, free OXPs: farsun v1.05 & tty v0.5! :0)
Switeck
---- E L I T E ----
---- E L I T E ----
Posts: 2411
Joined: Mon May 31, 2010 11:11 pm

Post by Switeck »

What command/s can I use to add more Thargoids in Witchspace to counter-balance the presence of a Behemoth + escorts?
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 »

Switeck wrote:
What command/s can I use to add more Thargoids in Witchspace to counter-balance the presence of a Behemoth + escorts?
Install Tharon_Threat.oxp. That oxp was designed to restore the balance in witchspace.
It adds extra thagoids for every police ship in witchspace. (However, it doesn't look at military ships that might also be there)
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 »

Kaks wrote:
OK, as of this morning,
system.legacyToCoordinates("pwr", [0, 0.6, 0.5]);
is implemented in trunk!
Of course, it accepts all coordinate systems, not just 'pwr'.
Correction! After some more thinking & tweaking & yet more thinking, we now have a complete set of coordinate translation functions! Well 2 of them anyway, plus a convenience method:

if we've got a Vector3D value stored inside a variable called myPosition, we can now use the following:

myPosition.fromCoordinateSystem(string:coordSystem) for 'pws','spu', etc... -> 'abs' conversions, and myPosition.toCoordinateSystem(string:coordSystem)for 'abs' -> 'pws','spu', etc... conversions


This would normally mean having to create a variable to store the legacy coordinates, and then call .fromCoordinateSystem() to find out the equivalent coordinates in the internal (aka 'abs') coordinate system, but not necessarily! :)

To help translate stuff like

Code: Select all

system.legacy_addShipsAtPrecisely("anarchies_hacker_outpost", 1, "psu", [0, 0.6, 0.5]);
to system.addShips (if so desired), without the need to create an extra variable, we've also added Vector3D.vectorFromCoordinateSystem(vector, coordinate system) (the equivalent of System.legacyToCoordinate mentioned by Eric).
Using that,
here's the equivalent command using addShips and .fromCoordinateSystem():

Code: Select all

system.addShips("anarchies_hacker_outpost", 1,Vector3D([0, 0.6, 0.5]).fromCoordinateSystem('psu'),1)
This should cover just about all coordinate conversion needs! :)

Please disregard any and all references to System.legacyToCoordinate - nothing to see here, move along, etc, etc...
Last edited by Kaks on Sat Jun 26, 2010 1:06 pm, edited 1 time in total.
Hey, free OXPs: farsun v1.05 & tty v0.5! :0)
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 »

Correction 2! The convenience method wasn't really that convenient! Removed it altogether from the code, and will edit my previous post accordingly!

PS: hmm, I seem to have one of them bad hair days... where's male pattern baldness when you need it! ;)
Hey, free OXPs: farsun v1.05 & tty v0.5! :0)
Post Reply