@energy8platform/game-engine 0.18.0 → 0.20.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/dist/audio.cjs.js +15 -5
- package/dist/audio.cjs.js.map +1 -1
- package/dist/audio.d.ts +5 -0
- package/dist/audio.esm.js +15 -5
- package/dist/audio.esm.js.map +1 -1
- package/dist/core.cjs.js +79 -174
- package/dist/core.cjs.js.map +1 -1
- package/dist/core.d.ts +13 -1
- package/dist/core.esm.js +80 -175
- package/dist/core.esm.js.map +1 -1
- package/dist/host.cjs.js +401 -251
- package/dist/host.cjs.js.map +1 -1
- package/dist/host.d.ts +117 -26
- package/dist/host.esm.js +403 -253
- package/dist/host.esm.js.map +1 -1
- package/dist/index.cjs.js +79 -174
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +23 -12
- package/dist/index.esm.js +80 -175
- package/dist/index.esm.js.map +1 -1
- package/dist/react.d.ts +13 -1
- package/package.json +3 -2
- package/src/audio/AudioManager.ts +17 -5
- package/src/core/GameApplication.ts +28 -10
- package/src/host/createSlotGame.ts +143 -23
- package/src/host/index.ts +4 -1
- package/src/host/overlayController.ts +81 -0
- package/src/host/pauseController.ts +21 -0
- package/src/host/runRound.ts +35 -43
- package/src/host/sceneAudio.ts +14 -0
- package/src/host/sceneController.ts +84 -19
- package/src/host/shellConfig.ts +53 -35
- package/src/host/skipGesture.ts +24 -0
- package/src/host/types.ts +5 -2
- package/src/loading/LoadingScene.ts +31 -174
- package/src/viewport/ViewportManager.ts +19 -9
package/dist/host.d.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { Container, ApplicationOptions, Application, Texture } from 'pixi.js';
|
|
2
2
|
import { GameModel } from '@energy8platform/platform-core/game-spec';
|
|
3
3
|
import { LoadingScreenConfig, AssetManifest, PlatformSession } from '@energy8platform/platform-core';
|
|
4
|
+
import { CurrencyConfig, GameInfoContent, BonusOption, ShellFeatures, ShellMode, PixiShellConfig, PixiGameShell } from '@energy8platform/pixi-shell';
|
|
4
5
|
import * as _energy8platform_platform_core_shell from '@energy8platform/platform-core/shell';
|
|
5
|
-
import {
|
|
6
|
+
import { Lang } from '@energy8platform/platform-core/shell';
|
|
6
7
|
export { socialize } from '@energy8platform/platform-core/shell';
|
|
7
8
|
import { BookAdapter, AdapterModule, StakeBridge } from '@energy8platform/stake-bridge';
|
|
8
9
|
import { CasinoGameSDK, InitData, GameConfigData, SessionData } from '@energy8platform/game-sdk';
|
|
@@ -333,6 +334,7 @@ declare class AudioManager {
|
|
|
333
334
|
private _persist;
|
|
334
335
|
private _storageKey;
|
|
335
336
|
private _categories;
|
|
337
|
+
private _masterGain;
|
|
336
338
|
private _currentMusic;
|
|
337
339
|
private _unlocked;
|
|
338
340
|
private _unlockHandler;
|
|
@@ -373,6 +375,10 @@ declare class AudioManager {
|
|
|
373
375
|
* Stop all sounds.
|
|
374
376
|
*/
|
|
375
377
|
stopAll(): void;
|
|
378
|
+
/** Global gain (0..1) folded into every category's effective volume. Driven by the shell's
|
|
379
|
+
* 'master' settingChange. Does not affect the persisted per-category volumes. */
|
|
380
|
+
setMasterVolume(volume: number): void;
|
|
381
|
+
getMasterVolume(): number;
|
|
376
382
|
/**
|
|
377
383
|
* Set volume for a category.
|
|
378
384
|
*/
|
|
@@ -575,6 +581,7 @@ declare class ViewportManager extends EventEmitter<ViewportEvents> {
|
|
|
575
581
|
private _app;
|
|
576
582
|
private _container;
|
|
577
583
|
private _config;
|
|
584
|
+
private _target;
|
|
578
585
|
private _resizeObserver;
|
|
579
586
|
private _currentOrientation;
|
|
580
587
|
private _currentWidth;
|
|
@@ -582,7 +589,7 @@ declare class ViewportManager extends EventEmitter<ViewportEvents> {
|
|
|
582
589
|
private _currentScale;
|
|
583
590
|
private _destroyed;
|
|
584
591
|
private _resizeTimeout;
|
|
585
|
-
constructor(app: Application, container: HTMLElement, config: ViewportConfig);
|
|
592
|
+
constructor(app: Application, container: HTMLElement, config: ViewportConfig, target?: Container);
|
|
586
593
|
/** Current canvas width in game units */
|
|
587
594
|
get width(): number;
|
|
588
595
|
/** Current canvas height in game units */
|
|
@@ -683,6 +690,12 @@ declare class GameApplication extends EventEmitter<GameEngineEvents> {
|
|
|
683
690
|
input: InputManager;
|
|
684
691
|
/** Viewport manager */
|
|
685
692
|
viewport: ViewportManager;
|
|
693
|
+
/** Scaled world root (holds scenes). Transformed by the ViewportManager to fit the design
|
|
694
|
+
* resolution; lives below the UI layer on app.stage. */
|
|
695
|
+
worldRoot: Container;
|
|
696
|
+
/** Unscaled, screen-space UI layer. Sits above {@link worldRoot} and is NOT touched by the
|
|
697
|
+
* viewport transform — children fill the real screen (e.g. the host's shell + overlay). */
|
|
698
|
+
uiLayer: Container;
|
|
686
699
|
/** SDK instance (null in offline mode) */
|
|
687
700
|
sdk: CasinoGameSDK | null;
|
|
688
701
|
/** FPS overlay instance (only when debug: true) */
|
|
@@ -737,7 +750,6 @@ interface WinTier {
|
|
|
737
750
|
}
|
|
738
751
|
|
|
739
752
|
interface SlotShellOptions {
|
|
740
|
-
mount?: HTMLElement;
|
|
741
753
|
/** Override the derived currency (normally taken from initData). */
|
|
742
754
|
currency?: CurrencyConfig;
|
|
743
755
|
/** Author-supplied info sections, MERGED over the host-derived set by section identity (an author
|
|
@@ -754,6 +766,11 @@ interface SlotShellOptions {
|
|
|
754
766
|
buyBonus?: BonusOption[];
|
|
755
767
|
tiers?: WinTier[];
|
|
756
768
|
features?: Partial<ShellFeatures>;
|
|
769
|
+
/** Per-game translation map. Keys are the English source strings (from the spec or copy);
|
|
770
|
+
* values are the translated strings for each language. Merged with the shell's built-in
|
|
771
|
+
* `LOCALES` catalog — game strings take precedence over the built-in entries for the same key.
|
|
772
|
+
* When not supplied, English source strings pass through verbatim (socialised in social mode). */
|
|
773
|
+
i18n?: Partial<Record<Lang, Record<string, string>>>;
|
|
757
774
|
}
|
|
758
775
|
/** Runtime context from the SDK handshake (initData) + the resolved mode. */
|
|
759
776
|
interface ShellRuntime {
|
|
@@ -795,8 +812,9 @@ interface JurisdictionRestrictions {
|
|
|
795
812
|
/** Total stake for an action = bet × the action's cost multiplier (1 for a base spin; e.g. 100 for
|
|
796
813
|
* a buy bonus). The host uses this to block a play the balance can't cover. */
|
|
797
814
|
declare function stakeForAction(model: GameModel, action: string, bet: number): number;
|
|
798
|
-
/** Pure: assemble
|
|
799
|
-
|
|
815
|
+
/** Pure: assemble the shell config (sans mount target) from the model + runtime context
|
|
816
|
+
* (currency/balance/language/mode). The host adds `app` at the call site. */
|
|
817
|
+
declare function buildShellConfig(opts: SlotShellOptions, model: GameModel, runtime: ShellRuntime): Omit<PixiShellConfig, 'app' | 'parent'>;
|
|
800
818
|
|
|
801
819
|
interface StakeIntegration {
|
|
802
820
|
/** The game's BookAdapter (or its module). modeMap + gameId come from the model. */
|
|
@@ -849,12 +867,15 @@ interface CreateSlotGameOptions<T extends SlotSpinResultBase = SlotSpinResultBas
|
|
|
849
867
|
dev?: boolean;
|
|
850
868
|
stake?: StakeIntegration;
|
|
851
869
|
shell?: SlotShellOptions;
|
|
870
|
+
/** Double-tap on the play area to skip the current spin animation. Default `true`. Set `false`
|
|
871
|
+
* to disable the gesture (e.g. games where a tap means something else). */
|
|
872
|
+
skipGesture?: boolean;
|
|
852
873
|
onFatalError?: (message: string) => void;
|
|
853
874
|
}
|
|
854
875
|
interface SlotGameHandle {
|
|
855
876
|
game: GameApplication;
|
|
856
877
|
stakeBridge: StakeBridge | null;
|
|
857
|
-
shell:
|
|
878
|
+
shell: PixiGameShell | null;
|
|
858
879
|
}
|
|
859
880
|
|
|
860
881
|
/**
|
|
@@ -882,34 +903,104 @@ declare function resolveReplayBonusId(model: GameModel, stakeMode: string): stri
|
|
|
882
903
|
*/
|
|
883
904
|
declare function resolveStartScene(scenes: SceneRegistration[], isReplay: boolean, explicitStart?: string): string;
|
|
884
905
|
|
|
885
|
-
/** Everything a scene needs to render one
|
|
906
|
+
/** Everything a scene needs to render one segment. The host builds it per segment. */
|
|
886
907
|
interface RenderContext {
|
|
887
|
-
/** Bet for this round (major units). Stable for the whole round
|
|
908
|
+
/** Bet for this round (major units). Stable for the whole round. */
|
|
888
909
|
bet: number;
|
|
889
|
-
/** Trigger action in the game's own vocabulary (
|
|
890
|
-
* 'buy_bonus' | … Stable for the whole round. */
|
|
910
|
+
/** Trigger action in the game's own vocabulary ('spin' | 'ante' | 'buy_bonus' | …). */
|
|
891
911
|
action: string;
|
|
892
|
-
/** Stake bet-mode of the round (
|
|
893
|
-
* Canonical per-round identifier of WHICH bonus/feature this is. Stable for the whole round. */
|
|
912
|
+
/** Stake bet-mode of the round ('BASE' | 'ANTE' | 'BONUS' | …). */
|
|
894
913
|
mode: string;
|
|
895
|
-
/** Currency-aware money formatter.
|
|
914
|
+
/** Currency-aware money formatter. */
|
|
896
915
|
formatAmount(value: number): string;
|
|
897
|
-
/** LIVE turbo level (0 = off, 1..3 = escalating speed)
|
|
898
|
-
* the moment of access (getter) so a mid-round toggle is reflected. */
|
|
916
|
+
/** LIVE turbo level (0 = off, 1..3 = escalating speed). Read at access. */
|
|
899
917
|
readonly turbo: number;
|
|
918
|
+
/** Aborted when the player skips this segment (double-tap). The scene's async pacing can race or
|
|
919
|
+
* cancel on it; on abort the scene must collapse to the segment's final visual state. */
|
|
920
|
+
signal: AbortSignal;
|
|
900
921
|
}
|
|
901
|
-
/**
|
|
902
|
-
|
|
922
|
+
/** Playback-only audio handle. Volume/mute are shell settings → host, never the scene. */
|
|
923
|
+
interface SceneAudio {
|
|
924
|
+
play(alias: string, opts?: {
|
|
925
|
+
volume?: number;
|
|
926
|
+
loop?: boolean;
|
|
927
|
+
speed?: number;
|
|
928
|
+
}): void;
|
|
929
|
+
playMusic(alias: string, fadeMs?: number): void;
|
|
930
|
+
stopMusic(): void;
|
|
931
|
+
duck(factor: number): void;
|
|
932
|
+
unduck(): void;
|
|
933
|
+
}
|
|
934
|
+
interface OverlayShowOptions {
|
|
935
|
+
/** Draw the overlay content into `container` (sized to the canvas). */
|
|
936
|
+
build(container: Container, size: {
|
|
937
|
+
width: number;
|
|
938
|
+
height: number;
|
|
939
|
+
}): void;
|
|
940
|
+
/** Auto-close after N ms (combine with closeOn — whichever fires first). */
|
|
941
|
+
autoCloseMs?: number;
|
|
942
|
+
/** Dismiss on a single tap. Default 'tap'. Set false to require an explicit close(). */
|
|
943
|
+
closeOn?: 'tap' | false;
|
|
944
|
+
/** Optional host-drawn backdrop alpha (0..1). Default: none (game draws its own). */
|
|
945
|
+
dim?: number;
|
|
946
|
+
}
|
|
947
|
+
/** Single host-owned layer above scene + shell. Eats pointer events so shell controls are
|
|
948
|
+
* unreachable while open. */
|
|
949
|
+
interface SceneOverlay {
|
|
950
|
+
/** Resolves when the overlay closes. Rejects if one is already open. */
|
|
951
|
+
show(opts: OverlayShowOptions): Promise<void>;
|
|
952
|
+
close(): void;
|
|
953
|
+
}
|
|
954
|
+
interface SceneShell {
|
|
955
|
+
/** Live insets (px). `bottom` = the shell bar height; read inside onResize. */
|
|
956
|
+
readonly safeArea: {
|
|
957
|
+
top: number;
|
|
958
|
+
right: number;
|
|
959
|
+
bottom: number;
|
|
960
|
+
left: number;
|
|
961
|
+
};
|
|
962
|
+
}
|
|
963
|
+
interface AutoplaySceneState {
|
|
964
|
+
running: boolean;
|
|
965
|
+
remaining: number;
|
|
966
|
+
}
|
|
967
|
+
/** Stable capabilities injected once via onCreate. */
|
|
968
|
+
interface SceneApi {
|
|
969
|
+
audio: SceneAudio;
|
|
970
|
+
overlay: SceneOverlay;
|
|
971
|
+
shell: SceneShell;
|
|
972
|
+
formatAmount(value: number): string;
|
|
973
|
+
readonly bet: number;
|
|
974
|
+
readonly mode: string;
|
|
975
|
+
readonly turbo: number;
|
|
976
|
+
}
|
|
977
|
+
/** The contract a slot scene implements. The HOST owns the play→present→ack→drain loop and the
|
|
978
|
+
* shell; the scene only renders + reacts. The core spin-lifecycle hooks are REQUIRED (implement
|
|
979
|
+
* them — empty bodies are fine where a game has nothing to do); the incidental reactions below
|
|
980
|
+
* stay optional. */
|
|
903
981
|
interface SlotSceneController<T extends SlotSpinResultBase = SlotSpinResultBase> {
|
|
904
|
-
/**
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
/**
|
|
911
|
-
|
|
982
|
+
/** Injected ONCE before the first round — capabilities, subscriptions, one-time setup. */
|
|
983
|
+
onCreate(api: SceneApi): void;
|
|
984
|
+
/** Fires once per round when the player presses spin (before the network result). */
|
|
985
|
+
onSpinStart(): void;
|
|
986
|
+
/** Render ONE segment (a spin or one free spin). Await your own pacing. */
|
|
987
|
+
onSpin(result: T, ctx: RenderContext): Promise<void>;
|
|
988
|
+
/** Fires when ctx.mode changes between segments (entering a non-BASE mode/bonus). */
|
|
989
|
+
onEnterMode(result: T, ctx: RenderContext): Promise<void>;
|
|
990
|
+
/** Fires when leaving a mode (back toward BASE). */
|
|
991
|
+
onExitMode(result: T, ctx: RenderContext): Promise<void>;
|
|
992
|
+
/** Fires once per round after the full drain (controls unlocked). */
|
|
993
|
+
onSpinEnd(result: T, ctx: RenderContext): void;
|
|
994
|
+
/** Shell events (may fire while idle) — optional. */
|
|
995
|
+
onBetChanged?(bet: number): void;
|
|
996
|
+
onTurboChanged?(level: number): void;
|
|
997
|
+
onAutoplayChanged?(state: AutoplaySceneState): void;
|
|
998
|
+
/** Double-tap skip during an active onSpin (gated by the skipGesture setting). */
|
|
999
|
+
onSkip?(): void;
|
|
1000
|
+
/** Tab focus lost / regained. */
|
|
1001
|
+
onPause?(): void;
|
|
1002
|
+
onResume?(): void;
|
|
912
1003
|
}
|
|
913
1004
|
|
|
914
1005
|
export { buildShellConfig, createSlotGame, resolveReplayBonusId, resolveStartScene, stakeForAction };
|
|
915
|
-
export type { CreateSlotGameOptions, RenderContext, SceneEntry, SceneNavData, SceneRegistration, SlotGameHandle, SlotSceneController, SlotShellOptions, StakeIntegration };
|
|
1006
|
+
export type { AutoplaySceneState, CreateSlotGameOptions, OverlayShowOptions, RenderContext, SceneApi, SceneAudio, SceneEntry, SceneNavData, SceneOverlay, SceneRegistration, SceneShell, SlotGameHandle, SlotSceneController, SlotShellOptions, StakeIntegration };
|