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

Station spawning oxps...

Discussion and information relevant to creating special missions, new ships, skins etc.

Moderators: winston, another_commander

User avatar
Mauiby de Fug
---- E L I T E ----
---- E L I T E ----
Posts: 847
Joined: Tue Sep 07, 2010 2:23 pm

Station spawning oxps...

Post by Mauiby de Fug »

Since I recently installed the Sothis and Wasps oxps, I've been paying a bit more attention to which extra stations are loaded.

Superhubv1.2, Sothis and Wasps oxps all are inconsistent.

With Superhub, they sometimes appear within a particular system, sometimes they don't. With the other two, they will always appear within the particular system, unless the game is reloaded whilst in the system (ie you restore from a saved game), when they don't.

What I would like is for them all to have a set of systems for which they appear, and for them to do this consistently.

So, I've been looking through the spawning scripts, and I think that I can get the behaviour I want by using functions from both.

Having recently become acquainted with the Oolite Javascript Reference wiki pages, the best way to get consistent random behaviour in a system is to use the pseudoRandomNumber method.

Both of Killer Wolf's oxps (namely the Sothis and Wasps) make use of Ahruman's scrambling method, which takes a seed value to give a different output:

Code: Select all

this.scrambledPseudoRandom = function(salt)
{
    // Convert from float in [0..1) with 24 bits of precision to integer.
    var n = Math.floor(system.pseudoRandomNumber * 16777216.0);
   
    // Add salt to enable generation of different sequences.
    n += salt;
   
    // Scramble with basic LCG psuedo-random number generator.
    n = (214013 * n + 2531011) & 0xFFFFFFFF;
    n = (214013 * n + 2531011) & 0xFFFFFFFF;
    n = (214013 * n + 2531011) & 0xFFFFFFFF;
   
    // Convert from (effectively) 32-bit signed integer to float in [0..1).
    return n / 4294967296.0 + 0.5;
}
However, they both use the same "salt" value of 10. Wasps spawns if the output is less than 0.5; Sothis when the output is less than 0.666. Therefore whenever there is a Sothis, there is always a wasps' nest. They are also only spawned upon the shipWillExitWitchspace method. This is why they won't appear when you reload a game in a system that previously contained them. It also explains why whenever I mis-jump, I end up with both the stations stuck together (mentioned recently here) - I assume that the generated value for interstellar space is less than 0.5.

Superhub, on the other hand, goes about things a slightly different way:

Code: Select all

this.name           = "PAGroove_superhubPopulator";
this.author         = "Thargoid";
this.copyright      = "This script is hereby placed in the public domain.";
this.version        = "1.1";
this.description    = "Script to add a single superhub near the system main station";


this.shipWillLaunchFromStation = function(station)
   {
   if(station.isMainStation)
      {
      this.spawnHub();
      }
   }

this.shipWillExitWitchspace = function()
   {
   this.spawnHub();
   }

this.spawnHub = function()
   {
   if(Math.random() < 0.5 || system.techLevel < 11 || system.government < 4 || system.countShipsWithRole("pagroove_superhub") > 0 || this.superHubBlock)   
      {
      this.superHubBlock = true;
      return;
      }
   else
      {
      this.xOffset = (Math.random() * 10000) + 10000; // x offset between 10 and 20km
      this.yOffset = (Math.random() * 10000) + 10000; // y offset between 10 and 20km

      if(Math.random() > 0.5) // 50:50 chance of offsetting in the other direction
         {
         this.xOffset = -this.xOffset;
         }
      if(Math.random() > 0.5) // 50:50 chance of offsetting in the other direction
         {
         this.yOffset = -this.yOffset;
         }

      system.legacy_addShipsAtPrecisely("pagroove_superhub", 1, "abs", system.mainStation.position.add([this.xOffset, this.yOffset, 0]));
      }
   }

this.shipWillEnterWitchspace = function()
   {
   this.superHubBlock = null;
   }
This script covers the fact that stations need to be added when one leaves the main station, but no more than once, and also checks this by using the variable this.superHubBlock. However, the fact that this uses Math.random() as a generating condition, rather than the pseudoRandomNumber method, means that the behaviour is not consistent.

Now, if I combine the two ways of doing things, by replacing Math.random() with the pseudoRandomNumber in the Superhub script, and adding the shipWillLaunchFromStation() event and similar checks to the KW scripts, whilst changing the "salt" values (and possibly the probablilties as well), I hope to get consistent behaviour from these things, and if I'm successful, I'll probably write myself a similar script for KW's Nuit station as well (as it only has a test spawning script that spawns upon every launch from the station!).

