@dice-o-rolla/dice-engine 0.1.1 → 0.3.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/README.md +65 -2
- package/dist/dice-engine.d.ts +9 -2
- package/dist/dice-engine.js +1155 -45
- package/dist/errors.d.ts +7 -0
- package/dist/errors.js +12 -0
- package/dist/index.d.ts +5 -3
- package/dist/index.js +3 -1
- package/dist/types.d.ts +124 -1
- package/dist/version.d.ts +2 -0
- package/dist/version.js +2 -0
- package/dist/visual-presets.d.ts +7 -0
- package/dist/visual-presets.js +20 -0
- package/package.json +7 -7
package/README.md
CHANGED
|
@@ -19,7 +19,9 @@ engine.destroy();
|
|
|
19
19
|
```
|
|
20
20
|
|
|
21
21
|
The browser entry point initializes Rapier WASM, creates the Three.js renderer, uses Web Crypto for
|
|
22
|
-
throw generation, and releases partially initialized resources if composition fails.
|
|
22
|
+
throw generation, and releases partially initialized resources if composition fails. Concurrent
|
|
23
|
+
`initialize()` calls coalesce, while every roll promise terminates by settlement, cancellation,
|
|
24
|
+
timeout, or failure.
|
|
23
25
|
|
|
24
26
|
## Custom adapters
|
|
25
27
|
|
|
@@ -32,6 +34,49 @@ await engine.initialize();
|
|
|
32
34
|
|
|
33
35
|
The main entry point depends on domain contracts rather than concrete Rapier or Three.js types.
|
|
34
36
|
|
|
37
|
+
## Deterministic simulation and replay
|
|
38
|
+
|
|
39
|
+
`simulate()` runs the configured physics adapter with a per-call seeded random source and returns a
|
|
40
|
+
JSON-serializable `PhysicalRollTrace`. It does not render or emit the ordinary roll lifecycle events.
|
|
41
|
+
Set `captureFrames: true` when the trace will be animated; otherwise the trace contains only its
|
|
42
|
+
terminal frame.
|
|
43
|
+
|
|
44
|
+
```ts
|
|
45
|
+
const trace = await engine.simulate('2d20kh1', {
|
|
46
|
+
seed: 2026,
|
|
47
|
+
captureFrames: true,
|
|
48
|
+
frameIntervalSteps: 2,
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
await engine.replay(trace, {
|
|
52
|
+
theme: { material: 'matte', roughness: 0.85 },
|
|
53
|
+
signal: abortController.signal,
|
|
54
|
+
});
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
`replay()` consumes the captured transforms without stepping physics. Its optional theme is applied
|
|
58
|
+
through the normal engine theme state, and the terminal dice remain rendered until the next roll,
|
|
59
|
+
replay, `clear()`, or `destroy()`. Simulation and replay require an idle engine because the facade
|
|
60
|
+
owns one physics world, renderer, and frame scheduler. Replay cancellation rejects with
|
|
61
|
+
`RollCancelledError`.
|
|
62
|
+
|
|
63
|
+
Traces include producer and physics profile metadata, initial throw conditions, definition
|
|
64
|
+
fingerprints, collision/impact events, and the immutable logical result. Replay validates registered
|
|
65
|
+
definitions, final orientation-derived faces, and the aggregate total before rendering. Default
|
|
66
|
+
trace limits are 1,200 frames, 60,000 die samples, and 20,000 events; customize them through
|
|
67
|
+
`DiceEngineOptions.traceLimits`. `TraceLimitExceededError` identifies the rejected dimension.
|
|
68
|
+
|
|
69
|
+
## Visual presets and optional effects
|
|
70
|
+
|
|
71
|
+
`registerVisualPreset()` associates a logical die with a validated physical geometry, scale, face
|
|
72
|
+
labels, and optional value map. `skinId` and `soundPackId` are opaque application-owned references;
|
|
73
|
+
the engine does not load assets. Skins and sound definitions belong in the optional
|
|
74
|
+
`@dice-o-rolla/dice-assets` package, which is not a dependency of the engine.
|
|
75
|
+
|
|
76
|
+
The engine emits `die:spawn` and `die:remove` lifecycle events. Collision events are opt-in through
|
|
77
|
+
`DiceEngineOptions.collisionEvents`, bounded by `maxEventsPerFrame`, and suitable for an external
|
|
78
|
+
sound or effects adapter.
|
|
79
|
+
|
|
35
80
|
## Supported notation
|
|
36
81
|
|
|
37
82
|
The initial grammar supports standard polyhedral expressions and integer modifiers, including:
|
|
@@ -39,11 +84,23 @@ The initial grammar supports standard polyhedral expressions and integer modifie
|
|
|
39
84
|
```text
|
|
40
85
|
d20
|
|
41
86
|
4d6 + 2
|
|
87
|
+
4d6kh3
|
|
88
|
+
2d20kl1
|
|
89
|
+
5d20s{1=-2,17..19=1,20=2}
|
|
42
90
|
d%
|
|
43
91
|
d100
|
|
44
92
|
d66
|
|
45
93
|
```
|
|
46
94
|
|
|
95
|
+
Keep/drop rolls retain every physical die in `result.dice` and expose the selection through
|
|
96
|
+
`included`. Score maps expose each contribution through `score`; unlisted faces contribute zero.
|
|
97
|
+
Selection is applied before scoring, followed by integer modifiers. Paired `d%`, `d100`, and `d66`
|
|
98
|
+
terms currently reject keep/drop and score operations.
|
|
99
|
+
|
|
100
|
+
Engine-produced dice also contain immutable `provenance`: stable term, logical-die, and physical-die
|
|
101
|
+
coordinates plus the settled face, inclusion state, and contribution. Consumers can explain a
|
|
102
|
+
total without reparsing notation or depending on renderer state.
|
|
103
|
+
|
|
47
104
|
Default resource limits reject oversized notation, more than 50 logical or physical dice, and more
|
|
48
105
|
than eight pending rolls. Consumers may lower or explicitly raise these limits through
|
|
49
106
|
`DiceEngineOptions.limits` after testing their target devices.
|
|
@@ -52,7 +109,13 @@ than eight pending rolls. Consumers may lower or explicitly raise these limits t
|
|
|
52
109
|
|
|
53
110
|
Client-side results are not authoritative for rankings, prizes, or wagering. Call `destroy()` when
|
|
54
111
|
the engine is no longer needed to release frame scheduling, observers, physics resources, WebGL
|
|
55
|
-
resources, and the renderer canvas.
|
|
112
|
+
resources, and the renderer canvas. `clear()` keeps the engine reusable; `destroy()` is idempotent
|
|
113
|
+
and final. See the canonical
|
|
114
|
+
[lifecycle and runtime contract](https://github.com/creepiest-space/dice-o-rolla/blob/main/docs/engine.md).
|
|
115
|
+
Consumers upgrading from `0.1` should also review the
|
|
116
|
+
[0.2 migration notes](https://github.com/creepiest-space/dice-o-rolla/blob/main/docs/migration-0.2.md).
|
|
117
|
+
Consumers upgrading from `0.2` should review the
|
|
118
|
+
[0.3 migration notes](https://github.com/creepiest-space/dice-o-rolla/blob/main/docs/migration-0.3.md).
|
|
56
119
|
|
|
57
120
|
## License
|
|
58
121
|
|
package/dist/dice-engine.d.ts
CHANGED
|
@@ -1,16 +1,23 @@
|
|
|
1
1
|
import { TypedEventEmitter } from '@dice-o-rolla/dice-core';
|
|
2
2
|
import type { RollResult } from '@dice-o-rolla/dice-core';
|
|
3
|
-
import type
|
|
4
|
-
import type { DiceEngineEvents, DiceEngineFacade, DiceEngineOptions, DiceTheme, RollOptions } from './types.js';
|
|
3
|
+
import { type RendererViewport, type VisualPresetDescriptor } from '@dice-o-rolla/dice-renderer';
|
|
4
|
+
import type { DiceEngineEvents, DiceEngineFacade, DiceEngineOptions, DiceTheme, PhysicalRollTrace, RegisterEngineVisualPresetOptions, ReplayOptions, RollOptions, SimulateOptions } from './types.js';
|
|
5
|
+
import { type PhysicalDieType } from './visual-presets.js';
|
|
5
6
|
export declare class DiceEngine extends TypedEventEmitter<DiceEngineEvents> implements DiceEngineFacade {
|
|
6
7
|
#private;
|
|
7
8
|
constructor(options: DiceEngineOptions);
|
|
8
9
|
initialize(): Promise<void>;
|
|
9
10
|
roll(notation: string, options?: RollOptions): Promise<RollResult>;
|
|
11
|
+
simulate(notation: string, options: SimulateOptions): Promise<PhysicalRollTrace>;
|
|
12
|
+
replay(trace: PhysicalRollTrace, options?: ReplayOptions): Promise<void>;
|
|
10
13
|
cancel(sessionId?: string): boolean;
|
|
11
14
|
clear(): void;
|
|
12
15
|
resize(viewport: RendererViewport): void;
|
|
13
16
|
setTheme(theme: Partial<DiceTheme>): DiceTheme;
|
|
14
17
|
get theme(): DiceTheme;
|
|
18
|
+
registerVisualPreset(source: VisualPresetDescriptor, options?: RegisterEngineVisualPresetOptions): VisualPresetDescriptor;
|
|
19
|
+
unregisterVisualPreset(id: string): boolean;
|
|
20
|
+
setVisualPreset(dieType: PhysicalDieType, presetId: string): void;
|
|
21
|
+
getVisualPreset(dieType: PhysicalDieType): VisualPresetDescriptor;
|
|
15
22
|
destroy(): void;
|
|
16
23
|
}
|