#### Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

# Can variables used as weights for a table?

Is it possible to use variables as the weights for a weighted table?

I want to weight the alignments of generated NPCs by their class and race. For example as a test I tried:

``````Table: NPC
A [@race] [@class] of [@alignment] alignment.  (DEBUG - L:{L}|N:{N}|C:{C})
EndTable:

Table: race
{N==9} {L==1} {C==1} human
EndTable:

Table: class
{N=={N}+9} warrior
EndTable:

Table: alignment
Type: Weighted
{L}:lawful
{N}:neutral
{C}:chaotic
EndTable:
``````

I would expect this to generate a human warrior of Neutral alignment about 18 out of 20 times. Instead, it generates as if each was evenly weighted.

Is there a different way to accomplish this?

• Not sure why that doesn't work, but this gives a somewhat similar result:

``````Table: NPC
A [@race] [@class] of [#{{\$N}+{1d100}} alignment] alignment.

Table: race
{N==50} human

Table: class
{N=={N}+9} warrior

Table: alignment
Type: Lookup
Roll: {\$1}
0-60:lawful
61-140:neutral
141-200:chaotic
``````

You can bias it towards law or chaos by adjusting N. But you can't decrease the chance of neutral while increasing both law and chaos.

You could of course use some When statements to implement any odds you want, it's just not as elegant.

• Yes, I though of trying it that way but ran into problems as the races and classes intersected and caused the elimination of certain combinations with this method. The push towards chaotic eliminated law completely in order to reduce neutral. And it just gets worse when I add the Good-N-Evil axis. And I eventually wanted a bias for races to choose certain classes.

I have no idea at all how to use When statements to do this.

Being able to use variables as weights for a table makes it all so clean and straight forward. I really want to use IPP for this, so I wish I knew if it was possible and I just have the wrong syntax or if it isn't currently possible at all.

• Here's how you would do it with When statements:

``````Table: NPC
A [@race] [@class] of [@alignment] alignment.  (L:{L}|N:{N}|C:{C}|Roll:{Roll})

Table: race
{N==9} {L==1} {C==1} human

Table: class
{N=={N}+9} warrior

Table: alignment
{Roll==1d{N+L+C}}[align==neutral][when]{Roll}<{L}+1[do][align==lawful][end][when]{Roll}>{L+N}[do][align==chaotic][end]{\$align}
``````

Since there are three conditions, and When really only checks for two, I assigned the alignment to a variable which can then be overwritten by one of the other conditions.

Note I had to put the assignments in square brackets. I think curly brackets only work for numerical values.

• Variables can't be used as weights because the weight is parsed by the program as the generator is loaded, while the table item lines are only processed as they are encountered.

• @Ed_NBOS - Thanks, that's good to know, saddening, but good to know.

@jdale - OK.. I can see how that would work. This will certainly help with other table ideas I have kicking around. Not sure I have the patience to figure it out across the 9 possible alignments and the plethora of race/class combinations for 5e.

Anyway, thanks for your help, it will help with other conversions if not this one.
I guess this is one table that won't get converted over from TS. I'll just upgrade it to work in TS5 instead.

That what I get for trying to reduce the volume of software I use at the table. Also, I really just wanted to have my TS tables available from within The Keep. Oh well, c'est la vie.

• Here's a long, rambling piece of code that may help a bit, if I haven't made too much of a mess of it. And it probably won't execute because it's just a piece of the overall .ipt file.

So looking at the TrainMod and Training tables...

TrainMod: Larger settlements will not only have more horses available for sale, but also more likelihood of horses that have been trained for special purposes (warhorse, trail horse, etc.). That might be along the lines of cities of more likely have a few more elves, villages a few more halflings, or something like that. (Maybe). So, I set the variable at 1.00 for "par value" and and make it less than 1.00 for larger settlements, greater than 1.00 for smaller settlements.

Training Table: Before this table runs, I do some arithmetic when rolling for breed and gender, to give me a unique 2 digit code for every possible breed/gender combo, then lookup that calculated (not rolled) two digit value. Now on this table, I have a very large die to roll (d450, d500, etc.) depending on which breed/gender combo (i.e. your elves can skew toward good and/or chaotic, gnomes neutral or whatever you're trying to weight by selecting the size of the die. Then multiplying that die by TrainMod factor makes it a bit larger or smaller die, depending on how large a settlement it is.

So a warm-blood mare in a hamlet would be rolling d625, while a warm-blood mare in a metropolis might be rolling a d300.

Now then, when we get to the tables that follow (one for each breed/gender possibility; in your case maybe just one per race), the rarer possibilities are the lowest range of rolls on the table.

For instance a warm-blood mare is trained as a warhorse on a roll of 31-60. For sale in a hamlet, that is a 30 in 625 chance; found in a metropolis, that is about twice as likely as it is a 30 in 300 chance.

Now for my horses, there needs to be a very large range default result at the high end of the table. For the horses, it's simple "untrained". The larger the die that is rolled (d625), the more likely to find an untrained horse/the more rare a trained horse.

Now, if there is no default, most likely alignment, there are other ways. I can follow up with weighting of gem sizes from another generator. I'll do that in another post. It's ugly, but it solved the problem of skewing the roll to highs or lows that completely eliminate the possibility of rolling any one choice.

This code is not going to be quite readily adapted to your generator, but it might give you a direction to explore:

{Code in next post}

• Code for horses part 1:

``````; Horses.ipt
; created 4/14/2017 4:43:34 PM

#Add pony as a breed. From 9.5 to 14.5 hands high, greater burden per hh, considerably slower movement even for walk, based on shorter leg length. Maybe prompt for predominant race of settlement... more hot bloods for elves, ponies for dwarf, halfling, gnome settlements.

Prompt: Settlement Size {hamlet|village|town|city|metropolis} town

;Set: Size={\$prompt1}

Maxreps: 1

Table: Main
#A veriable set [number] to be used in the essential command line of this table.
Set: number=[#{\$prompt1} Count]
#A variable set to determine the specialty training modifier for a given Settlement Size.
Set: TrainMod=[#{\$prompt1} Train]

#This is the main executable call for the generator.
#It includes a header-type line indicating the number of horses available, and the user value of Settlement Size.
#It then calls the GENDER table for output, repeating the call for the count of horses available.
There are {number} horses for sale in this {\$prompt1}.\n\n[@{number} Gender >> implode <br><br>]

#This table rolls the number of horses available for sale, per the user entered Settlement Size data.
#It is used in the MAIN table above to call the GENDER table once for each count of horses available.
Table: Count
Type: dictionary
Default:  117 //debug value
hamlet: {1d4} //1-4
village: {1d6 +1} //2-7
town: {1d10 +6}  //7-16
city: {10d8} //8-80
metropolis: {20d8} //16-160

Table: Train
Type: dictionary
Default:  117  //debug value
hamlet: 1.25
village: 1.05
town: 0.95
city: 0.8
metropolis: 0.6

#This table chooses the temperment (breed).
#It provides a BaseSize range by breed type, a modifyer [@c] for burden capacity, an index number for "breed number", and a lookup index for the rate of speed text string.
Table: Breed
25: Cold {@BaseSize==((6d4)/6)+15} {@c==120} {@Speed==1} {@BreedNo==1}  //BaseSize=16-19 hands; after GenderMod, 15.8 - 19.5 hands; Full burden 258-295 lbs.
15: Hot {@BaseSize==((6d4)/6)+12}   {@c==80}  {@Speed==3} {@BreedNo==3} //BaseSize=13-16 hands; after GenderMod, 12.8 - 16.5 hands; Full burden 208-245 lbs.
60: Warm {@BaseSize==((6d4)/6)+13}  {@c==100} {@Speed==2} {@BreedNo==2}  //BaseSize=14-17 hands; after GenderMod, 13.8 - 17.5 hands; Full burden 228-265 lbs.

#This is essentially the MAIN table, as it produces all the output and calls most of the other tables, either directly or indirectly.
#This table also calculates the size, modifying [BaseSize] for gender considerations.
#It also calculates "Full Burder" and the cost of the horse.
Table: Gender
6: {GenderNo==10} [#{1d100} MareAge] yr. old [#{1d100} Color] Mare, [@Breed] blooded breed, {@Size={ceil(({@BaseSize}-.25)*10)/10}} hands high, Full burden is {{@Size}*10+{@c}} lbs.\n[#{{GenderNo} + {@BreedNo}} Training] [#{@Speed} Rate]\n{Ceil({@Disc*85*@TrainValue})+{@racer}} gp
4: {GenderNo==20} [#{1d100} GeldingAge] yr. old [#{1d100} Color] Gelding, [@Breed] blooded breed, {@Size={ceil(({@BaseSize}+.5)*10)/10}} hands high, Full burden is {{@Size}*10+{@c}} lbs.\n[#{{GenderNo} + {@BreedNo}} Training] [#{@Speed} Rate]\n{Ceil({@Disc*80*@TrainValue})+{@racer}} gp
2: {GenderNo==30} [#{1d100} StallionAge] yr. old [#{1d100} Color] Stallion, [@Breed] blooded breed, {@Size={ceil(({@BaseSize}+.25)*10)/10}} hands high, Full burden is {{@Size}*10+{@c}} lbs.\n[#{{GenderNo} + {@BreedNo}} Training] [#{@Speed} Rate]\n{Ceil({@Disc*90*@TrainValue})+{@racer}} gp

#This table points to the appropriate specialty training table, based on the gender and temperment of the horse.
#The die roll sets the chance of having a specialty trained horse; only rolls 01 - 100 result in specialty training.
#As set in this table, there is a 100 in <400 to 500> chance that a horse has specialty training.
#Horses of a particular gender or temerpment are more likely to be selected for specialty training, than others.
#The [TrainMod] factor is a result of the size of settlment; larger settlements are more likely to have trainers, breeders, and commercial equine enterprises.
#The effect of the [TrainMod] factor is to reduce the die roll for larger settlements (and increase it for smaller settlements), causing larger settlements to have a higher occurance of trained horses.
Table: Training
Type: Lookup
11: <font color=red>[#{Ceil({d450} * [TrainMod])} MareCold]</font>
12: <font color=red>[#{Ceil({d500} * [TrainMod])} MareWarm]</font>
13: <font color=red>[#{Ceil({d400} * [TrainMod])} MareHot]</font>
21: <font color=red>[#{Ceil({d450} * [TrainMod])} GeldCold]</font>
22: <font color=red>[#{Ceil({d500} * [TrainMod])} GeldWarm]</font>
23: <font color=red>[#{Ceil({d400} * [TrainMod])} GeldHot]</font>
31: <font color=red>[#{Ceil({d450} * [TrainMod])} StallionCold]</font>
32: <font color=red>[#{Ceil({d450} * [TrainMod])} StallionWarm]</font>
33: <font color=red>[#{Ceil({d250} * [TrainMod])} StallionHot]</font>
``````
• Code for horses part 2:

# Next 9 tables are chance of specialty training, by gender and temperment

``````#[TrainValue] is horse cost multiplier for specialty training; it is currenlty consistent among the 9 tables, but could be edited for use (i.e. a hot-blooded stallion sprinter may be more highly valued than a warm-blooded gelding sprinter)
#[SpeedMod] currently only modifies the cantor and gallop rates of sprinters, and is uniform among the 9 tables.
Table: MareCold
Type: Lookup
Default: {@TrainValue==1.0} {@speedmod==1.0} {@racemod==0}
01 - 30: Broodmare, {@TrainValue==1.1} {@speedmod==1.0} {@racemod==0}
31 - 50: Warhorse, {@TrainValue==(@size/6+4+({@age}-5)/12)} {@speedmod==1.0} {@racemod==0.2}
51 - 55: Trail Horse, {@TrainValue==1.5} {@speedmod==1.0} {@racemod==0.2}
56 - 80: Heavy Draft, {@TrainValue==1.3} {@speedmod==0.9} {@racemod==0}
81 - 100: Pack Horse, {@TrainValue==1.2} {@speedmod==1.0} {@racemod==0}
101 - 700: \z{@TrainValue==1.0} {@speedmod==1.0} {@racemod==0} {@racemod==0}

Table: MareWarm
Type: Lookup
Default:  {@TrainValue==1.0} {@speedmod==1.0} {@racemod==0}
01 - 30: Broodmare, {@TrainValue==1.1} {@speedmod==1.0} {@racemod==0}
31 - 60: Warhorse, {@TrainValue==(@size/6+4+({@age}-5)/12)} {@speedmod==1.0} {@racemod==0.2}
61 - 85: Trail Horse, {@TrainValue==1.5} {@speedmod==1.0} {@racemod==0.2}
86 - 95: Sprinter, {@TrainValue==1+(1-@age/50)} {@speedmod==1.07} {@racemod==1.0}
96 - 100: Pack Horse, {@TrainValue==1.2} {@speedmod==1.0} {@racemod==0}
101 - 700: \z{@TrainValue==1.0} {@speedmod==1.0} {@racemod==0}

Table: MareHot
Type: Lookup
Default: {@TrainValue==1.0} {@speedmod==1.0} {@racemod==0}
01 - 40: Broodmare, {@TrainValue==1.1} {@speedmod==1.0} {@racemod==0}
41 - 45: Warhorse, {@TrainValue==(@size/6+4+({@age}-5)/12)} {@speedmod==1.0} {@racemod==0.2}
46 - 75: Trail Horse, {@TrainValue==1.5} {@speedmod==1.0} {@racemod==0.2}
76 - 100: Sprinter, {@TrainValue==1.4+(1-@age/50)} {@speedmod==1.1} {@racemod==1.0}
101 - 700: \z{@TrainValue==1.0} {@speedmod==1.0} {@racemod==0}

Table: GeldCold
Type: Lookup
Default: {@TrainValue==1.0} {@speedmod==1.0} {@racemod==0}
01 - 25: Warhorse, {@TrainValue==(@size/6+4+({@age}-5)/12)} {@speedmod==1.0} {@racemod==0.2}
26 - 30: Trail Horse, {@TrainValue==1.5} {@speedmod==1.0} {@racemod==0.2}
31 - 70: Heavy Draft, {@TrainValue==1.3} {@speedmod==0.9} {@racemod==0}
71 - 100: Pack Horse, {@TrainValue==1.2} {@speedmod==1.0} {@racemod==0}
101 - 700: \z{@TrainValue==1.0} {@speedmod==1.0} {@racemod==0}

Table: GeldWarm
Type: Lookup
Default: {@TrainValue==1.0} {@speedmod==1.0} {@racemod==0}
01 - 30: Warhorse, {@TrainValue==(@size/6+4+({@age}-5)/12)} {@speedmod==1.0} {@racemod==0.2}
31 - 60: Trail Horse, {@TrainValue==1.5} {@speedmod==1.0} {@racemod==0.2}
61 - 80: Sprinter, {@TrainValue==1+(1-@age/50)} {@speedmod==1.05} {@racemod==1.0}
81 - 85: Heavy Draft, {@TrainValue==1.3} {@speedmod==0.95} {@racemod==0}
86 - 100: Pack Horse, {@TrainValue==1.2} {@speedmod==1.0} {@racemod==0}
101 - 700: \z{@TrainValue==1.0} {@speedmod==1.0} {@racemod==0}

Table: GeldHot
Type: Lookup
Default: {@TrainValue==1.0} {@speedmod==1.0} {@racemod==0}
01 - 15: Warhorse, {@TrainValue==(@size/6+4+({@age}-5)/12)} {@speedmod==1.0} {@racemod==0.2}
16 - 50: Trail Horse, {@TrainValue==1.5} {@speedmod==1.0} {@racemod==0.2}
51 - 95: Sprinter, {@TrainValue==1.4+(1-@age/50)} {@speedmod==1.1} {@racemod==1.0}
96 - 100: Pack Horse, {@TrainValue==1.2} {@speedmod==1.0} {@racemod==0}
101 - 700: \z{@TrainValue==1.0} {@speedmod==1.0} {@racemod==0}

Table: StallionCold
Type: Lookup
Default: {@TrainValue==1.0} {@speedmod==1.0} {@racemod==0}
01 - 50: Stud, {@TrainValue==2} {@speedmod==1.0} {@racemod==0}
51 - 60: Warhorse, {@TrainValue==(@size/6+4+({@age}-5)/12)} {@speedmod==1.0} {@racemod==0.2}
61 - 70: Trail Horse, {@TrainValue==1.5} {@speedmod==1.0} {@racemod==0.2}
71 - 90: Heavy Draft, {@TrainValue==1.3} {@speedmod==0.95} {@racemod==0}
91 - 100: Pack Horse, {@TrainValue==1.2} {@speedmod==1.0} {@racemod==0}
101 - 700: \z{@TrainValue==1.0} {@speedmod==1.0} {@racemod==0}

Table: StallionWarm
Default: {@TrainValue==1.0} {@speedmod==1.0} {@racemod==0}
01 - 50: Stud, {@TrainValue==2} {@speedmod==1.0} {@racemod==0}
51 - 55: Warhorse, {@TrainValue==(@size/6+4+({@age}-5)/12)} {@speedmod==1.0} {@racemod==0.2}
56 - 70: Trail Horse, {@TrainValue==1.5} {@speedmod==1.0} {@racemod==0.2}
71 - 95: Sprinter, {@TrainValue==1.2+(1-@age/50)} {@speedmod==1.07} {@racemod==1.0}
96 - 100: Pack Horse, {@TrainValue==1.2} {@speedmod==1.0} {@racemod==0}
101 - 700: \z{@TrainValue==1.0} {@speedmod==1.0} {@racemod==0}

Table: StallionHot
Type: Lookup
Default: {@TrainValue==1.0} {@speedmod==1.0} {@racemod==0}
01 - 50: Stud,{@TrainValue==2} {@speedmod==1.0} {@racemod==0}
51 - 55: Trail Horse, {@TrainValue==1.5} {@speedmod==1.0} {@racemod==0.2}
56 - 97: Sprinter, {@TrainValue==1.8+(1-@age/50)} {@speedmod==1.1} {@racemod==1.0}
98 - 100: Pack Horse, {@TrainValue==1.2} {@speedmod==1.0} {@racemod==0}
101 - 700: \z{@TrainValue==1.0} {@speedmod==1.0} {@racemod==0}
``````
• edited June 2019

Here's the table for gem size. You see, it's a 1d100 roll. But that is modified in the line that calls the table base monster CR level. It could be 1d100 +0 up to 1d100 +180 (and there's also variability in the call beyond just simple CR).

So, while 1d100 +0 has: 40% small; 30% medium; 7% Large.

If the roll sent to the table is 1d100 +80, it will result in 0% small; 55% medium; 42% Large.

Basically, why would a high CR opponent be carrying around a small gem? But, I could have made 101-103 = small if I wanted a slight possibility of a small gem being found in a high level treasure stash.

``````Table: Size
Type: Lookup
Default: Medium {@SizeMod==3}
01-20: Tiny {@SizeMod==0.5}
21-60: Small {@SizeMod==1}
61-90: Medium {@SizeMod==3}
91-97: Large {@SizeMod==8}
98-99: <font color=red>Huge</font> {@SizeMod==15}
100: <font color=red>Monumental</font> {@SizeMod==40}
101-145: Medium {@SizeMod==3}
146-190: Large {@SizeMod==8}
191-197: <font color=red>Huge</font> {@SizeMod==15}
198-200: <font color=red>Monumental</font> {@SizeMod==40}
201-220: Medium {@SizeMod==3}
221-260: Large {@SizeMod==8}
261-272: <font color=red>Huge</font> {@SizeMod==15}
273-280: <font color=red>Monumental</font> {@SizeMod==40}
``````

And, apologies if this thread is way off the mark and not helpful.

• @Levendor ,
This looks quite promising.
OK, the horse tables are just, Wow! I can see how that would work. And I think I can see my way through that to make a start on converting my table.

Just to make sure I'm reading all of this correctly though, in the Count table, the comments for city and metropolis are wrong, right?

``````city: {10d8} //8-80
metropolis: {20d8} //16-160
``````

I would think they should have been 10-80 and 20-160 respectively.

Anyhow, I'll give it a go with a small subset of the races/classes and post what I get for further comment.

The Gem table, by the way, looks like pure simplicity until I trued working out relative probability, but it gives me some ideas.

Thanks

• Okay, here is the random adventurer sub-table collection that I have so far.

Sub-classes are not done at all yet. though they should be fairly easy as they will use the same format as sub-races. I'm using my Greyhawk setting's global values for distribution of races (instead of more accurate regional values) and currently, class choice is not-biased by race selected - which it really should be.

For the alignment determination, I used the dice multiplier idea from @Levendor and combined it (though perhaps inelegantly) with the conditionals idea I started on from @jdale . I did end up switching from when statements to nested If() statements as I was unable to get the when statements to work as 'I thought they should'.

Thanks for all the help. I'll re-post if I figure out a clean way of biasing classes and regionalizing races.

``````;Random Adventurer
;Generates a random adventurer based on my Greyhawk setting information
[@Race], [@Level] [@Class], [@Align1] [@Align2]

Table:Level
Type: Lookup
Roll:1d100
1:Level 1
2-5:Level 2
6-15:Level 3
16-35:Level 4
36-65:Level 5
66-85:Level 6
86-90:Level 7
91-95:Level 8
96-99:Level 9
100:Level 10

Table: Align1
[Law=={Ceil({{1d10}*{L}})}][Neut=={Ceil({{1d10}*{N}})}][Chaos=={Ceil({{1d10}*{C}})}] &
[LNC=={If({Law}>{Neut},&
{If({Law}>={Chaos},&
1,&
3)},&
{If({Neut}>={Chaos},&
2,&
3)}&
)}] &
[#{LNC} LNCAxis]

Table: LNCAxis
Type: Lookup
1:Lawful
2:Neutral
3:Chaotic

Table: Align2
[Good=={Ceil({{1d10}*{G}})}][TNeut=={Ceil({{1d10}*{T}})}][Evil=={Ceil({{1d10}*{E}})}] &
[GTE=={If({Good}>{TNeut},&
{If({Good}>={Evil},&
1,&
3)},&
{If({TNeut}>={Evil},&
2,&
3)})}] &
[#{GTE} GTEAxis]

Table: GTEAxis
Type: Lookup
1:Good
2:Neutral
3:Evil

Table: Class
Type: Lookup
Roll:1d100
1-15:Fighter//No Alignment Tendencies
16-30:Ranger{N=={N}+1}{T=={T}+.5}
31-40:Cleric//Need to finish God Sub-Table
41-50:Rogue{L=={L}-.2}
51-60:Wizard//Need to look at schools for alignment tendencies
61-65:Bard{T=={T}+1}
66-70:Monk{L=={L}+1}
71-75:Sorcerer//No Alignment Tendencies-Might change based on Origin
76-80:Warlock{G=={G}-.2}
81-90:Barbarian{L=={L}-.2}
96-100:Druid{N=={N}+1}{T=={T}+.5}

Table: Race //Based on continental norms. Should be regionally based
Type: Lookup
Roll:1d100
1-22:{N==1} {L==1} {C==1} {T==1} {G==1} {E==1} Human of [@Human] Descent
23-30:{N==1} {L==2} {C==0.5} {T==1} {G==1} {E==1} [#1d100 Dwarf] Dwarf
31-38:{N==1} {L==.5} {C==2} {T==1} {G==1} {E==1} [#1d100 Elf] Elf
39-46:{N==1} {L==1} {C==1} {T==1} {G==2} {E==.5} [#1d100 Gnome] Gnome
47-54:{N==1} {L==1} {C==1} {T==1} {G==1} {E==1} [#1d100 HalfElf]
55-62:{N==1} {L==.5} {C==2} {T==1} {G==1} {E==1} Half Orc
63-70:{N==1} {L==2} {C==.5} {T==1} {G==2} {E==.5} [#1d100 Halfling] Halfling
71-73:{N==1} {L==.8} {C==2} {T==1} {G==.5} {E==1.5} [#1d100 Tiefling] Tiefling
74-76:{N==1} {L==1} {C==1} {T==1} {G==1} {E==.5} [#1d4 Aasimar] Aasimar
77-78:{N==1} {L==1} {C==1} {T==1} {G==1} {E==1} Dragonborn of [#1d10 Dragonborn] Dragon Descent
79-80:{N==1} {L==1} {C==1} {T==1} {G==1} {E==1} [#1d100 Genasi] Genasi
81-82:{N==2} {L==1} {C==1} {T==2} {G==1} {E==1} Aarakocra
83:{N==1} {L==.5} {C==2} {T==1} {G==.5} {E==2} Bugbear
84-85:{N==2} {L==1} {C==1} {T==2.5} {G==2} {E==.5} Firbolg
86:{N==2} {L==1} {C==1} {T==1} {G==1} {E==2} Goblin
87:{N==1} {L==2} {C==1} {T==2} {G==1} {E==1} Goliath
88:{N==2} {L==1} {C==1} {T==2} {G==1} {E==1} Grung
89:{N==1} {L==2.5} {C==1} {T==1} {G==1} {E==2.5} Hobgoblin
90-91:{N==1} {L==1} {C==2} {T==2} {G==1} {E==1} Kenku
92:{N==1} {L==2} {C==.5} {T==1} {G==1} {E==1.5} Kobold
93-94:{N==2} {L==1} {C==1} {T==2} {G==1} {E==1.5} Lizardfolk
95:{N==1} {L==1} {C==1} {T==1} {G==.5} {E==2.5} Orc
96:{N==1} {L==1} {C==2} {T==2} {G==1} {E==.5} Tabaxi
97:{N==2} {L==1} {C==1} {T==2} {G==1} {E==1} Tortle
98:{N==1} {L==2.5} {C==1} {T==1} {G==2} {E==.5} Triton
99:{N==2.5} {L==.5} {C==1} {T==1} {G==1} {E==2.5} Yuan-Ti Pureblood
100:{N==1} {L==3} {C==1} {T==1} {G==1} {E==1} [Gith]

Table: Aasimar
Type: Lookup
1:Variant {G=={G}+1}
2:Protector {G=={G}+1}
3:Scourge {G=={G}+1}|
4:Fallen {G=={G}-.5}

Table: Dragonborn
Type: Lookup
1:Black {E=={E}+.5}
2:Blue {E=={E}+.5}
3:Brass {G=={G}+.5}
4:Bronze {G=={G}+.5}
5:Copper {G=={G}+.5}
6:Gold {G=={G}+.5}
7:Green {E=={E}+.5}
8:Red {E=={E}+.5}
9:Silver {G=={G}+.5}
10:White {E=={E}+.5}

Table: Dwarf
Type: Lookup
1-50:Hill {G=={G}+.5}
51-90:Mountain {G=={G}+.5}
91-100:Duergar {E=={E}+.5}

Table: Elf
Type: Lookup
1-50:High
51-80:Wood {T=={T}+1}
81-98:Drow {E=={E}+1}

Table: Genasi
Type: Lookup
1-25:Earth {N=={N}+1} {T=={T}+1}
26-50:Air {N=={N}+1} {T=={T}+1}
51-75:Fire {N=={N}+1} {T=={T}+1}
76-100:Water {N=={N}+1} {T=={T}+1}

Table: Gith
Type: Lookup
1-50:Githyanki {E=={E}+1}
51-100:Githzerai {T=={T}+1}

Table: Gnome
Type: Lookup
1-20:Deep|L-8||C-8|
21-60:Forest
61-100:Rock

Table: HalfElf
Type: Lookup
1-70:Half-Elf
71-80:Half-High Elf {T=={T}+.5}
81-90:Half-Wood Elf {T=={T}+.5}
91-100:Half-Drow Elf {E=={E}+.5}

Table: Halfling
Type: Lookup
1-48:Lightfoot
49-96:Stout
97-100:Ghostwise

Table: Human
4:Pure [!Human2]
8:[!Human2]-[!Human2]
6:[!Human2]-[!Human2]-[!Human2]
1:unrecognizably-mixed

Table: Human2 // These should be regionally based
4:{L=={L}+1}{C=={C}-.2}Baklunish
4:{L=={L}+1}{C=={C}-.2}Oeridian
4:{C=={C}+1}{G=={G}+.5}Flannae
4:{C=={C}+.2}{E=={E}+.2}Suloise
2:{N=={N}+1}{T=={T}+1}Olman
2:{N=={N}+1}{T=={T}+1}{G=={G}+1}Rhennee

Table: Tiefling
Type: Lookup
1-89:Normal
90-93:Feral
94-96:[#1d100 Infernal] {L=={L}+1.5}
97-100:Abyssal  {C=={C}+1}

Table: Infernal
Type: Lookup
1-91:Infernal
92:Infernal (Asmodeus)
93:Infernal (Baalzebul
94:Infernal (Dispater)
95:Infernal (Fierna)
96:Infernal (Glasya)
97:Infernal (Levistus)
98:Infernal (Mammon)
99:Infernal (Mephistopheles)
100:Infernal (Zariel)
``````
• Glad it gave you an idea. You're right on the city/metro comment. It still gives the intended result - more horses for sale to adventurers in a metro than a city.

I haven't had a chance to copy, run, and review your generator yet, but it looks like a grand thing!