Author Topic: Chaotic vs. Random  (Read 948 times)

Legacy_Rolo Kipp

  • Hero Member
  • *****
  • Posts: 4349
  • Karma: +0/-0
Chaotic vs. Random
« on: December 24, 2011, 05:53:18 pm »


                <striking a spark into the tinder...>

Ok, this will be a bit long-winded, but I gotta be me :-)

This post actually concerns (among other things) "Vegetation Distribution in Regional Nodes Using Template Areas".

The Goal: To distribute vegetation in a consitent, but unique manner in each regional node using template areas.  (Something in some ways similar to Skipnuttz idea of algorythmically generating tree placeables)

Problems: There may be thousands of nodes, with hundreds using the same template area.  Random placement will not work as the layout of the map would change everytime the node was woken up (completely defeating the purpose of using nodes for consistency).  Static placement in the template area will not work as every node using that template would look the same.

What is required is a chaotic algorythm for distributing vegetation in a variable probability, unpredictable fashion that is consistent per node.

(Chaotic vs. Random: Random functions will return different, unpredictable values every time. Chaotic will always return a consistent, but unpredictable value for the same "seed value".)

Set up: Each template area will have a variable number of waypoints (green flag - "wp_veg_(AreaIndex)") for placing vegetation in reasonable places (placed by design).
The WakeUpNode() function will (among other things) step through all wp_veg's for the area and call a GetVegValue() function seeded with the NodeIndex and the WpIndex (a local int stored on the wp_veg the first time it's called giving each a unique index).
GetVegValue() will return an int in the range -9 to +9.  
The values should be generated in a bell curve that peaks at 0. (Edit: there should be very few +/- 9s, and about half should be negative values)
Negative values will be clipped (values <1 will result in no vegetation for that wp_veg).  

With the default state, this means that about half the wp_veg will be empty, that most wp_veg will spawn low-level vegetation and that the *same* vegetation will spawn (in any given state) *every* time the node wakes up (for any given NodeIndex|WpIndex seed).

Dynamic States: Getting the range in a bell curve with negative clipping allows a very neat little trick that ties into my Dynamic States system; The default state modifies the VegValue by 0 (that is unmodified).
If the state of the node is below normal (say logged or even clearcut), the VegValue is decremented by up to -4, giving a new range of vegetation from -13 to 5 with the peak probability being -4. At the worst possible state (not counting special states, which is a different subject), *most* of the wp_veg would be empty and the highest possible wp_veg is 5 (small tree) - only a very few of them.
If the state of the node is above normal (deep forest, mature forest or even climax forest), the VegValue is incemented by up to +4, giving a new range of -5 to +13 (values >9 are considered 9) with the peak distribution being at +4 (small trees) and a huge shift toward the number of Giant trees placed.
One more point about how this ties in to dynamic states: The highest value wp_veg points are *always* the highest value wp_veg.  That small tree in the clearcut state will be the growth leader as the state improves toward climax forest. *That* tree will always be among the largest in that node. Similarly, the weakest wp_veg points will always be the weakest, and will be the first points to lose their vegetation.

The Question: I got this far before my coffee got cold ;-P So, what would be a good function to return chaotic integers in the range -9 to +9, with a bell curve distribution that peaks at 0, given two seed values - NodeIndex (range 1 to ~64K) and WpIndex (range 1 to 255)?

<...and blowing hard>
               
               

               


                     Modifié par Rolo Kipp, 24 décembre 2011 - 07:06 .
                     
                  


            

Legacy_Lightfoot8

  • Hero Member
  • *****
  • Posts: 4797
  • Karma: +0/-0
Chaotic vs. Random
« Reply #1 on: December 24, 2011, 06:31:30 pm »


               Sorry I do not have time to fully read your post,  

I will give what comes to my mind from the little I have read however.   I think you are looking for something that falls within "chaos theory"   A search of the web may help you in your search.  A search of "chaos functions" may also help.  I am not sure how fruitfull the  results of the searches will be.  I have not done them.  

