I don't think Selezen has got them all right. Cf wiki (and my experiences) it is like this:
1. void addShips(role, number): adds the specified number of ships with the specified role somewhere close to (but not exactly at) the witchpoint. (In which radius I can't say, and that goes for the following methods as well.)
2. void addSystemShips(role, number, position): adds the specified number of ships with the specified role somewhere close to a point on the line between witchpoint and main station. 0.0 means at the witchpoint, 1.0 means at the station. Position can be any fraction between those. As far as I can see addShips(role, number) acts as one specific case of addSystemShips(role, number, position), namely addSystemShips(role, number, 0.0). So addShips doesn't need to be used at all.
3. void addShipsAt(role, number, coordScheme, x, y, z): adds the specified number of ships with the specified role somewhere close to (but not exactly at) the position defined by the coordScheme and the coords. Obviously this is another piece of cake as the former two, because unless those two--which are confined to the witchpoint-station axis--addShipsAt can add ships
anywhere in the system. But again you can see the former two as a specific case of addShipsAt and therefore superfluous, because addSystemShips(role, number, 0.0..1.0) does the same as addShipsAt(role, number, wpu, 0, 0, 0.0..1.0).
4. void addShipsAtPrecisely(role, number, coordScheme, x, y, z): adds the specified number of ships with the specified role as close as possible to the position defined by the coordScheme and the coords. "As close as possible" is just limited by the mathematical capabilities of the engine, I guess. Now for the practical use of addShipsAt and addShipsAtPrecisely: With addShipsAt and a number > 1 you can add a small cluster of objects with the same role close to each other. With addShipsAtPrecisely however any number > 1 obviously is impossible, as adding several entities at exactly the same coordinates makes no sense, except for blowing these entities up immediatly, because of them colliding. Usually however even addShipsAt will be used with a very small number only, in order to avoid a collision of the added entities.
5. void addShipsWithinRadius(role, number, coordScheme, x, y, z, radius): adds the specified number of ships with the specified role somewhere in a radius around a point close to (but not exactly at) the position defined by the coordScheme and the coords (is that understandable? I'm trying to keep the definitions as similar as possible). So AFAIK in terms of precision it is like addShipsAt, not like addShipsAtPrecisely. But this time it gives the opportunity to produce bigger (custom-sized) clusters of objects with the same role. The most obvious and usual use is for creating asteroid fields, where you want to have many objects with role "asteroid" close to each other.
6. void spawn(role, number): adds the specified number of ships with the specified role as close as possible
to the calling entity. Its main use (and the only one that really makes sense) is in the death_actions-part of shipdata. Via this method an exploding entity can create something else that takes its location, e.g. a wreck. So you could script a station that can be blown up, spawning a clone of itself with a texture that has it half destroyed, only the skeleton left. The player would see the station exploding, and after the explosion only the skeleton of the station would still be visible. The same goes for any entity. I assume the engine uses this method to create all the rubble like the short-lived "wreckage" after an entity blows up. The basic difference between this method and the former ones (and the main advantage of this one) is that it is the
only method available that adds an entity
relative to another entity (instead of relative to a coord system). Its limitation is that it adds the new entity very close to the calling one, so it only makes sense when the calling entity disappears. A useful new method would be adding or spawning entities somewhere close to (but not exactly at) the location of the calling entity.
7. void spawnShip(shipdataKey): adds
one ship (instead of a number) with the specific
shipdataKey (instead of role) at a point that has to be specified in the shipdata-entry of this entity. The code for that is:
Code: Select all
<key>spawn</key><!-- data for when ship is spawned -->
<dict>
<key>position</key><!-- optional, sets the spawn position -->
<string>psm 0 0 200000</string>
<key>facing_position</key><!-- optional, sets the direction faced -->
<string>psm 0 0 0</string>
<key>spawn_actions</key><!-- optional, works like launch_actions -->
<array/><!-- no actions (empty array) for now -->
</dict>
Obviously this method is different to all the others in (a) that it can create only one entity and (b) that it does not call this entity by a role, but by the specific shipdataKey (is that used anywhere else in calling something?). I am not sure why Giles made it that way. Perhaps because the spawn-entry in shipdata is needed, so using spawnShip with one of the standard roles wouldn't do anything, because the standard ships have no spawn-entry. For using this method of adding a ship you always have to create a new shipdata-entry first, specifying the coords you want to use. The advantage of this method above all the others is that you can specify a facing direction other than the default or a random one for the entity you want to create. It is the only method that allows for this.
-----
The bottom line is:
a) 1. and 2. can easily be deprecated, because they are only special cases of 3.
b) I am not sure how useful the differentiation between 3., 4. and 5. really is. 3. seems to be the same as--or at least very similar to--5. with a small radius. So those two could be combined into one method.
c) 6. has its very own meaning and use, so it shouldn't be abandoned. Instead it could be differentiated according to 3. and 4. (or better 4. and 5.). So what is now spawn could become spawnAtPrecisely, while another one could be added along the lines drawn above, adding entities close to, but not exactly at the location of the caller.
d) 7. is even now working somehow out of the system. IMO it should be deprecated and substituted by the spawn-entry (containing facing_position) only. So no calling by shipdataKey any more. It is as easy to give my entity a unique role and a spawn-entry. If I then call it by its role through one of the remaining methods it would be added according to the coords in this method, facing the direction specified in the spawn-entry.
e) Or if facing_position could become one of the usual shipdata-keys there would be no need for this method at all anymore.
-----
So there would only four methods be left:
1) void addShipsAtPrecisely(role, number, coordScheme, x, y, z): adding an entity at a precise point according to a coordScheme
2) void addShipsWithinRadius(role, number, coordScheme, x, y, z, radius): adding a number of entities close to a point acording to a coordScheme
3) void spawnAtPrecisely(role, number): adding an entity at the precise location of the calling entity (usually replacing the caller)
4) void spawnWithinRadius(role, number, radius): adding a number of entities close to the calling entity
-----
And to simplify it even further: in the "AtPrecisely"-variants we don't need a number, it should by default be 1. So we are left with:
- void addShipsAtPrecisely(role, coordScheme, x, y, z)
void addShipsWithinRadius(role, number, coordScheme, x, y, z, radius)
void spawnAtPrecisely(role)
void spawnWithinRadius(role, number, radius)
-----
And, yes, before you mention it: All of that is formulated along the old scripting model, but I have not the slightest idea about javascript, and I'm sure you can easily translate it into a fitting syntax for javascript.
And I hope this was helpful.