Page 1 of 1

Proposals for Oolite 1.79/1.80, 4 of 5: New system populator

Posted: Tue Jun 18, 2013 6:08 pm
by cim
Here's the fourth one for comments. As with the last one there's a block in italics near the end where I can see arguments for doing this either way and don't have a strong preference.
Scriptable System Populator
A rewrite of the system populator to allow more JS control of system population.

Problem:
System populator is inflexible and does not expose enough information about the system. Difficult for OXPs to determine what system contents other OXPs are adding if interactions needed. Difficult for OXPs to override aspects of system populator either selectively or fully. Timing of system population for OXPs is variable - startUp, and various launch/witchspace events.

Ships added near witchpoint generate rings, which are often unwanted but require silly hacks to avoid.

If we later bring in support for adding new systems/galaxies will need easier way for OXPers to stop them looking exactly like the old ones.

Proposal:
Populator is controlled by an dictionary of dictionaries. systemWillPopulate() or interstellarSpaceWillPopulate() event will be called in worldscripts to allow modification of it (two separate events because virtually no-one wants to do the same thing for both!). Called at usual system population time (just before shipWillExitWitchspace).

It will then be possible to set a different function name in planetinfo.plist or through the SystemInfo object to call when populating the system. (For example, the nova mission would change the function to novaSystemWillPopulate after the event has occurred) This makes it easy for specific systems to have completely different population rules.

Event order on game start would be modified slightly so that only planet(s), sun, mainStation and player added initially. Then JS startUp() called. Then populator functions called.

Ships added by populator don't generate rings.

Addition from other JS functions (or even legacy code) of course still possible, but discouraged as a means of populating the system.

To fix minor bug with compass and commie astromines, nav/witchbuoy addition to happen before asteroids added.

Populator functions return a dictionary of dictionaries. Later-running populator functions may overwrite entries from earlier ones - though of course beyond "core scripts run before OXP scripts" inter-script communications may be needed to manage this as execution order is undefined; in practice changing the name of the population function is likely to be a better way to adjust system population ... this is mainly intended to allow overriding of the core populator. A system.populator read-only property may be used to query the existing entries, which would look like this.

Code: Select all

"oolite-route2-pirates" : {
	priority: 2, // default 100
	location: "LANE_PS", // default "LANE_WP"
	locationSeed: 0, // optional, default 0
	groupCount: 10 - system.government, // default 1
	callback: function(pos) {
		var num = 1+Math.floor(Math.random()*5);
		system.addGroup("pirate",num,pos,5E3);		
	}, // required, no default
	deterministic: false // optional, default false
}
(Note: these are examples, not the values actually used by the current or future system populator)

priority: 0..65535. All priority X run in arbitrary order, then move on to next lowest X.

location can be "LANE_WP", "LANE_PS", "LANE_WS", "WITCHPOINT", "STATION_AEGIS", "PLANET_ORBIT", "STAR_ORBIT", "PLANET_ORBIT_HIGH", "STAR_ORBIT_HIGH", "PLANET_ORBIT_LOW", "STAR_ORBIT_LOW", "TRIANGLE", "INNER_SYSTEM", "OUTER_SYSTEM", "INNER_SYSTEM_OFFPLANE", "OUTER_SYSTEM_OFFPLANE", or a vector expression. In interstellar space, all named locations are equivalent to WITCHPOINT. Named locations are translated to a vector at callback time to spread out groups.
  • WITCHPOINT: picks a location within scanner range of the witchpoint.
  • STATION_AEGIS: picks a location within twice scanner range of the main station.
  • LANE_*: picks a location within LANE_WIDTH (probably set to 2x scanner range) of a random point between the two endpoints, at least three radii from the centre of the object and at least scanner range from the witchpoint.
  • *_ORBIT: picks a random point between 1 and 3 radii from the surface of the main planet or sun. The _LOW suffix changes this to be between 0.1 and 1 radii, and _HIGH is between 3 and 7 radii.
  • TRIANGLE: picks a random point on the triangle formed by sun, witchpoint, and planet, at least 3 radii from the sun and planet, and 3 scanner radii from the witchpoint
  • INNER_SYSTEM: picks a random point closer to the sun than the planet is (but at least 3 radii out), within 50km of the triangle plane
  • OUTER_SYSTEM: picks a random point further from the sun than the planet is (but not more than 10^7 metres away), within 1% of the triangle plane
  • *_OFFPLANE: picks a point as for *_SYSTEM but without the orbital plane constraints.
locationSeed if set and greater than zero seeds the random number generator used for the named locations. Seeded locations would be system-specific: PLANET_ORBIT 3 is not going to be in the same place relative to the witchpoint and sun from one system to another.
Other named regions could be added if needed, though since at the start of the populator run the only known positions are the planet, sun, main station, and witchpoint, they would have to be relative to those in some way.
The *_SYSTEM and especially *_SYSTEM_OFFPLANE placements depend on the coordinate precision being improved to double-precision to be much use, so might be left for a later version.

