@energy8platform/game-engine 0.22.0 → 0.24.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/core.cjs.js +2 -2
- package/dist/core.cjs.js.map +1 -1
- package/dist/core.d.ts +3 -3
- package/dist/core.esm.js +2 -2
- package/dist/core.esm.js.map +1 -1
- package/dist/host.cjs.js +35 -10
- package/dist/host.cjs.js.map +1 -1
- package/dist/host.d.ts +22 -9
- package/dist/host.esm.js +24 -11
- package/dist/host.esm.js.map +1 -1
- package/dist/index.cjs.js +2 -2
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.esm.js +2 -2
- package/dist/index.esm.js.map +1 -1
- package/dist/shell.cjs.js +4 -4
- package/dist/shell.d.ts +1 -1
- package/dist/shell.esm.js +1 -1
- package/dist/slot.cjs.js +226 -75
- package/dist/slot.cjs.js.map +1 -1
- package/dist/slot.d.ts +137 -19
- package/dist/slot.esm.js +224 -76
- package/dist/slot.esm.js.map +1 -1
- package/package.json +4 -4
- package/src/core/GameApplication.ts +3 -3
- package/src/host/createSlotGame.ts +6 -3
- package/src/host/index.ts +11 -1
- package/src/host/shellConfig.ts +22 -12
- package/src/host/types.ts +13 -2
- package/src/shell/index.ts +4 -3
- package/src/slot/cascade/TumbleController.ts +6 -3
- package/src/slot/config/ReelSystemConfig.ts +19 -0
- package/src/slot/features/extra.ts +1 -2
- package/src/slot/features/symbols.ts +10 -10
- package/src/slot/features/types.ts +13 -5
- package/src/slot/features/wilds.ts +1 -1
- package/src/slot/grid/AnimatedSymbol.ts +20 -11
- package/src/slot/grid/ReelGrid.ts +80 -41
- package/src/slot/grid/SymbolCell.ts +14 -7
- package/src/slot/grid/SymbolView.ts +2 -2
- package/src/slot/grid/geometry.ts +155 -0
- package/src/slot/index.ts +3 -0
- package/src/slot/motion/SpinEngine.ts +1 -1
- package/src/slot/system/ReelSystem.ts +10 -0
- package/src/types.ts +1 -1
package/dist/host.d.ts
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
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,
|
|
5
|
-
|
|
6
|
-
import
|
|
7
|
-
export { socialize } from '@energy8platform/platform-core/shell';
|
|
4
|
+
import { CurrencyConfig, GameInfoContent, BonusOption, ShellFeatures, ShellMode, PixiShellConfig, Shell } from '@energy8platform/shell/pixi';
|
|
5
|
+
export { OverlayHandle, OverlayRequest, PixiRenderer, PixiShellConfig, ResolvedShellConfig, SafeArea, Shell, ShellActions, ShellHost, ShellLayoutMode, ShellRenderer, ShellSurface, ShellTokens, createPixiShell, createShell } from '@energy8platform/shell/pixi';
|
|
6
|
+
import * as _energy8platform_shell_html from '@energy8platform/shell/html';
|
|
8
7
|
import { BookAdapter, AdapterModule, StakeBridge } from '@energy8platform/stake-bridge';
|
|
9
8
|
import { CasinoGameSDK, InitData, GameConfigData, SessionData } from '@energy8platform/game-sdk';
|
|
9
|
+
import { Lang } from '@energy8platform/shell';
|
|
10
|
+
export { socialize } from '@energy8platform/shell';
|
|
10
11
|
import { SlotSpinResultBase, SlotResultNormalizer } from '@energy8platform/platform-core/slot-result';
|
|
11
12
|
|
|
12
13
|
declare enum ScaleMode {
|
|
@@ -64,7 +65,7 @@ interface GameApplicationConfig {
|
|
|
64
65
|
/** Enable debug overlay (FPS, draw calls) */
|
|
65
66
|
debug?: boolean;
|
|
66
67
|
/** When set, GameApplication mounts the branded game shell after the SDK handshake. */
|
|
67
|
-
shell?:
|
|
68
|
+
shell?: _energy8platform_shell_html.ShellConfig | false;
|
|
68
69
|
}
|
|
69
70
|
interface SceneConstructor {
|
|
70
71
|
new (): IScene;
|
|
@@ -705,7 +706,7 @@ declare class GameApplication extends EventEmitter<GameEngineEvents> {
|
|
|
705
706
|
/** Platform session (SDK + optional DevBridge). null until start() runs. */
|
|
706
707
|
platformSession: PlatformSession | null;
|
|
707
708
|
/** Branded game shell (only when config.shell is set). */
|
|
708
|
-
shell?:
|
|
709
|
+
shell?: _energy8platform_shell_html.GameShell;
|
|
709
710
|
/** Configuration */
|
|
710
711
|
readonly config: GameApplicationConfig;
|
|
711
712
|
private _running;
|
|
@@ -814,7 +815,9 @@ interface JurisdictionRestrictions {
|
|
|
814
815
|
declare function stakeForAction(model: GameModel, action: string, bet: number): number;
|
|
815
816
|
/** Pure: assemble the shell config (sans mount target) from the model + runtime context
|
|
816
817
|
* (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'
|
|
818
|
+
declare function buildShellConfig(opts: SlotShellOptions, model: GameModel, runtime: ShellRuntime): Omit<PixiShellConfig, 'app' | 'parent' | 'gameInfo'> & {
|
|
819
|
+
gameInfo: GameInfoContent;
|
|
820
|
+
};
|
|
818
821
|
|
|
819
822
|
interface StakeIntegration {
|
|
820
823
|
/** The game's BookAdapter (or its module). modeMap + gameId come from the model. */
|
|
@@ -865,15 +868,25 @@ interface CreateSlotGameOptions<T extends SlotSpinResultBase = SlotSpinResultBas
|
|
|
865
868
|
dev?: boolean;
|
|
866
869
|
stake?: StakeIntegration;
|
|
867
870
|
shell?: SlotShellOptions;
|
|
871
|
+
/** Override how the control-bar shell is built. The host resolves the full shell config (theme,
|
|
872
|
+
* features, gameInfo, currency, balance) and the Pixi mount (`app`/`parent`) and hands it to this
|
|
873
|
+
* factory; return any `Shell` — e.g. `createShell({ renderer: new MyRenderer(...), ...config })`
|
|
874
|
+
* to plug a custom renderer while the shell core still drives bet/balance/overlays. A custom
|
|
875
|
+
* renderer can ignore `app`/`parent` and mount elsewhere (a DOM overlay, another canvas).
|
|
876
|
+
* Default: the built-in Pixi shell (`createPixiShell`). */
|
|
877
|
+
shellFactory?: ShellFactory;
|
|
868
878
|
/** Double-tap on the play area to skip the current spin animation. Default `true`. Set `false`
|
|
869
879
|
* to disable the gesture (e.g. games where a tap means something else). */
|
|
870
880
|
skipGesture?: boolean;
|
|
871
881
|
onFatalError?: (message: string) => void;
|
|
872
882
|
}
|
|
883
|
+
/** Builds the shell the host drives. Receives the fully-resolved Pixi shell config (a custom
|
|
884
|
+
* renderer may ignore the `app`/`parent` mount fields). Must return a `Shell`. */
|
|
885
|
+
type ShellFactory = (config: PixiShellConfig) => Shell;
|
|
873
886
|
interface SlotGameHandle {
|
|
874
887
|
game: GameApplication;
|
|
875
888
|
stakeBridge: StakeBridge | null;
|
|
876
|
-
shell:
|
|
889
|
+
shell: Shell | null;
|
|
877
890
|
}
|
|
878
891
|
|
|
879
892
|
/**
|
|
@@ -1001,4 +1014,4 @@ interface SlotSceneController<T extends SlotSpinResultBase = SlotSpinResultBase>
|
|
|
1001
1014
|
}
|
|
1002
1015
|
|
|
1003
1016
|
export { buildShellConfig, createSlotGame, resolveReplayBonusId, resolveStartScene, stakeForAction };
|
|
1004
|
-
export type { AutoplaySceneState, CreateSlotGameOptions, OverlayShowOptions, RenderContext, SceneApi, SceneAudio, SceneNavData, SceneOverlay, SceneRegistration, SceneShell, SlotGameHandle, SlotSceneController, SlotShellOptions, StakeIntegration };
|
|
1017
|
+
export type { AutoplaySceneState, CreateSlotGameOptions, OverlayShowOptions, RenderContext, SceneApi, SceneAudio, SceneNavData, SceneOverlay, SceneRegistration, SceneShell, ShellFactory, SlotGameHandle, SlotSceneController, SlotShellOptions, StakeIntegration };
|
package/dist/host.esm.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { Ticker, Assets, Container, Text, Application, Graphics, TextureSource } from 'pixi.js';
|
|
2
2
|
import { createPlatformSession } from '@energy8platform/platform-core';
|
|
3
3
|
import { waitCSSPreloaderTap, removeCSSPreloader, setCSSPreloaderProgress, createCSSPreloader } from '@energy8platform/platform-core/loading';
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
export { PixiRenderer, createPixiShell, createShell } from '@energy8platform/shell/pixi';
|
|
5
|
+
import { socialize, createI18n } from '@energy8platform/shell';
|
|
6
|
+
export { socialize } from '@energy8platform/shell';
|
|
6
7
|
|
|
7
8
|
// ─── Scale Modes ───────────────────────────────────────────
|
|
8
9
|
var ScaleMode;
|
|
@@ -1886,7 +1887,7 @@ class GameApplication extends EventEmitter {
|
|
|
1886
1887
|
await this.initSDK();
|
|
1887
1888
|
// 4b. Mount the branded game shell after the SDK handshake (optional)
|
|
1888
1889
|
if (this.config.shell) {
|
|
1889
|
-
const { createGameShell } = await import('@energy8platform/
|
|
1890
|
+
const { createGameShell } = await import('@energy8platform/shell/html');
|
|
1890
1891
|
this.shell = createGameShell(this.config.shell);
|
|
1891
1892
|
}
|
|
1892
1893
|
// 5. Merge design dimensions from SDK config
|
|
@@ -1921,7 +1922,7 @@ class GameApplication extends EventEmitter {
|
|
|
1921
1922
|
this._destroyed = true;
|
|
1922
1923
|
this._running = false;
|
|
1923
1924
|
if (this.shell) {
|
|
1924
|
-
const { removeGameShell } = await import('@energy8platform/
|
|
1925
|
+
const { removeGameShell } = await import('@energy8platform/shell/html');
|
|
1925
1926
|
await removeGameShell();
|
|
1926
1927
|
this.shell = undefined;
|
|
1927
1928
|
}
|
|
@@ -2368,7 +2369,7 @@ async function createSlotGame(opts) {
|
|
|
2368
2369
|
ack: (raw) => game.platformSession.playAck(raw),
|
|
2369
2370
|
});
|
|
2370
2371
|
if (opts.shell) {
|
|
2371
|
-
const { createPixiShell } = await import('@energy8platform/pixi
|
|
2372
|
+
const { createPixiShell } = await import('@energy8platform/shell/pixi');
|
|
2372
2373
|
const { buildShellConfig } = await Promise.resolve().then(function () { return shellConfig; });
|
|
2373
2374
|
const { resolveReplayBonusId } = await Promise.resolve().then(function () { return replay; });
|
|
2374
2375
|
const ps = game.platformSession;
|
|
@@ -2418,7 +2419,10 @@ async function createSlotGame(opts) {
|
|
|
2418
2419
|
// pixi-shell mounts its root onto the engine's unscaled, screen-space UI layer (above the
|
|
2419
2420
|
// scaled world/scene root) so the control bar fills the real screen, not the letterboxed game.
|
|
2420
2421
|
// The host adds the mount target (`app`) + parent; buildShellConfig produces everything else.
|
|
2421
|
-
|
|
2422
|
+
const pixiShellCfg = { ...buildShellConfig(opts.shell, opts.model, runtime), app: game.app, parent: game.uiLayer };
|
|
2423
|
+
// The game may swap in its own shell (a custom renderer over the same core) via shellFactory;
|
|
2424
|
+
// default is the built-in Pixi shell. The host drives whichever it gets through the Shell contract.
|
|
2425
|
+
shell = (opts.shellFactory ?? createPixiShell)(pixiShellCfg);
|
|
2422
2426
|
// Scope the bar to the slot scene: show only when a SlotSceneController scene is current
|
|
2423
2427
|
// (hidden over the intro / non-slot scenes). Applies in BOTH base and replay modes.
|
|
2424
2428
|
shell.setVisible(!!gameScene());
|
|
@@ -2770,8 +2774,9 @@ async function createSlotGame(opts) {
|
|
|
2770
2774
|
}
|
|
2771
2775
|
|
|
2772
2776
|
// packages/game-engine/src/host/shellConfig.ts
|
|
2773
|
-
// `socialize` / `createI18n` are
|
|
2774
|
-
//
|
|
2777
|
+
// `socialize` / `createI18n` / `Lang` are renderer-agnostic helpers from the shell core
|
|
2778
|
+
// (@energy8platform/shell). Renderer-agnostic types (GameInfoSection/Content, PaytableRow,
|
|
2779
|
+
// GameMode) and the pixi-specific surface types come from the @energy8platform/shell/pixi entry.
|
|
2775
2780
|
/**
|
|
2776
2781
|
* Apply jurisdiction restrictions over the resolved shell features, in place. A restriction ALWAYS
|
|
2777
2782
|
* wins over the author's intent (a forbidden control must stay off even if the game enabled it).
|
|
@@ -2971,13 +2976,19 @@ function sectionKey(s) {
|
|
|
2971
2976
|
function mergeGameInfo(derived, override) {
|
|
2972
2977
|
if (!override)
|
|
2973
2978
|
return derived;
|
|
2979
|
+
// `GameInfoContent.sections` is typed with the core GameInfoSection (node?: unknown) because
|
|
2980
|
+
// shell/pixi re-exports GameInfoContent unchanged from core. Host-built sections never set `node`,
|
|
2981
|
+
// so they are structurally compatible with pixi's GameInfoSection (node?: Container). Cast once
|
|
2982
|
+
// here so the rest of the function works against the pixi-widened type.
|
|
2983
|
+
const derivedSections = (derived.sections ?? []);
|
|
2984
|
+
const overrideSections = (override.sections ?? []);
|
|
2974
2985
|
const authorByKey = new Map();
|
|
2975
|
-
for (const s of
|
|
2986
|
+
for (const s of overrideSections)
|
|
2976
2987
|
authorByKey.set(sectionKey(s), s);
|
|
2977
2988
|
const out = [];
|
|
2978
2989
|
const used = new Set();
|
|
2979
2990
|
// Keep derived order; swap in the author's version where identities collide.
|
|
2980
|
-
for (const s of
|
|
2991
|
+
for (const s of derivedSections) {
|
|
2981
2992
|
const k = sectionKey(s);
|
|
2982
2993
|
const replacement = authorByKey.get(k);
|
|
2983
2994
|
if (replacement) {
|
|
@@ -2988,7 +2999,7 @@ function mergeGameInfo(derived, override) {
|
|
|
2988
2999
|
out.push(s);
|
|
2989
3000
|
}
|
|
2990
3001
|
// Append author sections whose identity wasn't in the derived set, in author order.
|
|
2991
|
-
for (const s of
|
|
3002
|
+
for (const s of overrideSections) {
|
|
2992
3003
|
const k = sectionKey(s);
|
|
2993
3004
|
if (!used.has(k)) {
|
|
2994
3005
|
out.push(s);
|
|
@@ -3053,6 +3064,8 @@ function buildShellConfig(opts, model, runtime) {
|
|
|
3053
3064
|
const authored = typeof opts.gameInfo === 'function' ? opts.gameInfo(t) : opts.gameInfo;
|
|
3054
3065
|
// Pass t() through to spec-derived sections so symbol names, mode titles, and descriptions are
|
|
3055
3066
|
// pre-translated before they reach the shell renderer.
|
|
3067
|
+
// Cast to { sections?: GameInfoSection[] } (pixi-widened) so downstream map/filter calls work
|
|
3068
|
+
// against the pixi section union. Host-derived sections never set `node`, so the widening is safe.
|
|
3056
3069
|
let gameInfo = mergeGameInfo(defaultGameInfo(model, runtime, t), authored);
|
|
3057
3070
|
// The DISCLAIMER is required legal copy and must be shown VERBATIM — never socialized (its
|
|
3058
3071
|
// wording is mandated, and word-swaps like "bet → play" would corrupt the legal text).
|