@aethervtt/shard-dice 0.0.0-stage → 0.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/LICENSE +21 -0
- package/README.md +2 -2
- package/dist/attachments.d.ts +79 -0
- package/dist/attachments.js +43 -0
- package/dist/audio.d.ts +19 -0
- package/dist/audio.js +187 -0
- package/dist/builtins.d.ts +25 -0
- package/dist/builtins.js +335 -0
- package/dist/cells.d.ts +33 -0
- package/dist/cells.js +53 -0
- package/dist/components.d.ts +14 -0
- package/dist/components.js +27 -0
- package/dist/definition-asset.d.ts +19 -0
- package/dist/definition-asset.js +60 -0
- package/dist/definition.d.ts +98 -0
- package/dist/definition.js +320 -0
- package/dist/dice-worker.d.ts +1 -0
- package/dist/dice-worker.js +3 -0
- package/dist/effects.d.ts +99 -0
- package/dist/effects.js +200 -0
- package/dist/entrances.d.ts +48 -0
- package/dist/entrances.js +54 -0
- package/dist/families.d.ts +17 -0
- package/dist/families.js +131 -0
- package/dist/glyphs.d.ts +29 -0
- package/dist/glyphs.js +270 -0
- package/dist/golden.json +17 -0
- package/dist/hull.d.ts +32 -0
- package/dist/hull.js +154 -0
- package/dist/index.d.ts +32 -0
- package/dist/index.js +324 -0
- package/dist/landing.d.ts +29 -0
- package/dist/landing.js +93 -0
- package/dist/layout.d.ts +75 -0
- package/dist/layout.js +137 -0
- package/dist/marks.d.ts +54 -0
- package/dist/marks.js +543 -0
- package/dist/material.d.ts +80 -0
- package/dist/material.js +343 -0
- package/dist/math.d.ts +39 -0
- package/dist/math.js +136 -0
- package/dist/mesh.d.ts +9 -0
- package/dist/mesh.js +105 -0
- package/dist/methods.d.ts +2 -0
- package/dist/methods.js +42 -0
- package/dist/numerals.d.ts +9 -0
- package/dist/numerals.js +47 -0
- package/dist/plugin.d.ts +41 -0
- package/dist/plugin.js +176 -0
- package/dist/preview.d.ts +32 -0
- package/dist/preview.js +135 -0
- package/dist/quality.d.ts +12 -0
- package/dist/quality.js +18 -0
- package/dist/resources.d.ts +85 -0
- package/dist/resources.js +191 -0
- package/dist/roll.d.ts +68 -0
- package/dist/roll.js +97 -0
- package/dist/settle.d.ts +53 -0
- package/dist/settle.js +96 -0
- package/dist/skin.d.ts +64 -0
- package/dist/skin.js +313 -0
- package/dist/sound.d.ts +33 -0
- package/dist/sound.js +296 -0
- package/dist/studio.d.ts +3 -0
- package/dist/studio.js +48 -0
- package/dist/table.d.ts +227 -0
- package/dist/table.js +1818 -0
- package/dist/test-worker.d.ts +1 -0
- package/dist/test-worker.js +12 -0
- package/dist/track.d.ts +70 -0
- package/dist/track.js +304 -0
- package/dist/tray.d.ts +2 -0
- package/dist/tray.js +43 -0
- package/dist/variants.d.ts +9 -0
- package/dist/variants.js +46 -0
- package/dist/windows.d.ts +25 -0
- package/dist/windows.js +77 -0
- package/dist/worker.d.ts +6 -0
- package/dist/worker.js +9 -0
- package/package.json +47 -4
package/dist/table.d.ts
ADDED
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
import { type AssetRef, type Entity, ShardError, type World } from '@aethervtt/shard-core';
|
|
2
|
+
import { type TrackClient, type TrackWorkerLike } from '@aethervtt/shard-physics/worker';
|
|
3
|
+
import type { DieKind } from './builtins.js';
|
|
4
|
+
import { type DiceEffectRecipeValue } from './effects.js';
|
|
5
|
+
import { type FaceLayoutValue } from './layout.js';
|
|
6
|
+
import { DiceResources } from './resources.js';
|
|
7
|
+
import { type DiceRoll } from './roll.js';
|
|
8
|
+
import { type DiceTray } from './settle.js';
|
|
9
|
+
import { DiceSoundBank } from './sound.js';
|
|
10
|
+
export type DicePhase = 'idle' | 'simulating' | 'tumble' | 'entrance' | 'accent' | 'rest';
|
|
11
|
+
export type DiceOutcome = 'finished' | 'dismissed' | 'cancelled' | 'failed';
|
|
12
|
+
export interface DicePlayOptions {
|
|
13
|
+
/** Aborting it, in any phase, cancels the roll: `'cancelled'`. */
|
|
14
|
+
signal?: AbortSignal;
|
|
15
|
+
/** Dismiss a roll that's playing instead of rejecting with `dice/busy`. */
|
|
16
|
+
replace?: boolean;
|
|
17
|
+
}
|
|
18
|
+
export interface DiceTableOptions {
|
|
19
|
+
restMs: number;
|
|
20
|
+
maxDice: number;
|
|
21
|
+
/** Wall clock, ms: rests and releases run on it (tests pass their own). */
|
|
22
|
+
now: () => number;
|
|
23
|
+
kinds: Readonly<Record<DieKind, readonly string[]>>;
|
|
24
|
+
worker: (() => TrackWorkerLike) | 'inline';
|
|
25
|
+
/** The dice camera's vertical field of view, degrees. */
|
|
26
|
+
fovY: number;
|
|
27
|
+
/** How long a roll waits for an entrance's assets and warm-up past the physics (0065). */
|
|
28
|
+
entranceWaitMs: number;
|
|
29
|
+
}
|
|
30
|
+
/** The frame demand a presentation holds while it moves. */
|
|
31
|
+
export declare const PRESENTATION_DEMAND = "dice/presentation";
|
|
32
|
+
/** Held while dice of an animated family (at the display's rate) are shown. */
|
|
33
|
+
export declare const ANIMATED_DEMAND = "dice/animated";
|
|
34
|
+
/** Held while an entrance's scene is alive (0065). */
|
|
35
|
+
export declare const ENTRANCE_DEMAND = "dice/entrance";
|
|
36
|
+
/** How long a roll waits for an entrance's assets past the physics being ready, by default. */
|
|
37
|
+
export declare const ENTRANCE_WAIT_MS = 1500;
|
|
38
|
+
/** A fixed tray and seed for skin pickers. */
|
|
39
|
+
export declare const PREVIEW_TRAY: DiceTray;
|
|
40
|
+
export declare class DiceTableState {
|
|
41
|
+
/** The last failure's error (`'failed'` outcomes). */
|
|
42
|
+
lastError: ShardError | undefined;
|
|
43
|
+
/** Recordings sent to the track worker (reduced motion sends none). */
|
|
44
|
+
recordings: number;
|
|
45
|
+
readonly resources: DiceResources;
|
|
46
|
+
readonly sounds: DiceSoundBank;
|
|
47
|
+
readonly options: DiceTableOptions;
|
|
48
|
+
camera: Entity;
|
|
49
|
+
light: Entity;
|
|
50
|
+
floor: Entity;
|
|
51
|
+
/** Where shadows fall on the floor (x, z), from the key light: blobs lean that way. */
|
|
52
|
+
shadowDir: [number, number];
|
|
53
|
+
/** The tray material and quad, for the floor and contact blobs. */
|
|
54
|
+
trayMaterial: AssetRef<'Material'> | undefined;
|
|
55
|
+
quad: AssetRef<'Mesh'> | undefined;
|
|
56
|
+
private readonly world;
|
|
57
|
+
private client;
|
|
58
|
+
private current;
|
|
59
|
+
private nextId;
|
|
60
|
+
private disposed;
|
|
61
|
+
private fitted;
|
|
62
|
+
private warned;
|
|
63
|
+
/** Warm-ups waiting for the next frame (0065). */
|
|
64
|
+
private frameWaiters;
|
|
65
|
+
constructor(world: World, options: DiceTableOptions);
|
|
66
|
+
/** Where the presentation is: `'idle'` with none. */
|
|
67
|
+
get phase(): DicePhase;
|
|
68
|
+
/** The track client, started on first use; call early to have the worker warm. */
|
|
69
|
+
tracks(): TrackClient;
|
|
70
|
+
/**
|
|
71
|
+
* Presents a roll the host decided. Resolves once it's over: `'finished'` after the rest,
|
|
72
|
+
* `'dismissed'`, `'cancelled'` (the signal aborted), or `'failed'` (with the error in
|
|
73
|
+
* `lastError`; never a half-played roll). Rejects with `dice/busy` while another plays, unless
|
|
74
|
+
* `replace`.
|
|
75
|
+
*/
|
|
76
|
+
play(roll: DiceRoll, options?: DicePlayOptions): Promise<DiceOutcome>;
|
|
77
|
+
/** Plays a roll on a fixed seed and tray, for skin pickers. Replaces what's playing. */
|
|
78
|
+
preview(roll: DiceRoll, options?: Omit<DicePlayOptions, 'replace'>): Promise<DiceOutcome>;
|
|
79
|
+
/** Ends the presentation now: `'dismissed'`. False when nothing plays. */
|
|
80
|
+
dismiss(): boolean;
|
|
81
|
+
/** Shortens the rest to at most `ms` from now (or from when the dice land, if they haven't). */
|
|
82
|
+
shortenRest(ms: number): void;
|
|
83
|
+
/** Everything that can fail before anything plays: the roll's values, its skins and layouts. */
|
|
84
|
+
private check;
|
|
85
|
+
/**
|
|
86
|
+
* Loads what the roll's skins reference (layouts, recipes, the layouts' fonts), then checks the
|
|
87
|
+
* skins: an unknown family, a layout that can't show a value, a recipe over its bounds.
|
|
88
|
+
*/
|
|
89
|
+
private loadSkins;
|
|
90
|
+
layout(ref: AssetRef): FaceLayoutValue | undefined;
|
|
91
|
+
recipe(ref: AssetRef): DiceEffectRecipeValue | undefined;
|
|
92
|
+
/** Loads what the roll's layouts need (fonts), makes the dice's resources, then records or places. */
|
|
93
|
+
private prepare;
|
|
94
|
+
private prepareAudio;
|
|
95
|
+
private eventSound;
|
|
96
|
+
private loadFonts;
|
|
97
|
+
private acquire;
|
|
98
|
+
private screenUp;
|
|
99
|
+
/**
|
|
100
|
+
* The track is in (or there's none: every die enters): which dice land, where the rest go, each
|
|
101
|
+
* die's correction, and where entrance dice will land (0065).
|
|
102
|
+
*/
|
|
103
|
+
private land;
|
|
104
|
+
/**
|
|
105
|
+
* Rest poses for entrance dice: free spots near what each entrance wants (the tray's center by
|
|
106
|
+
* default), clear of where the physical dice ended, target up with the readable twist.
|
|
107
|
+
*/
|
|
108
|
+
private placeEntrances;
|
|
109
|
+
/** Reduced motion: no physics. Each die rests in its lane, target up and upright, fading in. */
|
|
110
|
+
private placeReduced;
|
|
111
|
+
private geometryOf;
|
|
112
|
+
/** Spawns the dice (and contact blobs) at their first pose. */
|
|
113
|
+
private spawnDice;
|
|
114
|
+
private spawnBlob;
|
|
115
|
+
private blobRadius;
|
|
116
|
+
/** How far a blob sits from under its die, toward the shadows: more as the die rises. */
|
|
117
|
+
private blobLean;
|
|
118
|
+
private blobStrength;
|
|
119
|
+
/** A die's pose at `time`, with its correction: rotation · C. Allocates nothing. */
|
|
120
|
+
private samplePose;
|
|
121
|
+
/** One frame of the table: the systems call it in Update. */
|
|
122
|
+
frame(): void;
|
|
123
|
+
private tumble;
|
|
124
|
+
/**
|
|
125
|
+
* Impact sounds up to the current step, as the track recorded them: at most one per die every
|
|
126
|
+
* 45 ms, and the strongest four in a frame. Allocates nothing without audio.
|
|
127
|
+
*/
|
|
128
|
+
private contacts;
|
|
129
|
+
/**
|
|
130
|
+
* One impact: a variation of its strength layer, louder faster than strength (light touches stay
|
|
131
|
+
* light), at a pitch and level picked around the contact's (0035's ranges).
|
|
132
|
+
*/
|
|
133
|
+
private impact;
|
|
134
|
+
/** The tumble ended: results light up, large pools get their shadow, effects or the rest begin. */
|
|
135
|
+
private landed;
|
|
136
|
+
/** Every die is down: the accent if anything plays in it, else the rest. */
|
|
137
|
+
private afterLanding;
|
|
138
|
+
/** The result ramp, over 350 ms from landing. */
|
|
139
|
+
private settleLook;
|
|
140
|
+
/**
|
|
141
|
+
* A large pool's landing, t from 0 to 1: the tray's shadow in, the opaque dice's blobs out
|
|
142
|
+
* (despawned at 1). Allocates nothing.
|
|
143
|
+
*/
|
|
144
|
+
private crossfadeShadows;
|
|
145
|
+
/** Reduced motion's fade in, over 150 ms. */
|
|
146
|
+
private fade;
|
|
147
|
+
private rest;
|
|
148
|
+
/**
|
|
149
|
+
* The roll's recipes, once each, and which dice carry each one (their skin names it): a
|
|
150
|
+
* recipe's conditions read the whole roll, but its effects play on its own skin's dice.
|
|
151
|
+
*/
|
|
152
|
+
private recipesOf;
|
|
153
|
+
private centroid;
|
|
154
|
+
/**
|
|
155
|
+
* The roll's recipes, matched once (the conditions read only the roll), and the entrance dice they
|
|
156
|
+
* choose (0065): at most 2, in the full tier, with effects on and full motion.
|
|
157
|
+
*/
|
|
158
|
+
private chooseEntrances;
|
|
159
|
+
/** Budgets for one burst of effects: one light, one cue, 32 particles. */
|
|
160
|
+
private static budget;
|
|
161
|
+
/** Starts a matched recipe's effects on `anchors`. Returns how long the longest runs, ms. */
|
|
162
|
+
private playRecipe;
|
|
163
|
+
/** Starts the accent phase if anything plays in it. */
|
|
164
|
+
private startAccent;
|
|
165
|
+
/** An accent cue, a little above the hardest impact at full gain. */
|
|
166
|
+
private accentSound;
|
|
167
|
+
private startRun;
|
|
168
|
+
private accent;
|
|
169
|
+
private attach;
|
|
170
|
+
/**
|
|
171
|
+
* What a scene on a die can reach and do (attachments, and entrances, 0065): the die, the camera,
|
|
172
|
+
* its screen point, lens fields and screen effects on it, sound at the roll's gain.
|
|
173
|
+
*/
|
|
174
|
+
private sceneContext;
|
|
175
|
+
private attachmentsFrame;
|
|
176
|
+
/**
|
|
177
|
+
* Lands every entrance still to come or playing, now: each die snaps to its rest pose, and scenes
|
|
178
|
+
* get 400 ms to wind down (`ctx.skipped`). False when no entrance is left to skip.
|
|
179
|
+
*/
|
|
180
|
+
skip(): boolean;
|
|
181
|
+
private entranceUnavailable;
|
|
182
|
+
/** While the physics records: the entrance's assets, then its scene drawn once. */
|
|
183
|
+
private readyEntrance;
|
|
184
|
+
/**
|
|
185
|
+
* Draws an entrance's scene once, away from everything, to an offscreen target on the app's
|
|
186
|
+
* device (as thumbnails are), so its uploads are done and its pipelines compiled before it plays.
|
|
187
|
+
* The warm copy's lens fields, screen effects and sounds go nowhere.
|
|
188
|
+
*/
|
|
189
|
+
private warmEntrance;
|
|
190
|
+
/**
|
|
191
|
+
* Resolves at the table's next frame (an idle app is woken for it); code after the `await` runs
|
|
192
|
+
* once that frame has rendered, with its stats in.
|
|
193
|
+
*/
|
|
194
|
+
private nextFrame;
|
|
195
|
+
/** An entrance's context: live on its die, or (warming up) on a stand-in, going nowhere. */
|
|
196
|
+
private entranceContext;
|
|
197
|
+
/** Starts the next entrance whose turn it is; with every die down, the accent (or the rest). */
|
|
198
|
+
private nextEntrance;
|
|
199
|
+
private startEntrance;
|
|
200
|
+
/** Each frame while an entrance is alive: scenes, the die's landing, its result ramp. */
|
|
201
|
+
private entrancesFrame;
|
|
202
|
+
/** The placed drop, t from 0 to 1: from above its spot down onto it, easing in. */
|
|
203
|
+
private dropPose;
|
|
204
|
+
/**
|
|
205
|
+
* The die lands: its rest pose, shown, its result from now (its own material), its impact, and
|
|
206
|
+
* the effects of the recipe that chose it, on it. Then the next entrance's turn.
|
|
207
|
+
*/
|
|
208
|
+
private landEntrance;
|
|
209
|
+
/** The skin's impact as the die lands, as hard as the entrance says (default 0.8). */
|
|
210
|
+
private entranceImpact;
|
|
211
|
+
private endEntrance;
|
|
212
|
+
private fail;
|
|
213
|
+
/** Ends a presentation: despawns what it spawned, lets go of frames, sounds and resources. */
|
|
214
|
+
private finish;
|
|
215
|
+
private warnOnce;
|
|
216
|
+
/** The dice view's aspect: its camera's target, or the window. */
|
|
217
|
+
aspect(): number;
|
|
218
|
+
/** The tray the camera frames: the roll's, or the viewport's while idle. */
|
|
219
|
+
private fitCamera;
|
|
220
|
+
private fovY;
|
|
221
|
+
/** The GPU device was lost: a playing roll fails (it would show nothing), fields cleared. */
|
|
222
|
+
deviceLost(message: string): void;
|
|
223
|
+
dispose(): void;
|
|
224
|
+
describe(): Record<string, unknown>;
|
|
225
|
+
}
|
|
226
|
+
/** The dice table: `world.resource(DiceTable).play(roll)`. */
|
|
227
|
+
export declare const DiceTable: import("@aethervtt/shard-core").ResourceDef<DiceTableState>;
|