@mcptoolshop/roll 1.0.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.
Files changed (75) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/LICENSE +21 -0
  3. package/README.es.md +204 -0
  4. package/README.fr.md +204 -0
  5. package/README.hi.md +204 -0
  6. package/README.it.md +204 -0
  7. package/README.ja.md +204 -0
  8. package/README.md +204 -0
  9. package/README.pt-BR.md +204 -0
  10. package/README.zh.md +204 -0
  11. package/dist/analyze/distribution.d.ts +6 -0
  12. package/dist/analyze/distribution.d.ts.map +1 -0
  13. package/dist/analyze/distribution.js +252 -0
  14. package/dist/analyze/distribution.js.map +1 -0
  15. package/dist/analyze/montecarlo.d.ts +5 -0
  16. package/dist/analyze/montecarlo.d.ts.map +1 -0
  17. package/dist/analyze/montecarlo.js +19 -0
  18. package/dist/analyze/montecarlo.js.map +1 -0
  19. package/dist/analyze/stats.d.ts +16 -0
  20. package/dist/analyze/stats.d.ts.map +1 -0
  21. package/dist/analyze/stats.js +66 -0
  22. package/dist/analyze/stats.js.map +1 -0
  23. package/dist/bin.d.ts +3 -0
  24. package/dist/bin.d.ts.map +1 -0
  25. package/dist/bin.js +267 -0
  26. package/dist/bin.js.map +1 -0
  27. package/dist/display/box.d.ts +5 -0
  28. package/dist/display/box.d.ts.map +1 -0
  29. package/dist/display/box.js +26 -0
  30. package/dist/display/box.js.map +1 -0
  31. package/dist/display/color.d.ts +12 -0
  32. package/dist/display/color.d.ts.map +1 -0
  33. package/dist/display/color.js +19 -0
  34. package/dist/display/color.js.map +1 -0
  35. package/dist/display/format.d.ts +13 -0
  36. package/dist/display/format.d.ts.map +1 -0
  37. package/dist/display/format.js +134 -0
  38. package/dist/display/format.js.map +1 -0
  39. package/dist/display/histogram.d.ts +7 -0
  40. package/dist/display/histogram.d.ts.map +1 -0
  41. package/dist/display/histogram.js +48 -0
  42. package/dist/display/histogram.js.map +1 -0
  43. package/dist/engine/random.d.ts +6 -0
  44. package/dist/engine/random.d.ts.map +1 -0
  45. package/dist/engine/random.js +17 -0
  46. package/dist/engine/random.js.map +1 -0
  47. package/dist/engine/roller.d.ts +19 -0
  48. package/dist/engine/roller.d.ts.map +1 -0
  49. package/dist/engine/roller.js +168 -0
  50. package/dist/engine/roller.js.map +1 -0
  51. package/dist/index.d.ts +27 -0
  52. package/dist/index.d.ts.map +1 -0
  53. package/dist/index.js +37 -0
  54. package/dist/index.js.map +1 -0
  55. package/dist/loot/table.d.ts +27 -0
  56. package/dist/loot/table.d.ts.map +1 -0
  57. package/dist/loot/table.js +92 -0
  58. package/dist/loot/table.js.map +1 -0
  59. package/dist/parser/ast.d.ts +27 -0
  60. package/dist/parser/ast.d.ts.map +1 -0
  61. package/dist/parser/ast.js +2 -0
  62. package/dist/parser/ast.js.map +1 -0
  63. package/dist/parser/lexer.d.ts +7 -0
  64. package/dist/parser/lexer.d.ts.map +1 -0
  65. package/dist/parser/lexer.js +126 -0
  66. package/dist/parser/lexer.js.map +1 -0
  67. package/dist/parser/parser.d.ts +7 -0
  68. package/dist/parser/parser.d.ts.map +1 -0
  69. package/dist/parser/parser.js +188 -0
  70. package/dist/parser/parser.js.map +1 -0
  71. package/dist/parser/tokens.d.ts +25 -0
  72. package/dist/parser/tokens.d.ts.map +1 -0
  73. package/dist/parser/tokens.js +21 -0
  74. package/dist/parser/tokens.js.map +1 -0
  75. package/package.json +55 -0
