roll-parser 3.0.0 → 3.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +61 -1
- package/MIGRATION.md +293 -4
- package/README.md +246 -55
- package/dist/cli/format.d.ts.map +1 -1
- package/dist/cli/format.js +8 -7
- package/dist/cli/format.js.map +1 -1
- package/dist/evaluator/die.d.ts +2 -1
- package/dist/evaluator/die.d.ts.map +1 -1
- package/dist/evaluator/die.js.map +1 -1
- package/dist/evaluator/env.d.ts +57 -0
- package/dist/evaluator/env.d.ts.map +1 -1
- package/dist/evaluator/env.js.map +1 -1
- package/dist/evaluator/evaluator.d.ts.map +1 -1
- package/dist/evaluator/evaluator.js +104 -56
- package/dist/evaluator/evaluator.js.map +1 -1
- package/dist/evaluator/modifiers/crit-threshold.d.ts +43 -5
- package/dist/evaluator/modifiers/crit-threshold.d.ts.map +1 -1
- package/dist/evaluator/modifiers/crit-threshold.js +24 -11
- package/dist/evaluator/modifiers/crit-threshold.js.map +1 -1
- package/dist/evaluator/modifiers/die-bound.d.ts +5 -2
- package/dist/evaluator/modifiers/die-bound.d.ts.map +1 -1
- package/dist/evaluator/modifiers/die-bound.js +6 -3
- package/dist/evaluator/modifiers/die-bound.js.map +1 -1
- package/dist/evaluator/modifiers/explode.d.ts.map +1 -1
- package/dist/evaluator/modifiers/explode.js +13 -5
- package/dist/evaluator/modifiers/explode.js.map +1 -1
- package/dist/evaluator/modifiers/flags.d.ts +17 -0
- package/dist/evaluator/modifiers/flags.d.ts.map +1 -1
- package/dist/evaluator/modifiers/flags.js +4 -4
- package/dist/evaluator/modifiers/flags.js.map +1 -1
- package/dist/evaluator/modifiers/keep-drop.d.ts +5 -5
- package/dist/evaluator/modifiers/keep-drop.d.ts.map +1 -1
- package/dist/evaluator/modifiers/keep-drop.js +7 -7
- package/dist/evaluator/modifiers/keep-drop.js.map +1 -1
- package/dist/evaluator/modifiers/reroll.d.ts.map +1 -1
- package/dist/evaluator/modifiers/reroll.js +16 -10
- package/dist/evaluator/modifiers/reroll.js.map +1 -1
- package/dist/evaluator/modifiers/sort.d.ts +1 -1
- package/dist/evaluator/modifiers/sort.d.ts.map +1 -1
- package/dist/evaluator/modifiers/sort.js +3 -3
- package/dist/evaluator/modifiers/sort.js.map +1 -1
- package/dist/evaluator/modifiers/success-count.d.ts +6 -2
- package/dist/evaluator/modifiers/success-count.d.ts.map +1 -1
- package/dist/evaluator/modifiers/success-count.js +9 -5
- package/dist/evaluator/modifiers/success-count.js.map +1 -1
- package/dist/notation.d.ts +13 -0
- package/dist/notation.d.ts.map +1 -0
- package/dist/notation.js +8 -0
- package/dist/notation.js.map +1 -0
- package/dist/parser/ast.d.ts +12 -7
- package/dist/parser/ast.d.ts.map +1 -1
- package/dist/parser/ast.js.map +1 -1
- package/dist/parser/guards.d.ts +38 -0
- package/dist/parser/guards.d.ts.map +1 -1
- package/dist/parser/guards.js +51 -0
- package/dist/parser/guards.js.map +1 -1
- package/dist/parser/parser.d.ts.map +1 -1
- package/dist/parser/parser.js +26 -2
- package/dist/parser/parser.js.map +1 -1
- package/dist/render.d.ts +95 -0
- package/dist/render.d.ts.map +1 -0
- package/dist/render.js +232 -0
- package/dist/render.js.map +1 -0
- package/dist/types.d.ts +64 -12
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +14 -4
- package/src/cli/format.ts +15 -23
- package/src/evaluator/die.ts +2 -1
- package/src/evaluator/env.ts +58 -0
- package/src/evaluator/evaluator.ts +192 -70
- package/src/evaluator/modifiers/crit-threshold.ts +81 -15
- package/src/evaluator/modifiers/die-bound.ts +13 -4
- package/src/evaluator/modifiers/explode.ts +21 -6
- package/src/evaluator/modifiers/flags.ts +21 -4
- package/src/evaluator/modifiers/keep-drop.ts +10 -8
- package/src/evaluator/modifiers/reroll.ts +20 -11
- package/src/evaluator/modifiers/sort.ts +9 -3
- package/src/evaluator/modifiers/success-count.ts +27 -5
- package/src/notation.ts +24 -0
- package/src/parser/ast.ts +12 -7
- package/src/parser/guards.ts +92 -1
- package/src/parser/parser.ts +56 -1
- package/src/render.ts +394 -0
- package/src/types.ts +64 -12
- package/src/version.ts +1 -1
package/src/types.ts
CHANGED
|
@@ -42,9 +42,12 @@ export type ResolvedComparePoint = {
|
|
|
42
42
|
};
|
|
43
43
|
|
|
44
44
|
/**
|
|
45
|
-
* A resolved crit threshold — `'default'` means the per-die default rule
|
|
46
|
-
*
|
|
47
|
-
*
|
|
45
|
+
* A resolved crit threshold — `'default'` means the per-die default rule,
|
|
46
|
+
* which is what bare `cs` / `cf` produce. It reads the natural face
|
|
47
|
+
* (`initialResult ?? result`): critical when it equals `sides`, fumble when
|
|
48
|
+
* it equals 1, both only for `sides > 1`. An explicit ComparePoint instead
|
|
49
|
+
* reads the die's current `result`, so a preceding modifier that rewrote it
|
|
50
|
+
* is visible to the comparison.
|
|
48
51
|
*
|
|
49
52
|
* @category Results
|
|
50
53
|
*/
|
|
@@ -70,10 +73,14 @@ export type ResolvedCritThreshold = ResolvedComparePoint | 'default';
|
|
|
70
73
|
*
|
|
71
74
|
* `'meta'` is the one tag with no counterpart in the notation. Dice counts,
|
|
72
75
|
* sides, modifier counts and computed thresholds may themselves be dice
|
|
73
|
-
* (`(1d4)d6`, `4d6kh(1d2)`, `1d6!>(1d2+3)`). Those inner dice
|
|
74
|
-
*
|
|
75
|
-
* `RollResult.rolls` tagged `'meta'` so an audit log can still
|
|
76
|
-
* meta-expression rolled.
|
|
76
|
+
* (`(1d4)d6`, `4d6kh(1d2)`, `1d6!>(1d2+3)`). Those inner dice belong to no
|
|
77
|
+
* pool: they never appear on a `dice` or `fateDice` part, and they are
|
|
78
|
+
* appended to `RollResult.rolls` tagged `'meta'` so an audit log can still
|
|
79
|
+
* show what the meta-expression rolled.
|
|
80
|
+
*
|
|
81
|
+
* The four whole-pool views — `sort`, `explode`, `reroll`, and `successCount`
|
|
82
|
+
* `rolls` — are snapshots of an evaluation context rather than of a pool, so
|
|
83
|
+
* they do carry meta dice. Filter them out when summing or displaying a pool.
|
|
77
84
|
*
|
|
78
85
|
* `'dc'` marks the DC side of a `vs` comparison. Unlike `'meta'` these dice do
|
|
79
86
|
* render — `1d20[3] vs 2d10[5, 6]` shows both sides — but they are not part of
|
|
@@ -158,17 +165,28 @@ export type DieResult = {
|
|
|
158
165
|
/** The rolled value */
|
|
159
166
|
result: number;
|
|
160
167
|
/**
|
|
161
|
-
* Raw first roll before any mutation
|
|
162
|
-
* Only populated when `result` has
|
|
168
|
+
* Raw first roll before any mutation — compound-explode accumulation, the
|
|
169
|
+
* `!p` decrement, or a `minN`/`maxN` clamp. Only populated when `result` has
|
|
170
|
+
* been overwritten with a computed value.
|
|
163
171
|
* Consumers that need the original face (nat-20 / nat-1 detection) should
|
|
164
172
|
* read `initialResult ?? result`.
|
|
165
173
|
*/
|
|
166
174
|
initialResult?: number;
|
|
167
175
|
/** Modifiers applied to this die */
|
|
168
176
|
modifiers: DieModifier[];
|
|
169
|
-
/**
|
|
177
|
+
/**
|
|
178
|
+
* True if the die met its critical criteria — by default, rolling the
|
|
179
|
+
* maximum face on a die with more than one side. That default never fires
|
|
180
|
+
* on `d1` or on Fate dice (`sides = 0` has no maximum face), but an
|
|
181
|
+
* explicit `cs` threshold does: `4dFcs>0` flags every `+1`.
|
|
182
|
+
*/
|
|
170
183
|
critical: boolean;
|
|
171
|
-
/**
|
|
184
|
+
/**
|
|
185
|
+
* True if the die met its fumble criteria — by default, rolling a 1 on a
|
|
186
|
+
* die with more than one side. As with {@link DieResult.critical}, the
|
|
187
|
+
* default never fires on `d1` or Fate dice, while an explicit `cf`
|
|
188
|
+
* threshold does: `4dFcf=-1` flags every `-1`.
|
|
189
|
+
*/
|
|
172
190
|
fumble: boolean;
|
|
173
191
|
};
|
|
174
192
|
|
|
@@ -217,7 +235,10 @@ export type RollPartBase = {
|
|
|
217
235
|
* - `literal.total === value` and `variable.total === value`.
|
|
218
236
|
* - Each part's `rolls[]` shares `DieResult` references with
|
|
219
237
|
* `RollResult.rolls[]`; both reflect post-evaluation state (explode
|
|
220
|
-
* accumulation, reroll flags, keep/drop flags). No deep
|
|
238
|
+
* accumulation, reroll flags, keep/drop flags, success/failure tags). No deep
|
|
239
|
+
* clone. A part's own numbers record what that part computed, so an inner
|
|
240
|
+
* `successCount` re-scored by an outer one (`{4d6>=5}<=2f5`) keeps its
|
|
241
|
+
* tally while the dice it shares show the outer count's tags.
|
|
221
242
|
*
|
|
222
243
|
* Meta-expression sub-trees (`4d6kh(1d2)`, `(1+1)d6` counts/sides, computed
|
|
223
244
|
* thresholds) are not surfaced as nested parts — their resolved numbers
|
|
@@ -299,12 +320,30 @@ export type RollPart =
|
|
|
299
320
|
type: 'explode';
|
|
300
321
|
variant: 'standard' | 'compound' | 'penetrating';
|
|
301
322
|
threshold?: ResolvedComparePoint;
|
|
323
|
+
/**
|
|
324
|
+
* The expanded pool. Standard and penetrating explosions append dice
|
|
325
|
+
* that exist nowhere under `target`, so this is the only view of the
|
|
326
|
+
* pool the modifier actually produced. Compound explosions accumulate
|
|
327
|
+
* in place, making it the same dice as `target` carries.
|
|
328
|
+
*
|
|
329
|
+
* Like `RollResult.rolls` — and unlike the pool under `target` — this
|
|
330
|
+
* keeps `'meta'` dice. Filter them out before counting or displaying.
|
|
331
|
+
*/
|
|
332
|
+
rolls: DieResult[];
|
|
302
333
|
target: RollPart;
|
|
303
334
|
})
|
|
304
335
|
| (RollPartBase & {
|
|
305
336
|
type: 'reroll';
|
|
306
337
|
once: boolean;
|
|
307
338
|
condition: ResolvedComparePoint;
|
|
339
|
+
/**
|
|
340
|
+
* The post-reroll pool: discarded intermediates (`'rerolled'` +
|
|
341
|
+
* `'dropped'`) alongside their replacements. Both are appended rather
|
|
342
|
+
* than substituted, so neither appears under `target`.
|
|
343
|
+
*
|
|
344
|
+
* Keeps `'meta'` dice, as `RollResult.rolls` does.
|
|
345
|
+
*/
|
|
346
|
+
rolls: DieResult[];
|
|
308
347
|
target: RollPart;
|
|
309
348
|
})
|
|
310
349
|
| (RollPartBase & { type: 'dieBound'; bound: 'min' | 'max'; value: number; target: RollPart })
|
|
@@ -312,6 +351,11 @@ export type RollPart =
|
|
|
312
351
|
type: 'successCount';
|
|
313
352
|
threshold: ResolvedComparePoint;
|
|
314
353
|
failThreshold?: ResolvedComparePoint;
|
|
354
|
+
/**
|
|
355
|
+
* The tallied pool, sharing `DieResult` references with `target`.
|
|
356
|
+
* Keeps `'meta'` dice, as `RollResult.rolls` does.
|
|
357
|
+
*/
|
|
358
|
+
rolls: DieResult[];
|
|
315
359
|
target: RollPart;
|
|
316
360
|
successes: number;
|
|
317
361
|
failures: number;
|
|
@@ -409,6 +453,14 @@ export type RollResult = Readonly<{
|
|
|
409
453
|
* arithmetic on top of a success count (e.g. `{5d6>=5}+2`) affects `total`
|
|
410
454
|
* but not `successes`. Success counts are terminal, so the group braces are
|
|
411
455
|
* required: `5d6>=5 * 2` is an `INVALID_SUCCESS_COUNT_TARGET` parse error.
|
|
456
|
+
*
|
|
457
|
+
* Braces also let a second count re-count the same pool (`{4d6>=5}<=2f5`).
|
|
458
|
+
* The outermost count owns the outcome: it re-scores the pool against its own
|
|
459
|
+
* thresholds, so no die is ever both a success and a failure, and dice it
|
|
460
|
+
* does not count come out untagged rather than keeping the inner count's
|
|
461
|
+
* tags. The DC side of a `vs` is never tallied here; it keeps whatever tags
|
|
462
|
+
* an inner count gave it, unless the outer count scores subtotals rather
|
|
463
|
+
* than dice, which leaves every die untagged.
|
|
412
464
|
*/
|
|
413
465
|
successes?: number;
|
|
414
466
|
/**
|
package/src/version.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
// Generated by `bun run generate:version` from package.json — do not edit.
|
|
2
|
-
export const version = '3.
|
|
2
|
+
export const version = '3.2.0';
|