Aller au contenu

Photo

Chaotic vs. Random


  • Veuillez vous connecter pour répondre
36 réponses à ce sujet

#1
Rolo Kipp

Rolo Kipp
  • Members
  • 2 791 messages
 <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 .


#2
Lightfoot8

Lightfoot8
  • Members
  • 2 535 messages
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.

#3
Rolo Kipp

Rolo Kipp
  • Members
  • 2 791 messages
<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>

#4
Lightfoot8

Lightfoot8
  • Members
  • 2 535 messages
<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 Image


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

Posted Image
 
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 .


#5
Failed.Bard

Failed.Bard
  • Members
  • 774 messages
  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 .


#6
Rolo Kipp

Rolo Kipp
  • Members
  • 2 791 messages
<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 Image
(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 .


#7
Rolo Kipp

Rolo Kipp
  • Members
  • 2 791 messages
<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>

#8
wyldhunt1

wyldhunt1
  • Members
  • 246 messages
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.

#9
Failed.Bard

Failed.Bard
  • Members
  • 774 messages
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.

#10
Rolo Kipp

Rolo Kipp
  • Members
  • 2 791 messages
<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>

#11
wyldhunt1

wyldhunt1
  • Members
  • 246 messages
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 .


#12
Lightfoot8

Lightfoot8
  • Members
  • 2 535 messages

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 .


#13
Failed.Bard

Failed.Bard
  • Members
  • 774 messages
  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.

#14
Failed.Bard

Failed.Bard
  • Members
  • 774 messages
  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 .


#15
Lightfoot8

Lightfoot8
  • Members
  • 2 535 messages
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.

#16
Rolo Kipp

Rolo Kipp
  • Members
  • 2 791 messages
<with eyes shining...>

Failed.Bard wrote...
 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.

Holy moly! You and LF are *fast*! That's even faster than the rumor system!

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.

Yes! Yes! That is very much where I was heading.

Caveat, though. Part of the purpose of using wps to spawn in placeables is to reduce the resources for *inactive* areas while *increasing* the resources in active areas.

Specifically, the 2DA chains (good word, that) actually specify a vegetation *group*. Each group must cover the footprint of the largest possible placeable (for forest, the Giant Tree, roughly 10m diameter). At low VegValue, placing a single grass placeable in an otherwise blank tile would be very patchwork-looking. So it works more along the lines of:
  • Groundcover group - rosette of 7 placeables
  • Groundcover w/ central bush - rosette
  • Bushes - rosette of 3 small bushes around larger bush
  • Saplings - rosette of large bushes (brush) with central sapling
  • Small tree - rosette of 3 small bushes (still too open for ferns) around small tree
  • Medium tree - rosette of 3 small ferns around medium (average) tree
  • Large tree - Large ferns around large tree
  • Huge tree - no extra groundcover
  • Giant tree - rare occurance, nearly fills tile.
Climax forest would have quite a few Giant trees, hopefully generating a cathedral like atmosphere (planning to tie atmospheric effects into the dynamic states functions later).

Additionally, I'd like a range of various Veggy groups for each level, that is also chosen chaotically, rather than randomly. I.e. Any given wp_veg *may* progress toward oak tree or maple or whatever, but it will always progress to the given variant, as you've set up with your 2DA. A wp_veg would chose a certain chain and progress or regress along it with the state of the area. The only difference would be to make each stage a group of 1 to 7 placeables, rather than a single resref. Perhaps a "|" delimited string in each column? What are the a/b variations? Seasonal?

For seasonal variation, I am currently planning a modification of the Seasonal Trinity Tileset round robin of modules (Spring->Summer->Autumn->Winter->Back to spring). I chose to go this way for several reasons, one of which is providing seasonal variation to my creatures (white foxes & hares! The Crone becoming the Maiden! ;-) and seasonally distinct scripting. I also want my open water tiles to morph into hard ice tiles (have a certain location that can only be reached by walking on water. Or flying).

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.

Fantastic! You are great! Thank you FB!

<...with shock and awe

Modifié par Rolo Kipp, 26 décembre 2011 - 07:21 .


#17
Rolo Kipp

Rolo Kipp
  • Members
  • 2 791 messages
<nodding...>

Lightfoot8 wrote...
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.

Yup, exactly! A Chaotic Number Generator. Provide a iSeed1,iSeed2, iLow, iHigh num and perhaps a curve slope value (i.e. the number of dice rolled?).

Given any set of variables, the CNG will always return a set integer in the range iLow<=result<=iHigh. Plotting the results for a large group of iSeed1 would yield a curve that is flat (iSlope=1) to increasingly steep.  Basically, I want the iLow & iHigh probabilities to be very rare.

iSeed1 (which would be the unique index of that particular node, a value of 1-64K)
iSeed2 (which would be the unique index of that particular wp_veg in that area, a value 1-255) might be the number of warm-up iterations of GenerateChaotic() in your example...
 

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 )
{
 *snip*
}
  


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);
...

