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