Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
Leperflesh
May 17, 2007

The Traveling CCircus thread has come to Trad Games! This is a thread for sharing your creative output with other goons from across the wide forums. Do browse it to see some of the cool poo poo people have made and done, and then please also feel free to post a sample of your (TG or non-TG related) creative stuff there!

I think it would be very cool if some of you folks posted some of your Actual Game Stuff You Made up in there.

Adbot
ADBOT LOVES YOU

Leperflesh
May 17, 2007

Go ahead, just no spamming. But feel free to make a post, and to respond to anyone who asks questions about it!

Leperflesh
May 17, 2007

I do online dice rolling using orokos.com but I don't know if you can do specifically your setup. It's pretty flexible, but the main feature is that dice rolls are logged and you don't need the logging I assume.

If you knew python it'd be a fairly easy thing to write.
You could do it in excel or google sheets, if you're willing to learn how to use cell functions to get the filtered results you want

but leaving that aside, what is that rather complicated dice mechanic supposed to actually accomplish? It seems likely to me at first glance that there's a simpler way to get the same probability curve.
Roll 10 to 20 d6,
then remove all the 1s
then each player takes turns counting fives and sixes (why did you remove the ones?) until... yeah I've lost what you're trying to say to do here

if you elaborate a bit I could probably set it up in a google sheet for you to look at

e. here's Orokos' dice roller help which is a popup so I can't link to it, the syntax is pretty straightforward and it has a lot of options:

quote:

Dice Roller
Format
XdY to roll X dice of Y sides. Prefix N# to roll the dice N separate times.

Operators allowed are +, -, *, and / which follow order of operations. Division rounds down. Use parentheses if needed. Full format is any number of terms combined with the operators, where term is a literal number or a roll. N can be a term itself.

Combinatorics are possible as well. N-choose-K results can be of the form NcK, the value will be the number of combinations to choose K items from a set of N items, and return a random one of these sets in the details. (i.e. 4c2 might result in 6 [4c2=1,3]) Permutations are possible in the form NpK. These terms are useful for generating sequences.

Options
Append the following modifiers as desired, if using multiple then they must be added in the order below. Some combinations may be invalid.

rZ - reroll die if result is Z or lower (Brutal property in D&D, etc.)
roZ - reroll die only once if result is Z or lower
mZ - count result as Z if roll is lower than Z
eZ or oZ - extra / open roll when the die is Z or higher, extra grants one bonus roll only
kZ or lZ - keep the highest / lowest Z rolls, drop others
tZ - target number Z, count rolls that meet or exceed Z as successes (if Z > Y, implicit oY)
hZ - hits Z, count rolls that meet or exceed Z as successes, max roll grants bonus roll (implicit oY) (WoD)
xZ - hits Z, count rolls that meet or exceed Z as successes, max roll grants bonus success (Exalted)
uZ - under Z, count rolls that are equal to or under Z as successes
! - when at the end of any roll, turns on verbose mode (shows all dice rerolled and modified)
Other Dice
Special system dice are available as XdY, where Y is one of:

F - Fudge (-1, 0, +1)
C - Cthulhutech (d10: scoring for highest multiple or straight)
H - Hero System damage (d6: Stun is sum of dice and Body is X modified -1 or +1 for each 1 or 6 rolled)
Edge of the Empire - XeY, where Y is the first letter of the die type: Ability, Boost, Challenge, Difficulty, Force, Proficiency, or Setback.

Warhammer Fantasy Roleplay 3e - XwY, where Y is the color of the die: Characteristic (Blue), Expertise (Yellow), Challenge (Purple), Reckless (Red), Conservative (Green), Fortune (White), or Misfortune (blacK).

Other symbol dice are available as XxY, where Y is one of:

