@yipe/dice 0.2.1 → 0.2.2
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/README.md +20 -30
- package/dist/builder/index.cjs +588 -552
- package/dist/builder/index.cjs.map +1 -1
- package/dist/builder/index.d.cts +15 -3
- package/dist/builder/index.d.ts +15 -3
- package/dist/builder/index.js +588 -552
- package/dist/builder/index.js.map +1 -1
- package/dist/index.cjs +63 -19
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +56 -20
- package/dist/index.js.map +1 -1
- package/dist/{pmf-DIegvlyA.d.cts → pmf-D1p2Re-J.d.cts} +29 -12
- package/dist/{pmf-DIegvlyA.d.ts → pmf-D1p2Re-J.d.ts} +29 -12
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -14,13 +14,18 @@
|
|
|
14
14
|
|
|
15
15
|
A TypeScript library for **D&D 5e damage-per-round (DPR) calculations**, designed for players, Dungeon Masters, and developers who want to analyze combat mathematically.
|
|
16
16
|
|
|
17
|
-
This library powers [dprcalc.com](https://dprcalc.com) and provides a precise, composable way to model dice rolls, attacks, and outcomes with probability mass functions (PMFs) — not just averages. This allows for rich charting and statistics with full outcome attribution.
|
|
17
|
+
This library powers [dprcalc.com](https://dprcalc.com) and provides a precise, composable way to model dice rolls, attacks, and outcomes with probability mass functions (PMFs) — not just averages. This allows for rich charting and statistics with full outcome attribution. It provides two main entry points: a fluent typescript interface or a dice expression string.
|
|
18
18
|
|
|
19
19
|
```ts
|
|
20
20
|
import { parse } from "@yipe/dice";
|
|
21
21
|
|
|
22
22
|
const attack = parse("(d20 + 8 AC 16) * (1d8 + 4) crit (2d8 + 4)");
|
|
23
23
|
console.log("DPR:", attack.mean());
|
|
24
|
+
|
|
25
|
+
// or
|
|
26
|
+
|
|
27
|
+
const attack = d20.plus(8).ac(16).onHit(d8.plus(4));
|
|
28
|
+
console.log("DPR:", attack.mean());
|
|
24
29
|
```
|
|
25
30
|
|
|
26
31
|
## ✨ Features
|
|
@@ -56,7 +61,7 @@ Here's a simple example of calculating damage for a basic attack:
|
|
|
56
61
|
```ts
|
|
57
62
|
import { parse, DiceQuery } from "@yipe/dice";
|
|
58
63
|
|
|
59
|
-
const query =
|
|
64
|
+
const query = d20.plus(8).ac(16).onHit(d4.plus(4)).toQuery();
|
|
60
65
|
|
|
61
66
|
console.log("Hit chance:", query.probAtLeastOne(["hit", "crit"]));
|
|
62
67
|
console.log("Crit chance:", query.probAtLeastOne(["crit"]));
|
|
@@ -76,36 +81,22 @@ DPR: 4.35
|
|
|
76
81
|
Conditional damage ("once-per-turn damage riders") like Sneak Attack can be modeled easily:
|
|
77
82
|
|
|
78
83
|
```ts
|
|
79
|
-
import {
|
|
80
|
-
|
|
81
|
-
function
|
|
82
|
-
const
|
|
83
|
-
const sneakAttack =
|
|
84
|
-
const
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
["hit", "crit"],
|
|
90
|
-
["crit"]
|
|
91
|
-
);
|
|
92
|
-
|
|
93
|
-
// Calculate the expected damage of sneak attack in both scenarios
|
|
94
|
-
const sneak = PMF.exclusive([
|
|
95
|
-
[sneakAttack, pSuccess],
|
|
96
|
-
[sneakAttackCrit, pCrit],
|
|
84
|
+
import { DiceQuery } from "@yipe/dice";
|
|
85
|
+
|
|
86
|
+
function sneakAttack() {
|
|
87
|
+
const attackPMF = d20.plus(8).ac(16).onHit(d4.plus(4)).pmf;
|
|
88
|
+
const sneakAttack = roll(3, d6);
|
|
89
|
+
const attacks = new DiceQuery([attackPMF, attackPMF]);
|
|
90
|
+
const [pHit, pCrit] = attacks.firstSuccessSplit(onAnyHit, onCritOnly);
|
|
91
|
+
const sneakPMF = PMF.exclusive([
|
|
92
|
+
[sneakAttack.pmf, pHit],
|
|
93
|
+
[sneakAttack.doubleDice().pmf, pCrit],
|
|
97
94
|
]);
|
|
98
95
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
const fullRound = new DiceQuery([attack, attack, sneak]);
|
|
102
|
-
const DPR = fullRound.mean();
|
|
103
|
-
|
|
104
|
-
console.log("full round DPR", DPR);
|
|
105
|
-
|
|
106
|
-
// Congrats, you can now chart and query this round!
|
|
107
|
-
return fullRound;
|
|
96
|
+
return new DiceQuery([attackPMF, attackPMF, sneakPMF]);
|
|
108
97
|
}
|
|
98
|
+
|
|
99
|
+
console.log("DPR with once-per-turn sneak attack: ", sneakAttack().mean());
|
|
109
100
|
```
|
|
110
101
|
|
|
111
102
|
## 📊 Statistics and Charts
|
|
@@ -235,7 +226,6 @@ Here is the basic example:
|
|
|
235
226
|
|
|
236
227
|
- [ ] Create a **web playground** with live examples
|
|
237
228
|
- [ ] Consider creating higher-level APIs: `Turn`, `Attack`, `DamageRider`
|
|
238
|
-
- [ ] Simplify and improve PMF and Query interface ergonomics
|
|
239
229
|
- [ ] Add more comprehensive 5e rule examples
|
|
240
230
|
- [ ] Performance improvements for DPR-only calculations
|
|
241
231
|
- [ ] Multi-round and sustained vs nova simulations
|