Chaos theroy is nothing more then random infuunces acting on a fixed set of laws.   For example a  snow flake,  Every show flake molecule has six nodes where the next molcule can attach.   It is random as to which node the next molecule will attach to.  The  molecule attaching to the first one then takes the up one of the nodes of the first molcule but adds 5 more nodes for random attachment.   Giving a unique snowflake,(they say no two are the same) That still has the same basic shape of other snowflakes.  

The Snowflake is a pretty setforth pattern.  There are other pattern types that follow pramerters that result in more chaotic looking patterns.  

Hope that is somewhere close to what you ar looking for.   Ill try and read your post more fully later.
               
               

               
            

Legacy_Rolo Kipp

  • Hero Member
  • *****
  • Posts: 4349
  • Karma: +0/-0
Chaotic vs. Random
« Reply #2 on: December 24, 2011, 06:42:52 pm »


               <offers a toast...>

You are always quick with help, LF. Love ya for that :-) Hope your Holidays are busy, bright and exciting =)

I'm a big fan of Chaos, as you might guess ;-) Wait until you see the tileset for Needlespire (based on a portion of a Julia Set) ...spiral peaks and spiral valleys and spiral ambush sites!

Quibble: Chaos Theory is actually "the behavior of dynamical systems that are highly sensitive to initial conditions" (from the Wiki), i.e. *not* random. Your snowflake molecules (as opposed to mine, which never behave properly :-P ) are sensitively dependent on initial location and brownian influences.

So I want my plant selection to be sensitively dependent on the NodeIndex and WpIndex :-)

Beats having to hire a landscaper (since that would be Cestus, and he gets *soooo* grumpy in the woods!).

<...rather than a roast>
               
               

               
            

Legacy_Lightfoot8

  • Hero Member
  • *****
  • Posts: 4797
  • Karma: +0/-0
Chaotic vs. Random
« Reply #3 on: December 24, 2011, 08:05:35 pm »


               <Still have not fully read.>

Rolo Kipp.
Quibble: Chaos Theory is actually "the behavior of dynamical systems that are highly sensitive to initial conditions" (from the Wiki), i.e. *not* random.

Yes, I never liked that as the all encompassing deffinition for the throey.   The theory covers so much more then that, At least the original book by that title that I read way back in 1985 or abouts.  I came away with more of a theory of random influnces to a set of laws that produce resultes within given perameters.    Just like Square and triangle Fractals. (interesting I dont see a quick link to the Square on the net. lol. )   

'Posted


And interesting paterns from combinations of patterns(laws with Random influnces)

'Posted
 
I guess the point is I could see you growing your forests with random inputs to your Natural Laws of growth.   For a Given area You would just Record and store the Random events in order to Reproduce it the same later.  

But I still have not fully read your post.  Will get to it latter.  So for now just excuse my obvious trolling.  
               
               

               


                     Modifié par Lightfoot8, 24 décembre 2011 - 08:06 .
                     
                  


            

Legacy_Failed.Bard

  • Hero Member
  • *****
  • Posts: 1409
  • Karma: +0/-0
Chaotic vs. Random
« Reply #4 on: December 24, 2011, 11:08:41 pm »


                 This would be a way to incorporate a spell like plant growth, so that PC druids can wander about helping restore the forest in areas that have been damaged.

I had some random desert areas I was going to (eventually) make for my mod, that would use a similar system to this, so I'll see if I can make up a script framework of some sort if you want. I've got another eight days off on our christmas shutdown I need to fill anyways.
               
               

               


                     Modifié par Failed.Bard, 24 décembre 2011 - 11:10 .
                     
                  


            

Legacy_Rolo Kipp

  • Hero Member
  • *****
  • Posts: 4349
  • Karma: +0/-0
Chaotic vs. Random
« Reply #5 on: December 24, 2011, 11:49:56 pm »


               <fracturing a few...>