But I don't really want a unique seed when called. I want the seed to be precisely the node index and the wp_veg index, so the value returned is the same *every* time I call it for that wp_veg at *that* particular node.

Example: Node 3141 (whose name just might be Pi's Zadora) might use template area 59 (which is actually named something like "tem_fffh_1ss0_3". Template 59 has a certain wp_veg with an index of 26.
*Every* time Node 3141 wakes up it will load template area 59.
Then it will work through all the wp_veg.
When it gets to wp_veg 26 it calls GenerateChaotic(3141, 26, -9, 9, 3) and returns... 7 perhaps.  
It will *always* return 7 for that wp_veg in that Node.
It will always return a different (allowing for the probability of repetition) number for that same wp_veg in *other* nodes (with a possible 64K nodes and a target of 100-200 templates, each template will "serve" hundreds of nodes).

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.

Exactly! Except that the dice roll slope-variable is very coarse grained at small values, and I was sorta hoping a more mathematically insightful scripter would jump in, laugh at all of us (in a friendly, if superior way) and jot down one of those truly elegant one-line equations that makes us all say "Doh! I shoulda thought of that!"

But a value of 3 would actually give me the sort of steep slope I was looking for.

BTW, your pm idea for fractally generating the distribution is pretty interesting, too. I just don't like the precise placement (location) being algorythm. Too much chance for ugly groupings and border-of-tile drops. Not insurmountable challenges, but, for now, I think the seeded wp idea will be easier, quicker and (thanks to FB!) already implemented ;-)

Even though NWN handles this as a D6 *2...

<jaw drops in astonishment>
They *didn't*! Oh, *please* say you're joking? <looks rather completely disillusioned>

I... don't have anything to say about that. Nothing good.

...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. *code snipped*

  
Yes, adding a slope (incline, dx) to the function, at least until we found a comfortable setting, would be good.

And that would make the function more generally available for *other* spawns, like carnivores, herbivores, citizens in cities... etc.

I hope that answers the original question.
L8.

Yup :-) Thank you very much :-)

Modifié par Rolo Kipp, 26 décembre 2011 - 08:03 .


#18
Failed.Bard

Failed.Bard
  • Members
  • 774 messages

Rolo Kipp wrote...

<with eyes shining...>

Failed.Bard wrote...
...

Yes! Yes! That is very much where I was heading.

Caveat, though. Part of the purpose of using wps to spawn in placeables is to reduce the resources for *inactive* areas while *increasing* the resources in active areas.

Specifically, the 2DA chains (good word, that) actually specify a vegetation *group*. Each group must cover the footprint of the largest possible placeable (for forest, the Giant Tree, roughly 10m diameter). At low VegValue, placing a single grass placeable in an otherwise blank tile would be very patchwork-looking. So it works more along the lines of:
  • Groundcover group - rosette of 7 placeables
  • Groundcover w/ central bush - rosette
  • Bushes - rosette of 3 small bushes around larger bush
  • Saplings - rosette of large bushes (brush) with central sapling
  • Small tree - rosette of 3 small bushes (still too open for ferns) around small tree
  • Medium tree - rosette of 3 small ferns around medium (average) tree
  • Large tree - Large ferns around large tree
  • Huge tree - no extra groundcover
  • Giant tree - rare occurance, nearly fills tile.