Does this make sense to people? Or am I insane and there are added complications that I haven't thought of/seen (though I'll probably find them in the middle of scripting if there are...)?
User avatar
Thargoid
Thargoid
Thargoid
Posts: 5527
Joined: Thu Jun 12, 2008 6:55 pm

Post by Thargoid »

My script (the one reproduced above) was done before Ahruman came up with his random but repeatable number generation that you mention.

If you replace my random number with it, then you should get what you want. It is better than using pseudoRandomNumber, as you have the option for what salt figure you give it, so as you say you don't get things appearing in synch or anything like that unless you really want that to happen.

Indeed my script above can be optimised a little further by having the spawn on first launch as a self-deleting function (as you will only ever need it once, when you first leave the station after a save game reload or new commander start), but what is above does work.
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:

Re: Station spawning oxps...

Post by Commander McLane »

Mauiby de Fug wrote:
With Superhub, they sometimes appear within a particular system, sometimes they don't.
Note that—according to its backstory—the Superhub is a mobile station (hence the two massive engines attached to it). Therefore it is expected to not always appear in the same systems all the time.

Perhaps you should get acquainted with the OXP-related Wiki pages as well, in this case the Superhub-page (or alternatively with the OXP's readMe). :wink:
Switeck
---- E L I T E ----
---- E L I T E ----
Posts: 2411
Joined: Mon May 31, 2010 11:11 pm

Post by Switeck »

The Superhub is often moved into place and the engines removed, hence the 2 hollowed-out pods still attached to it.
It was mobile, but is not now...at whatever location you find it.
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 »

Perhaps I've misunderstood it then. I was under the impression that the Superhub could move way again.
User avatar
Mauiby de Fug
---- E L I T E ----
---- E L I T E ----
Posts: 847
Joined: Tue Sep 07, 2010 2:23 pm

Post by Mauiby de Fug »

Thargoid wrote:
My script (the one reproduced above) was done before Ahruman came up with his random but repeatable number generation that you mention.

If you replace my random number with it, then you should get what you want. It is better than using pseudoRandomNumber, as you have the option for what salt figure you give it, so as you say you don't get things appearing in synch or anything like that unless you really want that to happen.

Indeed my script above can be optimised a little further by having the spawn on first launch as a self-deleting function (as you will only ever need it once, when you first leave the station after a save game reload or new commander start), but what is above does work.
Ah, I meant to say "scrambledPseudoRandom" rather than "pseudoRandomNumber"! So much for proof reading! Interesting point about the deleting of the function! I'm not really familiar with self-deleting functions, but I can see how they would be more efficient - thanks!

Commander McLane wrote:
Note that—according to its backstory—the Superhub is a mobile station (hence the two massive engines attached to it). Therefore it is expected to not always appear in the same systems all the time.

Perhaps you should get acquainted with the OXP-related Wiki pages as well, in this case the Superhub-page (or alternatively with the OXP's readMe). :wink:
I'm perfectly familiar with the relative wiki page and readMe file.
Superhub wiki page wrote:
About The Superhub
Traffic congestion in the Ooniverse is growing and while the stations are getting more advanced the market asked for a more radical solution. This solution comes in the form of the GASEC Superhub. The GASEC Superhub is the first station that is capable of transporting itself to its destination, two engine bays allow the GASEC SR-GD (Space Rotary Galactic Drive) to be fitted. At the destination these engines can be taken out for re-use in other transport missions.

Safer to dock
Problem of the older stations was that docking always was dangerous, especially in larger freighters. How many times we have witnessed the sad sight of an exploding workers commuter? The superhub is accommodated for larger ships. Just fly into the blue orb and docking is taken care of.

State of the art facilities
A superhub is far more than a space port. It's a modern hospital, office space or even an industrial park. Due to the Flex space (TM) technology Governments can design the superhub to their needs.

It's sturdy
How sturdy? we won't tell. And we don't encourage you to try it.

Habitat rings with a view
Our luxury apartments always have a birds eye view on space. Handy for the commander who can oversee his freight operations from afar.
I interpret this as follows: a busy high-tech system needs additional capacity, so orders another station. Rather than needing to be built in orbit, it is built at the shipyards (in Vetitice), and then transports itself out to its destination, where the engines can be taken out (as is clearly stated). There, it serves to expand the planetary system's facilities, and provides a safer means for large trade ships to dock.

It also states that it can be used for office space, and luxury apartments. Is it reasonable to expect a government's offices to up and wander about the galaxy, ending up in a completely different system!?

Furthermore, often it will disappear upon reloading a game. Now, realistically between docking and reloading and launching, not that much game time has passed (I know that launching takes about 10 minutes, and there may be other things like that that I'm not aware of). I fail to see how it makes sense for a busy spaceport to evacuate ships and visitors, and jump out of a system, in the space of 10 minutes. Therefore, even if the ship/station's engines were still operational and was still capable of jumping out, I would expect it to still be there when I re-launched from a station, even if it wasn't there when I jumped back into that system a few game-hours later.

Edit: just proof-reading the post, I've realised it seems unnecessarily argumentative, which is not the intention. I'm merely stating my reasons for changing the script.
Switeck
---- E L I T E ----
---- E L I T E ----
Posts: 2411
Joined: Mon May 31, 2010 11:11 pm

Post by Switeck »

Mauiby de Fug wrote:
I interpret this as follows: a busy high-tech system needs additional capacity, so orders another station. ... There, it serves to expand the planetary system's facilities, and provides a safer means for large trade ships to dock.
And how well it does that! Just having 2 stations would mean at least double the traffic-handling ability. But the Superhub's double-ended and very huge bay design...ships could dock at speeds that are insane with narrow slot docking port stations. For rich industrial systems over tech level ~10...it's almost a must-have. They can attract the really large trade ships. At the least, they can be presumed to have enough traffic that if they don't have that...then they probably need some other "secondary" station to handle their traffic.

So what I did was have a few OXP stations spawned based on government, economy, and tech level...but done in such a way that each system gets at most 1 "general purpose" OXP station near the planet. I combined the station creating scripts into 1 script so it could easily control which station gets created.

A Corporate State TL12-15 Rich Industrial is very likely to get a Superhub. Middle-range systems might have a Globe Station or even a rare Nuit Station (called Medusa internally for some reason). Lower-tech systems might have a Sothis Station, which is notable for its simplicity and ease-of-construction. (I tested other OXP stations but those were the ones I liked.) Going a little further, I edited their commodities menus so they had slightly more or less of an item for sale.
User avatar
Mauiby de Fug
---- E L I T E ----
---- E L I T E ----
Posts: 847
Joined: Tue Sep 07, 2010 2:23 pm

Post by Mauiby de Fug »

Switeck wrote:
So what I did was have a few OXP stations spawned based on government, economy, and tech level...but done in such a way that each system gets at most 1 "general purpose" OXP station near the planet. I combined the station creating scripts into 1 script so it could easily control which station gets created.

A Corporate State TL12-15 Rich Industrial is very likely to get a Superhub. Middle-range systems might have a Globe Station or even a rare Nuit Station (called Medusa internally for some reason). Lower-tech systems might have a Sothis Station, which is notable for its simplicity and ease-of-construction. (I tested other OXP stations but those were the ones I liked.) Going a little further, I edited their commodities menus so they had slightly more or less of an item for sale.
Interesting! I'm not sure I'd like to combine them all into a single script - I like to be able to take out individual oxps easily. Although I do like the idea of setting the conditions based on government, economy and tech level. The Superhub does this, and I intend to do something similar for the Sothis. At some point. 'Tis not high on my list of things to do, and I'd need to decide on the parameters.

I need to modify the frequency of the Globe stations. I've had them in my AddOns folder for ages and have never seen one yet. But from the look of the shipdata.plist, they replace icosahedron, but rarely, and I hardly ever see icosahedron stations themselves!
Last edited by Mauiby de Fug on Tue Nov 23, 2010 3:09 am, edited 1 time in total.
User avatar
pagroove
---- E L I T E ----
---- E L I T E ----
Posts: 3035
Joined: Wed Feb 21, 2007 11:52 pm
Location: On a famous planet

Post by pagroove »

Mauby de Fug is right about the statement that after the transport a Superhub is meant to stay in place. I myself am not a good scripter so I asked Thargoid for making a script. After long term use I also noticed that it wouldn't spawn everytime and intended to fix it but I couldn't really understand how the spawning script worked. Thargoid was at that time busy with finishing some of his own projects. But as you can see in the script it is placed within the public domain. So if anyone could enhance the script, repackage the file and update the readme and version number I would be very grateful.

I am very interested in your all in one station-script Switeck. I have been searching a long time for such a script. Does it aldo includes the P.A.Groove stations?

@ Cmndr Mc Lane: Good to know and honoured someone did read the background stories. ;)

Now I fantasize about a scripted mission for GASEC to help to protect a newly constructed Superhub on its journey to a new destination. This mission would includ a scripted process of taking the engines out.

A sweet dreams ....
For P.A. Groove's music check
https://soundcloud.com/p-a-groove
Famous Planets v 2.7. (for Povray)
Image
https://bb.oolite.space/viewtopic.php?f=4&t=13709
Switeck
---- E L I T E ----
---- E L I T E ----
Posts: 2411
Joined: Mon May 31, 2010 11:11 pm

Post by Switeck »

This may be overkill, but the if statements control the appearance...or not...of a station:

Code: Select all

this.shipWillLaunchFromStation = function () {
	if (this.firstLaunch) this.tryAddingCasinoship();
};
//this.shipWillExitWitchspace = function() {
this.shipExitedWitchspace = function () {
	this.firstLaunch = true;
	this.tryAddingCasinoship();
};
this.tryAddingCasinoship = function () {
	if(system.sun.isGoingNova || system.sun.hasGoneNova || system.isInterstellarSpace || !this.firstLaunch)
		{
		return;
		}

	if (system.techLevel > 9 && system.economy < 6 && ( system.government > 4 || system.government === 3 ) && system.pseudoRandom100 < (system.techLevel*5 + system.government*5 - system.economy*5 + 15) && system.countShipsWithRole("casinoship") < 1 )
	{
		system.addShipsToRoute("casinoship", 1, 0.995);
	}

	if(system.economy < 4 && system.government > 4 && system.techLevel > 10 && system.countShipsWithRole("pagroove_superhub") < 1)
	{
		this.xOffset = (Math.random() * 10000) + 10000; // x offset between 10 and 20km
		this.yOffset = (Math.random() * 10000) + 10000; // y offset between 10 and 20km
		if(Math.random() > 0.5) // 50:50 chance of offsetting in the other direction
			{
			this.xOffset = -this.xOffset;
			}
		if(Math.random() > 0.5) // 50:50 chance of offsetting in the other direction
			{
			this.yOffset = -this.yOffset;
			}
		system.legacy_addShipsAtPrecisely("pagroove_superhub", 1, "abs", system.mainStation.position.add([this.xOffset, this.yOffset, 0]));
	}

	if(system.economy < 2 && ( system.government > 4 || system.government === 3 ) && system.techLevel > 9 && system.countShipsWithRole("pagroove_superhub") < 1 && system.countShipsWithRole("medusa") < 1 )
	{
		system.legacy_addSystemShips("medusa", 1, 0.993);
	}

	if(system.economy < 4 && ( system.government > 4 || system.government === 2 || system.government === 3 ) && system.techLevel > 7 && system.countShipsWithRole("pagroove_superhub") < 1 && system.countShipsWithRole("medusa") < 1 && system.countShipsWithRole("globestation") < 1 )
	{
		system.legacy_addSystemShips("globestation", 1, 0.993);
	}

	if(system.economy > 1 && system.economy < 7 && ( system.government > 4 || system.government === 2 || system.government === 3 ) && system.techLevel > 3 && system.techLevel < 11 && system.countShipsWithRole("pagroove_superhub") < 1 && system.countShipsWithRole("medusa") < 1 && system.countShipsWithRole("globestation") < 1 && system.countShipsWithRole("sothis") < 1 )
	{
		system.legacy_addShipsAt("sothis", 1, "pwp", [(Math.random()*0.1), (Math.random()*0.2), 2]);
	}

	this.firstLaunch = false;
};
It could probably use a little improvement. :P
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 »

It's obvious now that I misunderstood the background of the Superhub. Probably my own imagination got in the way. I somehow found the idea cool that a station would let lots of traders dock, and then move into another system, thereby delivering the traders as well. So I ended up misinterpreting.

Anyway, under these circumstances it should be found in the same systems consistently, and Oolite's pseudo random is perfectly suited to do that.

May I add another suggestion? If the station is indeed immobile, it should also appear at the same place every time. Currently, if you visit the same system more than once, it gets relocated every time. The player will at least notice that its distance from the main station varies, but its direction varies as well. So this.xOffset and this.yOffset should be based on pseudo random too.
Switeck wrote:
It could probably use a little improvement. :P
You could for instance keep the if-statements shorter by moving the countShipsWithRole-queries into the first if-statement:

Code: Select all

   if(system.sun.isGoingNova || system.sun.hasGoneNova || system.isInterstellarSpace || !this.firstLaunch || system.countShipsWithRole("casinoship") > 0 || system.countShipsWithRole("pagroove_superhub") > 0 || etc.) 
      { 
      return; 
      } 
Then you don't need the ever-growing queries later on. If any one of them already exists, the script execution stops right here. The only thing you have to add below is an additional return after each adding-command:

Code: Select all

   { 
      system.addShipsToRoute("casinoship", 1, 0.995); 
      return;
   } 
This way you make sure that the code execution stops after successfully adding any one of the stations. No need to further evaluate the odds for the other stations.
User avatar
Killer Wolf
---- E L I T E ----
---- E L I T E ----
Posts: 2268
Joined: Tue Jan 02, 2007 12:38 pm

Post by Killer Wolf »

Well as i said in other threads, i have zero JS capabilities :-(
if anyone can cobble a quick script that populates the Sothis/Nest as per the randomiser but makes sure it's there on launch/exit from WS etc, i'll update my OXPs. i'd think it's a simple matter of putting OR statements in and checking a station doesn't already exist?
perhaps this should be in the Script Request bit instead?
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 »

Killer Wolf wrote:
i'd think it's a simple matter of putting OR statements in and checking a station doesn't already exist?
In principle, yes (like my suggestion in my post above).

On a second thought, however, checking for each type of station individually is not really satisfactory. It means that you have to update the spawning scripts of all stations (and/or a general spawning script) each time a new station OXP is released.

So it would be more sustainable not to check for the presence of each individual station, but to have one single check that would capture any station that is part of the mutually exclusive set. I can imagine two basic ways to achieve that.

1) Add a new, common role to all stations in question. They can continue to be spawned by their individual roles, but they all would have another role, common only to each other, and there would only a check for the presence of an object with that role be needed. One check catches any possible station.

The drawback of this method is obviously that the existing OXPs have to be changed in order to add this role; and future OXPs would need the role too, in order to get included in the mechanism.

2) Find the common determinator of all stations in question, and perform a search for this one, instead of checking for individual stations. For instance, if all the stations in question are added somewhere in the aegis of the main station, you only need to check whether there is another station close to the main station, regardless of its role.

The tricky part in this approach is of course to determine the common determinator. If one of the stations is supposed to be spawned near the witchpoint, but shall nevertheless be mutually exclusive to the other stations, it gets much harder to find one. And you can't just check for the presence of any dockable object, because there are still some which shall be spawned together with the additional stations (like Rock Hermits, or Salvage Gangs).

I think the first approach may be the way to go. Give all stations taking part an additional role, something like mutually_exclusive_additional_station or somesuch. If re-releasing a station OXP is not possible for some reason, it can also be done by a shipdata-overrides.plist.
User avatar
Thargoid
Thargoid
Thargoid
Posts: 5527
Joined: Thu Jun 12, 2008 6:55 pm

Post by Thargoid »

Depending on the pool involved, it may also be worth considering taking an overall pool of all stations (for example everything scanClass STATION, or some similar baseline) and then explicitly removing stations from that list by role or other factors (Rock Hermits, Salvage gangs etc to re-use the previous examples).

Depends a little if you want new OXP stations included or excluded by default. But by explicit exclusion you only have to worry about one OXP (the one with the spawning script) being kept up to date and under control).

It's the same basic idea as 1) above, but may be more flexible or easier to maintain.
User avatar
Micha
Commodore
Commodore
Posts: 815
Joined: Tue Sep 02, 2008 2:01 pm
Location: London, UK
Contact:

Post by Micha »

Commander McLane wrote:
May I add another suggestion? If the station is indeed immobile, it should also appear at the same place every time. Currently, if you visit the same system more than once, it gets relocated every time. The player will at least notice that its distance from the main station varies, but its direction varies as well. So this.xOffset and this.yOffset should be based on pseudo random too.
I dunno - having stations near a planet shift positions every time the player enters the system afresh gives the illusion that they're orbiting the planet. The main issue I think is that it's odd for stations to be randomly in a system or not, rather than pseudo-randomly.
The glass is twice as big as it needs to be.
Post Reply