K - King of Tokyo die (d6: 1, 2, 3, Heart, Energy, Attack)
M - Mage Knight mana die (d6: Black, White, Red, Green, Blue, Gold)
R - Fate of the Norns runes (draw from 24 runes)
Double Cross dice are available as XxxY to roll X dice (d10s) with a crit threshold of Y. Takes the highest single result, unless one or more dice are Y or higher. The result is increased by 10 and the dice Y or higher are rerolled and the process repeated.

Examples
D&D: 2#1d20+6 close blast 3 vs Reflex; (1d6+4)/2 damage, 2d20k1+8 Oath of Enmity attack
SR3: 5d6t8 Electronics 5 vs TN 8, 4d6o6k1 Stealth 4 open roll
WoD: 7d10o9h7 Seven dice, hits on 7+, roll again on 9+
Fudge: 4dF fudge dice! (-4 to +4)
Cthulhutech: 3dC+7 Marksmanship
Hero System: 8.5dH damage roll with a half-die!
Edge of the Empire: 2eA+1eP+3eD 2 Ability 1 Proficiency 3 Difficulty dice
WFRP 3e: 2wB+1wY+1wP+1wK 2 Characteristic 1 Expertise 1 Challenge 1 Misfortune dice
Double Cross: 6xx8 Pool of 6 dice, critical 8+

Leperflesh fucked around with this message at 19:54 on Feb 8, 2024

Leperflesh
May 17, 2007

OK so I'm just gonna clarify slightly more, and then see what I can put together because doing this is more interesting than working lol

Each player A and B has a starting number of dice. Let's call this DA and DB. It doesn't actually matter that it's dice, it's just a counter.
Each "round" both players will roll Xd6. Player A rolls XAd6 and Player B rolls XBd6. We need these values before we run the program.
Each resulting die that is value Y or lower, reduces D by 1. Y is usually 1 or 2. Players can have different Y values from each other, so we also store this as YA and YB before we run the program.
Each resulting die that is Z or higher is accumulated (that is, added to) by a variable, RA for player A and RB for player B. Z is usually 5 or 6, and can be different values for each player, so we store this as ZA and ZB and set those values before we run the program.
Subtract RA from RB. If the result is nonzero: if the result is a negative number, subtract the absolute value of the result from DB, if the result is a positive number, subtract the value from DA. If the result is zero, do nothing.
Now check both player's D values. If either or both of D is less than or equal to 5, the match is over.
If it is not, begin a new round. (At the beginning of each round, reset RA and RB to zero.)

Starting values of DA, DB, XA, XB, YA, YB, ZA, ZB can all be changed independently as starting conditions.

The above is like 90% of the way to a python script, or a script in any other scripting language you care to get. You need to add a randomizer function, store values and return them, display those values, etc. and then build an output that stores results, and then let it run for a few tens of thousands of iterations which will probably take a modern computer like... five seconds, and then dump the results into some charting software.

I am not totally sure I can do this in excel but I may take a stab at it.

Leperflesh fucked around with this message at 22:00 on Feb 8, 2024

Leperflesh
May 17, 2007

ok I used an AI to get started and then modified the code to fix all the bugs and misunderstandings. I don't actually know python, but I've edited enough of other people's random code to figure it out.

This works. I don't know how to get the output into a file, but it works to get the result of individual matches.
code:
# Online Python - IDE, Editor, Compiler, Interpreter
import random

def play_game(DA, DB, XA, XB, YA, YB, ZA, ZB):
    RA = 0
    RB = 0

    
    while DA > 5 and DB > 5:
        # Reset accumulated values at the start of each round
        RA = 0
        RB = 0
        
        # Player A rolls XA dice
        rolls_A = [random.randint(1, 6) for _ in range(XA)]
        print("Player A rolls:", rolls_A)
        
        # Player B rolls XB dice
        rolls_B = [random.randint(1, 6) for _ in range(XB)]
        print("Player B rolls:", rolls_B)
        
        # Process rolls
        for roll in rolls_A:
            if roll <= YA:
                DA -= 1
            elif roll >= ZA:
                RA += 1
        
        for roll in rolls_B:
            if roll <= YB:
                DB -= 1
            elif roll >= ZB:
                RB += 1
        
        # Subtract RA from RB
        diff = RA - RB
        if diff < 0:
            DB -= abs(diff)
        elif diff > 0:
            DA -= diff
        
        print("Current status: Player A D={}, Player B D={}".format(DA, DB))
    
    if DA <= 5:
        print("Player B wins!")
    elif DB <= 5:
        print("Player A wins!")

