FGI - Re: UDR: Authoritative Feature List / Grammar

  • From: duluxoz <duluxoz@xxxxxxxxx>
  • To: fgi@xxxxxxxxxxxxx
  • Date: Thu, 3 Sep 2020 14:25:32 +1000

Authoritative Source:
It's up to us, really, as the Project Doco is subject to 
improvement/updates just like everything else. The UDR Grammar document 
was written for the first draft of the UDR, and I don't think I updated 
it when I updated the  Possible Die Codes document and set up the 
Project - in fact, I'm sure I didn't.

So, of the two, the Possible Die Codes document is more up-to-date, so 
that's the one *I'd* be using as Authoritative - and so the Grammar 
document, which was used as a guide for the first Parser/Lexer, should 
be updated so that it matches what's being done in the new Parser/Lexer.

So follow the Possible Die Codes and we'll update the Grammar - this 
should resolve a lot of the issues @Ben raised - plus there's some 
notes/thoughts below.

5d12!kt7s5+2d4!kt3s5:

I don't thinks this is legal. Target numbers (& therefore successes) should 
only apply to final rolls, not sub rolls, and thus should be the last set of 
die-code-elements, and so we should return this as an error (as we should do 
with all "illegal rolls"). It's a bit of a contrived example (although a good 
one, because it highlights the issue) because I can't think of *any* game 
system where you'd want a roll like that - but please chip in people and tell 
me I'm wrong.

A similar (legal) roll, without any ambiguity, would be:

({5d12!k}+{2d4!k})t3s5 = 5d12!k+2d4!kt3s5

Anything in the Die Boxes would/should apply to the entire roll - there's no 
other way to treat it without going insane - and yes, that means that at the 
moment we can't set up a Deadlands Classic Weapon Melee Roll (DLCWMR: eg 
3d10!k+2d6!t5s5) because there's no way to specify that a Keep Flag should only 
apply to one of the die-sets. - at the moment if you set up the Die Boxes to 
Explode, Keep=5, Success=5, and then dropped 3d10 & 2d6 (or put in /roll 
3d10+2d6) what you'd get would be:

(3d10!+2d6!)kt5s5

How do we fix this? I'm not sure, but a DLCWMR is the most complex roll I've 
ever come across, so maybe we don't need to, as DLCMWRs should be coded into 
the Character Sheet.

I think the best way to handle things (via dice code) is to "error" anything 
that is ambiguous.

Happy to have a more detailed (group) discussion around this and any other 
complex rolls people know about.

1st Issue:

Dice should have precedence over addition, multiplication, etc, so d5+5 = 
(d5)+5, and if we want d(5+5) then that's what we need to write. I thought I'd 
implied that in the Precedence section of the one of the docos, but I mustn't 
have had. a "d" should go right after "{}" and "()" in precedence order.

We don't need and (extra) syntax because we already have it ie "()".

The second example also sort of "goes away" because of the statement above: 
"Target numbers (& therefore successes) should only apply to final rolls... and 
thus should be the last set of die-code-elements". 5d12!kt7s5+2 (without the 
"|") should be interpreted as 5d12!kt7s(5+2) - if we want to add a modifier to 
the roll it need to go *before* the "k", etc (or use "()"):

5d12+2!kt7s5 or 5d12!+2kt7s5

I think a good "rule" is to enforce all die rolls and modifiers come before all 
keeps, crits, target numbers, etc - thoughts everyone?

2nd Issue:

If you bust the strength part of a DLCWMR then the whole roll is a bust (you're 
not strong enough to do any damage - you've got to do some damage with the 
strength part to get any damage from the weapon part - & you can't go bust on a 
non-strength-part damage roll).

Do we need an extra die code for this? All rolls is Deadlands which we "k1" 
also (have the potential to) bust - at least as I can recall (jump in guys and 
let me know if I'm wrong). Wouldn't we be better off simple coding that into 
the Ruleset?

However, if we do need a new code then let's use "b" by itself; we don't need 
"bN" because N is a quick calculation based off of MdX ie N=ceil(M/2+0.5).

Open Qs:

As I said, the Grammar was to help me to the initial Parser/Lexer. I'm OK if we 
don't update it, but I like we should (as it should form part of the final 
doco). And I have no problem with it being a hybrid- or two-stage grammar (if 
that's what's required).

  
On 02/09/2020 09:26, Ben Kolera wrote:

Heya,

What's the authoritative source of what we want to do with the UDR? I
ask because the Grammar [1] and the Possible die codes [2] disagree.
Are we intending to keep the grammar up to date (the Grammar already
doesn't line up to develop) and correct as we go (like actually make
it proper ebnf, lol) or will the code and tests become the doco and
examples of the die codes that we support?

Possible_Die-Codes.md suggests this an example:

{4d8+3d12,5d20+3,5d10+1}>20

But if you look at the grammar the only things that can be part of
expressions are number literals, so the above case is not something
that is allowed by the grammar.

Taking a step back from all the documentation though, as users of our
two current games we want to be able to do:

3d6!+5d10!k  (This lines up to a sabre damage roll with the strength
and weapon damage smooshed into one).

The current rewrite went down the route of treating DicePools as the
whole set of {NumDice,Sides,Exploding,Keep,Target,Raises} (it doesn't
do rerolls or crits yet) and it works out poorly when trying to add
these things together. I mean, what should the result of

5d12!kt7s5+2d4!kt3s5

be? Is it just adding the successes of both groups together? Is the
entire roll a success or a failure if one reaches its target and the
other fails? If you have a modifier in the modifier box in the UI,
does it apply to both groups or does it add extra successes to the
final result? It is really messy and suggests that this needs more
thought and precision.

I don't think that these have any clear answers in the context of our
game (and maybe not clear answers in general), so I'd prefer it if we
disallowed adding anything that has a target/raises from the grammar
but while still allowing the sabre roll that would be handy for
deadlands.

What I suggest is that the Target and Raises syntax can only apply at
the top level something like this (I've ignored functions and
Multiplication and Exponents here because I don't want to write out
the nested precedence, lol):

DieCode = DiceGroupExpr,[GlobalModifier],[Target],[Crit],[SortCode]
GlobalModifier=("+"|"-"), NumberLit
Target=("t"|"<"|">"),NumberExpr,[("s"|"r"),NumberExpr]
SortCode= "s", ("a" | "d")
DiceGroupExpr=DiceGroup,["+",DiceGroupExpr]
DiceGroup= DicePool | DicePools
DicePools = "{", { DicePool }, "}"
DicePool = [NumberExpr], "d", DieSides, [Exploding], [Keep], [Reroll]
<snip>

This seem to work in my head except for two issues:

1st Issue:
The global modifier is ambiguous! In spirit, it's supposed to handle
cases like these: "5d12!k+2t7s5" and "d100-60" but because we allow
arbitrary numeric expression in the diesides there's nothing in the
grammar that distinguishes "5d(5+5)" from "(5d5)+5". We need to
disambiguate this somehow. Some ideas:
   - Always forcing dice pools into a grouping even if single pooled
(kinda ugly) "{5d5}+5"
   - Putting some syntactic distinguisher before the global modifier
like "5d5|+5". Kinda looks weird with keep dice though "5d12!kt7s5|+2"
(is that clear that it'll add the +2 before doing the target number
calc? "5d12!k|+5t7s5" just looks weird so if we thought the ordering
is important we may need a better distinguisher than "|")