Climax forest would have quite a few Giant trees, hopefully generating a cathedral like atmosphere (planning to tie atmospheric effects into the dynamic states functions later).

Additionally, I'd like a range of various Veggy groups for each level, that is also chosen chaotically, rather than randomly. I.e. Any given wp_veg *may* progress toward oak tree or maple or whatever, but it will always progress to the given variant, as you've set up with your 2DA. A wp_veg would chose a certain chain and progress or regress along it with the state of the area. The only difference would be to make each stage a group of 1 to 7 placeables, rather than a single resref. Perhaps a "|" delimited string in each column? What are the a/b variations? Seasonal?


  The a and b aren't variations, it's for when it makes more sense to keep the plant from the stage before in addition to the one for the current stage.  A small tree growing out of the middle of the bush, for example.
  Since most of the stages in your idea seem to only have two different placeables, though with varying amounts of the secondary ones, that could likely be scripted in off of the current 2da reads.  a is the primary vegetation, b the secondary.

  The only issue I could see with this, is that the position of the secondaries could either be  persistant or dynamic, not both, unlike the main tree.  The only way to make them persistant without bloating the DB would be to have them all appear the same position relative to the main tree, which would be fine with one but might look bad once you apply it across every tree.
  The alternative to that, is to allow them to be a random distance and facing, within a certain range, for each of the sub trees, which would give the illusion of randomly sprouting around the main tree without being so vastly different as to be immediately obvious if a PC walks past it on multiple spawn.despawn instances.
 
  I'll take a look at the scripts and see how hard it would be to set it up that way.  The only immediate issue I can think of is if the main tree WP is slightly raised compared to the ground aroung it, that it might lead to floating plants.  Since there's no reliable check for ground level aside from porting a creature to that spot and getting their z axis, it'll make for a bit more work.

#19
Rolo Kipp

Rolo Kipp
  • Members
  • 2 791 messages
<sipping rich hazelnut coffee...>

re primary/secondary: Brilliant! I love it.

re dynamic placing, I'd rather have it chaotic, vector being a chaotic function of iSeed1=wp_veg index and iSeed2 perhaps being the number of the secondary? So a seed from 1-6. Give it a flat slope=1 and that way the distance/direction and facing of each secondary would be chaotic, but persistent.

re floating plants: And I was floating so high...:-/

Not sure the extra instructions would be worth bringing them to ground, though. Particularly for ground cover, as quite a lot of that seems to float anyway, to get the leaves/blossoms up around calf-level.

Don't placeables drop to the walkmesh? I know you can't spawn in a placeable up a mountainside, for example. Wouldn't the secondaries drop/pop up to the proper Z?

<...happily>

#20
Rolo Kipp

Rolo Kipp
  • Members
  • 2 791 messages
<grinning slyly...>

Of course, there's no reason this system has to be limited to temperate forest... It would work equally as well for dynamic swamp, jungle, or alpine (mountain) tilesets.

It would work for deserts and undersea, as well. They'd just need their own 2DA with context sensitive chains (a very useful mechanic, IMO).

They'd even work for the Crystal Forest in the Underways... Though I imagine recovery times for disasters would be a problem. Takes quite a while to re-grow gem-quality "trees"... ;-)

Edit: I'll be working on the proof-of-concept Regional mod as soon as we wrap up our CCC contributions this month. I'll be trying out FB's work there (combined with my own and LFs contributions) and we'll see what happens.

<...at Cestus>

Modifié par Rolo Kipp, 26 décembre 2011 - 08:40 .


#21
Lightfoot8

Lightfoot8
  • Members
  • 2 535 messages

Rolo Kipp wrote...

But I don't really want a unique seed when called. I want the seed to be precisely the node index and the wp_veg index, so the value returned is the same *every* time I call it for that wp_veg at *that* particular node.



Correct.  I Think you misread that part.  Or I explained it poorly.  The Function does not Give you a unique seed.   It take a unique seed(node index) to seed the chaotic generator.   The Generator then gives you a constant string of chaotic numbers.  

ie.