Lightfoot8 wrote...
<Still have not fully read.>

Yes, I never liked that as the all encompassing deffinition for the throey.   The theory covers so much more then that, At least the original book by that title that I read way back in 1985 or abouts.

Chaos by James Gleick?

Loved that book... It's what got me started in quantum physics :-)
(edit: Well, that and the names of quarks - strange & charmed especially ;-)

I came away with more of a theory of random influnces to a set of laws that produce resultes within given perameters.    Just like Square and triangle Fractals. (interesting I dont see a quick link to the Square on the net. lol. )    

Ahhh! Serpenski's Triangle =) A Serpenski Pyramid was my first ever Sculpt3D object!
'Posted
(note: this is *not* my version, which is long lost and was metallic gold besides)


I guess the point is I could see you growing your forests with random inputs to your Natural Laws of growth.   For a Given area You would just Record and store the Random events in order to Reproduce it the same later.

Wouldn't that be nice? However, at least for now, I've a more prosaic and (relatively) reasonable demand upon the NwN engine.  I hope.

<...fairy tales himself>
               
               

               


                     Modifié par Rolo Kipp, 25 décembre 2011 - 12:05 .
                     
                  


            

Legacy_Rolo Kipp

  • Hero Member
  • *****
  • Posts: 4349
  • Karma: +0/-0
Chaotic vs. Random
« Reply #6 on: December 24, 2011, 11:57:07 pm »


               <planting a seed...>

Failed.Bard wrote...
This would be a way to incorporate a spell like plant growth, so that PC druids can wander about helping restore the forest in areas that have been damaged.

Exactly what I had in mind. Along with a mechanism that allows catastrophic damage from rampaging terrasques and ticked off red dragons, or even the long-term effects of over-harvesting.
Druids & rangers (and Briarmages) try to build up the forest (or other ecosystem). Farmers and other monsters try to tear it down... Sounds like a great opportunity for conflict management :-)

I had some random desert areas I was going to (eventually) make for my mod, that would use a similar system to this, so I'll see if I can make up a script framework of some sort if you want. I've got another eight days off on our christmas shutdown I need to fill anyways.

Well, not today or tomorrow...
Just because *I'm* at loose ends doesn't mean I want to take other people away from warmth and bubbly (laughter, I mean ;-). But I'm always interested in what you code. You do a lot of things the way I like, so it's doubly interesting when you do things different :-)

<...because it was too hard a nut to crack>
               
               

               
            

Legacy_wyldhunt1

  • Sr. Member
  • ****
  • Posts: 443
  • Karma: +0/-0
Chaotic vs. Random
« Reply #7 on: December 25, 2011, 12:27:58 am »


               This is something we have already started work on for our instancing system also.
Our basic theory on the setup is something along these lines:
Our map is laid out on a grid, wherein each square is a 13X13 area.
Each template area has (among other things) a name that ends with the its place in the template array. So, we would have TemplateArea1, TemplateArea2, etc. Another template area would be OtherTemplate1, OtherTemplate2, etc.
We create arrays listing all of the potential templates in each block of map squares (We call them zones). We lay them out from the South-West corner and make rows of the templates in order.
The SouthWest area will spawn TemplateArea1. One square East will spawn OtherTemplate1. Then TemplateArea2 (Areas are created on the fly as needed and named appropriately).
In each base (Static) template area, there are placed waypoints with arrays of potential placeables.
A 'random' placement of placeables on the waypoints is generated by using the x/y coordinates of the map as a seed of sorts. I sort through the potential placeable templates on a pattern that matches those numbers. x first, then y. If the end of the placeable array is reached, it begins again at the first one.
In this way, an apparently random pattern can be created which will always spawn the same.

The system is still a work in progress, but the initial tests appear to confirm that it'll work fine.
               
               

               
            

Legacy_Failed.Bard

  • Hero Member
  • *****
  • Posts: 1409
  • Karma: +0/-0
Chaotic vs. Random
« Reply #8 on: December 25, 2011, 12:43:02 am »


               It looks like the growth chains will be easiest to handle off a 2da, though for my initial testing I'm also including a switch/case since there's only one type (* 10 stages) to handle.

 If you're planning to dynamically create areas from generic re-usable map instances the coding will be slightly harder, though not really terribly so.  You'd just need to set the appropriate variables on the area before the vegetation is added so that it's using the proper stored DB entries for filling it.

 I'm a bit curious how many WPs you'll be using in any given area as an expected maximum, and a bit more detail on how you want to handle seasonal vegetation losses would help, though that part wouldn't be going in right off regardless.
               
               

               
            

Legacy_Rolo Kipp

  • Hero Member
  • *****
  • Posts: 4349
  • Karma: +0/-0
Chaotic vs. Random
« Reply #9 on: December 25, 2011, 01:42:49 am »


               <wrapping up...>

@WH: I'm not sure I am picturing how your zones are constructed from areas. Are your templates used for many areas? How do you generate areas on the fly? Are they consistent topologically (i.e. *every* time a PC goes that way, they find the same area)? Discuss in a new thread?

@FB: "If you're planning to dynamically create areas from generic re-usable map instances" Yes,l that's pretty much it.  The appropriate vegetation will be chosen from 2DA tables related to tileset (I think).

Maximum of 255 wps per template, but 50-75 expected to be average.

