diff orpg/dieroller/dieroller.txt @ 0:4385a7d0efd1 grumpy-goblin

Deleted and repushed it with the 'grumpy-goblin' branch. I forgot a y
author sirebral
date Tue, 14 Jul 2009 16:41:58 -0500
parents
children bf799efe7a8a
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/orpg/dieroller/dieroller.txt	Tue Jul 14 16:41:58 2009 -0500
@@ -0,0 +1,309 @@
+The New Dicing System:  A Proposal for OpenRPG
+----------------------------------------------
+
+The current dice system for OpenRPG has several limitations.  Foremost
+among these are the fact that adding a new, non-standard dicing mechanism
+requires editing of the basic dice code.  There are several secondary 
+limitations, such as the fact that while the dice system can handle math,
+it cannot be used as a calculator -- it will not allow expressions that do
+not involve dice.
+
+This proposal is for a new dicing system to replace the current one in
+OpenRPG.  Since the dicing system is something that users will interact
+with frequently, a new system needs to be considered carefully.  This
+document attempts to describe the new dicing system so that such 
+consideration can be given to it.  It is expected that this document will
+grow and change as it is scrutinized.
+
+
+Design goals for this dicing system:
+
+ 1. Should be easy for new users to get started with, based on knowing
+    standard RPG dice notation (NdX) and basic math.
+
+ 2. Should, as far as practical, maintain compatibility with existing
+    character sheets, etc., that use the current dice system.
+
+ 3. Should allow users to create new dice types and new ways of 
+    counting dice.  Ideally, this should not require programming, except
+    in exceptional cases.
+
+ 4. The dice system should be usable for doing basic math that does
+    not involve dice.
+
+ 5. The dice system should be able to handle most current RPG dicing
+    systems.
+
+Things this dicing system is designed to NOT do:
+
+ 1. Be a programming language.  There are no facilities in it for 
+    user input, output formatting, loops, if-then-else, or similar
+    things.  If these are desired for something involving dice, an
+    appropriate node and nodehandler can be created.
+
+ 2. Handle all theoretically possible dicing systems without the
+    need for programming plugins.  First off, this is impossible.  
+    Second, even making an attempt to would require supporting 
+    dicing methods that don't actually turn up in any real game.
+
+ 3. Handle floating-point math.  I don't know of any systems that
+    use it in their dice schemes right now.  If there are some,
+    we might have to consider adding it.
+
+
+Syntax Specification 
+
+What follows is a BNF specification for the proposed dicing system, with
+explanatory text interleaved.  At the end of this document is a copy of
+the BNF with no explanations, for those who would like to look at it "all
+together".  Note that BNF describes only syntax, and not semantics; thus,
+while anything generated with this grammar should be syntactically correct,
+that doesn't mean it will make sense or be allowed.
+
+
+dice string ::= <expression>
+                <expression> of <comparison> | <comparison>
+
+This is the top level.  The major thing of note here is that comparisons
+only occur at this level.  This is intentional; the result of a comparison
+is a boolean true/false flag rather than a number.  Thus, it makes no 
+sense to allow people to perform further numerical operations on the 
+result of a comparison.  Systems where dice are triggered by the results 
+of other dice are left for the realm of plugins.
+
+                
+comparison ::= <expression> <relation> <expression>
+
+expression ::= <factor> | <factor> <low-op> <factor>
+
+The separation into "low-op" and "high-op" of the operators is to allow
+order of operations to be handled more easily.  Syntactically, it's not
+really necessary, but it should be helpful in implementation.
+
+
+factor :: = <term> | <term> <high-op> <term> |
+            <multi-dice> | <multi-dice> <high-op> <term> |
+            <term> <high-op> <multi-dice>
+
+Here we start to hit some complication.  The intent of the different 
+entries for multi-dice is that we don't want to allow things like
+[3d6 each * 2d6 each].  We are *not* doing vector multiplication!
+The "expression" level doesn't have any such limitation on syntax; 
+things like [3d6 each + 2d6 each] we'll have to either think of a 
+logical way to handle, or disallow on a semantic level.  (Well... I 
+suppose it could be handled in the BNF, but I think it would get
+kind of messy.)
+
+
+term ::= <dice> | <unit>
+
+unit ::= <number> | ( <expression> )
+
+Dice are not considered a unit.  This means that things like [3d6d10] can't
+be done without using parentheses.  I consider that to be a win for 
+clarity.
+
+
+dice ::= <unit>d<unit> | <unit>d<name> | <dice> <flag> | lastroll
+
+The <name> entry here allows for user-created dice (in the syntax, at 
+least...).
+
+
+multi-dice ::= ( <dice>, <dice>+ ) |               # (1d6,1d8)
+               <dice> each |                       # 3d6 each
+               ( <expression> of <expression> ) |  # (3 of 2d6)
+               lastroll |                          # lastroll
+               <multi-dice> <flag>                 # (3 of 2d6) best 2
+
+"lastroll" by itself can be either dice or multi-dice.  I'm thinking that it
+ 
+should be whatever type the last roll was.
+
+
+flag ::= reroll <condition> |          # repeats
+         reroll <slice> |              # once only
+         grow <condition> |            # reroll and add
+         shrink <condition> |          # reroll and subtract
+         drop <condition> |
+         drop <slice> |
+         take <condition> |
+         take <slice> |
+         <slice> |                     # implied "take"
+         <name> <condition> |          # user-created
+         <name>                        # user-created
+
+Technically, we don't need both "drop" and "take" -- one implies the 
+other.  However, having both should make the language easier to use.
+
+"reroll" will work differently depending on whether a condition or a 
+slice is given.  If a condition is given, it will reroll until none of
+the dice in the set meet the reroll condition (or until it hits a maximum
+allowed number of rerolls).  If a slice is given, it will reroll those
+dice once.  IMHO, this behavior makes the most sense.
+
+The <name> entries here are to allow for user-created flags.  Note that
+as I've specified things right now, a user-created flag can have a
+ condition,
+but not a slice.  That's mostly because I couldn't think of a case where
+a slice would be useful... should we add it anyways?
+
+
+slice ::= highest | lowest | highest <number> | lowest <number>
+
+"highest" and "lowest" without a number are equivalent to doing them with
+1 as the number.  This is to simplify things like [4d6 drop lowest].
+
+
+condition ::= <relation> <unit>
+
+This is for conditions on flags.  Note that it can take a unit, so you could
+
+use dice in a condition; however, I think the unit should only be evaluated 
+
+once, to make things faster.  Anyone for repetitive evaluation?
+
+
+low-op ::= + | - | min | max
+
+"min" takes two values and returns the highest of them, and "max"
+returns the lowest of them.  This might seem counterintuitive, but
+it's meant to be used with dice, like so:
+
+  3d6 min 8   - always returns 8 or higher
+
+  3d6 max 15  - always returns 15 or lower
+
+I decided to put min and max as having the same precedence as + and -,
+because if they had higher precedence, then:
+
+  3d6+2 min 10 
+
+would be equivalent to 3d6+10.  (It would take the max of 2 and 10, then
+add that to 3d6).  One problem that does arise here is with multiplication 
+and division:  [1d6 min 5 * 2] will be equivalent to [1d6 min 10], since
+multiplication has higher precedence.  We may just want to warn people 
+that min and max can be screwy unless you parenthesize, unless someone can
+think of a better way to handle them.
+
+
+high-op ::= * | / | mod
+
+The / is integer division, of course, since we're doing integer math.  
+
+
+number ::= <digit>+ | -<digit>+
+
+Positive and negative numbers are allowed.  This means that, syntactically,
+[-2d-4] is legal.  Do we want to modify the BNF to disallow this, or handle
+it on a semantic level?
+
+
+name ::= <letter>[<letter>|<digit>]*
+
+We may want to expand to allow underscores and dashes in user-created names.
+
+
+
+letter ::= A-Z | a-z
+
+digit ::= 0-9
+
+relation ::= < | > | <= | >= | => | =< | = | ==
+
+
+
+Well, that's the BNF.  Again, at the end is a copy without all the running
+commentary.
+
+
+Thoughts on Implementation:
+
+First, I think a sort of "dice library" of common functions needs to be
+created.  This would include rolling a set of dice, getting the highest
+of a group of dice, growing and shrinking dice from a set based on 
+conditions, and so on.  These functions should be available for use by
+custom-written dice types.
+
+Next, that library should be used as a tool in implementing a dice-string
+interpreter.  That will require creating a parser for the dice-string 
+'language'.  This could be either a custom-written parser, or possibly
+one created with some of the Python parser generators.  A custom-written
+parser may take longer to do and be a bit more finicky to maintain, but
+it would remove a dependency from the code.
+
+User-created flags and dice types could be supported in two ways:
+
+ - First, by allowing users to specify strings in the dice language
+   that the flags/expressions would expand to -- basically, allowing
+   dice macros.
+
+ - Second, by adding hooks for python modules to be associated with
+   user-created dice or flag types.  This is likely to be the more
+   complicated of the two solutions, but it would also be more 
+   flexible.
+
+Personally, I think both are desirable -- the first, so that 
+non-programming users can create simple die and flag types.  The
+second, because by design, there are some things this dice system 
+just won't do.
+
+
+Further work needed:
+
+ - specs for the "dice library"
+
+ - specs on an interface for python modules meant to be dice and
+   flag types.
+
+----------------------------------------------------------------
+
+start ::= <expression> |
+          <comparison>
+
+comparison ::= <expression> <condition>
+
+expression ::= <term> | <term> <low-op> <factor>
+
+term ::= <factor> | <factor> <high-op> <unit>
+
+factor ::= <atom> | <dice_set>
+
+atom ::= <number> | ( <expression> )
+
+dice_set ::= <dice> <dice_set>, <dice> | <expr> of <dice> | <dice> each |
+             lastroll
+
+dice ::= <atom>d<atom> | <atom>d<name> | <dice> <flag>
+
+flag ::= reroll <condition> |
+         reroll <slice> |
+         grow <condition> |  
+         shrink <condition> |        
+         drop <condition> |
+         drop <slice> |
+         take <condition> |
+         take <slice> |
+         <slice> |         
+         <name> <condition> |
+	 <name> <slice> |
+         <name>
+
+slice ::= highest | lowest | highest <number> | lowest <number>
+
+condition ::= <relation> <unit>
+
+low-op ::= + | -
+
+high-op ::= * | / | mod| max | min
+
+number ::= <digit>+ | -<digit>+
+
+name ::= <letter>[<letter>|<digit>]*
+
+letter ::= A-Z | a-z
+
+digit ::= 0-9
+
+relation ::= < | > | <= | >= | => | =< | = | ==
+