request: Example of a dice roller
-
I'm working on learning to do some MUX softcoding(eventually hoping to do a small savage worlds sandbox), and am having difficulties finding working examples to deconstruct. The ones that I do find seem to be built into really complicated systems and aren't exactly easy for a n00b to follow.
Does anyone have anything basic laying around? Some features I'm looking for to see how they work:
A command to roll different types of dice, 1d4, 1d6 3d8 etc.
A command to roll those as explody dice. If a 1d4 gets a 4, then add 1d4.
Modifiers to the dice. 1d4-2
Rolling against a stat on a characterI've tried farting around with the dice(x, x) command built in, but I get a lot of huh? messages coming back to me, so I think I'm missing something fundamental here.
any tips?
-
Looks like on MUX it's die(#,#).
One you could look at (though it uses regexp, and is thus more complex than a basic one) is here: http://www.mushcode.com/File/Noltars-Dice-Roller
-
@SG said:
Does anyone have anything basic laying around? Some features I'm looking for to see how they work:
Sort of.
A command to roll different types of dice, 1d4, 1d6 3d8 etc.
As you note below, the die(n,sides) function is what you want.
I've tried farting around with the dice(x, x) command built in, but I get a lot of huh? messages coming back to me, so I think I'm missing something fundamental here.
It's a function, not a command; functions are evaluated within leading buffer context (which you don't need to worry about yet, it won't be on the test). Put it in a command.
For testing, to yourself:
think dice(3,6)
For outputting to a room, perhaps:
@remit %L=<dice> %N rolled 3d6 for [dice(3,6)].
And putting that into a command on an object:
@create dice code object (dco) &cmd_dice dco=$+dice *d*:@remit %L=<dice> %N rolled %1d%2 for [dice(%1,%2)].
A command to roll those as explody dice. If a 1d4 gets a 4, then add 1d4.
Mush doesn't have while-loop style iteration unless you restructure things into a
@trigger
loop. You don't want to do that, generally. Instead, most nwod dice and other explodey types use recursion-- that is, a function that calls itself, but only for exploding values.Modifiers to the dice. 1d4-2
For arbitrary syntax, this becomes a problem of lexing and parsing the tokens, which is something that mush is fairly bad at. It can be done, but is more complicated than I can type up right now.
For simple syntax matching what you have there, something like:
&cmd_dice dco=$^\+dice ([0-9]+)d([0-9]+)\+?(-?[0-9]+)?$:@remit %L=<+dice> %N rolled %1d%2[if(strlen(%3),if(gte(%3, 1),+,-)%3,)] for [add(dice(%1,%2),%3)]. @set dco/cmd_dice=regexp
Rolling against a stat on a character
You can read attributes with get(dbref/attr) or the like, but stats should usually be hidden and/or read-only. You may need to set up api functions for accessing them in a global function of some sort.
Parsing dice with stats, especially for multiplayer rolls, e.g.
+roll strength+brawl+item(katar) resisted by PLAYERNAME:defense
And then showing the results but not the number of dice rolled, etc, is... tricky.
Note: just typed this up. Code above not tested, may have stupid typos.
edit: fixing codeblock boundaries in post
-
-
@Chime Awesome, after working off of your examples and adjusting a bit, it looks like I have a working rudimentary dice roller hifive:
CMD_DICE: $+dice *d*:@remit %L=<Dice> %N rolled %0d%1 for [die(%0, %1)] CMD_ADICE [R]: $^\+adice ([0-9]+)d([0-9]+)\+?(-?[0-9]+)?$:@remit %L=<Dice> %N rolled %1d%2[if(strlen(%3),if(gte(%3, 2),+,-)%3,)] for [add(die(%1, %2),%3)].
While it seems to be working, the adice is doing something strange, it's adding an extra '-' to the output and I can't tell why:
Dice:
<Dice> Famine rolled 3d10 for 14 <Dice> Famine rolled 3d10 for 15 <Dice> Famine rolled 3d12 for 28
Adice:
<Dice> Famine rolled 2d6+4 for 11. <Dice> Famine rolled 2d6--4 for 4.
I'm also a bit puzzled why I basically had to +1 the %s in the adice.
ETA:
got it checking an attribute off of my bit. Look at me go!
&tdice dco=$+check *:@remit %L=<Dice> %N checked %0 for die(1, [get(%N/%0)]).
-
@SG
Try it with:$^\+adice ([0-9]+)d([0-9]+)\+?(-?[0-9]+)?$:@remit %L=<Dice> %N rolled %1d%2[if(strlen(%3),if(gte(%3, 2),+,)%3,)] for [add(die(%1, %2),%3)].
Looks like that might get rid of your trailing -.
-
What @Bobotron said. Is what I get for not testing.
Note that some communities like to see the values of each die rolled. Mathematically this is usually pointless, but it does make it feel more like a traditional tabletop would. Sometimes these little things mean a lot to people.
Also, fair warning that the human mind doesn't handle random bad luck very well. We have an astonishing amount of mental capacity geared for noticing patterns-- and that tends to trigger even where it probably shouldn't. Fudging the dice roller to optimize for perceptual randomness is a whole different thing and a somewhat open area of research. Likely it would involve re-weighting probabilities based on perceived frequency in some span of former rolls. (Don't worry about this for now; no games are this clever yet.)
Another weird thing that can be useful for GMs that warrants tracking each die is best-of/worst-of operators. Consider:
+roll best 3 of 4d6
These work great for gently leaning results in one direction or another.
-
One thing I'd suggest for the 'check vs. stat' notation, is to set it to see if the character does or does not have the stat. Your baseline works; you'd just need to add an if() around the code, or @switch. I code primarily with side-effect functions, so my code probably won't work first immediate try.
&tdice dco=$+check *:@select 1=[hasattrval(%#,%0)],{@remit %L=<Dice> %N checked %0 for die(1, [get(%N/%0)])},{@pemit %#=<Dice> You do not have that stat.}
Also, just for giggles, here's an example of your adice with the dice laid out. It SHOULD work directly.
$^\+adice ([0-9]+)d([0-9]+)\+?(-?[0-9]+)?$:@remit %L=<Dice> %N rolled %1d%2[if(strlen(%3),if(gte(%3, 2),+,)%3,)] for [setq(1,[iter([repeat(1,%1)],[die(1,%2)])])][lmath(add,%q1 %3)] (%q1).
-
And for folks who want to look at the sorts of results they should expect from their dice: Anydice
-
@Bobotron Yeah, I'll try to get the if thing working tonight, I wasn't able to figure it out last night while I was at home. When I ran it, it did... something? Didn't show any output, not even a huh? response. When stuff like that happens, I can't help but think some little centrifuge inside my laptop is spinning out of control.
I was playing around with the second one a little bit, and it'll take some work for me to understand what's going on.
-
@SG Which thing didn't even return a huh? The first command or the second command?
-
@Bobotron the tdice one that checks to see if the stat is an attribute.
I got sucked into the witcher tonight so didn't get around to playing as much as I wanted to
-
@SG
I threw it up on my tester, and found one error. You used %N; whenever you want to get something, use %#. %N uses an @name, %# uses the dbref (database reference number), which is an absolute reference to the enactor of a command, and is the most reliable way to grab stuff.I did a small tweak...
&tdice object=$+check *:@select 1=[hasattrval(%#,%0)],{@remit %L=<Dice> [name(%#)] checked %0 for [die(1,[xget(%#,%0)])]},{@pemit %#=<Dice> You do not have that stat.}
That version worked on my testbed.
EDIT: You could also just switch @select for @switch as well, it works the same overall on my Penn testbed.
-
@Bobotron oh awesome, that did the trick
I wouldn't have expected it to, since when I looked for the help on @select, it didn't seem to exist on MUX.
-
@SG said:
I wouldn't have expected it to, since when I looked for the help on @select, it didn't seem to exist on MUX.
Look in your compat.conf file, included by the default netmux.conf:
alias @select @switch/first
Which explains what's going on here; it's a legacy command equivalent to using
@switch
with the/first
switch. Seehelp @switch
. But I'd expect that compat alias isn't going away ever, so whichever you like. -
So, I'm trying to add a Target number function, and I just can't make the last if statement work.
&cmd_TNroll dco=$^\+tndice ([0-9]+)d([0-9]+)\+?(-?[0-9]+)?\/?([0-9]+)?$:@remit %L=<Dice> %N rolled %1d%2[if(strlen(%3),if(gte(%3, 2),+,)%3,)] for [add(die(%1, %2),%3)] TN:%4 [if((gte(%q0, %4)),Success!,Failure!)]
shouldn't %q0 be the die roll result?
-
Only if you set the '0' register somewhere in there. You don't. You probably meant (untested):
&cmd_TNroll dco=$^\+tndice ([0-9]+)d([0-9]+)\+?(-?[0-9]+)?\/?([0-9]+)?$:@remit %L=<Dice> %N rolled %1d%2[if(strlen(%3),if(gte(%3, 2),+,)%3,)] for [setr( 0, add(die(%1, %2),%3))] TN:%4 [if((gte(%q0, %4)),Success!,Failure!)]
-
@Thenomain Awesome, thanks! it turned out the if statement had one too many (s, but not setting the register was also big. Got it working with:
CMD_RROLL [R]: $^\+rdice ([0-9]+)d([0-9]+)\+?(-?[0-9]+)?\/?([0-9]+)?$:@remit %L=<Dice> %N rolled %1d%2[if(strlen(%3),if(gte(%3, 2),+,)%3,)] for [setr(0, [add(die(%1, %2),%3)])] TN:%4 [setr(1, [ifelse(gte(%q0,%4),Success!,Failure!)])] [idiv(sub(%q0,%4),4)] Raises
Originally I was picturing it putting a nice bright green + for each raise, but I'm too n00b for that bullshit.
Now, to make it work checking against a stat instead of numbers input. Actually, figuring out an explosion might be more important.