Conditionally Weighted Table Pick Possible?

Hey all,

I just tried this on one of my generators and it didn't seem to work, but is it possible to have a prompt-based, weighting for table picks?

Specifically, a prompt like Psychic: Yes|No.

If yes, one of the options in a table goes to 1000000:Table Entry instead of just a blank Table Entry. I tried when|do|end and it didn't work for me.

The end goal is to guarantee the selection of an option in almost all cases of Yes (I still want a little possibility of it not being there or I'd just hard code it), and then just have it be a normally randomized option for Nos.

Comments

  • I don't think you can do that with a simple weighted table. But two ways you could achieve that:
    * Use two different tables. Call the table as tablename{prompt1} and then have tables tablenameYes and tablenameNo.
    * Use a lookup table rather than a weighted table. E.g. lookup 1-100 for No and add 10 (or whatever) to the lookup value for Yes so the values are 11-111. The table then has entries for 1-111. Weighted tables are a little easier to set up than lookup tables, but anything you can do with a weighted table is also possible with a lookup table.

  • Thanks, jdale. I think the two table option is probably going to work best/easiest for what I'm trying to do.

  • I use the second method jdale describes in my Knight's Troop generator. It's a d100 table that has entries up to 119. If it's a simple patrol of a knight and few retainers, I call the table with a 1d104 roll... just a 4% chance of a minor noble leading a patrol;

    If it's a larger unit - say a regiment - I call the table with maybe a d28+80, giving it a result of 81 to 118, or about 50% chance of being led by a noble, excluding the possibility of only the king himself.

    For an full army the call is d10+109, insuring the army is led by a major noble or a royal up to and including the king.

    It's a nice method to shift results up the table to the more rare/more powerful selections.

    Here's the table:

            Table: Title
            Type: Lookup
            1 - 100: Sir
            101 - 102: Baronnet
            103 - 106: Baron
            107: Archbaron
            108: Viscount
            109 - 111: Count
            112: Marquis
            113 - 114: Duke
            115: Grand Duke
            116: Archduke
            117: Prince
            118: Crown Prince
            119: King
    
  • Alright, I'm struggling and need help with the Lookup table option. I'm doing a slight variation of the above. I'm doing a lookup table with numbers 1-8 based on my choice from my prompt - the different game worlds that I'm building this generator to cover (the animals in fantasy D&D settings aren't the same in space opera Star Wars settings).

    This table will call out to subtables for each game world. I feel like I need to do it this way because the number of worlds will remain static but the amount of choices for each game will be different as I flesh them out.

    I have a prompt with 8 options for the game worlds, like I said.

    How do I assign a number to each prompt world and have the Lookup table recognize it? Example: Normal = 1, Star Wars = 2, Fantasy = 3, etc.

    I'm mentally stuck on a when/do function, but I'm having no luck making this work.

  • Oh, I also should mention that I'm wanting to stick to this methodology because I can apply the sort and implode filters and have this result nest alphabetically in a larger output list. At least, it seems to do that when I'm only doing one option and not all of the various prompts.

  • edited December 2020

    Here's a super short example generator. Hopefully it hits on the question you have. I'm not sure why you would need the variable "Number" that I have set, but I dropped it there just to show how you can assign it inline in that dictionary table. Only 5e and SW have some bogus data tables, the other prompt choices will be missing errors.

    EDIT: Tweaked the table calls for 5e and SW to be multiple picks, sorted and imploded.

    EDIT 2: Your when-do could work, but with 8 items, it's a very long nested string or series of 8 similar looking statements. The Table: Game that I use below is essentially doing the same thing... depending on the user selection in prompt1, go to a particular weighted table (and assign a numerical value to the selected game, maybe for use elsewhere in the generator so you don't have to keep typing {$prompt1}).

    ; Game System.ipt
    ; created 12/12/2020 3:26:00 AM
    Prompt: Choose Game System {BX|5e|RMu|SM|SW|40k} 5e
    
    Maxreps:1
    
    Table: Main
    [#{$prompt1} Game]\n Game Number {@Number}
    
    Table: Game
    Type: Dictionary
    BX: [@BX] {@Number==1}
    5e: [@{1d6} 5e>>sort>>implode] {@Number==2}
    RMu: [@RMu] {@Number==3}
    SM: [@SM] {@Number==4}
    SW: [@{1d4} SW>>sort>>implode] {@Number==5}
    40k: [@40k] {@Number==6}
    
    Table: 5e
    10: Orc
    6: Goblin
    2: Troll
    1: Green Dragon
    
    Table: SW
    6: Ewok
    2: Wookie
    10: Human
    1: Sith
    1: Jedi
    
  • Dictionary table is what I need! I forget about the Help file to look for other options. Forget is the wrong word, I fixate on figuring out a way to brute force what I want instead of looking for a different/better way.

    How do I get the Dictionary table to look for Prompt3, though? I have Prompt1 which will result in Mundane|Exotic|Supernatural and Prompt2 which will result in a numeric 0-12. As you can see below, I want to consolidate a lot of separate generators into one and then send them back to the parent generator.

    Here is my experiment code:

    `; Prompt3 should feed into animalhandling table from the parent NPC generator.

    table: animalhandling
    type: Dictionary
    Normal:[!{1d2} morrowanimaltypes >> sort >> implode]
    Morrow Project:[!{1d2} starwarsanimaltypes >> sort >> implode]
    Outlanders:[!{1d2} normalanimaltypes >> sort >> implode]
    Stargate:[!{1d2} outlandersanimaltypes >> sort >> implode]
    Star Wars:[!{1d2} riftsanimaltypes >> sort >> implode]
    Star Trek:[!{1d2} stargateanimaltypes >> sort >> implode]
    Rifts:[!{1d2} fantasyanimaltypes >> sort >> implode]
    Fantasy:[!{1d2} startrekanimaltypes >> sort >> implode]

    table: normalanimaltypes
    Animal Handling (Bears)-{!{1d9-1} + {$IQ}}
    Animal Handling (Big Cats)-{!{1d9-1} + {$IQ}}
    50:Animal Handling (Camels)-{!{1d9-1} + {$IQ}}
    100:Animal Handling (Dogs)-{!{1d9-1} + {$IQ}}
    Animal Handling (Dolphins)-{!{1d9-1} + {$IQ}}
    50:Animal Handling (Elephants)-{!{1d9-1} + {$IQ}}
    100:Animal Handling (Equines)-{!{1d9-1} + {$IQ}}
    Animal Handling (Raptors)-{!{1d9-1} + {$IQ}}
    Animal Handling (Reptiles)-{!{1d9-1} + {$IQ}}
    Animal Handling (Small Cats)-{!{1d9-1} + {$IQ}}
    Animal Handling (Whales)-{!{1d9-1} + {$IQ}}

    Table: morrowanimaltypes
    [!normalanimaltypes]
    Animal Handling (Setting Specific Animal)-{!{1d9-1} + {$IQ}}

    table: outlandersanimaltypes
    [!normalanimaltypes]
    Animal Handling (Setting Specific Animal)-{!{1d9-1} + {$IQ}}

    table: starwarsanimaltypes
    Animal Handling (Taun Taun)-{!{1d9-1} + {$IQ}}
    Animal Handling (Blurrg)-{!{1d9-1} + {$IQ}}
    Animal Handling (Bantha)-{!{1d9-1} + {$IQ}}

    table: stargateanimaltypes
    [!normalanimaltypes]
    Animal Handling (Setting Specific Animal)-{!{1d9-1} + {$IQ}}

    table: riftsanimaltypes
    [!normalanimaltypes]
    Animal Handling (Setting Specific Animal)-{!{1d9-1} + {$IQ}}

    table: startrekanimaltypes
    [!normalanimaltypes]
    Animal Handling (Setting Specific Animal)-{!{1d9-1} + {$IQ}}

    table: fantasyanimaltypes
    [!normalanimaltypes]
    Animal Handling (Setting Specific Animal)-{!{1d9-1} + {$IQ}}`

  • Nevermind. I see it.

  • edited December 2020

    Alright, mainly because I'm picky but also because I want to know the limits...I'd like to have multiple words written normally, like Star Wars instead of StarWars/Star_Wars/abbreviations.

    A dictionary table can't have spaces in the selections, correct?

    I've created a Define: command in my parent generator that use a when/do to set Star Wars to Star_Wars. I have a simple repeat of the variable that proves it's assigning it correctly.

    I'm setting it to a variable titled GAME and passing that to my outside generator. If I change the variable to Prompt3 and put in underscores, it works perfect. If I use anything other it gives me a missing error in the display table.

    From the parent:

    Prompt: Game {Morrow Project|Outlanders|Star Wars|Stargate|Rifts|Normal|Fantasy|Star Trek} Normal
    
    Define: GAME = [when] {$Prompt3} = Outlanders [do]Outlanders[end][when] {$Prompt3} = Star Wars [do]Star_Wars[end]
    

    From the outside generator:

    table: animalhandling
    [#{$GAME} animalhandlingskill]
    
    table: animalhandlingskill
    type: Dictionary
    Anythingbutnormal: [!{1d2} normalanimaltypes >> sort >> implode]
    MorrowProject: [!{1d2} morrowprojectanimaltypes >> sort >> implode]
    Outlanders: [!{1d2} outlandersanimaltypes >> sort >> implode]
    Stargate: [!{1d2} stargateanimaltypes >> sort >> implode]
    Star_Wars: [!{1d2} starwarsanimaltypes >> sort >> implode]
    StarTrek: [!{1d2} startrekanimaltypes >> sort >> implode]
    Rifts: [!{1d2} riftsanimaltypes >> sort >> implode]
    Fantasy: [!{1d2} fantasyanimaltypes >> sort >> implode]
    

    And yes, I'm selecting Star Wars even though I haven't finished my when/dos for all 8 games yet.

  • I found a way to make it work. I took the define statement out of the parent and placed it in the first line of the animalhandling sub-table.

    It seems to work everytime while giving me the aesthetics of normal words without abbreviations or underscores in my drop down.

    I think one of the limits on dictionary tables is that they're limited to only 10 characters?

    I'd be curious to see if there are any other, more elegant ways to achieve what I'm doing here.

    And as always, I appreciate the time and effort you guys are spending to help educate me.

  • There is a char limit to dictionary tables. The other thing to let you know, before you get too far, is that there is a limit of only 4 prompts in a generator. There are some possible work arounds to that, but nothing elegant or simple.

  • Yeah, I saw the thread you guys had going about the prompts. Right now, I've only found a need for three, so I think I'm good with it.

  • The limit on the length of dictionary table keys is a little restrictive, but you can use a dictionary table to expand them to full length. E.g. you randomly determine the skill is AnimHand but you display it as [@{$Skill} FullSkillName] to expand that out to the full name. That lets you safely reduce the length, get rid of spaces, etc, while still displaying it nicely.

  • edited March 2023

    @jdale -

    Ran across your reply while wrestling with a dictionary table, and I understand the idea of using the dictionary table to expand a shortened entry to a full name.

    For example, I have a random lair table that chooses a monster then uses the monster name to look up a stat block on a dictionary table:

    set lairMonster=[encounterBarrens]
    
    Table: encounterBarrens
    1:acolyte
    2:apeWhite
    2:bandit
    
    ---
    
    [#{lairMonster} monsterStatBlock]
    Table: monsterStatBlock
    Type: dictionary
    acolyte:(<b>AC</b> 2 \[17\]; <b>HD</b> 1 ({1d8}hp); <b>Att</b> 1 x mace (1d6); <b>THAC0</b> 19 \[+0\]; <b>MV</b> 60' (20'); <b>SV</b> D11 W12 P14 B16 S15 (C1); <b>ML</b> 7; <b>AL</b> A; <b>XP</b> 10; <b>NA</b> {1d8} ({1d20})) <blockquote>[@treasureTypeU]</blockquote>
    apeWhite:(<b>AC</b> 6 \[13\]; <b>HD</b> 4 ({4d8}hp); <b>Att</b> 2 x claw (1d4) or 1 x thrown rock (1d6); <b>THAC0</b> 16 \[+3\]; <b>MV</b> 120' (40'); <b>SV</b> D12 W13 P14 B15 S16 (2); <b>ML</b> 7; <b>AL</b> N; <b>XP</b> 75; <b>NA</b> {1d6} ({2d4})) <blockquote>[@treasureTypeNone]</blockquote>
    bandit:(<b>AC</b> 6 \[13\]; <b>HD</b> ½ ({1d4}hp); <b>Att</b> 1 x weapon (by weapon); <b>THAC0</b> 19 \[+0\]; <b>MV</b> 120' (40'); <b>SV</b> D13 W14 P13 B16 S15 (T1); <b>ML</b> 8; <b>AL</b> N or C; <b>XP</b> 5; <b>NA</b> {1d8} ({3d10}) <blockquote>[@treasureTypeU] [@treasureTypeA]</blockquote>
    

    What I'm having trouble with is using the dictionary entry to expand the monster name properly. In this example, I want "apeWhite" to display as "Ape, White". I also want to assign the monster name to a variable so I can display it elsewhere in the results, like:

    Ape, White (AC 6 [13]; HD 4 (12hp); Att 2 x claw (1d4) or 1 x thrown rock (1d6); THAC0 16 [+3]; MV 120' (40'); SV D12 W13 P14 B15 S16 (2); ML 7; AL N; XP 75; NA 4 (4))

    Incidental Treasure

    •No Treasure

    I've tried creating a new variable "monsterName" and assigning it with each dictionary entry (e.g., {monsterName=Ape, White}, but I think IPP is tripping on the space and the results show (missing).

    Any suggestions?

    Thanks,
    -Erin

    ---
    UPDATE (3/23/23):
    I sorted this out. Turns out I wasn't assigning the variables correctly (seems every time I return to IPP after a long absence, I forget how to make it work).

    The solution was using the full monster name in the encounter table, then setting an inline variable to create an abbreviation for the monster to look it up on the dictionary table (the abbreviation is necessary to limit the entry to 10 characters and remove spaces).

    # LAIR OVERVIEW
    # Create a lair based on terrain
    # -------------------------
    Table: lairOverview
    <p>This lair is occupied by [@monsterName=encounter{prompt2}]:</p> &
    <p>[#{monsterAbbr} monsterStatBlock]</p>
    
    Table: encounterBarrens
    1:acolytes[monsterAbbr==acolyte] //monsterAbbr is the dictionary table lookup
    1:white apes[monsterAbbr==apeWhite]
    1:bandits[monsterAbbr==bandit]
    
    # MONSTER STATS
    # -------------------------
    Table: monsterStatBlock
    Type: dictionary
    acolyte:(<b>AC</b> 2 \[17\]; <b>HD</b> 1 ({1d8}hp); <b>Att</b> 1 x mace (1d6); <b>THAC0</b> 19 \[+0\]; <b>MV</b> 60' (20'); <b>SV</b> D11 W12 P14 B16 S15 (C1); <b>ML</b> 7; <b>AL</b> A; <b>XP</b> 10; <b>NA</b> {1d8} ({1d20})) <blockquote>[@treasureTypeU]</blockquote>
    apeWhite:(<b>AC</b> 6 \[13\]; <b>HD</b> 4 ({4d8}hp); <b>Att</b> 2 x claw (1d4) or 1 x thrown rock (1d6); <b>THAC0</b> 16 \[+3\]; <b>MV</b> 120' (40'); <b>SV</b> D12 W13 P14 B15 S16 (2); <b>ML</b> 7; <b>AL</b> N; <b>XP</b> 75; <b>NA</b> {1d6} ({2d4})) <blockquote>[@treasureTypeNone]</blockquote>
    bandit:(<b>AC</b> 6 \[13\]; <b>HD</b> 1/2 ({1d4}hp); <b>Att</b> 1 x weapon (by weapon); <b>THAC0</b> 19 \[+0\]; <b>MV</b> 120' (40'); <b>SV</b> D13 W14 P13 B16 S15 (T1); <b>ML</b> 8; <b>AL</b> N or C; <b>XP</b> 5; <b>NA</b> {1d8} ({3d10})) <blockquote>[@treasureTypeU] [@treasureTypeA]</blockquote>
    

    This produces output like:

    This lair is occupied by white apes:

    (AC 6 [13]; HD 4 (22hp); Att 2 x claw (1d4) or 1 x thrown rock (1d6); THAC0 16 [+3]; MV 120' (40'); SV D12 W13 P14 B15 S16 (2); ML 7; AL N; XP 75; NA 4 (8))

    Incidental Treasure

    •No Treasure

  • Exactly where you do the lookup depends what you are trying to do, just make sure all the dictionary table references use the original short form. But for example:

    set lairMonster=[encounterBarrens]
    
    Table: encounterBarrens
    1:[#acolyte monsterStatBlock]\nThe monster is {monsterName}
    2:[#apeWhite monsterStatBlock]\nThe monster is {monsterName}
    2:[#bandit monsterStatBlock]\nThe monster is {monsterName}
    
    [#{lairMonster} monsterStatBlock]
    Table: monsterStatBlock
    Type: dictionary
    acolyte:[monsterName=[#acolyte FullName]] (<b>AC</b> 2 \[17\]; <b>HD</b> 1 ({1d8}hp); <b>Att</b> 1 x mace (1d6); <b>THAC0</b> 19 \[+0\]; <b>MV</b> 60' (20'); <b>SV</b> D11 W12 P14 B16 S15 (C1); <b>ML</b> 7; <b>AL</b> A; <b>XP</b> 10; <b>NA</b> {1d8} ({1d20})) <blockquote>[@treasureTypeU]</blockquote>
    apeWhite:[monsterName=[#apeWhite FullName]] (<b>AC</b> 6 \[13\]; <b>HD</b> 4 ({4d8}hp); <b>Att</b> 2 x claw (1d4) or 1 x thrown rock (1d6); <b>THAC0</b> 16 \[+3\]; <b>MV</b> 120' (40'); <b>SV</b> D12 W13 P14 B15 S16 (2); <b>ML</b> 7; <b>AL</b> N; <b>XP</b> 75; <b>NA</b> {1d6} ({2d4})) <blockquote>[@treasureTypeNone]</blockquote>
    bandit:[monsterName=[#bandit FullName]] (<b>AC</b> 6 \[13\]; <b>HD</b> ½ ({1d4}hp); <b>Att</b> 1 x weapon (by weapon); <b>THAC0</b> 19 \[+0\]; <b>MV</b> 120' (40'); <b>SV</b> D13 W14 P13 B16 S15 (T1); <b>ML</b> 8; <b>AL</b> N or C; <b>XP</b> 5; <b>NA</b> {1d8} ({3d10}) <blockquote>[@treasureTypeU] [@treasureTypeA]</blockquote>
    
    Table: FullName
    Type: dictionary
    acolyte:Acolyte of Doom
    apeWhite: Ape, White
    bandit:[|Bandit|Brigand]
    
  • Dictionary tables are the tool of choice at times, but sometimes the key limitations get in the way (max 10 characters, no spaces). One example above tries to use Anythingbutnormal and MorrowProject as keys, but both have more than 10 characters.

    You can of course use something like {index==substr(game,1,10)} and [#{index} animalhandlingskill] if you truncate each key to 10 characters, and if every key is unique in its first 10 characters.

    Another workaround, however, is to create a separate table for each entry instead of making one dictionary table. This lets you use long names with spaces, and case doesn't matter. For example:

    [@Animal Skill {GAME}]
    
    table: Animal Skill Anything but normal
    [!{1d2} normalanimaltypes >> sort >> implode]
    table: Animal Skill Morrow Project
    [!{1d2} morrowprojectanimaltypes >> sort >> implode]
    table: Animal Skill Outlanders
    [!{1d2} outlandersanimaltypes >> sort >> implode]
    table: Animal Skill Stargate
    [!{1d2} stargateanimaltypes >> sort >> implode]
    table: Animal Skill Star Wars
    [!{1d2} starwarsanimaltypes >> sort >> implode]
    table: Animal Skill Star Trek
    [!{1d2} startrekanimaltypes >> sort >> implode]
    table: Animal Skill Rifts
    [!{1d2} riftsanimaltypes >> sort >> implode]
    table: Animal Skill Fantasy
    [!{1d2} fantasyanimaltypes >> sort >> implode]
    

Leave a Comment