@energy8platform/game-engine 0.38.0 → 0.40.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 +82 -2
- package/dist/devtools.cjs.js +36 -4
- package/dist/devtools.cjs.js.map +1 -1
- package/dist/devtools.d.ts +67 -0
- package/dist/devtools.esm.js +36 -4
- package/dist/devtools.esm.js.map +1 -1
- package/dist/host.cjs.js +276 -109
- package/dist/host.cjs.js.map +1 -1
- package/dist/host.d.ts +5 -0
- package/dist/host.esm.js +276 -109
- package/dist/host.esm.js.map +1 -1
- package/dist/reel-panel-client.cjs.js +36 -4
- package/dist/reel-panel-client.cjs.js.map +1 -1
- package/dist/reel-panel-client.esm.js +36 -4
- package/dist/reel-panel-client.esm.js.map +1 -1
- package/dist/slot.cjs.js +229 -43
- package/dist/slot.cjs.js.map +1 -1
- package/dist/slot.d.ts +123 -8
- package/dist/slot.esm.js +229 -44
- package/dist/slot.esm.js.map +1 -1
- package/package.json +2 -2
- package/src/host/autoplay.ts +25 -3
- package/src/host/connectionRecovery.ts +113 -0
- package/src/host/createSlotGame.ts +83 -103
- package/src/host/playError.ts +23 -0
- package/src/host/resumeDrain.ts +156 -0
- package/src/host/shellConfig.ts +9 -0
- package/src/slot/config/ReelSystemConfig.ts +96 -4
- package/src/slot/devtools/fieldSchema.ts +7 -0
- package/src/slot/index.ts +5 -0
- package/src/slot/motion/AnticipationController.ts +62 -17
- package/src/slot/motion/SpinEngine.ts +151 -23
- package/src/slot/system/ReelSystem.ts +59 -9
package/dist/slot.d.ts
CHANGED
|
@@ -366,6 +366,14 @@ declare function easingByName(name?: string): EasingFunction;
|
|
|
366
366
|
|
|
367
367
|
/** Names of easing functions available in the engine's `Easing` map (see anim/easing-map.ts). */
|
|
368
368
|
type EasingName = 'linear' | 'easeInQuad' | 'easeOutQuad' | 'easeInOutQuad' | 'easeInCubic' | 'easeOutCubic' | 'easeInOutCubic' | 'easeInBack' | 'easeOutBack' | 'easeInOutBack' | 'easeOutBounce' | 'easeInBounce' | 'easeOutElastic' | 'easeInSine' | 'easeOutSine' | 'easeInOutSine';
|
|
369
|
+
/**
|
|
370
|
+
* A value that is either flat across the board, or per-reel: an array indexed by REEL INDEX
|
|
371
|
+
* (holes fall back to the scalar default). Used for anticipation timings so a game can make
|
|
372
|
+
* each successive reel slower than the last.
|
|
373
|
+
*/
|
|
374
|
+
type PerReel<T> = T | (T | undefined)[];
|
|
375
|
+
/** Resolve a `PerReel<T>` for one reel. `undefined` (or a hole in the array) yields `fallback`. */
|
|
376
|
+
declare function perReelValue<T>(value: PerReel<T> | undefined, reel: number, fallback: T): T;
|
|
369
377
|
/** Win-evaluation model. Purely presentational here (affects geometry + highlight), the math lives in Lua. */
|
|
370
378
|
type EvaluationMode = 'lines' | 'ways' | 'anywhere' | 'cluster' | 'megaways' | 'infinity';
|
|
371
379
|
interface GridConfig {
|
|
@@ -403,6 +411,10 @@ interface GridConfig {
|
|
|
403
411
|
}
|
|
404
412
|
type MotionStyle = 'swap' | 'strip' | 'cascade-drop';
|
|
405
413
|
type StopMode = 'sequential' | 'sync' | 'random';
|
|
414
|
+
/** `cascade-drop` fill direction within one reel. */
|
|
415
|
+
type DropOrder = 'top-down' | 'bottom-up';
|
|
416
|
+
/** How `cascade-drop` spaces reels: by formula, or one strictly after the other. */
|
|
417
|
+
type DropSequence = 'parallel' | 'chained' | 'chained-when-anticipated';
|
|
406
418
|
type StopOrder = 'ltr' | 'rtl';
|
|
407
419
|
type Intensity = 'full' | 'reduced' | 'minimal';
|
|
408
420
|
interface SettleConfig {
|
|
@@ -448,6 +460,40 @@ interface MotionConfig {
|
|
|
448
460
|
slamStop: boolean;
|
|
449
461
|
/** Symbols visible on a reel tape while spinning (swap/strip). */
|
|
450
462
|
symbolsPerReel: number;
|
|
463
|
+
/** `cascade-drop`: ms between consecutive cells of ONE reel (top→bottom). Default 24. */
|
|
464
|
+
cellStagger: number;
|
|
465
|
+
/** `cascade-drop`: multiplier on `stopStagger` for the per-reel offset. Default 0.4. */
|
|
466
|
+
reelStaggerFactor: number;
|
|
467
|
+
/** `cascade-drop`: fall duration as a fraction of `spinUp`. Default 0.6. */
|
|
468
|
+
dropFallFactor: number;
|
|
469
|
+
/**
|
|
470
|
+
* `cascade-drop`: which cell of a reel lands first. `'top-down'` (default, the engine's original
|
|
471
|
+
* behaviour) deals the reel like cards from the top; `'bottom-up'` fills it the way gravity
|
|
472
|
+
* would — the lowest cell arrives first and the rest stack on top of it.
|
|
473
|
+
*/
|
|
474
|
+
dropOrder: DropOrder;
|
|
475
|
+
/**
|
|
476
|
+
* `cascade-drop`: how reels are spaced.
|
|
477
|
+
* - `'parallel'` (default) starts every reel at its own formula offset —
|
|
478
|
+
* `reel * stopStagger * reelStaggerFactor` — so a reel can open while the previous one is
|
|
479
|
+
* still dropping. Fast, and what a normal spin wants.
|
|
480
|
+
* - `'chained'` starts a reel only once the previous one has seated its LAST cell, plus that
|
|
481
|
+
* same offset as the gap. One reel at a time, always — correct, but it makes every spin as
|
|
482
|
+
* long as the sum of its reels.
|
|
483
|
+
* - `'chained-when-anticipated'` runs the un-armed reels in parallel and switches to the chain
|
|
484
|
+
* from the first ANTICIPATED reel onwards. The base spin keeps its stop window; the hunt for
|
|
485
|
+
* the last scatter goes strictly reel by reel, each slower than the last.
|
|
486
|
+
*/
|
|
487
|
+
dropSequence: DropSequence;
|
|
488
|
+
}
|
|
489
|
+
/** What a game-supplied `AnticipationConfig.decide` may return instead of a bare reel list. */
|
|
490
|
+
interface AnticipationOverride {
|
|
491
|
+
/** Reels to anticipate, in the order the progression should ramp. Empty = no anticipation. */
|
|
492
|
+
reels: number[];
|
|
493
|
+
/** Speed factor (lower = slower). Scalar, or per-reel indexed by reel index. */
|
|
494
|
+
slowdown?: PerReel<number>;
|
|
495
|
+
/** Extra hold before landing. Scalar, or per-reel indexed by reel index. */
|
|
496
|
+
holdMs?: PerReel<number>;
|
|
451
497
|
}
|
|
452
498
|
interface AnticipationConfig {
|
|
453
499
|
enabled: boolean;
|
|
@@ -461,6 +507,21 @@ interface AnticipationConfig {
|
|
|
461
507
|
slowdownFactor: number;
|
|
462
508
|
/** Extra hold (ms) before the final anticipation reel lands (300–500 typical). */
|
|
463
509
|
holdMs: number;
|
|
510
|
+
/**
|
|
511
|
+
* Game-supplied decision, REPLACING the built-in `triggerSymbols`/`threshold` counting.
|
|
512
|
+
* Return the reels to anticipate (or an `AnticipationOverride`); `null` / `[]` = no anticipation.
|
|
513
|
+
* Use this when the trigger is not expressible as "N of symbol X landed" — e.g. "the round is
|
|
514
|
+
* still alive on every reel so far", or "reel 3 missed its symbol, so let 4 and 5 stop normally".
|
|
515
|
+
*/
|
|
516
|
+
decide?: ((targetGrid: CellData[][]) => number[] | AnticipationOverride | null) | null;
|
|
517
|
+
/**
|
|
518
|
+
* Ramp the slowdown across successive anticipated reels: reel #i of the decision gets
|
|
519
|
+
* `slowdownFactor * progressiveSlowdown ** i`. 1 = flat (default); < 1 = each reel slower
|
|
520
|
+
* than the last.
|
|
521
|
+
*/
|
|
522
|
+
progressiveSlowdown: number;
|
|
523
|
+
/** Extra hold (ms) added per successive anticipated reel: reel #i gets `holdMs + i * this`. */
|
|
524
|
+
progressiveHoldMs: number;
|
|
464
525
|
/** Optional grid zoom while anticipating (magnum-opus uses 1.3×). */
|
|
465
526
|
zoom: {
|
|
466
527
|
enabled: boolean;
|
|
@@ -701,8 +762,25 @@ interface SpinRunOpts {
|
|
|
701
762
|
turbo?: boolean;
|
|
702
763
|
/** Reels to slow for anticipation (computed by the ReelSystem from config + targetGrid). */
|
|
703
764
|
anticipateReels?: number[];
|
|
704
|
-
|
|
705
|
-
|
|
765
|
+
/** Speed factor for anticipated reels (lower = slower). Scalar, or per-reel indexed by reel. */
|
|
766
|
+
anticipateSlowdown?: PerReel<number>;
|
|
767
|
+
/** Extra hold (ms) for anticipated reels. Scalar, or per-reel indexed by reel. */
|
|
768
|
+
anticipateHoldMs?: PerReel<number>;
|
|
769
|
+
/**
|
|
770
|
+
* Reels whose tape runs normally but whose landing is NOT handed back. The engine stops and
|
|
771
|
+
* disposes of the tape as usual and leaves the real cells hidden and unseated; the caller owns
|
|
772
|
+
* their data and visibility from that point (and `skip()` will not reveal them either).
|
|
773
|
+
*/
|
|
774
|
+
deferReveal?: number[];
|
|
775
|
+
/** The resolved schedule, handed over before the first frame runs. Schedule against THESE
|
|
776
|
+
* numbers rather than re-deriving `plan()`'s formula. */
|
|
777
|
+
onPlan?: (plan: ReelStopPlan[]) => void;
|
|
778
|
+
/** Fires on the frame a reel lands — after its cells are seated, before settle/squash/shake.
|
|
779
|
+
* For a deferred reel it still fires (the reel DID stop); nothing was seated. */
|
|
780
|
+
onReelStop?: (reel: number, plan: ReelStopPlan) => void;
|
|
781
|
+
/** Fires as each cell takes its landing symbol. In `cascade-drop` this is the per-cell impact
|
|
782
|
+
* frame (after the fall, before the squash) — the hook for a per-cell sound or shake. */
|
|
783
|
+
onCellSeated?: (reel: number, row: number, data: CellData) => void;
|
|
706
784
|
}
|
|
707
785
|
interface ReelStopPlan {
|
|
708
786
|
reel: number;
|
|
@@ -714,6 +792,17 @@ interface ReelStopPlan {
|
|
|
714
792
|
ms: number;
|
|
715
793
|
};
|
|
716
794
|
anticipated: boolean;
|
|
795
|
+
/** Time-stretch applied to this reel's tape (>= 1, longer = slower). 1 when not anticipated. */
|
|
796
|
+
slowdown: number;
|
|
797
|
+
/** True when `deferReveal` withheld this reel's landing (see `SpinRunOpts.deferReveal`). */
|
|
798
|
+
deferred: boolean;
|
|
799
|
+
/**
|
|
800
|
+
* `cascade-drop` only: ms from spin start at which each cell of this reel seats, INDEXED BY ROW.
|
|
801
|
+
* The reel's fill direction lives in these numbers (`motion.dropOrder` decides which row is the
|
|
802
|
+
* smallest), as does its place in the chain (`motion.dropSequence`). `stopTime` is the largest
|
|
803
|
+
* of them — the frame the whole reel has landed.
|
|
804
|
+
*/
|
|
805
|
+
cellStopTimes?: number[];
|
|
717
806
|
}
|
|
718
807
|
declare class SpinEngine {
|
|
719
808
|
private _grid;
|
|
@@ -723,6 +812,7 @@ declare class SpinEngine {
|
|
|
723
812
|
private _killed;
|
|
724
813
|
private _shaking;
|
|
725
814
|
private _temp;
|
|
815
|
+
private _deferred;
|
|
726
816
|
constructor(grid: ReelGrid, resolve: SymbolResolver, cfg: MotionConfig, win?: WinConfig);
|
|
727
817
|
setConfig(cfg: MotionConfig): void;
|
|
728
818
|
setWin(win: WinConfig): void;
|
|
@@ -731,10 +821,17 @@ declare class SpinEngine {
|
|
|
731
821
|
private scale;
|
|
732
822
|
/** PURE: per-reel stop schedule. No Pixi mutation. */
|
|
733
823
|
plan(data: SpinData, opts?: SpinRunOpts): ReelStopPlan[];
|
|
824
|
+
/**
|
|
825
|
+
* `cascade-drop` lays its reels out on a different clock from the tape styles: a reel is a
|
|
826
|
+
* sequence of per-cell arrivals, not one deceleration. Overwrite `stopTime` with the moment the
|
|
827
|
+
* reel has fully landed and fill in `cellStopTimes`, so `plan()` stays the single source of truth
|
|
828
|
+
* for WHEN anything happens — `_runDrop` below only executes these numbers.
|
|
829
|
+
*/
|
|
830
|
+
private _planDrop;
|
|
734
831
|
/** Execute the spin for every reel concurrently. */
|
|
735
832
|
run(data: SpinData, opts?: SpinRunOpts): Promise<void>;
|
|
736
833
|
private _runReel;
|
|
737
|
-
/** Anticipation time-stretch factor for a reel (>=1, longer = slower). */
|
|
834
|
+
/** Anticipation time-stretch factor for a reel (>=1, longer = slower). Resolved in `plan()`. */
|
|
738
835
|
private slowOf;
|
|
739
836
|
private _runSwap;
|
|
740
837
|
private _runStrip;
|
|
@@ -750,10 +847,13 @@ declare class SpinEngine {
|
|
|
750
847
|
|
|
751
848
|
interface AnticipationDecision {
|
|
752
849
|
active: boolean;
|
|
753
|
-
/** Reel indices that should spin slower / longer. */
|
|
850
|
+
/** Reel indices that should spin slower / longer, in the order the ramp applies. */
|
|
754
851
|
reels: number[];
|
|
755
|
-
|
|
756
|
-
|
|
852
|
+
/** Speed factor. A scalar when flat; a per-reel array when the decision ramps (see
|
|
853
|
+
* `progressiveSlowdown` / a game-supplied `decide`). Resolve with `perReelValue`. */
|
|
854
|
+
slowdown: PerReel<number>;
|
|
855
|
+
/** Extra hold before landing. Scalar or per-reel array, same as `slowdown`. */
|
|
856
|
+
holdMs: PerReel<number>;
|
|
757
857
|
}
|
|
758
858
|
declare class AnticipationController {
|
|
759
859
|
private _cfg;
|
|
@@ -767,6 +867,13 @@ declare class AnticipationController {
|
|
|
767
867
|
* is flagged for the slow treatment (this mirrors "searching for the last scatter").
|
|
768
868
|
*/
|
|
769
869
|
decide(targetGrid: CellData[][]): AnticipationDecision;
|
|
870
|
+
/** Assemble a decision, applying the configured progression unless the caller pinned values. */
|
|
871
|
+
private build;
|
|
872
|
+
/**
|
|
873
|
+
* A flat scalar when the progression is a no-op, else an array INDEXED BY REEL so the engine can
|
|
874
|
+
* read a per-reel value straight out of `plan()`.
|
|
875
|
+
*/
|
|
876
|
+
private ramp;
|
|
770
877
|
/** Optionally zoom the grid in while anticipating, then settle back. Returns a reset fn. */
|
|
771
878
|
zoomIn(grid: ReelGrid): Promise<() => Promise<void>>;
|
|
772
879
|
}
|
|
@@ -947,6 +1054,14 @@ interface ReelSystem {
|
|
|
947
1054
|
/** Replace the whole config. */
|
|
948
1055
|
setConfig(config: ReelSystemConfig): void;
|
|
949
1056
|
spin(target: CellData[][], opts?: SpinRunOpts): Promise<void>;
|
|
1057
|
+
/**
|
|
1058
|
+
* The schedule `spin(target, opts)` WOULD run, without running it — same anticipation decision,
|
|
1059
|
+
* same numbers. Schedule landing sounds / camera moves against this instead of re-deriving the
|
|
1060
|
+
* engine's formula. (`spin`'s `onPlan` hands you the same array once the spin is under way.)
|
|
1061
|
+
*/
|
|
1062
|
+
planSpin(target: CellData[][], opts?: SpinRunOpts): ReelStopPlan[];
|
|
1063
|
+
/** The anticipation decision `spin(target, opts)` would use (run options override the config). */
|
|
1064
|
+
anticipationFor(target: CellData[][], opts?: SpinRunOpts): AnticipationDecision;
|
|
950
1065
|
/** Run a cascade chain. With `freeSpins` + `cascade.multiplier.persistInFreeSpins`, the multiplier
|
|
951
1066
|
* carries over instead of resetting. Generic in the step type, so `onStep` hands back the game's
|
|
952
1067
|
* own step (with its per-step win) rather than the bare TumbleStep. */
|
|
@@ -1056,5 +1171,5 @@ declare class MultiplierAccumulator {
|
|
|
1056
1171
|
reset(boundary: CarryPolicy): void;
|
|
1057
1172
|
}
|
|
1058
1173
|
|
|
1059
|
-
export { AnimatedSymbol, AnticipationController, BigWinOverlay, CascadeController, CountUpDisplay, DEFAULT_REEL_CONFIG, EASING_BY_NAME, FEATURES, FEATURE_KEYS, FEATURE_LIST, INTENSITY_SCALE, MultiplierAccumulator, PRESETS, PRESET_LIST, ReelGrid, ReelSpinController, ReelStepController, SpinEngine, SymbolCell, TumbleController, buildReelStepTape, cellPositionOf, createReelSystem, easingByName, effectiveRowsPerReel, mergeReelConfig, pickTier, resolveGeometry, resolveGridGeometry, resolveReelConfig, tierIndexAtValue, valueAt, waysCount };
|
|
1060
|
-
export type { AnimatedSymbolConfig, AnticipationConfig, AnticipationDecision, BigWinOverlayConfig, BlurConfig, CarryPolicy, CascadeAnim, CascadeConfig, CascadeStepData, CascadeTimings, CellData, CellFrameStyle, CellSizeSpec, CellState, CountUpConfig, CreateReelSystemOptions, DecorationConfig, DeepPartial, EasingName, EvaluationMode, ExpandingWildConfig, FeatureContext, FeatureKey, FeaturesConfig, GeometryInput, GiantConfig, GridConfig, HoldAndSpinConfig, Intensity, MotionConfig, MotionStyle, MultiplierConfig, MysteryConfig, NudgeConfig, PresetId, RandomWildConfig, ReelFeature, ReelGridConfig, ReelModifierConfig, ReelPreset, ReelSpinData, ReelSpinTimings, ReelStepData, ReelStopPlan$1 as ReelStopPlan, ReelSystem, ReelSystemConfig, ResolvedGeometry, SettleConfig, SpinData, SpinRunOpts, ReelStopPlan as SpinStopPlan, SplitConfig, SquashConfig, StackedConfig, StepRunOpts, StickyConfig, StopMode, StopOrder, SymbolCellConfig, SymbolResolver, SymbolTextures, SymbolView, TransformConfig, TumbleStep, WalkingWildConfig, WinConfig, WinTier };
|
|
1174
|
+
export { AnimatedSymbol, AnticipationController, BigWinOverlay, CascadeController, CountUpDisplay, DEFAULT_REEL_CONFIG, EASING_BY_NAME, FEATURES, FEATURE_KEYS, FEATURE_LIST, INTENSITY_SCALE, MultiplierAccumulator, PRESETS, PRESET_LIST, ReelGrid, ReelSpinController, ReelStepController, SpinEngine, SymbolCell, TumbleController, buildReelStepTape, cellPositionOf, createReelSystem, easingByName, effectiveRowsPerReel, mergeReelConfig, perReelValue, pickTier, resolveGeometry, resolveGridGeometry, resolveReelConfig, tierIndexAtValue, valueAt, waysCount };
|
|
1175
|
+
export type { AnimatedSymbolConfig, AnticipationConfig, AnticipationDecision, AnticipationOverride, BigWinOverlayConfig, BlurConfig, CarryPolicy, CascadeAnim, CascadeConfig, CascadeStepData, CascadeTimings, CellData, CellFrameStyle, CellSizeSpec, CellState, CountUpConfig, CreateReelSystemOptions, DecorationConfig, DeepPartial, DropOrder, DropSequence, EasingName, EvaluationMode, ExpandingWildConfig, FeatureContext, FeatureKey, FeaturesConfig, GeometryInput, GiantConfig, GridConfig, HoldAndSpinConfig, Intensity, MotionConfig, MotionStyle, MultiplierConfig, MysteryConfig, NudgeConfig, PerReel, PresetId, RandomWildConfig, ReelFeature, ReelGridConfig, ReelModifierConfig, ReelPreset, ReelSpinData, ReelSpinTimings, ReelStepData, ReelStopPlan$1 as ReelStopPlan, ReelSystem, ReelSystemConfig, ResolvedGeometry, SettleConfig, SpinData, SpinRunOpts, ReelStopPlan as SpinStopPlan, SplitConfig, SquashConfig, StackedConfig, StepRunOpts, StickyConfig, StopMode, StopOrder, SymbolCellConfig, SymbolResolver, SymbolTextures, SymbolView, TransformConfig, TumbleStep, WalkingWildConfig, WinConfig, WinTier };
|