2nd Issue:
I want to add some syntax to the grammar that marks a pool with the
fact that it will bust if there are a majority of 1s in the pool.
However, this would have to go on the dicepools and with the proposed
grammar above that's still part of arithmetic so we need to figure out
what it means to do arithmetic on potentially busted pools is (5 +
bust = 5, or 5 + bust = 5?). I think that it's good to ground this in
deadlands. What happens if you bust a strength check on a weapon
damage roll? Do you still get the weapon damage or do you do a big fat
0 damage? Or do strength checks for hand to hand damage not bust? My
intuition is that a bust is an annihilator[3] (i.e X + bust = bust and
bust + X = bust, func(bust) = bust) that's akin to the expression
throwing an exception.

--- end issues ----

This is the problem with striving towards the kitchen sink! Trying to
figure out ways to make sure all of the features work precisely when
combined becomes harder. Being perfectionistic and wanting a kitchen
sink but being imprecise and doing funky things is a very sad state to
be in and I absolutely don't want the UDR ending up that way on my
watch. Precision is key with such a core piece of things, so we either
have something simple that covers our usecases in our games precisely
or we have to go through these thought exercises trying to hammer out
precisely what we mean and want in all these cases that we don't have
a concrete use case for.

---

Summarising, the proposed action points for this email are:
- Targets & Raises at top level only
- Need to distinguish the global modifier syntactically. Just going to
roll with a code terminating "|",("+","-"),NumberLit for now but we
can change that later if we want
- Crits go on the top level (they are basically a second target number)
- Busts go on the pool and (X <opr> bust = bust, bust <opr> X = bust
and func(bust) = bust).

Open Questions are:
- Are we planning to output a proper EBNF at the end of the UDR work
or is a test suite and the way that the parser is defined enough (the
nice thing about LPeg style parsers is that they read a lot like ebnf
anyway)? My vote would be that the parser & tests will be enough and
are better because they are machine checked. If we were generating a
parser from the ebnf this would be different, but we aren't so the
docs have the great risk of getting stale (the current ones are stale
and also contain a handful of errors).

I won't be doing any work on UDR today but when I get back to this
probably tomorrow or Friday I won't be blocked if folk haven't had the
time for a response yet so dw. We need to move in the direction of the
proposals anyway (unless we're cutting features, ofc!) so it feels
like the main things we'll need to discuss here are finer bikeshedding
type stuff anyway. I can just move as though those action points are
decided and I can adjust as we discuss the colour of the bikeshed. :)

Cheers,
Ben

[1] 
https://github.com/Dulux-Oz/FGI/blob/master/Support_Files/Die-Code_EBNF_Grammar_Definition.md
[2] 
https://github.com/Dulux-Oz/FGI/blob/master/Support_Files/Possible_Die-Codes.md
[3] https://en.wikipedia.org/wiki/Annihilator_(ring_theory)

-- 
Peregrine IT Signature

*Matthew J BLACK*
 Â Â M.Inf.Tech.(Data Comms)
 Â Â MBA
 Â Â B.Sc.
 Â Â MACS (Snr), CP, IP3P

When you want it done /right/ â€’ the first time!

Phone:  +61 4 0411 0089
Email:  matthew@xxxxxxxxxxxxxxx <mailto:matthew@xxxxxxxxxxxxxxx>
Web:    www.peregrineit.net <http://www.peregrineit.net>

View Matthew J BLACK's profile on LinkedIn 
<http://au.linkedin.com/in/mjblack>

This Email is intended only for the addressee.  Its use is limited to 
that intended by the author at the time and it is not to be distributed 
without the author’s consent.  You must not use or disclose the contents 
of this Email, or add the sender’s Email address to any database, list 
or mailing list unless you are expressly authorised to do so.  Unless 
otherwise stated, Peregrine I.T. Pty Ltd accepts no liability for the 
contents of this Email except where subsequently confirmed in 
writing.  The opinions expressed in this Email are those of the author 
and do not necessarily represent the views of Peregrine I.T. Pty 
Ltd.  This Email is confidential and may be subject to a claim of legal 
privilege.

If you have received this Email in error, please notify the author and 
delete this message immediately.




Other related posts: