• Please note: In an effort to ensure that all of our users feel welcome on our forums, we’ve updated our forum rules. You can review the updated rules here: http://forums.wolflair.com/showthread.php?t=5528.

    If a fellow Community member is not following the forum rules, please report the post by clicking the Report button (the red yield sign on the left) located on every post. This will notify the moderators directly. If you have any questions about these new rules, please contact support@wolflair.com.

    - The Lone Wolf Development Team

Random Tables lookups?

feel fre to upload it to my github page. the idea is so that people could put their stuff there and share it. part of the reason i made it public.
 
OK - next question my java experts.

I am now working on the random encounters for Kingmaker part 2 and some of the encounters call for 2d4 of a creature.

Obviously the 'Rand ()' function I have been using wont work for 2 dice, so what function do I need to use?

Thankyou in Advance :D
 
you can do one of two things.

First, 2d4 is 7 possible values (2 to 8) so you could just use the same random function with 7 as the highest value possible then add one (+1) to get a range of 2 to 8.

Second, you could call the random 4 value twice storing the results in two separate variables (call the variables DieRoll1 and DieRoll2) and then add the two variables together to get the final result.

I'm sure someone will come along to give you the actual code. Personally, I'd go with the first option but that's just me.
 
the problem with that is that it skews the probabilities.

you have a one in 7 chance of getting a 2 with your probabilities, and a 1 in 7 chance of getting a 5.

but in 2d4, there are multiple ways of getting a 5

1,4
2,3
3,2
4,1

4 chances out of a total 16. (1 in 4)

whereas the chance of getting 2 or 8 is actually 1 in 16 for either. (there are actually 16 different combinations when rolling 2d4) 2 dice skew to the middle, but make it much harder to get either the min or the max.
 
we can add a new method that uses the existing rand method

Code:
function randDice(numDice, diceType, modifier) {
   var total = 0;
   if (!numDice) {
     numDice) = 1;
   }

   for (i = 0; i < numDice; i++) {
      total += rand(diceType);
   }
   if (modifier) {
      total += modifier;
   }
   return total;
}

2d4 would be called like

randDice(2,4)

2d4+3 would be called by
randDice(2,4,3)

its not the prettiest version. i can write a prettier one later
 
Last edited:
If you look at my RotRL Encounter tables, I just did rand(4) + rand(4) in the honoured KISS method. :-)
 
Last edited:
If you look at my RotRL Encounter tables, I just did rand(4) + rand (4) in the honoured KISS method. :-)

Hurr Durr! Why didn't I think of that? :confused:
(no programming skills, remember?)

OK - I have now completed the random chart for Kingmaker book 2 (posted below).
Cleaned up the code a bit and put everything in order too.
Will try to up load to github, but not sure how to do so....might be a trial and error thing....!

*Edit* I tried to upload the file, but it got 'forked' (no really, that is actually the word the site used, not the other thing :D).
Then I created a 'pull' request.
Not sure if successful or not.
Let me know if there is anything else I need to do.

Code:
<HTML>
<HEAD>
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<TITLE>Kingmaker - Rivers Run Red</TITLE>
</HEAD>
<BODY>

<script language="JavaScript">

// Some Arrays



function rand(x) {
return Math.floor(Math.random() * x) + 1;
}

function tableResults(argument) {

var hexencounterArray = [];
var DayornightArray = [];
var forestArray = [];
var lakeArray = [];
var plainsArray = [];
var hillsArray = [];

hexencounterArray.push({"max": 5, "content": "Random Encounter"});
hexencounterArray.push({"max": 100, "content": "No Encounter"});

DayornightArray.push({"max": 15, "content": "Random Encounter"});
DayornightArray.push({"max": 100, "content": "No Encounter"});

forestArray.push({"max": 5, "content": "1 barghest; CR 4"});
forestArray.push({"max": 13, "content": rand(8) + " Boars; CR 6"});
forestArray.push({"max": 17, "content": rand(4) + rand (4) + " boggards; CR 3"});
forestArray.push({"max": 23, "content": rand(6) + " brush thylacines; CR 5"});
forestArray.push({"max": 29, "content": rand(6) + rand(6) + " elk; CR 6"});
forestArray.push({"max": 35, "content": "1 faerie dragon; CR 2"});
forestArray.push({"max": 42, "content": rand(4) + rand(4) + " giant Spiders; CR 5"});
forestArray.push({"max": 49, "content": rand(4) + " grizzly bears; CR 6"});
forestArray.push({"max": 53, "content": "1 hydra; CR 4"});
forestArray.push({"max": 57, "content": "1 manticore; CR 5"});
forestArray.push({"max": 63, "content": "1 owlbear; CR 4"});
forestArray.push({"max": 68, "content": "1 shambling mound; CR 6"});
forestArray.push({"max": 71, "content": rand(6) + " shocking lizards; CR 5"});
forestArray.push({"max": 75, "content": rand(6) + " tatzlwyrms; CR 5"});
forestArray.push({"max": 79, "content": rand(4) + rand(4) + " trolls; CR 9"});
forestArray.push({"max": 82, "content": "1 werewolf; CR 2"});
forestArray.push({"max": 85, "content": "1 will o wisp; CR 6"});
forestArray.push({"max": 93, "content": rand(6) + rand(6) + " wolves; CR 6"});
forestArray.push({"max": 97, "content": rand(6) + rand(6) + " worgs; CR 7"});
forestArray.push({"max": 100, "content": "1 wyvern; CR 6"});

lakeArray.push({"max": 3, "content": "1 barghest; CR 4"});
lakeArray.push({"max": 10, "content": rand(8) + " Boars; CR 6"});
lakeArray.push({"max": 17, "content": rand(4) + rand (4) + " boggards; CR 3"});
lakeArray.push({"max": 21, "content": rand(6) + " brush thylacines; CR 5"});
lakeArray.push({"max": 28, "content": rand(6) + rand(6) + " elk; CR 6"});
lakeArray.push({"max": 32, "content": "1 faerie dragon; CR 2"});
lakeArray.push({"max": 35, "content": rand(4) + rand(4) + " giant Spiders; CR 5"});
lakeArray.push({"max": 41, "content": rand(4) + " grizzly bears; CR 6"});
lakeArray.push({"max": 47, "content": "1 hydra; CR 4"});
lakeArray.push({"max": 54, "content": "1 nixie; CR 1"});
lakeArray.push({"max": 59, "content": "1 owlbear; CR 4"});
lakeArray.push({"max": 68, "content": "1 shambling mound; CR 6"});
lakeArray.push({"max": 75, "content": rand(6) + " shocking lizards; CR 5"});
lakeArray.push({"max": 79, "content": rand(6) + " tatzlwyrms; CR 5"});
lakeArray.push({"max": 83, "content": rand(4) + rand(4) + " trolls; CR 9"});
lakeArray.push({"max": 88, "content": "1 will o wisp; CR 6"});
lakeArray.push({"max": 94, "content": rand(6) + rand(6) + " wolves; CR 6"});
lakeArray.push({"max": 98, "content": rand(6) + rand(6) + " worgs; CR 7"});
lakeArray.push({"max": 100, "content": "1 wyvern; CR 6"});

plainsArray.push({"max": 4, "content": "1 barghest; CR 4"});
plainsArray.push({"max": 15, "content": rand(8) + " Boars; CR 6"});
plainsArray.push({"max": 20, "content": rand(6) + " brush thylacines; CR 5"});
plainsArray.push({"max": 28, "content": rand(6) + rand(6) + " elk; CR 6"});
plainsArray.push({"max": 32, "content": "1 faerie dragon; CR 2"});
plainsArray.push({"max": 38, "content": rand(4) + rand(4) + " giant Spiders; CR 5"});
plainsArray.push({"max": 40, "content": rand(4) + " grizzly bears; CR 6"});
plainsArray.push({"max": 51, "content": rand(6) + rand(6) + " Kobolds; CR 2"});
plainsArray.push({"max": 54, "content": "1 manticore; CR 5"});
plainsArray.push({"max": 59, "content": "1 owlbear; CR 4"});
plainsArray.push({"max": 63, "content": "1 shambling mound; CR 6"});
plainsArray.push({"max": 66, "content": rand(6) + " tatzlwyrms; CR 5"});
plainsArray.push({"max": 71, "content": rand(4) + rand(4) + " trolls; CR 9"});
plainsArray.push({"max": 75, "content": "1 werewolf; CR 2"});
plainsArray.push({"max": 77, "content": "1 will o wisp; CR 6"});
plainsArray.push({"max": 86, "content": rand(6) + rand(6) + " wolves; CR 6"});
plainsArray.push({"max": 95, "content": rand(6) + rand(6) + " worgs; CR 7"});
plainsArray.push({"max": 100, "content": "1 wyvern; CR 6"});

hillsArray.push({"max": 7, "content": "1 barghest; CR 4"});
hillsArray.push({"max": 14, "content": rand(8) + " Boars; CR 6"});
hillsArray.push({"max": 19, "content": rand(6) + " brush thylacines; CR 5"});
hillsArray.push({"max": 27, "content": rand(6) + rand(6) + " elk; CR 6"});
hillsArray.push({"max": 30, "content": "1 faerie dragon; CR 2"});
hillsArray.push({"max": 35, "content": rand(4) + rand(4) + " giant Spiders; CR 5"});
hillsArray.push({"max": 43, "content": rand(6) + rand(6) + " Kobolds; CR 2"});
hillsArray.push({"max": 45, "content": "1 manticore; CR 5"});
hillsArray.push({"max": 53, "content": "1 owlbear; CR 4"});
hillsArray.push({"max": 58, "content": "1 shambling mound; CR 6"});
hillsArray.push({"max": 65, "content": rand(6) + " tatzlwyrms; CR 5"});
hillsArray.push({"max": 70, "content": rand(4) + rand(4) + " trolls; CR 9"});
hillsArray.push({"max": 74, "content": "1 werewolf; CR 2"});
hillsArray.push({"max": 81, "content": "1 will o wisp; CR 6"});
hillsArray.push({"max": 88, "content": rand(6) + rand(6) + " wolves; CR 6"});
hillsArray.push({"max": 95, "content": rand(6) + rand(6) + " worgs; CR 7"});
hillsArray.push({"max": 100, "content": "1 wyvern; CR 6"});



var allArrays = {
"Hex": hexencounterArray,
"DayNight": DayornightArray,
"lake": lakeArray,
"forest": forestArray,
"hills": hillsArray,
"plains": plainsArray
};

var randomNum = rand(100) + 1;
var arrayOfChoices = allArrays[argument];
if (!arrayOfChoices) {
return "no such set: " + argument;
}

var chosenString = "";
for (var itemIndex in arrayOfChoices) {
var item = arrayOfChoices[itemIndex];
if (randomNum <= item.max) {
chosenString = item.content;
break;
} 
}
return chosenString;
}

</script>

As the PCs enter a hex, hit the button to see if there is an encounter (5% chance)

<form>
<input type="button" name="Button1" value="Hex Encounter" onClick="this.form.textField1.value = 

tableResults('Hex')" size="" />
<textarea name="textField1" cols="40" rows="1" wrap="soft"></textarea>
</form>

For each day or night cycle spent exploring, hit the button to see if there is an encounter (15% chance) 

<form>
<input type="button" name="Button2" value="Day or Night encounter" onClick="this.form.textField1.value = 

tableResults('DayNight')" size="" />
<textarea name="textField1" cols="40" rows="1" wrap="soft"></textarea>
</form>

If there is a random encounter, hit the button of the corresponding terrain to generate an encounter.

<form>
<input type="button" name="Button3" value="Forest" onClick="this.form.textField1.value = 

tableResults('forest')" size="" />
<textarea name="textField1" cols="40" rows="1" wrap="soft"></textarea>
</form>

<form>
<input type="button" name="Button4" value="Lake/River" onClick="this.form.textField1.value = 

tableResults('lake')" size="" />
<textarea name="textField1" cols="40" rows="1" wrap="soft"></textarea>
</form>

<form>
<input type="button" name="Button5" value="Plains" onClick="this.form.textField1.value = 

tableResults('plains')" size="" />
<textarea name="textField1" cols="40" rows="1" wrap="soft"></textarea>
</form>

<form>
<input type="button" name="Button6" value="Hills" onClick="this.form.textField1.value = 

tableResults('hills')" size="" />
<textarea name="textField1" cols="40" rows="1" wrap="soft"></textarea>
</form>

</BODY>
</HTML>
 
Last edited:
OK - last time :)

Books 5 & 6 have been added, plus a chart for another encounter in book 6 (very basic).

I have modified the layout for the book 5 encounter chart and would appreciate feedback on this file.

I also had to set one of the encounter frequencies to 1% (1 out of 100) for 'chexencounter' but setting the line as
Code:
chexencounterArray.push({"max": 1, "content": "Random Encounter"});
seemed to return only a 'no encounter' response, so I worked backwards and on a '2' it will return an encounter result (infrequently). I must have clicked 500-600 times with the max value of 1, with no encounter result returned!

Currently the code is
Code:
chexencounterArray.push({"max": 2, "content": "Random Encounter"});
but I am not sure this is right for generating a 1% encounter chance, however it does return an encounter result fairly rarely.

Thanks again for everyone's help - couldn't have done it without you :)

Files uploaded to github.

Will try to make some time to update the previous pages to the 'nicer' format if you guys like it.
 
Last edited:
Hi there!

Iam did not lookat all at the previous pages, but it should be possible do print the used random seed number on screen as well. This way you can control if everything is working.
 
Thanks for the effort that went into this. After never being able to get the html to work before, I worked through this and managed it. It turned out that my big stumbling block was merely figuring out that I needed something like Notepad ++ to be able to save the source code as a file rather than cutting and pasting it into a snippet.

Blindingly obvious to most of you, I'm sure but it's been a long time since I tried to learn Fortran using punch cards at university.
 
NPC fast

hi there !
thank you for the inspiration and the code.

Using the first script of this thread and a table created by http://theaussiegm.tumblr.com/ I made a quick and dirty NPC generator

it generates descriptions like these:

"Brifley is a impatient tall and wide sized venerable female monster with a religious symbol, who thinks that the most important is knowledge first "

