@energy8platform/game-engine 0.20.0 → 0.21.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 +121 -0
- package/dist/animation.cjs.js +18 -3
- package/dist/animation.cjs.js.map +1 -1
- package/dist/animation.esm.js +18 -3
- package/dist/animation.esm.js.map +1 -1
- package/dist/core.cjs.js +18 -3
- package/dist/core.cjs.js.map +1 -1
- package/dist/core.esm.js +18 -3
- package/dist/core.esm.js.map +1 -1
- package/dist/host.cjs.js +18 -3
- package/dist/host.cjs.js.map +1 -1
- package/dist/host.esm.js +18 -3
- package/dist/host.esm.js.map +1 -1
- package/dist/index.cjs.js +18 -3
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.esm.js +18 -3
- package/dist/index.esm.js.map +1 -1
- package/dist/react.cjs.js +18 -3
- package/dist/react.cjs.js.map +1 -1
- package/dist/react.esm.js +18 -3
- package/dist/react.esm.js.map +1 -1
- package/dist/slot.cjs.js +1872 -31
- package/dist/slot.cjs.js.map +1 -1
- package/dist/slot.d.ts +555 -5
- package/dist/slot.esm.js +1857 -33
- package/dist/slot.esm.js.map +1 -1
- package/dist/ui.cjs.js +18 -3
- package/dist/ui.cjs.js.map +1 -1
- package/dist/ui.esm.js +18 -3
- package/dist/ui.esm.js.map +1 -1
- package/package.json +1 -1
- package/src/animation/Tween.ts +14 -3
- package/src/slot/anim/easing-map.ts +16 -2
- package/src/slot/cascade/TumbleController.ts +230 -0
- package/src/slot/config/ReelSystemConfig.ts +559 -0
- package/src/slot/config/presets.ts +222 -0
- package/src/slot/features/extra.ts +189 -0
- package/src/slot/features/index.ts +44 -0
- package/src/slot/features/symbols.ts +183 -0
- package/src/slot/features/types.ts +136 -0
- package/src/slot/features/wilds.ts +151 -0
- package/src/slot/grid/ReelGrid.ts +93 -24
- package/src/slot/grid/SymbolCell.ts +45 -11
- package/src/slot/index.ts +61 -0
- package/src/slot/motion/AnticipationController.ts +96 -0
- package/src/slot/motion/SpinEngine.ts +384 -0
- package/src/slot/system/ReelSystem.ts +295 -0
package/dist/slot.d.ts
CHANGED
|
@@ -106,7 +106,10 @@ interface DecorationConfig {
|
|
|
106
106
|
}
|
|
107
107
|
interface ReelGridConfig {
|
|
108
108
|
cols: number;
|
|
109
|
+
/** Uniform row count. Ignored per-reel when `rowsPerReel` is provided. */
|
|
109
110
|
rows: number;
|
|
111
|
+
/** Per-reel row counts for Megaways / variable-height reels. Length must equal `cols`. */
|
|
112
|
+
rowsPerReel?: number[];
|
|
110
113
|
cellSize: number;
|
|
111
114
|
gap?: number;
|
|
112
115
|
resolve: SymbolResolver;
|
|
@@ -114,23 +117,40 @@ interface ReelGridConfig {
|
|
|
114
117
|
decoration?: DecorationConfig;
|
|
115
118
|
mask?: boolean;
|
|
116
119
|
}
|
|
120
|
+
/**
|
|
121
|
+
* A grid of `SymbolCell`s. Supports uniform grids and variable-height reels (Megaways):
|
|
122
|
+
* when `rowsPerReel` is set each reel is vertically centred inside the tallest reel's envelope.
|
|
123
|
+
*/
|
|
117
124
|
declare class ReelGrid extends Container {
|
|
118
125
|
readonly __uiComponent: true;
|
|
119
126
|
private _cols;
|
|
120
|
-
private
|
|
127
|
+
private _rowsPerReel;
|
|
128
|
+
private _maxRows;
|
|
121
129
|
private _cellSize;
|
|
122
130
|
private _gap;
|
|
123
131
|
private _cells;
|
|
124
132
|
private _cellLayer;
|
|
133
|
+
private _resolve;
|
|
134
|
+
private _frameStyle?;
|
|
135
|
+
private _mask;
|
|
125
136
|
constructor(config: ReelGridConfig);
|
|
137
|
+
private _buildCells;
|
|
138
|
+
private _applyMask;
|
|
126
139
|
get cols(): number;
|
|
140
|
+
/** Tallest reel's row count (the grid's visual height in rows). */
|
|
127
141
|
get rows(): number;
|
|
142
|
+
get cellSize(): number;
|
|
143
|
+
rowsOf(col: number): number;
|
|
144
|
+
get rowsPerReel(): number[];
|
|
145
|
+
/** Cell centre position. Variable-height reels are centred in the max-rows envelope. */
|
|
128
146
|
cellPosition(col: number, row: number): {
|
|
129
147
|
x: number;
|
|
130
148
|
y: number;
|
|
131
149
|
};
|
|
132
150
|
getCell(col: number, row: number): SymbolCell;
|
|
133
151
|
setGrid(cells: CellData[][]): void;
|
|
152
|
+
/** Rebuild the grid with new per-reel row counts (Megaways re-roll / dynamic rows). */
|
|
153
|
+
reshape(rowsPerReel: number[]): void;
|
|
134
154
|
resize(cellSize: number): void;
|
|
135
155
|
}
|
|
136
156
|
|
|
@@ -204,7 +224,7 @@ interface ReelSpinTimings {
|
|
|
204
224
|
stopStagger: number;
|
|
205
225
|
settle: number;
|
|
206
226
|
}
|
|
207
|
-
interface ReelStopPlan {
|
|
227
|
+
interface ReelStopPlan$1 {
|
|
208
228
|
reel: number;
|
|
209
229
|
stopTime: number;
|
|
210
230
|
landing: CellData[];
|
|
@@ -221,7 +241,7 @@ declare class ReelSpinController {
|
|
|
221
241
|
/** PURE: per-reel stop timing + landing window. No Pixi mutation. */
|
|
222
242
|
plan(data: ReelSpinData, opts?: {
|
|
223
243
|
turbo?: boolean;
|
|
224
|
-
}): ReelStopPlan[];
|
|
244
|
+
}): ReelStopPlan$1[];
|
|
225
245
|
/** Execute the spin: scroll each reel, decelerate, land on target, settle-bounce. Not unit-tested. */
|
|
226
246
|
run(data: ReelSpinData, opts?: {
|
|
227
247
|
turbo?: boolean;
|
|
@@ -230,6 +250,536 @@ declare class ReelSpinController {
|
|
|
230
250
|
skip(): void;
|
|
231
251
|
}
|
|
232
252
|
|
|
253
|
+
type EasingFunction = (t: number) => number;
|
|
254
|
+
|
|
255
|
+
/** Resolve a descriptor's string easing name to the engine's easing function. */
|
|
256
|
+
declare const EASING_BY_NAME: Record<string, EasingFunction>;
|
|
257
|
+
/** Resolve an easing name to a function, falling back to easeOutQuad. */
|
|
258
|
+
declare function easingByName(name?: string): EasingFunction;
|
|
259
|
+
|
|
260
|
+
/** Names of easing functions available in the engine's `Easing` map (see anim/easing-map.ts). */
|
|
261
|
+
type EasingName = 'linear' | 'easeInQuad' | 'easeOutQuad' | 'easeInOutQuad' | 'easeInCubic' | 'easeOutCubic' | 'easeInOutCubic' | 'easeInBack' | 'easeOutBack' | 'easeInOutBack' | 'easeOutBounce' | 'easeInBounce' | 'easeOutElastic' | 'easeInSine' | 'easeOutSine' | 'easeInOutSine';
|
|
262
|
+
/** Win-evaluation model. Purely presentational here (affects geometry + highlight), the math lives in Lua. */
|
|
263
|
+
type EvaluationMode = 'lines' | 'ways' | 'anywhere' | 'cluster' | 'megaways' | 'infinity';
|
|
264
|
+
interface GridConfig {
|
|
265
|
+
cols: number;
|
|
266
|
+
/** Uniform row count. Ignored when `rowsPerReel` is set. */
|
|
267
|
+
rows: number;
|
|
268
|
+
/** Per-reel row counts (Megaways / variable-height reels). Length should equal `cols`. */
|
|
269
|
+
rowsPerReel?: number[];
|
|
270
|
+
cellSize: number;
|
|
271
|
+
gap: number;
|
|
272
|
+
evaluation: EvaluationMode;
|
|
273
|
+
/** For Megaways: clamp per-reel rows to [minRows, maxRows]. */
|
|
274
|
+
minRows?: number;
|
|
275
|
+
maxRows?: number;
|
|
276
|
+
/** Megaways top horizontal reel (renders above the grid, adds to ways). */
|
|
277
|
+
topReel?: {
|
|
278
|
+
size: number;
|
|
279
|
+
} | null;
|
|
280
|
+
mask: boolean;
|
|
281
|
+
frameStyle?: CellFrameStyle;
|
|
282
|
+
decoration?: {
|
|
283
|
+
padding?: number;
|
|
284
|
+
};
|
|
285
|
+
}
|
|
286
|
+
type MotionStyle = 'swap' | 'strip' | 'cascade-drop';
|
|
287
|
+
type StopMode = 'sequential' | 'sync' | 'random';
|
|
288
|
+
type StopOrder = 'ltr' | 'rtl';
|
|
289
|
+
type Intensity = 'full' | 'reduced' | 'minimal';
|
|
290
|
+
interface SettleConfig {
|
|
291
|
+
/** Overshoot amplitude in px applied to the reel before it springs back. */
|
|
292
|
+
amp: number;
|
|
293
|
+
ms: number;
|
|
294
|
+
easing: EasingName;
|
|
295
|
+
}
|
|
296
|
+
/** Squash & stretch on landing impact (Stone-Rush / magnus style). */
|
|
297
|
+
interface SquashConfig {
|
|
298
|
+
enabled: boolean;
|
|
299
|
+
scaleX: number;
|
|
300
|
+
scaleY: number;
|
|
301
|
+
ms: number;
|
|
302
|
+
}
|
|
303
|
+
interface BlurConfig {
|
|
304
|
+
enabled: boolean;
|
|
305
|
+
/** Alpha applied to in-motion symbols (hot-ross uses 0.82). */
|
|
306
|
+
alpha: number;
|
|
307
|
+
/** Runtime BlurFilter strength factor (PixiJS slots demo uses ~8), 0 disables the filter. */
|
|
308
|
+
strength: number;
|
|
309
|
+
/** Draw vertical motion streaks behind moving symbols. */
|
|
310
|
+
streaks: boolean;
|
|
311
|
+
}
|
|
312
|
+
interface MotionConfig {
|
|
313
|
+
style: MotionStyle;
|
|
314
|
+
/** Base spin-up duration (ms) before the first reel can stop. */
|
|
315
|
+
spinUp: number;
|
|
316
|
+
/** Extra hold (ms) at full speed before deceleration. */
|
|
317
|
+
hold: number;
|
|
318
|
+
/** Delay (ms) between consecutive reel stops in sequential mode. */
|
|
319
|
+
stopStagger: number;
|
|
320
|
+
stopMode: StopMode;
|
|
321
|
+
stopOrder: StopOrder;
|
|
322
|
+
settle: SettleConfig;
|
|
323
|
+
squash: SquashConfig;
|
|
324
|
+
blur: BlurConfig;
|
|
325
|
+
/** Multiply all durations in turbo mode (0.5 = twice as fast). */
|
|
326
|
+
turboFactor: number;
|
|
327
|
+
/** Global animation-intensity scale (accessibility): full=1, reduced=0.7, minimal=0.4. */
|
|
328
|
+
intensity: Intensity;
|
|
329
|
+
/** Allow slam/quick-stop (snaps reels to target without changing outcome). */
|
|
330
|
+
slamStop: boolean;
|
|
331
|
+
/** Symbols visible on a reel tape while spinning (swap/strip). */
|
|
332
|
+
symbolsPerReel: number;
|
|
333
|
+
}
|
|
334
|
+
interface AnticipationConfig {
|
|
335
|
+
enabled: boolean;
|
|
336
|
+
/** Symbols that count toward the anticipation threshold (scatter/bonus). */
|
|
337
|
+
triggerSymbols: string[];
|
|
338
|
+
/** Number of trigger symbols already landed that arms anticipation (N−1, usually 2). */
|
|
339
|
+
threshold: number;
|
|
340
|
+
/** Which reels get the slow treatment: the still-spinning trailing reels, or explicit indices. */
|
|
341
|
+
reels: 'trailing' | number[];
|
|
342
|
+
/** Multiply the trailing reel's spin speed (lower = slower / longer). */
|
|
343
|
+
slowdownFactor: number;
|
|
344
|
+
/** Extra hold (ms) before the final anticipation reel lands (300–500 typical). */
|
|
345
|
+
holdMs: number;
|
|
346
|
+
/** Optional grid zoom while anticipating (magnum-opus uses 1.3×). */
|
|
347
|
+
zoom: {
|
|
348
|
+
enabled: boolean;
|
|
349
|
+
scale: number;
|
|
350
|
+
ms: number;
|
|
351
|
+
};
|
|
352
|
+
}
|
|
353
|
+
interface CascadeConfig {
|
|
354
|
+
enabled: boolean;
|
|
355
|
+
/** Animate surviving symbols sliding down into the gaps (true tumble). */
|
|
356
|
+
gravity: boolean;
|
|
357
|
+
timings: {
|
|
358
|
+
reveal: number;
|
|
359
|
+
highlight: number;
|
|
360
|
+
remove: number;
|
|
361
|
+
drop: number;
|
|
362
|
+
refill: number;
|
|
363
|
+
wait: number;
|
|
364
|
+
};
|
|
365
|
+
easings: {
|
|
366
|
+
highlight: EasingName;
|
|
367
|
+
remove: EasingName;
|
|
368
|
+
drop: EasingName;
|
|
369
|
+
};
|
|
370
|
+
/** Slow each successive cascade step to build tension: factor = 1 + step*perStepDecel (capped). */
|
|
371
|
+
perStepDecel: number;
|
|
372
|
+
perStepDecelCap: number;
|
|
373
|
+
/** Dim non-winning symbols during the highlight phase. */
|
|
374
|
+
dimNonWinners: boolean;
|
|
375
|
+
dimAlpha: number;
|
|
376
|
+
/** Running win multiplier that climbs per cascade (Pragmatic Tumble / Avalanche). */
|
|
377
|
+
multiplier: {
|
|
378
|
+
enabled: boolean;
|
|
379
|
+
start: number;
|
|
380
|
+
/** 'add' → +step each step; 'mul' → ×step each step. */
|
|
381
|
+
mode: 'add' | 'mul';
|
|
382
|
+
step: number;
|
|
383
|
+
cap: number | null;
|
|
384
|
+
/** Keep climbing across free-spins instead of resetting per spin. */
|
|
385
|
+
persistInFreeSpins: boolean;
|
|
386
|
+
};
|
|
387
|
+
}
|
|
388
|
+
interface WinConfig {
|
|
389
|
+
highlightScale: number;
|
|
390
|
+
glow: boolean;
|
|
391
|
+
/** Frame shake on landing/win. */
|
|
392
|
+
frameShake: {
|
|
393
|
+
enabled: boolean;
|
|
394
|
+
amp: number;
|
|
395
|
+
ms: number;
|
|
396
|
+
onlyOnSymbols: string[] | null;
|
|
397
|
+
};
|
|
398
|
+
}
|
|
399
|
+
interface ExpandingWildConfig {
|
|
400
|
+
enabled: boolean;
|
|
401
|
+
symbol: string;
|
|
402
|
+
/** Reels that may host an expanding wild (empty = all). */
|
|
403
|
+
reels: number[];
|
|
404
|
+
/** Expand to the full reel height. */
|
|
405
|
+
toFullReel: boolean;
|
|
406
|
+
ms: number;
|
|
407
|
+
easing: EasingName;
|
|
408
|
+
onlyInFreeSpins: boolean;
|
|
409
|
+
}
|
|
410
|
+
interface StickyConfig {
|
|
411
|
+
enabled: boolean;
|
|
412
|
+
symbols: string[];
|
|
413
|
+
/** How many spins a sticky symbol persists (0 = whole feature/bonus). */
|
|
414
|
+
durationSpins: number;
|
|
415
|
+
/** Ring colour drawn around sticky cells. */
|
|
416
|
+
ringColor: number;
|
|
417
|
+
}
|
|
418
|
+
interface WalkingWildConfig {
|
|
419
|
+
enabled: boolean;
|
|
420
|
+
symbol: string;
|
|
421
|
+
direction: 'left' | 'right';
|
|
422
|
+
stepPerSpin: number;
|
|
423
|
+
awardsRespin: boolean;
|
|
424
|
+
asStacked: boolean;
|
|
425
|
+
}
|
|
426
|
+
interface MultiplierConfig {
|
|
427
|
+
enabled: boolean;
|
|
428
|
+
/** Multiplier symbol id (carries a value), or null when multipliers are per-cell data. */
|
|
429
|
+
symbol: string | null;
|
|
430
|
+
scope: 'perSymbol' | 'perReel' | 'global';
|
|
431
|
+
combine: 'additive' | 'multiplicative';
|
|
432
|
+
attachedToWild: boolean;
|
|
433
|
+
max: number;
|
|
434
|
+
accumulateAcrossFreeSpins: boolean;
|
|
435
|
+
}
|
|
436
|
+
interface MysteryConfig {
|
|
437
|
+
enabled: boolean;
|
|
438
|
+
symbol: string;
|
|
439
|
+
/** Eligible reveal targets; all mystery tiles reveal the SAME single draw per spin. */
|
|
440
|
+
revealPool: string[];
|
|
441
|
+
canRevealWild: boolean;
|
|
442
|
+
ms: number;
|
|
443
|
+
}
|
|
444
|
+
interface TransformConfig {
|
|
445
|
+
enabled: boolean;
|
|
446
|
+
/** Trigger symbol whose landing fires the transform (null = data-driven). */
|
|
447
|
+
trigger: string | null;
|
|
448
|
+
/** 'randomLow' picks one low symbol at random; or pin a specific source. */
|
|
449
|
+
source: 'randomLow' | string;
|
|
450
|
+
target: string;
|
|
451
|
+
/** Convert every instance of the source symbol. */
|
|
452
|
+
allInstances: boolean;
|
|
453
|
+
/** Restrict to low→high (upgrade) direction. */
|
|
454
|
+
upgradeOnly: boolean;
|
|
455
|
+
ms: number;
|
|
456
|
+
}
|
|
457
|
+
interface GiantConfig {
|
|
458
|
+
enabled: boolean;
|
|
459
|
+
/** Footprint in cells. */
|
|
460
|
+
width: number;
|
|
461
|
+
height: number;
|
|
462
|
+
/** Symbols that may appear giant (empty = any). */
|
|
463
|
+
symbols: string[];
|
|
464
|
+
/** Pick one giant symbol type per spin. */
|
|
465
|
+
chosenPerSpin: boolean;
|
|
466
|
+
onlyInFreeSpins: boolean;
|
|
467
|
+
}
|
|
468
|
+
interface SplitConfig {
|
|
469
|
+
enabled: boolean;
|
|
470
|
+
symbol: string;
|
|
471
|
+
factor: number;
|
|
472
|
+
/** Reels that can host the split trigger (xSplit lands on the last reel). */
|
|
473
|
+
reels: number[];
|
|
474
|
+
/** Defer the split execution until all respins finish. */
|
|
475
|
+
deferUntilRespinsEnd: boolean;
|
|
476
|
+
}
|
|
477
|
+
interface StackedConfig {
|
|
478
|
+
enabled: boolean;
|
|
479
|
+
symbols: string[];
|
|
480
|
+
/** Max stack height (positions of the same symbol on one reel). */
|
|
481
|
+
height: number;
|
|
482
|
+
}
|
|
483
|
+
interface NudgeConfig {
|
|
484
|
+
enabled: boolean;
|
|
485
|
+
/** Reels eligible to nudge. */
|
|
486
|
+
reels: number[];
|
|
487
|
+
step: number;
|
|
488
|
+
/** xNudge: nudge a stacked wild into full view, +1 multiplier per nudge. */
|
|
489
|
+
toFullReel: boolean;
|
|
490
|
+
multiplierStart: number;
|
|
491
|
+
multiplierPerNudge: number;
|
|
492
|
+
}
|
|
493
|
+
interface ReelModifierConfig {
|
|
494
|
+
enabled: boolean;
|
|
495
|
+
/** Random pre-spin modifiers, each with a trigger weight. */
|
|
496
|
+
pool: {
|
|
497
|
+
effect: 'addRows' | 'addWilds' | 'setGiant' | 'guaranteedWilds';
|
|
498
|
+
magnitude: number;
|
|
499
|
+
weight: number;
|
|
500
|
+
}[];
|
|
501
|
+
appliesIn: 'base' | 'freeSpins' | 'both';
|
|
502
|
+
}
|
|
503
|
+
interface HoldAndSpinConfig {
|
|
504
|
+
enabled: boolean;
|
|
505
|
+
lockSymbols: string[];
|
|
506
|
+
triggerThreshold: number;
|
|
507
|
+
respinsAwarded: number;
|
|
508
|
+
/** Reset the respin counter to full whenever a new symbol locks. */
|
|
509
|
+
resetOnNewSymbol: boolean;
|
|
510
|
+
jackpotTiers: string[];
|
|
511
|
+
fullGridAwardsGrand: boolean;
|
|
512
|
+
}
|
|
513
|
+
interface RandomWildConfig {
|
|
514
|
+
enabled: boolean;
|
|
515
|
+
/** Fixed count, or [min,max] range. */
|
|
516
|
+
count: number | [number, number];
|
|
517
|
+
sticky: boolean;
|
|
518
|
+
multiplier: number;
|
|
519
|
+
trigger: 'randomBaseSpin' | 'onFreeSpins';
|
|
520
|
+
chance: number;
|
|
521
|
+
}
|
|
522
|
+
interface FeaturesConfig {
|
|
523
|
+
expandingWild: ExpandingWildConfig;
|
|
524
|
+
sticky: StickyConfig;
|
|
525
|
+
walkingWild: WalkingWildConfig;
|
|
526
|
+
multiplier: MultiplierConfig;
|
|
527
|
+
mystery: MysteryConfig;
|
|
528
|
+
transform: TransformConfig;
|
|
529
|
+
giant: GiantConfig;
|
|
530
|
+
split: SplitConfig;
|
|
531
|
+
stacked: StackedConfig;
|
|
532
|
+
nudge: NudgeConfig;
|
|
533
|
+
reelModifier: ReelModifierConfig;
|
|
534
|
+
holdAndSpin: HoldAndSpinConfig;
|
|
535
|
+
randomWild: RandomWildConfig;
|
|
536
|
+
}
|
|
537
|
+
/** Ordered list of feature keys (resolve order matters; see docs §3.4). */
|
|
538
|
+
type FeatureKey = keyof FeaturesConfig;
|
|
539
|
+
declare const FEATURE_KEYS: FeatureKey[];
|
|
540
|
+
interface ReelSystemConfig {
|
|
541
|
+
grid: GridConfig;
|
|
542
|
+
motion: MotionConfig;
|
|
543
|
+
anticipation: AnticipationConfig;
|
|
544
|
+
cascade: CascadeConfig;
|
|
545
|
+
win: WinConfig;
|
|
546
|
+
features: FeaturesConfig;
|
|
547
|
+
}
|
|
548
|
+
/** Deep-partial helper for overrides. */
|
|
549
|
+
type DeepPartial<T> = {
|
|
550
|
+
[K in keyof T]?: T[K] extends (infer U)[] ? T[K] : T[K] extends object ? DeepPartial<T[K]> : T[K];
|
|
551
|
+
};
|
|
552
|
+
declare const DEFAULT_REEL_CONFIG: ReelSystemConfig;
|
|
553
|
+
/** Intensity → duration scale (accessibility). */
|
|
554
|
+
declare const INTENSITY_SCALE: Record<Intensity, number>;
|
|
555
|
+
/** Deep-merge `partial` onto `base` (arrays replace, objects merge). Returns a new object. */
|
|
556
|
+
declare function mergeReelConfig<T>(base: T, partial?: DeepPartial<T>): T;
|
|
557
|
+
/** Resolve a partial config to a fully-populated `ReelSystemConfig`. */
|
|
558
|
+
declare function resolveReelConfig(partial?: DeepPartial<ReelSystemConfig>): ReelSystemConfig;
|
|
559
|
+
/** Effective per-reel row counts (resolves Megaways `rowsPerReel`, else uniform `rows`). */
|
|
560
|
+
declare function effectiveRowsPerReel(grid: GridConfig): number[];
|
|
561
|
+
/** Total ways-to-win for a ways/megaways grid (product of per-reel heights). */
|
|
562
|
+
declare function waysCount(grid: GridConfig): number;
|
|
563
|
+
|
|
564
|
+
type PresetId = 'classic' | 'kitsune-wrath' | 'moon-spice' | 'stone-rush' | 'hot-ross' | 'magnus' | 'megaways';
|
|
565
|
+
interface ReelPreset {
|
|
566
|
+
id: PresetId;
|
|
567
|
+
name: string;
|
|
568
|
+
note: string;
|
|
569
|
+
config: DeepPartial<ReelSystemConfig>;
|
|
570
|
+
}
|
|
571
|
+
declare const PRESETS: Record<PresetId, ReelPreset>;
|
|
572
|
+
declare const PRESET_LIST: ReelPreset[];
|
|
573
|
+
|
|
574
|
+
interface SpinData {
|
|
575
|
+
/** Target board: targetGrid[col][row]. */
|
|
576
|
+
targetGrid: CellData[][];
|
|
577
|
+
/** Optional per-reel symbol tape for the spinning illusion (defaults to random of the landing symbols). */
|
|
578
|
+
strip?: (reel: number) => string[];
|
|
579
|
+
}
|
|
580
|
+
interface SpinRunOpts {
|
|
581
|
+
turbo?: boolean;
|
|
582
|
+
/** Reels to slow for anticipation (computed by the ReelSystem from config + targetGrid). */
|
|
583
|
+
anticipateReels?: number[];
|
|
584
|
+
anticipateSlowdown?: number;
|
|
585
|
+
anticipateHoldMs?: number;
|
|
586
|
+
}
|
|
587
|
+
interface ReelStopPlan {
|
|
588
|
+
reel: number;
|
|
589
|
+
/** Wall-clock time (ms) from spin start when this reel stops. */
|
|
590
|
+
stopTime: number;
|
|
591
|
+
landing: CellData[];
|
|
592
|
+
settle: {
|
|
593
|
+
amp: number;
|
|
594
|
+
ms: number;
|
|
595
|
+
};
|
|
596
|
+
anticipated: boolean;
|
|
597
|
+
}
|
|
598
|
+
declare class SpinEngine {
|
|
599
|
+
private _grid;
|
|
600
|
+
private _resolve;
|
|
601
|
+
private _cfg;
|
|
602
|
+
private _win;
|
|
603
|
+
private _killed;
|
|
604
|
+
private _shaking;
|
|
605
|
+
private _temp;
|
|
606
|
+
constructor(grid: ReelGrid, resolve: SymbolResolver, cfg: MotionConfig, win?: WinConfig);
|
|
607
|
+
setConfig(cfg: MotionConfig): void;
|
|
608
|
+
setWin(win: WinConfig): void;
|
|
609
|
+
/** Quick decaying frame shake when a landed reel carries a configured trigger symbol. */
|
|
610
|
+
private _frameShake;
|
|
611
|
+
private scale;
|
|
612
|
+
/** PURE: per-reel stop schedule. No Pixi mutation. */
|
|
613
|
+
plan(data: SpinData, opts?: SpinRunOpts): ReelStopPlan[];
|
|
614
|
+
/** Execute the spin for every reel concurrently. */
|
|
615
|
+
run(data: SpinData, opts?: SpinRunOpts): Promise<void>;
|
|
616
|
+
private _runReel;
|
|
617
|
+
/** Anticipation time-stretch factor for a reel (>=1, longer = slower). */
|
|
618
|
+
private slowOf;
|
|
619
|
+
private _runSwap;
|
|
620
|
+
private _runStrip;
|
|
621
|
+
private _runDrop;
|
|
622
|
+
private _settle;
|
|
623
|
+
private _squashCell;
|
|
624
|
+
/** Apply motion blur (alpha + optional BlurFilter) to targets; returns a disposer that clears it. */
|
|
625
|
+
private _applyBlur;
|
|
626
|
+
private _cleanupTemp;
|
|
627
|
+
/** Slam / quick stop: snap everything to the target and stop animating. */
|
|
628
|
+
skip(): void;
|
|
629
|
+
}
|
|
630
|
+
|
|
631
|
+
interface AnticipationDecision {
|
|
632
|
+
active: boolean;
|
|
633
|
+
/** Reel indices that should spin slower / longer. */
|
|
634
|
+
reels: number[];
|
|
635
|
+
slowdown: number;
|
|
636
|
+
holdMs: number;
|
|
637
|
+
}
|
|
638
|
+
declare class AnticipationController {
|
|
639
|
+
private _cfg;
|
|
640
|
+
constructor(cfg: AnticipationConfig);
|
|
641
|
+
setConfig(cfg: AnticipationConfig): void;
|
|
642
|
+
/** Count how many trigger symbols land on a given reel. */
|
|
643
|
+
private countOnReel;
|
|
644
|
+
/**
|
|
645
|
+
* Decide anticipation from the landing grid. Trigger symbols are counted left→right;
|
|
646
|
+
* once the running total reaches `threshold`, every still-spinning reel after that point
|
|
647
|
+
* is flagged for the slow treatment (this mirrors "searching for the last scatter").
|
|
648
|
+
*/
|
|
649
|
+
decide(targetGrid: CellData[][]): AnticipationDecision;
|
|
650
|
+
/** Optionally zoom the grid in while anticipating, then settle back. Returns a reset fn. */
|
|
651
|
+
zoomIn(grid: ReelGrid): Promise<() => Promise<void>>;
|
|
652
|
+
}
|
|
653
|
+
|
|
654
|
+
interface TumbleStep {
|
|
655
|
+
winningCells: {
|
|
656
|
+
col: number;
|
|
657
|
+
row: number;
|
|
658
|
+
}[];
|
|
659
|
+
removedCells: {
|
|
660
|
+
col: number;
|
|
661
|
+
row: number;
|
|
662
|
+
}[];
|
|
663
|
+
/** Optional explicit survivor slides (col, fromRow→toRow). When omitted, gravity is derived. */
|
|
664
|
+
drops?: {
|
|
665
|
+
col: number;
|
|
666
|
+
fromRow: number;
|
|
667
|
+
toRow: number;
|
|
668
|
+
}[];
|
|
669
|
+
newCells: {
|
|
670
|
+
col: number;
|
|
671
|
+
row: number;
|
|
672
|
+
symbol: string;
|
|
673
|
+
}[];
|
|
674
|
+
settledGrid: CellData[][];
|
|
675
|
+
}
|
|
676
|
+
declare class TumbleController {
|
|
677
|
+
private _grid;
|
|
678
|
+
private _cfg;
|
|
679
|
+
private _win;
|
|
680
|
+
private _killed;
|
|
681
|
+
private _mult;
|
|
682
|
+
constructor(grid: ReelGrid, cfg: CascadeConfig, win?: WinConfig);
|
|
683
|
+
setConfig(cfg: CascadeConfig): void;
|
|
684
|
+
setWin(win: WinConfig): void;
|
|
685
|
+
/** Killed, or the grid was torn down underneath us (rebuild during a cascade). */
|
|
686
|
+
private get _dead();
|
|
687
|
+
get multiplier(): number;
|
|
688
|
+
resetMultiplier(): void;
|
|
689
|
+
private advanceMultiplier;
|
|
690
|
+
/** Derive survivor slides for one column when explicit drops aren't supplied. */
|
|
691
|
+
private deriveDrops;
|
|
692
|
+
/** Run a single cascade step. `stepIndex` drives per-step deceleration. */
|
|
693
|
+
step(step: TumbleStep, stepIndex?: number, opts?: {
|
|
694
|
+
turbo?: boolean;
|
|
695
|
+
}): Promise<void>;
|
|
696
|
+
private _dim;
|
|
697
|
+
private _undim;
|
|
698
|
+
private _resetPositions;
|
|
699
|
+
skip(): void;
|
|
700
|
+
}
|
|
701
|
+
|
|
702
|
+
interface FeatureContext {
|
|
703
|
+
grid: ReelGrid;
|
|
704
|
+
resolve: SymbolResolver;
|
|
705
|
+
cfg: ReelSystemConfig;
|
|
706
|
+
/** Overlay layer above the grid for rings/labels/sprites. */
|
|
707
|
+
fx: Container;
|
|
708
|
+
/** Mutable view of the current board (featureN may rewrite it). */
|
|
709
|
+
board: CellData[][];
|
|
710
|
+
/** Whether the current spin is a free-spin (gates onlyInFreeSpins features). */
|
|
711
|
+
freeSpins?: boolean;
|
|
712
|
+
/** Emit a human-readable note for the playground log. */
|
|
713
|
+
log?: (msg: string) => void;
|
|
714
|
+
}
|
|
715
|
+
interface ReelFeature {
|
|
716
|
+
/** Unique id. Built-ins use a `FeatureKey`; custom features may use any string. */
|
|
717
|
+
readonly key: FeatureKey | string;
|
|
718
|
+
readonly label: string;
|
|
719
|
+
/** Whether this feature is active for the given config. Custom features can just return `true`. */
|
|
720
|
+
enabled(cfg: ReelSystemConfig): boolean;
|
|
721
|
+
/** Run the feature presentation on the current board. */
|
|
722
|
+
demo(ctx: FeatureContext): Promise<void>;
|
|
723
|
+
}
|
|
724
|
+
|
|
725
|
+
/** All feature modules keyed by their FeatureKey. */
|
|
726
|
+
declare const FEATURES: Record<FeatureKey, ReelFeature>;
|
|
727
|
+
/** Features in canonical resolve order (see docs §3.4). */
|
|
728
|
+
declare const FEATURE_LIST: ReelFeature[];
|
|
729
|
+
|
|
730
|
+
interface CreateReelSystemOptions {
|
|
731
|
+
resolve: SymbolResolver;
|
|
732
|
+
config?: DeepPartial<ReelSystemConfig>;
|
|
733
|
+
/** Initial board (board[col][row]); defaults to empty cells. */
|
|
734
|
+
board?: CellData[][];
|
|
735
|
+
log?: (msg: string) => void;
|
|
736
|
+
/** Custom feature modules to register alongside the 13 built-ins. */
|
|
737
|
+
features?: ReelFeature[];
|
|
738
|
+
}
|
|
739
|
+
interface ReelSystem {
|
|
740
|
+
/** Root container — add this to your scene. */
|
|
741
|
+
readonly view: Container;
|
|
742
|
+
readonly grid: ReelGrid;
|
|
743
|
+
/** Overlay layer above the grid (masked off) — draw bespoke rings/labels/sprites here. */
|
|
744
|
+
readonly fx: Container;
|
|
745
|
+
readonly config: ReelSystemConfig;
|
|
746
|
+
/** Current board (board[col][row]). */
|
|
747
|
+
readonly board: CellData[][];
|
|
748
|
+
/** Ways-to-win for the current grid (ways/megaways evaluation). */
|
|
749
|
+
readonly ways: number;
|
|
750
|
+
setBoard(board: CellData[][]): void;
|
|
751
|
+
/** Merge a partial config; rebuilds the grid when geometry changes. */
|
|
752
|
+
update(partial: DeepPartial<ReelSystemConfig>): void;
|
|
753
|
+
/** Replace the whole config. */
|
|
754
|
+
setConfig(config: ReelSystemConfig): void;
|
|
755
|
+
spin(target: CellData[][], opts?: SpinRunOpts): Promise<void>;
|
|
756
|
+
/** Run a cascade chain. With `freeSpins` + `cascade.multiplier.persistInFreeSpins`, the multiplier carries over instead of resetting. */
|
|
757
|
+
cascade(steps: TumbleStep[], opts?: {
|
|
758
|
+
turbo?: boolean;
|
|
759
|
+
freeSpins?: boolean;
|
|
760
|
+
}): Promise<void>;
|
|
761
|
+
/** Current running cascade multiplier. */
|
|
762
|
+
readonly multiplier: number;
|
|
763
|
+
/** Register a custom feature (or override a built-in by reusing its key). */
|
|
764
|
+
registerFeature(feature: ReelFeature): void;
|
|
765
|
+
/** All registered features (built-ins + custom) in canonical order. */
|
|
766
|
+
features(): ReelFeature[];
|
|
767
|
+
/** Enabled feature modules (built-ins + custom). */
|
|
768
|
+
enabledFeatures(): ReelFeature[];
|
|
769
|
+
/** Run a feature by key — built-in `FeatureKey` or a custom feature's key. */
|
|
770
|
+
runFeature(key: FeatureKey | string, opts?: {
|
|
771
|
+
freeSpins?: boolean;
|
|
772
|
+
}): Promise<void>;
|
|
773
|
+
/** Build a FeatureContext for driving a feature/bespoke animation yourself. */
|
|
774
|
+
featureContext(opts?: {
|
|
775
|
+
freeSpins?: boolean;
|
|
776
|
+
}): FeatureContext;
|
|
777
|
+
resize(cellSize: number): void;
|
|
778
|
+
skip(): void;
|
|
779
|
+
destroy(): void;
|
|
780
|
+
}
|
|
781
|
+
declare function createReelSystem(opts: CreateReelSystemOptions): ReelSystem;
|
|
782
|
+
|
|
233
783
|
interface WinTier {
|
|
234
784
|
id: string;
|
|
235
785
|
minMultiplier: number;
|
|
@@ -329,5 +879,5 @@ declare class MultiplierAccumulator {
|
|
|
329
879
|
reset(boundary: CarryPolicy): void;
|
|
330
880
|
}
|
|
331
881
|
|
|
332
|
-
export { AnimatedSymbol, BigWinOverlay, CascadeController, CountUpDisplay, FreeSpinsSession, MultiplierAccumulator, ReelGrid, ReelSpinController, SymbolCell, pickTier, tierIndexAtValue, valueAt };
|
|
333
|
-
export type { AnimatedSymbolConfig, BigWinOverlayConfig, CarryPolicy, CascadeAnim, CascadeStepData, CascadeTimings, CellData, CellFrameStyle, CellState, CountUpConfig, DecorationConfig, FreeSpinsSessionConfig, ReelGridConfig, ReelSpinData, ReelSpinTimings, ReelStopPlan, SymbolCellConfig, SymbolResolver, SymbolTextures, SymbolView, WinTier };
|
|
882
|
+
export { AnimatedSymbol, AnticipationController, BigWinOverlay, CascadeController, CountUpDisplay, DEFAULT_REEL_CONFIG, EASING_BY_NAME, FEATURES, FEATURE_KEYS, FEATURE_LIST, FreeSpinsSession, INTENSITY_SCALE, MultiplierAccumulator, PRESETS, PRESET_LIST, ReelGrid, ReelSpinController, SpinEngine, SymbolCell, TumbleController, createReelSystem, easingByName, effectiveRowsPerReel, mergeReelConfig, pickTier, resolveReelConfig, tierIndexAtValue, valueAt, waysCount };
|
|
883
|
+
export type { AnimatedSymbolConfig, AnticipationConfig, AnticipationDecision, BigWinOverlayConfig, BlurConfig, CarryPolicy, CascadeAnim, CascadeConfig, CascadeStepData, CascadeTimings, CellData, CellFrameStyle, CellState, CountUpConfig, CreateReelSystemOptions, DecorationConfig, DeepPartial, EasingName, EvaluationMode, ExpandingWildConfig, FeatureContext, FeatureKey, FeaturesConfig, FreeSpinsSessionConfig, GiantConfig, GridConfig, HoldAndSpinConfig, Intensity, MotionConfig, MotionStyle, MultiplierConfig, MysteryConfig, NudgeConfig, PresetId, RandomWildConfig, ReelFeature, ReelGridConfig, ReelModifierConfig, ReelPreset, ReelSpinData, ReelSpinTimings, ReelStopPlan$1 as ReelStopPlan, ReelSystem, ReelSystemConfig, SettleConfig, SpinData, SpinRunOpts, ReelStopPlan as SpinStopPlan, SplitConfig, SquashConfig, StackedConfig, StickyConfig, StopMode, StopOrder, SymbolCellConfig, SymbolResolver, SymbolTextures, SymbolView, TransformConfig, TumbleStep, WalkingWildConfig, WinConfig, WinTier };
|