Page 1 of 1

Deterministic Oolite

Posted: Sat Aug 26, 2017 2:35 pm
by Astrobe
Two major aspects of Oolite are driven by random numbers:
  • The default populator and customizations of it like Skilled NPCs, Deep Space Pirates, ...
  • Market prices and quantities.

Randomness in games has several roles:
  • Give you a chance when you are in a dire situation, or transform a normal situation into a challenge,
  • Introduce variety without using complex computations and by extension to simulate complexity (this results from Kolmogorov's randomness and complexity: a piece of data is said random if the shortest program that can generate it is larger than the data itself, and the complexity of a piece of data can be measured by the length of the shortest program that can generate it).

Default Oolite scripts and OXPs often use system properties as probability weights or even directly. However, the government type/economy type/Tech level trinity is very often used, because those properties are what one sees on the galactic charts.

There are two issues with this:
  • Systems "lack personality": Xexedi is not a nice system because it's Xexedi, but because it's a high tech rich industrial corporate system. Other high tech rich industrial corporate systems will look
    mostly like Xexedi because OXPs introduce features using the same deterministic criteria everywhere. Also, because many OXPs add features using a similar logic, rich high TL tend to be overcrowded and poor low TL systems tend to be deserts.
  • Whenever randomness is used, neither OXPs nor players can make smart choices. A side effect is that randomness cannot be too random because it would be too arbitrary and/or very hard to deal with, so we end up with the infamous computer-fur trade and with dead Jamesons in Cobra III ships who did nothing very wrong.

Oolite's scripting interface has a function that allows to avoid those issues: pseudoRandomNumber(). This function takes a "meaningless" number and returns a random constant for a given system. This function can be understood as providing additional properties to the system; writing something like average_planet_temp=pseudoRandomNumber(0)*20 would completely make sense. I'd like to promote its use by showing an example where it shines.

Deterministic markets. Commodity prices can be computed with a simple deterministic formula. For instance (1+ sin t)*universal_average_price, where t is the in-game time. It looks uninteresting at first because it would make prices the same everywhere at a given time. However, because it depends on time and because it takes time to travel from system to system, what players see is prices that vary randomly, at least at first. I think it won't take long before they figure out how it works and how to use that knowledge to plan their moves and maximize their profits reliably, though.

One can make it a little bit more complex by introducing system-specific constants like the period, phase or magnitude of the oscillations with pseudoRandomNumber(). One can still use something like economy type to offset a bit the universal_average_price and some easy predictability for the player, but one should also throw a pseudoRandomNumber() in the mix to give each system its own flavor.

With about a dozen of commodities and both prices and quantities for each to compute, the TL/GT/ET trinity won't provide enough "entropy" anyway, so pseudoRandomNumber() is almost mandatory. So we can have simple formulas with hidden constants that yield numbers that look more-or-less random but aren't. Different methods, same results?

One thing that determinism allow, for instance, is "multiplay". One can play with two (or more) commanders: one two scoot ahead prices (and other deterministic system features like the skill level of the local pirates; it only takes a little script that changes a variable of Skilled NPCs), and one to actually trade. This requires to keep both commanders in the same in-game time window, so one can hardly call it a cheat or an exploit.

A second opportunity one can think of is to turn annoying masslocking NPC traders into valuable sources of information, with OXPs like Broadcast Comms. This is possible only because other OXPs can query the prices and quantities for any past (and future) time, any system and any commodity. This goes beyond the current "I've heard there's good price at Xexedi", which the players can easily figure out themselves. Alternatively, it can translates into an MFD displaying the current prices in nearby systems. That could be a solution to boredom on the lanes.

Deterministic and predictable are two different things because complexity can make a deterministic system difficult to predict to the point it looks random. Complexity in turn doesn't mean complex programming; it can result from many simple interactions. This phenomenon is known as emergence. Although a sufficiently complex deterministic system and a weighed random system can look the same, as far as video games are concerned, the deterministic approach is more interesting because providing tools to help players with the complexities of the game is more valuable than providing tools to shield players from the unfairness of a random generator.

Re: Deterministic Oolite

Posted: Mon Aug 28, 2017 9:04 am
by phkb
I like the idea of making markets more deterministic. The only fly in the ointment (for the moment, anyway), is that pseudoRandomNumber (and scrambledPseudoRandomNumber), don't work for a system when you're outside that system. So if I'm in Lave, I don't know what a random number using these methods will be for, say, Zaonce.

It's not an insurmountable problem, though. If an OXP re-wrote the market calculations, it could implement it's own version of these functions that would do the job.

Re: Deterministic Oolite

Posted: Mon Aug 28, 2017 10:38 am
by Astrobe
You are correct, I just assumed it worked "remotely" even if it was obvious it doesn't because one doesn't pass the system ID/galaxy ID to the function (plus, I wrote pseudoRandomNumber when I really had scrambledPseudoRandomNumber in mind). Don't mind the details anyway :-)

Furthermore I quickly looked at the source code to see if it could be reused to get that sort of thing, and the generation of those numbers seem to me a bit more "heavy" than expected.

Another thing I've noticed is that sometimes, OXPs really want to get random numbers with a normal distribution ("bell curve" distribution) instead of the uniform distribution RNGs typically provide. Different authors use different methods, and I'm not sure the results they get is actually what they wanted.

So I'm thinking an extra core RNG function to which one could pass a seed that would return a random number using a normal bell curve distribution could be useful to build a JS library of handy functions. It looks like something I can do.

Re: Deterministic Oolite

Posted: Sat Sep 02, 2017 2:24 pm
by NewtSoup
You can easily get a bell curve by summing multiple random numbers between values.

for example the ever popular D6

roll a single D6 100 times and plot the results on a graph of occurrence / resut and you will get roughly equal columns for each number between 1 and 6

roll 3D6 ( for that magic STR, CON, DEX, INT, WIS, CHR ) 100 times and plot the results and you will get a bell curve for the numbers 3 to 18 ( 16 values total ) You can make that 0-15 simply by subtracting 3

Re: Deterministic Oolite

Posted: Sat Sep 02, 2017 3:21 pm
by Astrobe
NewtSoup wrote: Sat Sep 02, 2017 2:24 pm
You can easily get a bell curve by summing multiple random numbers between values.
Yep, I remembered that rolling two D6 statistically yields more often values around 7. So I tried to average 4 random numbers in the range [0-63], and for 1 million rolls I get an almost perfect bell curve. I've just realized that the standard deviation (the "narrowness" of the peak) is probably controlled by averaging more or less randoms, as I remember that with an average over two randoms I got an almost triangle shape. Gotta try it but my test program is on my other machine.

edit: now I remember I even did an average on one number to check that I got a uniform distribution as expect. And all this time I was thinking that maybe a uniform distribution is just a normal distribution with a huge standard deviation... I'm an idiot.

Re: Deterministic Oolite

Posted: Sat Sep 02, 2017 3:46 pm
by NewtSoup
Right, so in Javascript

Math.floor ((Math.random()*11)+1);

gives you random number between 1 and 11 with a linear distribution

for a number between 0 and 100 with a standard distribution we could do

Code: Select all

function myFunction() {
	var x=0;
    for ( n=0;n<10;n++){
     	x += Math.floor((Math.random() * 11) + 1);
    }
    	return x-10;
}
By summing multiples of D11 we end up with a greater number of "middling" results.