or

"Elith is a cheerful short and thin sized very young male human with a big scar, who thinks that the most important is good and law"

the page is attached to this post

enjoy
 

Attachments

Hi there,

great stuff! Even if it would be way better, if RW had this onboard itself, especially with topics as input ("give me a random magic item out of my magic trinkets category").

I tried to adapt what I've seen here into a simple script to generate the results of criticals hits and misses. Unfortunately having no JS experience lead to me failing :( There's obviously something I missed as it's not working.

Here's what I produced, maybe one of you guys can spot the error:
Code:
<HTML>
<HEAD>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<TITLE>Critical Hits and Misses</TITLE>
</HEAD>
<BODY>

<script language="JavaScript">
rnd.today=new Date();
rnd.seed=rnd.today.getTime();

crit = new makeArray(20);
crit[0] = "​Double damage​";
crit[1] = "​Double damage​";
crit[2] = "​Double damage​";
crit[3] = "​Double damage​";
crit[4] = "​Double damage​";
crit[5] = "​Double damage​";
crit[6] = "​Double damage​";
crit[7] = "​Double damage​";
crit[8] = "​Double damage​";
crit[9] = "​Double damage​";
crit[10] = "​Double damage and foe drops weapons (5-30 feet away)​";
crit[11] = "​Double damage and foe is knocked down.​";
crit[12] = "​Double damage and foe's weapon or attacking appendage is broken/destroyed.​";
crit[13] = "​Double damage and foe is -1 to hit until healed​";
crit[14] = "​Double damage and loses one round of action (STUNNED, No DEX Modifier on AC).​";
crit[15] = "​Double damage and foe is -2 to hit until healed.​";
crit[16] = "​Double damage and loses two rounds of action (STUNNED, No DEX Modifier on AC).​";
crit[17] = "​Triple damage, foe loses their weapon arm (or attacking appendage).​";
crit[18] = "​Foe is dropped to 0 hp.* You may choose to coup de grâce or knock them unconscious.​";
crit[19] = "​Foe is decapitated.​";

fail = new makeArray(20);
fail[0] = "​You have killed yourself (0 HP, bleeding out).​";
fail[1] = "​Double damage and you knock yourself unconscious for 1d4 rounds​";
fail[2] = "​Maximum single damage to yourself and you break your weapon.​";
fail[3] = "​Maximum single damage to yourself and you are stunned for one round (STUNNED, No DEX Modifier on AC).​";
fail[4] = "​Maximum single damage to yourself and you are stunned for one round (STUNNED, No DEX Modifier on AC) and you are -1 to hit until healed.​";
fail[5] = "​You accidentally knock out your closest ally for 1d4 rounds.​";
fail[6] = "​You accidentally break the weapon of your nearest ally.​";
fail[7] = "​You accidentally strike your nearest ally for maximum single damage.​";
fail[8] = "​You accidentally knock the weapon out of the hand of your closest ally.​";
fail[9] = "​You accidentally knock down your closest ally down.​";
fail[10] = "​You fall down, break your weapon and sustain normal damage.​";
fail[11] = "​You fall down, lose your weapon (5-30 feet away) and sustain normal damage.​";
fail[12] = "​You break your weapon and sustain normal damage.​";
fail[13] = "​You fall down (No DEX Modifier on AC next round) and sustain normal damage.​";
fail[14] = "​You lose your weapon (5-30 feet away) and sustain normal damage.​";
fail[15] = "​You break your weapon.​";
fail[16] = "​You fall down (No DEX Modifier on AC next round).​";
fail[17] = "​You lose your weapon (5-30 feet away).​";
fail[18] = "​You sustain normal damage on yourself.​";
fail[19] = "​Your failed attack leaves you exposed, +2 to hit on you next round.​";

function rnd() {
rnd.today=new Date();
rnd.seed=rnd.today.getTime();
rnd.seed = (rnd.seed*9301+49297) % 233280;
return rnd.seed/(233280.0);
};

function rand(number) {
return Math.ceil(rnd()*number)-1;
};

function makeArray(n) {
this.length = n;
for(var i = 1; i <= n; i++)
this[i] = "";
return this;
} ;// End of function makeArray

function f_crit() { // crits
return crit_value[rand(20)];
};

function f_fail() { // fails
return fail_value[rand(20)];
};

</script>

<form>
<input type="button" name="Crits" value="Generate Crit" onClick="this.form.textField1.value = f_crit()" size="" />
<textarea name="textField1" cols="60" rows="1" wrap="soft"></textarea>
</form>
<form>
<input type="button" name="Fails" value="Generate Fail" onClick="this.form.textField1.value = f_fail()" size="" />
<textarea name="textField1" cols="60" rows="1 wrap="soft"></textarea>
</form>

</BODY>
</HTML>
 
Back
Top