package/README.it.md ADDED
@@ -0,0 +1,204 @@
1
+ <p align="center">
2
+ <a href="README.ja.md">日本語</a> | <a href="README.zh.md">中文</a> | <a href="README.es.md">Español</a> | <a href="README.fr.md">Français</a> | <a href="README.hi.md">हिन्दी</a> | <a href="README.md">English</a> | <a href="README.pt-BR.md">Português (BR)</a>
3
+ </p>
4
+
5
+ <p align="center"><img src="https://raw.githubusercontent.com/mcp-tool-shop-org/brand/main/logos/roll/readme.png" width="400" alt="Roll"></p>
6
+
7
+ <p align="center">
8
+ <a href="https://github.com/mcp-tool-shop-org/roll/actions"><img src="https://github.com/mcp-tool-shop-org/roll/actions/workflows/ci.yml/badge.svg" alt="CI"></a>
9
+ <a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-blue.svg" alt="MIT License"></a>
10
+ <a href="https://mcp-tool-shop-org.github.io/roll/"><img src="https://img.shields.io/badge/Landing_Page-online-brightgreen" alt="Landing Page"></a>
11
+ <a href="https://www.npmjs.com/package/@mcptoolshop/roll"><img src="https://img.shields.io/npm/v/@mcptoolshop/roll" alt="npm version"></a>
12
+ </p>
13
+
14
+ <p align="center">RPG dice engine with probability analysis, loot tables, and beautiful terminal output.</p>
15
+
16
+ ```
17
+ npx @mcptoolshop/roll 4d6dl1 --analyze
18
+ ```
19
+
20
+ ```
21
+ Distribution
22
+
23
+ 3 0.08%
24
+ 4 █ 0.31%
25
+ 5 ███ 0.77%
26
+ 6 ███████ 1.62%
27
+ 7 █████████████ 2.93%
28
+ 8 ██████████████████████ 4.78%
29
+ 9 ████████████████████████████████ 7.02%
30
+ 10 ███████████████████████████████████████████ 9.41%
31
+ 11 ████████████████████████████████████████████████████ 11.42%
32
+ 12 ██████████████████████████████████████████████████████████ 12.89%
33
+ 13 ████████████████████████████████████████████████████████████ 13.27%
34
+ 14 ████████████████████████████████████████████████████████ 12.35%
35
+ 15 ██████████████████████████████████████████████ 10.11%
36
+ 16 █████████████████████████████████ 7.25%
37
+ 17 ███████████████████ 4.17%
38
+ 18 ███████ 1.62%
39
+
40
+ ┌─ Statistics ─────────────────────────────────┐
41
+ │ Mean: 12.24 │
42
+ │ Median: 12 │
43
+ │ Mode: 13 │
44
+ │ Std Dev: 2.85 │
45
+ │ Range: 3–18 │
46
+ │ Entropy: 3.53 bits │
47
+ │ │
48
+ │ Percentiles: │
49
+ │ p10:8 p25:10 p50:12 p75:14 p90:16 p95:17│
50
+ └───────────────────────────────────────────────┘
51
+ ```
52
+
53
+ ## Installazione
54
+
55
+ ```bash
56
+ npm install @mcptoolshop/roll
57
+ ```
58
+
59
+ Richiede Node.js >= 22.
60
+
61
+ ## Utilizzo da riga di comando
62
+
63
+ ### Lancia i dadi
64
+
65
+ ```bash
66
+ roll 2d6+3
67
+ roll d20+5
68
+ roll 4d6kh3
69
+ roll 1d6!
70
+ roll d%
71
+ roll 4dF
72
+ roll "(2d6+3)*2"
73
+ ```
74
+
75
+ ### Analizza la probabilità
76
+
77
+ ```bash
78
+ roll 2d6 --analyze # Full distribution + statistics
79
+ roll d20+5 --at-least 15 # P(result >= 15)
80
+ ```
81
+
82
+ ### Confronta le distribuzioni
83
+
84
+ ```bash
85
+ roll --compare "4d6dl1" "3d6"
86
+ ```
87
+
88
+ Statistiche affiancate (media, mediana, moda, deviazione standard, intervallo, entropia) con colonna delle differenze, più entrambi gli istogrammi.
89
+
90
+ ### Tabelle di bottino
91
+
92
+ ```bash
93
+ roll --loot treasure.json
94
+ ```
95
+
96
+ Formato JSON:
97
+
98
+ ```json
99
+ {
100
+ "tables": [
101
+ {
102
+ "table": "Treasure",
103
+ "items": [
104
+ { "name": "Gold", "weight": 40, "roll": "2d6*10" },
105
+ { "name": "Potion of Healing", "weight": 30 },
106
+ { "name": "Scroll", "weight": 15, "quantity": "1d3" },
107
+ { "name": "Rare Item", "weight": 5, "table": "Rare Weapons" }
108
+ ]
109
+ },
110
+ {
111
+ "table": "Rare Weapons",
112
+ "items": [
113
+ { "name": "Vorpal Blade", "weight": 5 },
114
+ { "name": "Frost Brand", "weight": 25 }
115
+ ]
116
+ }
117
+ ]
118
+ }
119
+ ```
120
+
121
+ Funzionalità: selezione ponderata, riferimenti a tabelle nidificate, espressioni per i dadi per quantità e valore.
122
+
123
+ ### Altre opzioni
124
+
125
+ ```bash
126
+ roll 2d6+3 --times 5 # Roll 5 times
127
+ roll 2d6+3 --json # Machine-readable output
128
+ roll --help # Full usage
129
+ roll --version # Version
130
+ ```
131
+
132
+ ## Notazione dei dadi
133
+
134
+ | Notazione | Significato |
135
+ |----------|---------|
136
+ | `2d6` | Lancia 2 dadi a sei facce |
137
+ | `d20` | Lancia 1 dado a venti facce |
138
+ | `4d6kh3` | Lancia 4d6, conserva i 3 più alti |
139
+ | `4d6dl1` | Lancia 4d6, scarta il più basso |
140
+ | `1d6!` | Dado esplosivo (rilancia al massimo, aggiungi) |
141
+ | `1d6!>4` | Esplode se ottieni 4 o più |
142
+ | `d%` | Dado percentile (da 1 a 100) |
143
+ | `4dF` | Dadi Fate/Fudge (-1, 0, +1 ciascuno) |
144
+ | `(2d6+3)*2` | Operazioni aritmetiche con raggruppamento |
145
+ | `2d6+1d4+3` | Espressioni concatenate |
146
+
147
+ ## API della libreria
148
+
149
+ ```typescript
150
+ import { roll, analyze, parse, evaluate, computeDistribution } from '@mcptoolshop/roll';
151
+
152
+ // Quick roll
153
+ const result = roll('4d6kh3');
154
+ console.log(result.total); // 14
155
+ console.log(result.groups[0].dice); // per-die breakdown
156
+
157
+ // Full analysis
158
+ const analysis = analyze('2d6+3');
159
+ console.log(analysis.stats.mean); // 10
160
+ console.log(analysis.stats.percentiles[95]); // 14
161
+ console.log(analysis.probabilityAtLeast(12)); // 0.2778
162
+
163
+ // Low-level: parse → AST → evaluate
164
+ import { seededRng } from '@mcptoolshop/roll';
165
+ const ast = parse('4d6dl1');
166
+ const r = evaluate(ast, seededRng(42)); // deterministic
167
+
168
+ // Loot tables
169
+ import { rollLootTable } from '@mcptoolshop/roll';
170
+ const tables = [{ table: "Loot", items: [{ name: "Gold", weight: 50, roll: "2d6*10" }] }];
171
+ const drops = rollLootTable(tables);
172
+ ```
173
+
174
+ ## Motore di probabilità
175
+
176
+ - **Distribuzioni esatte** tramite convoluzione polinomiale per i dadi NdM di base
177
+ - **Enumerazione completa** per le meccaniche di conservazione/scarto (4d6 = 1.296 stati)
178
+ - **Ricorsione troncata** per i dadi esplosivi (limitata a 10 esplosioni)
179
+ - **Fallback Monte Carlo** (100.000 campioni) quando il calcolo esatto supera i 10 milioni di stati
180
+
181
+ ## Nessuna dipendenza esterna
182
+
183
+ Costruito interamente con le funzionalità integrate di Node.js 22+:
184
+ - `util.styleText` per i colori del terminale
185
+ - `util.parseArgs` per l'analisi degli argomenti da riga di comando
186
+ - `crypto.randomInt` per la generazione di numeri casuali crittograficamente sicuri per i tiri di dado
187
+
188
+ ## Sicurezza e affidabilità
189
+
190
+ `@mcptoolshop/roll` elabora solo espressioni per i dadi e nient'altro. Non effettua richieste di rete, non scrive file e non raccoglie dati. L'unico accesso al file system è tramite il flag `--loot`, che legge un singolo file JSON specificato dall'utente.
191
+
192
+ Non sono presenti telemetrie, analisi o tracciamenti di alcun tipo. Non sono coinvolti segreti, token o credenziali in nessuna operazione.
193
+
194
+ Tutti i tiri di dado utilizzano `crypto.randomInt` dal modulo `crypto` di Node.js, fornendo una casualità crittograficamente sicura adatta per risultati equi.
195
+
196
+ Consultare [SECURITY.md](./SECURITY.md) per la politica di segnalazione delle vulnerabilità.
197
+
198
+ ## Licenza
199
+
200
+ MIT
201
+
202
+ ---
203
+
204
+ Creato da <a href="https://mcp-tool-shop.github.io/">MCP Tool Shop</a>
package/README.ja.md ADDED
@@ -0,0 +1,204 @@
1
+ <p align="center">
2
+ <a href="README.md">English</a> | <a href="README.zh.md">中文</a> | <a href="README.es.md">Español</a> | <a href="README.fr.md">Français</a> | <a href="README.hi.md">हिन्दी</a> | <a href="README.it.md">Italiano</a> | <a href="README.pt-BR.md">Português (BR)</a>
3
+ </p>
4
+
5
+ <p align="center"><img src="https://raw.githubusercontent.com/mcp-tool-shop-org/brand/main/logos/roll/readme.png" width="400" alt="Roll"></p>
6
+
7
+ <p align="center">
8
+ <a href="https://github.com/mcp-tool-shop-org/roll/actions"><img src="https://github.com/mcp-tool-shop-org/roll/actions/workflows/ci.yml/badge.svg" alt="CI"></a>
9
+ <a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-blue.svg" alt="MIT License"></a>
10
+ <a href="https://mcp-tool-shop-org.github.io/roll/"><img src="https://img.shields.io/badge/Landing_Page-online-brightgreen" alt="Landing Page"></a>
11
+ <a href="https://www.npmjs.com/package/@mcptoolshop/roll"><img src="https://img.shields.io/npm/v/@mcptoolshop/roll" alt="npm version"></a>
12
+ </p>
13
+
14
+ <p align="center">RPG dice engine with probability analysis, loot tables, and beautiful terminal output.</p>
15
+
16
+ ```
17
+ npx @mcptoolshop/roll 4d6dl1 --analyze
18
+ ```
19
+
20
+ ```
21
+ Distribution
22
+
23
+ 3 0.08%
24
+ 4 █ 0.31%
25
+ 5 ███ 0.77%
26
+ 6 ███████ 1.62%
27
+ 7 █████████████ 2.93%
28
+ 8 ██████████████████████ 4.78%
29
+ 9 ████████████████████████████████ 7.02%
30
+ 10 ███████████████████████████████████████████ 9.41%
31
+ 11 ████████████████████████████████████████████████████ 11.42%
32
+ 12 ██████████████████████████████████████████████████████████ 12.89%
33
+ 13 ████████████████████████████████████████████████████████████ 13.27%
34
+ 14 ████████████████████████████████████████████████████████ 12.35%
35
+ 15 ██████████████████████████████████████████████ 10.11%
36
+ 16 █████████████████████████████████ 7.25%
37
+ 17 ███████████████████ 4.17%
38
+ 18 ███████ 1.62%
39
+
40
+ ┌─ Statistics ─────────────────────────────────┐
41
+ │ Mean: 12.24 │
42
+ │ Median: 12 │
43
+ │ Mode: 13 │
44
+ │ Std Dev: 2.85 │
45
+ │ Range: 3–18 │
46
+ │ Entropy: 3.53 bits │
47
+ │ │
48
+ │ Percentiles: │
49
+ │ p10:8 p25:10 p50:12 p75:14 p90:16 p95:17│
50
+ └───────────────────────────────────────────────┘
51
+ ```
52
+
53
+ ## インストール
54
+
55
+ ```bash
56
+ npm install @mcptoolshop/roll
57
+ ```
58
+
59
+ Node.js 22 以降が必要です。
60
+
61
+ ## CLI の使用方法
62
+
63
+ ### サイコロを振る
64
+
65
+ ```bash
66
+ roll 2d6+3
67
+ roll d20+5
68
+ roll 4d6kh3
69
+ roll 1d6!
70
+ roll d%
71
+ roll 4dF
72
+ roll "(2d6+3)*2"
73
+ ```
74
+
75
+ ### 確率を分析する
76
+
77
+ ```bash
78
+ roll 2d6 --analyze # Full distribution + statistics
79
+ roll d20+5 --at-least 15 # P(result >= 15)
80
+ ```
81
+
82
+ ### 分布を比較する
83
+
84
+ ```bash
85
+ roll --compare "4d6dl1" "3d6"
86
+ ```
87
+
88
+ 統計情報(平均、中央値、最頻値、標準偏差、範囲、エントロピー)を並べて表示し、差分を表示。ヒストグラムも表示します。
89
+
90
+ ### アイテムテーブル
91
+
92
+ ```bash
93
+ roll --loot treasure.json
94
+ ```
95
+
96
+ JSON 形式:
97
+
98
+ ```json
99
+ {
100
+ "tables": [
101
+ {
102
+ "table": "Treasure",
103
+ "items": [
104
+ { "name": "Gold", "weight": 40, "roll": "2d6*10" },
105
+ { "name": "Potion of Healing", "weight": 30 },
106
+ { "name": "Scroll", "weight": 15, "quantity": "1d3" },
107
+ { "name": "Rare Item", "weight": 5, "table": "Rare Weapons" }
108
+ ]
109
+ },
110
+ {
111
+ "table": "Rare Weapons",
112
+ "items": [
113
+ { "name": "Vorpal Blade", "weight": 5 },
114
+ { "name": "Frost Brand", "weight": 25 }
115
+ ]
116
+ }
117
+ ]
118
+ }
119
+ ```
120
+
121
+ 機能:重み付けされた選択、ネストされたテーブル参照、サイコロの個数と値を指定するための数式。
122
+
123
+ ### その他のオプション
124
+
125
+ ```bash
126
+ roll 2d6+3 --times 5 # Roll 5 times
127
+ roll 2d6+3 --json # Machine-readable output
128
+ roll --help # Full usage
129
+ roll --version # Version
130
+ ```
131
+
132
+ ## サイコロの表記法
133
+
134
+ | 表記 | 意味 |
135
+ |----------|---------|
136
+ | `2d6` | 6面サイコロを2個振る |
137
+ | `d20` | 20面サイコロを1個振る |
138
+ | `4d6kh3` | 6面サイコロを4個振り、最も高い3個を残す |
139
+ | `4d6dl1` | 6面サイコロを4個振り、最も低い1個を捨てる |
140
+ | `1d6!` | 爆発サイコロ(最大値が出たら再ロールし、加算する) |
141
+ | `1d6!>4` | 4以上が出たら爆発 |
142
+ | `d%` | パーセントサイコロ(1~100) |
143
+ | `4dF` | Fate/Fudge サイコロ(-1、0、+1) |
144
+ | `(2d6+3)*2` | グループ化された算術演算 |
145
+ | `2d6+1d4+3` | 連鎖した数式 |
146
+
147
+ ## ライブラリ API
148
+
149
+ ```typescript
150
+ import { roll, analyze, parse, evaluate, computeDistribution } from '@mcptoolshop/roll';
151
+
152
+ // Quick roll
153
+ const result = roll('4d6kh3');
154
+ console.log(result.total); // 14
155
+ console.log(result.groups[0].dice); // per-die breakdown
156
+
157
+ // Full analysis
158
+ const analysis = analyze('2d6+3');
159
+ console.log(analysis.stats.mean); // 10
160
+ console.log(analysis.stats.percentiles[95]); // 14
161
+ console.log(analysis.probabilityAtLeast(12)); // 0.2778
162
+
163
+ // Low-level: parse → AST → evaluate
164
+ import { seededRng } from '@mcptoolshop/roll';
165
+ const ast = parse('4d6dl1');
166
+ const r = evaluate(ast, seededRng(42)); // deterministic
167
+
168
+ // Loot tables
169
+ import { rollLootTable } from '@mcptoolshop/roll';
170
+ const tables = [{ table: "Loot", items: [{ name: "Gold", weight: 50, roll: "2d6*10" }] }];
171
+ const drops = rollLootTable(tables);
172
+ ```
173
+
174
+ ## 確率エンジン
175
+
176
+ - 基本的な NdM の場合、多項式畳み込みによる**正確な分布**
177
+ - keep/drop メカニズムの場合の**完全な列挙**(4d6 = 1,296 通りの状態)
178
+ - 爆発サイコロの場合の**切り捨てられた再帰**(爆発回数は最大10回)
179
+ - 正確な計算が 100 万以上の状態を超える場合、**モンテカルロ法**(10万サンプル)を使用
180
+
181
+ ## 依存関係なし
182
+
183
+ Node.js 22 以降の組み込み機能のみを使用:
184
+ - ターミナルカラー表示用の `util.styleText`
185
+ - CLI 引数解析用の `util.parseArgs`
186
+ - 暗号学的に安全なサイコロの出目生成用の `crypto.randomInt`
187
+
188
+ ## セキュリティと信頼性
189
+
190
+ `@mcptoolshop/roll` は、サイコロの数式を処理するのみです。ネットワークリクエストは行わず、ファイルへの書き込みも行わず、データも収集しません。ファイルシステムへのアクセスは、`--loot` オプションを使用した場合のみで、これはユーザーが指定した単一の JSON ファイルを読み込みます。
191
+
192
+ テレメトリー、分析、およびあらゆる種類のトラッキングは一切ありません。秘密、トークン、または認証情報は、いかなる操作にも使用されません。
193
+
194
+ すべてのサイコロの出目は、Node.js の `crypto` モジュールにある `crypto.randomInt` を使用しており、暗号学的に安全な乱数を生成し、公平な結果を得ることができます。
195
+
196
+ 脆弱性報告ポリシーについては、[SECURITY.md](./SECURITY.md) を参照してください。
197
+
198
+ ## ライセンス
199
+
200
+ MIT
201
+
202
+ ---
203
+
204
+ <a href="https://mcp-tool-shop.github.io/">MCP Tool Shop</a> が作成しました。
package/README.md ADDED
@@ -0,0 +1,204 @@
1
+ <p align="center">
2
+ <a href="README.ja.md">日本語</a> | <a href="README.zh.md">中文</a> | <a href="README.es.md">Español</a> | <a href="README.fr.md">Français</a> | <a href="README.hi.md">हिन्दी</a> | <a href="README.it.md">Italiano</a> | <a href="README.pt-BR.md">Português (BR)</a>
3
+ </p>
4
+
5
+ <p align="center"><img src="https://raw.githubusercontent.com/mcp-tool-shop-org/brand/main/logos/roll/readme.png" width="400" alt="Roll"></p>
6
+
7
+ <p align="center">
8
+ <a href="https://github.com/mcp-tool-shop-org/roll/actions"><img src="https://github.com/mcp-tool-shop-org/roll/actions/workflows/ci.yml/badge.svg" alt="CI"></a>
9
+ <a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-blue.svg" alt="MIT License"></a>
10
+ <a href="https://mcp-tool-shop-org.github.io/roll/"><img src="https://img.shields.io/badge/Landing_Page-online-brightgreen" alt="Landing Page"></a>
11
+ <a href="https://www.npmjs.com/package/@mcptoolshop/roll"><img src="https://img.shields.io/npm/v/@mcptoolshop/roll" alt="npm version"></a>
12
+ </p>
13
+
14
+ <p align="center">RPG dice engine with probability analysis, loot tables, and beautiful terminal output.</p>
15
+
16
+ ```
17
+ npx @mcptoolshop/roll 4d6dl1 --analyze
18
+ ```
19
+
20
+ ```
21
+ Distribution
22
+
23
+ 3 0.08%
24
+ 4 █ 0.31%
25
+ 5 ███ 0.77%
26
+ 6 ███████ 1.62%
27
+ 7 █████████████ 2.93%
28
+ 8 ██████████████████████ 4.78%
29
+ 9 ████████████████████████████████ 7.02%
30
+ 10 ███████████████████████████████████████████ 9.41%
31
+ 11 ████████████████████████████████████████████████████ 11.42%
32
+ 12 ██████████████████████████████████████████████████████████ 12.89%
33
+ 13 ████████████████████████████████████████████████████████████ 13.27%
34
+ 14 ████████████████████████████████████████████████████████ 12.35%
35
+ 15 ██████████████████████████████████████████████ 10.11%
36
+ 16 █████████████████████████████████ 7.25%
37
+ 17 ███████████████████ 4.17%
38
+ 18 ███████ 1.62%
39
+
40
+ ┌─ Statistics ─────────────────────────────────┐
41
+ │ Mean: 12.24 │
42
+ │ Median: 12 │
43
+ │ Mode: 13 │
44
+ │ Std Dev: 2.85 │
45
+ │ Range: 3–18 │
46
+ │ Entropy: 3.53 bits │
47
+ │ │
48
+ │ Percentiles: │
49
+ │ p10:8 p25:10 p50:12 p75:14 p90:16 p95:17│
50
+ └───────────────────────────────────────────────┘
51
+ ```
52
+
53
+ ## Install
54
+
55
+ ```bash
56
+ npm install @mcptoolshop/roll
57
+ ```
58
+
59
+ Requires Node.js >= 22.
60
+
61
+ ## CLI Usage
62
+
63
+ ### Roll dice
64
+
65
+ ```bash
66
+ roll 2d6+3
67
+ roll d20+5
68
+ roll 4d6kh3
69
+ roll 1d6!
70
+ roll d%
71
+ roll 4dF
72
+ roll "(2d6+3)*2"
73
+ ```
74
+
75
+ ### Analyze probability
76
+
77
+ ```bash
78
+ roll 2d6 --analyze # Full distribution + statistics
79
+ roll d20+5 --at-least 15 # P(result >= 15)
80
+ ```
81
+
82
+ ### Compare distributions
83
+
84
+ ```bash
85
+ roll --compare "4d6dl1" "3d6"
86
+ ```
87
+
88
+ Side-by-side stats (mean, median, mode, stddev, range, entropy) with diff column, plus both histograms.
89
+
90
+ ### Loot tables
91
+
92
+ ```bash
93
+ roll --loot treasure.json
94
+ ```
95
+
96
+ JSON format:
97
+
98
+ ```json
99
+ {
100
+ "tables": [
101
+ {
102
+ "table": "Treasure",
103
+ "items": [
104
+ { "name": "Gold", "weight": 40, "roll": "2d6*10" },
105
+ { "name": "Potion of Healing", "weight": 30 },
106
+ { "name": "Scroll", "weight": 15, "quantity": "1d3" },
107
+ { "name": "Rare Item", "weight": 5, "table": "Rare Weapons" }
108
+ ]
109
+ },
110
+ {
111
+ "table": "Rare Weapons",
112
+ "items": [
113
+ { "name": "Vorpal Blade", "weight": 5 },
114
+ { "name": "Frost Brand", "weight": 25 }
115
+ ]
116
+ }
117
+ ]
118
+ }
119
+ ```
120
+
121
+ Features: weighted selection, nested table references, dice expressions for quantity and value.
122
+
123
+ ### Other flags
124
+
125
+ ```bash
126
+ roll 2d6+3 --times 5 # Roll 5 times
127
+ roll 2d6+3 --json # Machine-readable output
128
+ roll --help # Full usage
129
+ roll --version # Version
130
+ ```
131
+
132
+ ## Dice Notation
133
+
134
+ | Notation | Meaning |
135
+ |----------|---------|
136
+ | `2d6` | Roll 2 six-sided dice |
137
+ | `d20` | Roll 1 twenty-sided die |
138
+ | `4d6kh3` | Roll 4d6, keep highest 3 |
139
+ | `4d6dl1` | Roll 4d6, drop lowest 1 |
140
+ | `1d6!` | Exploding d6 (reroll on max, add) |
141
+ | `1d6!>4` | Explode on 4 or higher |
142
+ | `d%` | Percentile die (1-100) |
143
+ | `4dF` | Fate/Fudge dice (-1, 0, +1 each) |
144
+ | `(2d6+3)*2` | Arithmetic with grouping |
145
+ | `2d6+1d4+3` | Chained expressions |
146
+
147
+ ## Library API
148
+
149
+ ```typescript
150
+ import { roll, analyze, parse, evaluate, computeDistribution } from '@mcptoolshop/roll';
151
+
152
+ // Quick roll
153
+ const result = roll('4d6kh3');
154
+ console.log(result.total); // 14
155
+ console.log(result.groups[0].dice); // per-die breakdown
156
+
157
+ // Full analysis
158
+ const analysis = analyze('2d6+3');
159
+ console.log(analysis.stats.mean); // 10
160
+ console.log(analysis.stats.percentiles[95]); // 14
161
+ console.log(analysis.probabilityAtLeast(12)); // 0.2778
162
+
163
+ // Low-level: parse → AST → evaluate
164
+ import { seededRng } from '@mcptoolshop/roll';
165
+ const ast = parse('4d6dl1');
166
+ const r = evaluate(ast, seededRng(42)); // deterministic
167
+
168
+ // Loot tables
169
+ import { rollLootTable } from '@mcptoolshop/roll';
170
+ const tables = [{ table: "Loot", items: [{ name: "Gold", weight: 50, roll: "2d6*10" }] }];
171
+ const drops = rollLootTable(tables);
172
+ ```
173
+
174
+ ## Probability Engine
175
+
176
+ - **Exact distributions** via polynomial convolution for basic NdM
177
+ - **Full enumeration** for keep/drop mechanics (4d6 = 1,296 states)
178
+ - **Truncated recursion** for exploding dice (capped at 10 explosions)
179
+ - **Monte Carlo fallback** (100k samples) when exact computation exceeds 10M states
180
+
181
+ ## Zero Dependencies
182
+
183
+ Built entirely on Node.js 22+ builtins:
184
+ - `util.styleText` for terminal colors
185
+ - `util.parseArgs` for CLI argument parsing
186
+ - `crypto.randomInt` for cryptographically secure dice rolls
187
+
188
+ ## Security & Trust
189
+
190
+ `@mcptoolshop/roll` processes dice expressions and nothing else. It makes no network requests, writes no files, and collects no data. The only filesystem access is the `--loot` flag, which reads a single user-specified JSON file.
191
+
192
+ There is no telemetry, no analytics, and no tracking of any kind. No secrets, tokens, or credentials are involved in any operation.
193
+
194
+ All dice rolls use `crypto.randomInt` from the Node.js `crypto` module, providing cryptographically secure randomness suitable for fair outcomes.
195
+
196
+ See [SECURITY.md](./SECURITY.md) for the vulnerability reporting policy.
197
+
198
+ ## License
199
+
200
+ MIT
201
+
202
+ ---
203
+
204
+ Built by <a href="https://mcp-tool-shop.github.io/">MCP Tool Shop</a>