Seasonal vegetation is handled through the ecology system which will incorporate "biomass" as an inertial calorie sink (and is the node's "state") and will grow or reduce in response to seasons, player actions and other factors. High state upgrades vegetation, low state degrades.

The biomass has a variable energy input (seasonal) from the sun (based somewhat loosely on the nitrogen cycle, instead of the carbon cycle).

It has a variable drain (herbivores). Herbivore biomass in turn interacts with carnivore biomass, which closes the cycle back to vegetative biomass. The entire system will trend toward a stable average but will be capable of being nurtured to climax. Or destroyed.

<...because *Bucks is closing>
               
               

               
            

Legacy_wyldhunt1

  • Sr. Member
  • ****
  • Posts: 443
  • Karma: +0/-0
Chaotic vs. Random
« Reply #10 on: December 25, 2011, 02:14:53 am »


               We use NWNX Areas and NWNX ResMan, and NWN Funcs to add any content we want on the fly.
Zones are pre-determined groups of areas that are nearby eachother and would share an ecosystem and similar habitats. It's based on a string on the area, which is set from a 2da when the area is created. All areas with the same zone var share the same group of templates. We plan to have a fairly large number of base templates, and then make copies of them as we need them. Because the areas are constructed by a cronological base, they will always be the same area every time, but every copy of that area (The same template, but in a different x,y coord) will spawn different things from the waypoints.
This allows for true instancing, such as WoW style instanced dungeons, or unlimited template areas which have wide diversity while maintaining each individual areas map.
               
               

               


                     Modifié par wyldhunt1, 25 décembre 2011 - 02:29 .
                     
                  


            

Legacy_Lightfoot8

  • Hero Member
  • *****
  • Posts: 4797
  • Karma: +0/-0
Chaotic vs. Random
« Reply #11 on: December 25, 2011, 05:39:12 am »


               

Rolo Kipp wrote...
...
The Question: I got this far before my coffee got cold ;-P So, what would be a good function to return chaotic integers in the range -9 to +9, with a bell curve distribution that peaks at 0, given two seed values - NodeIndex (range 1 to ~64K) and WpIndex (range 1 to 255)?

<...and blowing hard>


The first step should be the creation of your own Random Number Generator.  This way you can control the Seed that is feed to the generator giving you your chaotic numbers in place of the uncontrolled seduo random ones.  When you load your area set your seed for that area also.   If it is just a single script you can just keep track of the seed/random progression in the script itself. if you are going to use the system in more then one script then you will need to set the seed to a local integer either on the area or an object of your choosing.  

After that is in place,  I would need more information on the shape  of the Bell  you are looking for.   There may be better ways  then the quadratic equations  needed for the bell curve  evulation.   I thing that NWscript could slow down a bit on lengthy equations, They get evaulated by the VM, and I just have no faith in the speed there.   

Here is an example for your possiable Random ChaoticNumberGenerator. Taken from this source.  with a little modification, since we do not have an unsinged data type in NWN.   

// With a little bit of test code in the void main();;  Had to test it out after all. 

const int a = 16807; // 7^5  /// x^y is x to the y power in the comments.
const int c = 0;
const int m = 1073741823; // (2^30) -1
int rSeed;
float rRandom ()
{
   rSeed = abs(a * rSeed + c) % m;
   //SpeakString(IntToString(rSeed));
   return  IntToFloat(rSeed) / m;
}
void SeedGenerator(int nSeed)
{
   rSeed = nSeed;
   rRandom();rRandom(); // Just burn two for the hell of it.
}
 

void main()
{
    SpeakString("555");
    SeedGenerator(555);
    int x;
    for (x= 1; x<20 ; x++)
    {
       SpeakString (FloatToString(rRandom ()));
    }

    SpeakString("next 554");
    SeedGenerator(554);
    for (x= 1; x<20 ; x++)
    {
       SpeakString (FloatToString(rRandom ()));
    }
    SpeakString("next 1");
    SeedGenerator(1);
    for (x= 1; x<20 ; x++)
    {
       SpeakString (FloatToString(rRandom ()));
    }
    SpeakString("next 2");
    SeedGenerator(2);
    for (x= 1; x<20 ; x++)
    {
       SpeakString (FloatToString(rRandom ()));
    }
}    


I am not really sure how well it works with the fact that we do not have the unsinged data type.  I reduced it from 32 bit to 31 bit.    I almost think that a 16 bit system qould be better though.     It would still leave a period larget then anything you would use in NWN.  
Some playing with the 'a'  factor could be needed to get a good spread though.    

   
               
               

               


                     Modifié par Lightfoot8, 25 décembre 2011 - 05:39 .
                     
                  


            

Legacy_Failed.Bard

  • Hero Member
  • *****
  • Posts: 1409
  • Karma: +0/-0
Chaotic vs. Random
« Reply #12 on: December 25, 2011, 06:54:31 pm »


                 I have an initial framework finished and working.  The growth routine is pretty crude at the moment (straight 1 in 10 chance if the regrowth local is set, determined at tree creation), but the initial random generation of the area works, as does the 2da system, and the database system to handle it.

  I might still pare the DB calls down, by combining the stage and chain stored ints into a single string (since it's stored as a string anyways), which will halve the read/write calls on creation and cleaning.

  Here's a chopped down snippet of the 2da, I've removed most of the columns for readability:
2DA v2.0

      Label                                       Stage1a                 Stage1b     <snip>     Stage10a            Stage10b        
0    EMPTY_NULL_FOREST     ****                          ****                              ****                       ****
1    TEMPERATE_FOREST_1   x3_plc_grass001 ****                              x3_plc_treel000 ****
2    TEMPERATE_FOREST_2   x3_plc_grass001 ****                              x3_plc_treel001 ****
... etc ....
  The actual trees are the last three steps, it's grass, then bushes, then trees in the five temperate forest chains I'd added.  Each chain in those five starts the same, but has a different final tree, stage 8 is small, 9 medium, 10 large.

  I'll upload the initial bit with the include and the base 2da once I've cleaned the code up a little.  It still needs work, but it's in a good enough state to take a look at.  The script can be spawned easily enough off an area or a trigger, the trigger being the easier of the two since you can walk in and out more easily, for checking the growth progression.
               
               

               
            

Legacy_Failed.Bard

  • Hero Member
  • *****
  • Posts: 1409
  • Karma: +0/-0
Chaotic vs. Random
« Reply #13 on: December 26, 2011, 02:57:56 am »


                 Okay, I cleaned it up a bit, and the link for the early version of it is here:

  The DB support is through NWNX.  WHile it's most easily implimented in the areas OnEnter/OnExit, using NWNXFuncs_GetFirstArea(); / NWNXFuncs_GetNextArea(); would allow a loop to be established to spawn all of the trees in globally on mod load if that was desired instead.

  Some of what I add to it for my own use won't likely work for others, since I'll be tying my regrowth settings into my weather system, and I'll be adding CEP based trees to the 2da.  The example 2da I included just uses vanilla grass and tree plabeables.

  That's a bit off though.  The core system still needs some work, so any suggestions anyone might have for improving it this next week I'll try to get into it.

  I'll likely add a seasonal switch to it, to allow an areas vegetation to be set up for at the least summer/winter.  One chain in the 2da being normal, the other could have snow drifts instead of grass, for example.

  Edit: Uploaded a new version.  Minor tweaks to allow easier instancing, replaced OBJECT_SELF references with the oArea variable in case the original call was made off a different object.
               
               

               


                     Modifié par Failed.Bard, 26 décembre 2011 - 04:07 .
                     
                  


            

Legacy_Lightfoot8

  • Hero Member
  • *****
  • Posts: 4797
  • Karma: +0/-0
Chaotic vs. Random
« Reply #14 on: December 26, 2011, 09:22:42 am »


               Ok, I am back on the track of refining the answer to your question.   Your question was:

Rolo Kipp wrote...

The Question: I got this far before my coffee got cold ;-P So, what would be a good function to return chaotic integers in the range -9 to +9, with a bell curve distribution that peaks at 0, given two seed values - NodeIndex (range 1 to ~64K) and WpIndex (range 1 to 255)?


The First step is the creation of a seedable random number generator.  Since you like the word of chaotic for such a critter we will call it a Chaotic Generator,  I also added a High and Low range arguments for ease of use.
 
Assuming that the Generator is going to be used in a single script Per seeding and the Current postion does not need to be stored into a local.  This would be the Include for the Generator.

const int a = 16807; // 7^5  /// x^y is x to the y power in the comments.
const int c = 0;
const int m = 1073741823; // (2^30) -1
int rSeed;

int GenerateChaotic (int nHigh ,int nLow = 1 )
{
   rSeed = abs(a * rSeed + c) % m;
   return  FloatToInt( IntToFloat(rSeed)/m  * (nHigh-nLow+1)) +nLow;
}

void SeedChaoticGenerator(int nSeed)
{
   rSeed = nSeed;
   GenerateChaotic(1);GenerateChaotic(1); // Just burn two for the hell of it.
}
  


Giving the Generator a unique seed per script based on you request would not be that hard from here. 
...
int nSeed = (NodeIndex << 8) + WpIndex;
SeedChaoticGenerator( nSeed);
...

To give the results a bell I would use the same trick used by just about every dice game out there(even though nwn missed the trick in most cases) .  Take a great sword for example. It does 2 to 12 damage.    Even though NWN handles this as a D6 *2, It really should be 2D6,  Making a roll of 7 the most common and 2 and 12 the hardest rolls to get, Just like the game of craps.     For your results however,   since it is hard to roll a 9.5 die to get the range you want,  I suggest just getting the average of two Chaotic numbers in the range you want for the same result.

int nResult = (GenerateChaotic(9,-9) + GenerateChaotic(9,-9)) / 2;  

If you wanted a function to controll the dx  of the bell It would not be that complex with this system.    It could however start burnning up the instruction count if you started getting to many itterations.   

Sample Function; 

int BellChaotic( int nHigh ,int nLow = 1, int nIncline=1)
{
   int nReturn;
   int x= nIncline;
   while (x--) nReturn=GenerateChaotic(nHigh, nLow);
  return nReturn/nIncline;
}

I hope that answers the original question.
L8.