# starting conditions
DA = 20
DB = 20
XA = 5
XB = 5
YA = 2
YB = 2
ZA = 5
ZB = 5

play_game(DA, DB, XA, XB, YA, YB, ZA, ZB)
Paste that into https://www.online-python.com/ and click run to see the results, and change the values under #starting conditions to alter dice values to see how that affects the results.

Here's an example output with the above values:
code:
Player A rolls: [3, 2, 1, 3, 4]
Player B rolls: [1, 3, 6, 1, 2]
Current status: Player A D=18, Player B D=16
Player A rolls: [2, 5, 2, 2, 4]
Player B rolls: [6, 3, 5, 1, 5]
Current status: Player A D=15, Player B D=13
Player A rolls: [1, 5, 6, 1, 6]
Player B rolls: [1, 1, 2, 6, 6]
Current status: Player A D=12, Player B D=10
Player A rolls: [2, 2, 5, 1, 6]
Player B rolls: [4, 2, 4, 4, 1]
Current status: Player A D=7, Player B D=8
Player A rolls: [2, 6, 3, 5, 4]
Player B rolls: [4, 2, 5, 6, 4]
Current status: Player A D=6, Player B D=7
Player A rolls: [5, 5, 6, 5, 4]
Player B rolls: [3, 4, 6, 1, 3]
Current status: Player A D=3, Player B D=6
Player B wins!
this is of course a coinflip, when player A and B have the same starting values and dice values. There's no need to monte carlo it. If you want to see what the results of individual roll-off rounds are, add a print line. If you want to see how tweaking individual values changes the result, that'd be where doing the simulations can get you a curve.

My intuition is that you can get very similar curves with much less complexity but the complexity gives you many different places to tweak numbers and that's where I guess the "game" lies.

Leperflesh fucked around with this message at 22:22 on Feb 8, 2024

Leperflesh
May 17, 2007

OK so it occurs to me that I can just wrap the middle part of the script in another While statement, with another variable of "matches" - tell it to run a thousand times, output only the match results (which numbers do you care about? Just win/loss, or by how much, or how many rounds it took to get to a result, etc?) and then print that out at the end. Dump those numbers into a spreadsheet to get a chart if you want a chart.

Leperflesh
May 17, 2007

Yup ok. Change the value of M to decide how many matches to run. I commented out the verbose messages but you can remove the # to keep them. You need to edit the value of DA and DB in two places now, both at the bottom and on lines 10/11, because I don't know how to write python lol.

code:
# Online Python - IDE, Editor, Compiler, Interpreter
import random

def play_game(DA, DB, XA, XB, YA, YB, ZA, ZB, M):
    RA = 0
    RB = 0
    
    while M > 0:
        M -= 1
        DA = 20
        DB = 20
        while DA > 5 and DB > 5:
            # Reset accumulated values at the start of each round
            RA = 0
            RB = 0
            
            # Player A rolls XA dice
            rolls_A = [random.randint(1, 6) for _ in range(XA)]
            # print("Player A rolls:", rolls_A)
            
            # Player B rolls XB dice
            rolls_B = [random.randint(1, 6) for _ in range(XB)]
            # print("Player B rolls:", rolls_B)
            
            # Process rolls
            for roll in rolls_A:
                if roll <= YA:
                    DA -= 1
                elif roll >= ZA:
                    RA += 1
            
            for roll in rolls_B:
                if roll <= YB:
                    DB -= 1
                elif roll >= ZB:
                    RB += 1
            
            # Subtract RA from RB
            diff = RA - RB
            if diff < 0:
                DB -= abs(diff)
            elif diff > 0:
                DA -= diff
            
            # print("Current status: Player A D={}, Player B D={}".format(DA, DB))
        
        # print("Current status: Player A D={}, Player B D={}".format(DA, DB))
        if DA <= 5:
            print("Player B wins!")
        elif DB <= 5:
            print("Player A wins!")

# starting conditions

DA = 20
DB = 20
XA = 5
XB = 5
YA = 2
YB = 2
ZA = 5
ZB = 5
M = 3

play_game(DA, DB, XA, XB, YA, YB, ZA, ZB, M)
Now you can just run at many iterations at a time as you want. If you want a counter that accumulates wins, that's probably really easy to add, and you can remove the "player A wins" message and just give an end result of # of wins for each player or w/e. Python at this level is pretty easy to understand.

Leperflesh
May 17, 2007

Well that's thematically very cool. I didn't realize you also want to keep track of "hits" so I didn't create a variable for that, but it'd be pretty easy to add in. I think it also makes the system much more interesting, as it gives you choices about hitting harder vs. lasting longer, etc.

On its face, dice pools are commonly used in several different RPGs, and are a useful baseline mechanic to build off of. You can add in things like: one-offs that recover dice or let you roll an extra, having just one or two "special" dice in your pool that you choose when to roll and have higher value faces, but if you lose anyway that die is lost rather than going back into your pool, three and four way matches, etc.

I kind of enjoyed figuring this out because I've been thinking of learning some python for a while anyway. At first glance your eyes might glaze over but "roll some dice" is like absolutely a babby's first program in most any language, so it's a great starting point.

Adbot
ADBOT LOVES YOU

Leperflesh
May 17, 2007

Yeah a game that gives players various resources to spend can make one or more of those resources (mechanically) dice, which really just means the resource has some probability curve to its utility. There's nothing wrong with that foundationally, but it can easily be a problem if you don't think about (and math out and understand) what those probability curves actually are and mean, or pay attention to other critical game elements like pacing. I always say that what makes a game a game is that player(s) have interesting choices to make: you have to make sure that your dice pool mechanic is giving the players something interesting to do, rather than just killing time with pointless randomness or forcing players to make random choices because they cannot straightforwardly analyze their probabilities (this is making uninteresting choices).

For example, the 2d20 system from Modiphius gives players the ability to roll 2d20, plus additional d20s (up to a maximum of 5) if they draw from a shared resource pool to get extra dice. They don't add the d20's results together, but rather compare the result on each die to target numbers to determine successes. So the "dice pool" in this case doesn't particularly complicate odds: it's very straightforward to understand what your chances are for each die to succeed (five percent per integer value on the die), and not especially hard to calculate (and fairly easy to "get" through the experience of some play) how your odds change when you add additional dice.

This system adds risk in that each die has a 1/20th chance of an unavoidable negative consequence, so there's an interesting tradeoff to be made: buy a higher chance of success, but you are also buying a higher chance of drawbacks along with it.

The various 2d20 games Modiphius has published have varying receptions in terms of game balance and quality, but I haven't really seen anyone criticize the underlying mechanic, it's very solid. I think the strengths come from limiting the maximum size of the dice pool and using just one die type, using success mechanics to avoid having to intuit a probability curve's changes from adding or removing lots of dice in an additive system, and only using one dice pool rather than several interacting ones. It doesn't feel especially necessary for the game designers to print success charts to clarify an obscure set of outcome results for those who aren't interested in writing Python programs to work it out.

There's other ways to go. IMO dice pools are a useful tool, but shouldn't be treated as a default tool or just thrown into any game because they seem cool. You want to have a diverse toolkit in your game design box, and reach for the right tool for each job you're trying to accomplish, and then not abuse that tool by trying to force it to extremes where it's going to break or produce undesirable effects.

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply