unorthodox-paradox / omsi_2_csb_ai_enhancements

AI enhancements for CSB vehicles
1 stars 0 forks source link

Improve random number generation #15

Open unorthodox-paradox opened 5 years ago

unorthodox-paradox commented 5 years ago

Background

OMSI offers two facilities for random number generation:

It goes without saying that many scripts of this mod heavily depend on random number generation, particularly when, during initialization, several hundred per-vehicle traits, such as those contributing to the "personality" of each individual AI vehicle, are established. Such scripts were authored with certain (rather reasonable, in our opinion) assumptions in mind:

Problem statement

Unfortunately, casual observation thus far, combined with the fact that the (atrociously vague) SDK documentation promises none of the above, have given rise to suspicion on the quality of random number generation:

Course of action

For now the above are merely speculation. Proper tests should be written and executed in a "vehicle-busy", ideally "strained" / low FPS setting, to test the aforementioned observations' validity. If OMSI's random number generation indeed turns out flawed, the only real workaround would be to write a plugin that consumes an OS-exposed PRNG's output and delivers it back to the scripts. To mitigate potential performance impact, the two approaches could also be combined, with the OS being used for obtaining crucial initial seeds and those being subsequently plugged into OMSI's facilities for further / subsequent generation.

Progress thus far

As a temp-fix, most initialization calls to random (in ai_pre_cockpit.osc, lights_ai.osc, and lights.osc) have been replaced by random→NrSpecRandom to at least mitigate cross-vehicle initialization similarities. The results are mixed. Post-initialization random number generation still relies on plain random.

unorthodox-paradox commented 5 years ago

Some preliminary testing was conducted. At X10/Hertzallee any spawned AI buses would generate 100 random values concurrently at variable intervals. The values generated turned out to be distinct and not following a common pattern per vehicle (type) or frame, thus suggesting that OMSI is not the one to blame here.

Instead the fault lies with the following assumption of ours, which is anything but reasonable:

The distribution of random numbers generated through either facility is (expected to be) normal.

No, obviously it ought to be uniform (duh!).

This makes it crystal clear why, whenever we generate a random value without otherwise bounding its interval by probability -- which, unfortunately, in at least as many as half of all applicable instances we do not -- the probability of a value close to the interval's bounds being generated (typically implying an unusual trait being selected, or an exceptional exception occurring) is just as high as the one of a value close to the norm. This is of clearly not what we had in mind.

Revised course of action

  1. Revert from the random→NrSpecRandom idiom back to plain random, save for those (rare to non-existent in the scope of this project) cases where per-vehicle-instance generation of characteristics is actually desired. It hurts readability (it might hurt performance as well, even though that's pure speculation) for no good reason.
  2. Revisit every single instance in the script base where random number generation occurs, thinking long and hard whether in that particular case a normally- or uniformly-distributed one makes more sense.
  3. Figure out how to conveniently convert from uniformly-distributed OMSI random to (approximately) normally-distributed randoms. Update all instances requiring normally-distributed randoms as appropriate.