The callback function will be called groupCount times. If the location was not a vector expression, then the callback will get a new random position each time (if it was a vector expression, there's not much point in having groupCount > 1). If the named location is seeded, the RNG will only be seeded before generating the first location: so the rest will also be deterministic based on the seed and the count, but distinct from the first location.

deterministic is a statement (unenforceable) that if the system is regenerated later (at least using the same populator function, and without the player leaving the system and returning with some state changed), this populator call will be made again in exactly the same way and will achieve the same results. It is forced to false if the location is an unseeded named location, and perhaps in other circumstances (e.g. sun gone nova).
At the moment, this doesn't do anything, but my reason for including it now is that for some later version is that stations populated with the deterministic flag could have save/load. So save at the local Constore, which will 'always' be there (with fallbacks for OXPset changes (re)moving it, of course) but not on that Super Bulk Hauler that happens to be there right now but won't be later.

Oolite would for 1.79/1.80 add default population functions to approximately match the current situation. The semi-persistent rock hermits might change location on the switchover, since keeping identical RNG behaviour would be trickier, but that's probably not important since they were going to move anyway.

OXPs calling system.addShips/addGroup on shipWillExitWitchspace, startUp and often shipWillLaunchFromStation should then be encouraged to use the system populator instead. This will allow other OXPs to completely remake a system, sector or even galaxy without needing to worry too much about which of the more generic flavour OXPs a player has installed.

Repopulation
The current repopulation mechanism is that ships exiting the system to witchspace usually cause a new ship with the same primary role to be added later on. In general most ships leaving this way are traders launched from stations, so the system tends over time to only have traders in it.

This could be replaced by a set of repopulation functions using the same methods as above: default names systemWillRepopulate() or interstellarSpaceWillRepopulate(). These would be called from time to time and would add new ships to the system - most likely by addShips at the witchpoint but equally these functions might call the various launch methods of stations.

How often should they run? Every minute? Every five minutes? Every time a ship leaves and/or is destroyed? Should the expectation be for the core Oolite populator that it adds something every time repopulation is called, or should it be called more often and most of the time not queue anything?

In general the repopulation functions would not be doing anywhere near as much ship addition as the initial population, of course. Witchspace exit rings would be generated as usual for repopulating the system.

Re: Proposals for Oolite 1.79/1.80, 4 of 5: New system popul

Posted: Tue Jun 18, 2013 8:07 pm
by Cody
How often should they run? Every minute? Every five minutes? Every time a ship leaves and/or is destroyed? Should the expectation be for the core Oolite populator that it adds something every time repopulation is called, or should it be called more often and most of the time not queue anything?
I'm gonna have to think about that... what worries me is that I understand it (I think). <chuckles>

Re: Proposals for Oolite 1.79/1.80, 4 of 5: New system popul

Posted: Tue Jun 18, 2013 8:23 pm
by Switeck
An example problem I had was I wanted to do a special base "deep" in interstellar space, reached only after misjumping multiple times to reach it.
I didn't want Thargoids around, since it's not along any system-to-system routes, but system populator would spawn them anyway.

Removing the Thargoids using a small script that consisted of a for-loop worked, but could leave graphical glitches as well as increase the remote chance of a crash due to (quickly?) allocating/unallocating the associated memory, objects, and variables associated with those Thargoids.

Another idea which I actually got far enough along to actually use on a regular basis was "safe"(r) systems that had reduced levels of pirates. These were a handful of "safer" government-type systems near Lave, which only stayed "safe" for however long the player had few kills and low/no bounty. I converted the existing pirates along the witchpoint-planet route into traders and removed their bounties, but this might cause their escorts to break off and go rogue due to bounty differences. The escorts had their bounties removed as well, but that was only done in a second for-loop after the pirates' one finished.

Adding stations to a system might work better if it could be fed through the system populator as well, that way conflicts could be avoided and exclusions (this OR that, but not both) could be easily done. Proximity checks might be needed to avoid stations being positioned touching or at least very close to each other. I've seen a rare case where a station's exit had an asteroid <3 km in front of it.

As for ship replacement in-system, traders get replaced but I don't think pirates are...so after only a handful of minutes the number of pirates in-system has often decreased to less than half.

Re: Proposals for Oolite 1.79/1.80, 4 of 5: New system popul

Posted: Tue Jun 18, 2013 9:20 pm
by JazHaz
Does the system populator also add rock hermits etc?

I would like to see systems being populated the same each time you jump into it, so the same hermits and stations. They don't have to be in the exactly the same positions (but near enough). If you are doing a milk run, it seems weird for stations to have disappeared the next time you visit.

Perhaps the population for each system could be generated from a seed, similar to the way the galaxies were originally generated by Braben & Bell in the original game?

Re: Proposals for Oolite 1.79/1.80, 4 of 5: New system popul

Posted: Thu Jun 20, 2013 2:05 pm
by pagroove
JazHaz wrote:
Does the system populator also add rock hermits etc?

I would like to see systems being populated the same each time you jump into it, so the same hermits and stations. They don't have to be in the exactly the same positions (but near enough). If you are doing a milk run, it seems weird for stations to have disappeared the next time you visit.

Perhaps the population for each system could be generated from a seed, similar to the way the galaxies were originally generated by Braben & Bell in the original game?
+1.

This is a long time wish for me also.

Re: Proposals for Oolite 1.79/1.80, 4 of 5: New system popul

Posted: Thu Jun 20, 2013 2:19 pm
by cim
JazHaz wrote:
I would like to see systems being populated the same each time you jump into it, so the same hermits and stations. They don't have to be in the exactly the same positions (but near enough). If you are doing a milk run, it seems weird for stations to have disappeared the next time you visit.
For the objects added by the populator in 1.77 this is already the case:
- the main station is always of the same type and in the same place relative to the planet (and that position is currently determined by the system_seed value). This has been the case for a very long time.
- on-lane rock hermits will remain in the same place in each system for some time, but are periodically repositioned (monthly or thereabouts, I think). This is new in 1.77
Those are the only two core objects you'd expect to be static, aren't they? (As a consequence of the hermits, non-hermit asteroid fields also behave the same way, I think)