void main()
{
    nNodeIndex = GetNodeIndex(); // Your custom function.
   
    //Seed the generator with the seed..
    SeedChaoticGenerator(nNodeIndex);
   
    int x=1;
    int nRnd;
    object oWP  = GetNearestObjectByTag("WPTag");
    while (GetIsObjectValid(oWP))
    {
      nRnd = GenerateChaotic(9, -9);
      /*
          Code dealing with the result
      */
     oWP=GetNearestObjectByTag("WPTag",OBJECT_SELF,++x);
    }
}

Would have the same result for nNodeIndex every single time.  A different NodeIndex used for the seed would return a different set of consistant results for the random/chaotic numbers.    The Seed will not change when spawned unless the NodeIndex is changed.   Giving you  1,073,741,823   Differand seeds to choose from for consistant results. 

  

Modifié par Lightfoot8, 26 décembre 2011 - 09:04 .


#22
Failed.Bard

Failed.Bard
  • Members
  • 774 messages

Rolo Kipp wrote...

<grinning slyly...>

Of course, there's no reason this system has to be limited to temperate forest... It would work equally as well for dynamic swamp, jungle, or alpine (mountain) tilesets.

It would work for deserts and undersea, as well. They'd just need their own 2DA with context sensitive chains (a very useful mechanic, IMO).

They'd even work for the Crystal Forest in the Underways... Though I imagine recovery times for disasters would be a problem. Takes quite a while to re-grow gem-quality "trees"... ;-)

Edit: I'll be working on the proof-of-concept Regional mod as soon as we wrap up our CCC contributions this month. I'll be trying out FB's work there (combined with my own and LFs contributions) and we'll see what happens.

<...at Cestus>


Other environments wouldn't need a seperate 2da, just seperate line entries in it.  The entires are read from the seed string as three digits, so rows 0 to 999 are viable under the current system.  I'd thought about using it for crystals as well, in addition to the possibility of controlling the size of snow and ice drifts and formations in perpetually frozen climates.
  There's no reason it wouldn't work for any sort of scaling placeable system.  For seasonal you'd just have to make it use a different set of lines depending on the season.

Edit: I was just thinking, I should be able to create a "random" placement of the sub-vegetation around the main tree based on the wp count that could be consistent every time as well, similar to Lightfoot8's system.  It would only change if another WP was added to the area and the engine created a new list in a different order when that happened.

Modifié par Failed.Bard, 26 décembre 2011 - 09:46 .


#23
Rolo Kipp

Rolo Kipp
  • Members
  • 2 791 messages
<weighing a handful of scrolls in one hand...>

Failed.Bard wrote...
Other environments wouldn't need a seperate 2da, just seperate line entries in it. 

They wouldn't need it, no. But having a separate 2da for each tileset/purpose would make managing things easier, I think :-)

The entires are read from the seed string as three digits, so rows 0 to 999 are viable under the current system.  I'd thought about using it for crystals as well, in addition to the possibility of controlling the size of snow and ice drifts and formations in perpetually frozen climates.
  There's no reason it wouldn't work for any sort of scaling placeable system.

Yup :-) I'm quite excited, actually. 

For seasonal you'd just have to make it use a different set of lines depending on the season.

Or you could leave the seasonal aspect to the seasonal over-ride hak as I will. Same placeable resref, but new textures or even geometry for different seasons.

<...and eyeing a massive tome with one eye>

#24
Rolo Kipp

Rolo Kipp
  • Members
  • 2 791 messages
<pours a little oil...>

Lightfoot8 wrote...
Correct.  I Think you misread that part.  Or I explained it poorly.  The Function does not Give you a unique seed.   It take a unique seed(node index) to seed the chaotic generator.   The Generator then gives you a constant string of chaotic numbers.  

Ahhh. Yes, I misread it.

I think this will work nicely :-)

<...on the waters>

#25
Rolo Kipp

Rolo Kipp
  • Members
  • 2 791 messages
<looking quite interested...>

wyldhunt1 wrote...
We use NWNX Areas and NWNX ResMan, and NWN Funcs to add any content we want on the fly.
*snip*
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.

I think I understand better. *Very* intriguing.

I really do have to look into NwNX. Downloaded it and have it ready for investigation/experimentation... 

*sigh*

Soon, RSN...

<...but also too busy to pursue the elusive ideal>