@energy8platform/game-engine 0.23.0 → 0.25.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/devtools.cjs.js +577 -0
- package/dist/devtools.cjs.js.map +1 -0
- package/dist/devtools.d.ts +424 -0
- package/dist/devtools.esm.js +565 -0
- package/dist/devtools.esm.js.map +1 -0
- package/dist/harness.cjs.js +33 -0
- package/dist/harness.cjs.js.map +1 -0
- package/dist/harness.d.ts +25 -0
- package/dist/harness.esm.js +30 -0
- package/dist/harness.esm.js.map +1 -0
- 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/reel-panel-client.cjs.js +610 -0
- package/dist/reel-panel-client.cjs.js.map +1 -0
- package/dist/reel-panel-client.d.ts +5 -0
- package/dist/reel-panel-client.esm.js +608 -0
- package/dist/reel-panel-client.esm.js.map +1 -0
- 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 +17 -2
- package/src/core/GameApplication.ts +3 -3
- package/src/harness/index.ts +35 -0
- 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/devtools/configDiff.ts +41 -0
- package/src/slot/devtools/controlPanel.ts +151 -0
- package/src/slot/devtools/fieldSchema.ts +190 -0
- package/src/slot/devtools/index.ts +31 -0
- package/src/slot/devtools/panelClient.ts +113 -0
- package/src/slot/devtools/protocol.ts +29 -0
- package/src/slot/devtools/reelDevBridge.ts +80 -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
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { HarnessPlugin } from '@energy8platform/harness';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* `@energy8platform/game-engine/harness` — node-only entry.
|
|
5
|
+
*
|
|
6
|
+
* Contributes the reel-config **panel** to `@energy8platform/harness`: a docked
|
|
7
|
+
* right sidebar that tunes a running game's ReelSystem live. Pair it with
|
|
8
|
+
* `mountReelDevBridge` (from `@energy8platform/game-engine/devtools`) in the game.
|
|
9
|
+
*
|
|
10
|
+
* Usage in a game's vite.config:
|
|
11
|
+
* import { createHarness } from '@energy8platform/harness';
|
|
12
|
+
* import { reelDevtoolsPlugin } from '@energy8platform/game-engine/harness';
|
|
13
|
+
* createHarness({ plugins: [ reelDevtoolsPlugin() ] });
|
|
14
|
+
*
|
|
15
|
+
* Node-only: resolves the built, self-contained panel-client ESM the harness serves.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
interface ReelDevtoolsPluginOptions {
|
|
19
|
+
/** Sidebar header / tab label. Default 'Reels'. */
|
|
20
|
+
title?: string;
|
|
21
|
+
}
|
|
22
|
+
declare function reelDevtoolsPlugin(opts?: ReelDevtoolsPluginOptions): HarnessPlugin;
|
|
23
|
+
|
|
24
|
+
export { reelDevtoolsPlugin };
|
|
25
|
+
export type { ReelDevtoolsPluginOptions };
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { fileURLToPath } from 'node:url';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* `@energy8platform/game-engine/harness` — node-only entry.
|
|
5
|
+
*
|
|
6
|
+
* Contributes the reel-config **panel** to `@energy8platform/harness`: a docked
|
|
7
|
+
* right sidebar that tunes a running game's ReelSystem live. Pair it with
|
|
8
|
+
* `mountReelDevBridge` (from `@energy8platform/game-engine/devtools`) in the game.
|
|
9
|
+
*
|
|
10
|
+
* Usage in a game's vite.config:
|
|
11
|
+
* import { createHarness } from '@energy8platform/harness';
|
|
12
|
+
* import { reelDevtoolsPlugin } from '@energy8platform/game-engine/harness';
|
|
13
|
+
* createHarness({ plugins: [ reelDevtoolsPlugin() ] });
|
|
14
|
+
*
|
|
15
|
+
* Node-only: resolves the built, self-contained panel-client ESM the harness serves.
|
|
16
|
+
*/
|
|
17
|
+
function reelDevtoolsPlugin(opts = {}) {
|
|
18
|
+
// The self-contained panel client sits next to this module in dist/.
|
|
19
|
+
const clientEntry = fileURLToPath(new URL('./reel-panel-client.esm.js', import.meta.url));
|
|
20
|
+
const panel = {
|
|
21
|
+
id: 'reels',
|
|
22
|
+
title: opts.title ?? 'Reels',
|
|
23
|
+
placement: 'sidebar',
|
|
24
|
+
clientEntry,
|
|
25
|
+
};
|
|
26
|
+
return { panel };
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export { reelDevtoolsPlugin };
|
|
30
|
+
//# sourceMappingURL=harness.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"harness.esm.js","sources":["../src/harness/index.ts"],"sourcesContent":[null],"names":[],"mappings":";;AAAA;;;;;;;;;;;;;AAaG;AAWG,SAAU,kBAAkB,CAAC,IAAA,GAAkC,EAAE,EAAA;;AAErE,IAAA,MAAM,WAAW,GAAG,aAAa,CAAC,IAAI,GAAG,CAAC,4BAA4B,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACzF,IAAA,MAAM,KAAK,GAAiB;AAC1B,QAAA,EAAE,EAAE,OAAO;AACX,QAAA,KAAK,EAAE,IAAI,CAAC,KAAK,IAAI,OAAO;AAC5B,QAAA,SAAS,EAAE,SAAS;QACpB,WAAW;KACZ;IACD,OAAO,EAAE,KAAK,EAAE;AAClB;;;;"}
|
package/dist/host.cjs.js
CHANGED
|
@@ -3,7 +3,8 @@
|
|
|
3
3
|
var pixi_js = require('pixi.js');
|
|
4
4
|
var platformCore = require('@energy8platform/platform-core');
|
|
5
5
|
var loading = require('@energy8platform/platform-core/loading');
|
|
6
|
-
var
|
|
6
|
+
var pixi = require('@energy8platform/shell/pixi');
|
|
7
|
+
var shell = require('@energy8platform/shell');
|
|
7
8
|
|
|
8
9
|
// ─── Scale Modes ───────────────────────────────────────────
|
|
9
10
|
var ScaleMode;
|
|
@@ -1887,7 +1888,7 @@ class GameApplication extends EventEmitter {
|
|
|
1887
1888
|
await this.initSDK();
|
|
1888
1889
|
// 4b. Mount the branded game shell after the SDK handshake (optional)
|
|
1889
1890
|
if (this.config.shell) {
|
|
1890
|
-
const { createGameShell } = await import('@energy8platform/
|
|
1891
|
+
const { createGameShell } = await import('@energy8platform/shell/html');
|
|
1891
1892
|
this.shell = createGameShell(this.config.shell);
|
|
1892
1893
|
}
|
|
1893
1894
|
// 5. Merge design dimensions from SDK config
|
|
@@ -1922,7 +1923,7 @@ class GameApplication extends EventEmitter {
|
|
|
1922
1923
|
this._destroyed = true;
|
|
1923
1924
|
this._running = false;
|
|
1924
1925
|
if (this.shell) {
|
|
1925
|
-
const { removeGameShell } = await import('@energy8platform/
|
|
1926
|
+
const { removeGameShell } = await import('@energy8platform/shell/html');
|
|
1926
1927
|
await removeGameShell();
|
|
1927
1928
|
this.shell = undefined;
|
|
1928
1929
|
}
|
|
@@ -2369,7 +2370,7 @@ async function createSlotGame(opts) {
|
|
|
2369
2370
|
ack: (raw) => game.platformSession.playAck(raw),
|
|
2370
2371
|
});
|
|
2371
2372
|
if (opts.shell) {
|
|
2372
|
-
const { createPixiShell } = await import('@energy8platform/pixi
|
|
2373
|
+
const { createPixiShell } = await import('@energy8platform/shell/pixi');
|
|
2373
2374
|
const { buildShellConfig } = await Promise.resolve().then(function () { return shellConfig; });
|
|
2374
2375
|
const { resolveReplayBonusId } = await Promise.resolve().then(function () { return replay; });
|
|
2375
2376
|
const ps = game.platformSession;
|
|
@@ -2419,7 +2420,10 @@ async function createSlotGame(opts) {
|
|
|
2419
2420
|
// pixi-shell mounts its root onto the engine's unscaled, screen-space UI layer (above the
|
|
2420
2421
|
// scaled world/scene root) so the control bar fills the real screen, not the letterboxed game.
|
|
2421
2422
|
// The host adds the mount target (`app`) + parent; buildShellConfig produces everything else.
|
|
2422
|
-
|
|
2423
|
+
const pixiShellCfg = { ...buildShellConfig(opts.shell, opts.model, runtime), app: game.app, parent: game.uiLayer };
|
|
2424
|
+
// The game may swap in its own shell (a custom renderer over the same core) via shellFactory;
|
|
2425
|
+
// default is the built-in Pixi shell. The host drives whichever it gets through the Shell contract.
|
|
2426
|
+
shell = (opts.shellFactory ?? createPixiShell)(pixiShellCfg);
|
|
2423
2427
|
// Scope the bar to the slot scene: show only when a SlotSceneController scene is current
|
|
2424
2428
|
// (hidden over the intro / non-slot scenes). Applies in BOTH base and replay modes.
|
|
2425
2429
|
shell.setVisible(!!gameScene());
|
|
@@ -2771,8 +2775,9 @@ async function createSlotGame(opts) {
|
|
|
2771
2775
|
}
|
|
2772
2776
|
|
|
2773
2777
|
// packages/game-engine/src/host/shellConfig.ts
|
|
2774
|
-
// `socialize` / `createI18n` are
|
|
2775
|
-
//
|
|
2778
|
+
// `socialize` / `createI18n` / `Lang` are renderer-agnostic helpers from the shell core
|
|
2779
|
+
// (@energy8platform/shell). Renderer-agnostic types (GameInfoSection/Content, PaytableRow,
|
|
2780
|
+
// GameMode) and the pixi-specific surface types come from the @energy8platform/shell/pixi entry.
|
|
2776
2781
|
/**
|
|
2777
2782
|
* Apply jurisdiction restrictions over the resolved shell features, in place. A restriction ALWAYS
|
|
2778
2783
|
* wins over the author's intent (a forbidden control must stay off even if the game enabled it).
|
|
@@ -2972,13 +2977,19 @@ function sectionKey(s) {
|
|
|
2972
2977
|
function mergeGameInfo(derived, override) {
|
|
2973
2978
|
if (!override)
|
|
2974
2979
|
return derived;
|
|
2980
|
+
// `GameInfoContent.sections` is typed with the core GameInfoSection (node?: unknown) because
|
|
2981
|
+
// shell/pixi re-exports GameInfoContent unchanged from core. Host-built sections never set `node`,
|
|
2982
|
+
// so they are structurally compatible with pixi's GameInfoSection (node?: Container). Cast once
|
|
2983
|
+
// here so the rest of the function works against the pixi-widened type.
|
|
2984
|
+
const derivedSections = (derived.sections ?? []);
|
|
2985
|
+
const overrideSections = (override.sections ?? []);
|
|
2975
2986
|
const authorByKey = new Map();
|
|
2976
|
-
for (const s of
|
|
2987
|
+
for (const s of overrideSections)
|
|
2977
2988
|
authorByKey.set(sectionKey(s), s);
|
|
2978
2989
|
const out = [];
|
|
2979
2990
|
const used = new Set();
|
|
2980
2991
|
// Keep derived order; swap in the author's version where identities collide.
|
|
2981
|
-
for (const s of
|
|
2992
|
+
for (const s of derivedSections) {
|
|
2982
2993
|
const k = sectionKey(s);
|
|
2983
2994
|
const replacement = authorByKey.get(k);
|
|
2984
2995
|
if (replacement) {
|
|
@@ -2989,7 +3000,7 @@ function mergeGameInfo(derived, override) {
|
|
|
2989
3000
|
out.push(s);
|
|
2990
3001
|
}
|
|
2991
3002
|
// Append author sections whose identity wasn't in the derived set, in author order.
|
|
2992
|
-
for (const s of
|
|
3003
|
+
for (const s of overrideSections) {
|
|
2993
3004
|
const k = sectionKey(s);
|
|
2994
3005
|
if (!used.has(k)) {
|
|
2995
3006
|
out.push(s);
|
|
@@ -3054,6 +3065,8 @@ function buildShellConfig(opts, model, runtime) {
|
|
|
3054
3065
|
const authored = typeof opts.gameInfo === 'function' ? opts.gameInfo(t) : opts.gameInfo;
|
|
3055
3066
|
// Pass t() through to spec-derived sections so symbol names, mode titles, and descriptions are
|
|
3056
3067
|
// pre-translated before they reach the shell renderer.
|
|
3068
|
+
// Cast to { sections?: GameInfoSection[] } (pixi-widened) so downstream map/filter calls work
|
|
3069
|
+
// against the pixi section union. Host-derived sections never set `node`, so the widening is safe.
|
|
3057
3070
|
let gameInfo = mergeGameInfo(defaultGameInfo(model, runtime, t), authored);
|
|
3058
3071
|
// The DISCLAIMER is required legal copy and must be shown VERBATIM — never socialized (its
|
|
3059
3072
|
// wording is mandated, and word-swaps like "bet → play" would corrupt the legal text).
|
|
@@ -3499,6 +3512,18 @@ var autoplay = /*#__PURE__*/Object.freeze({
|
|
|
3499
3512
|
createAutoplayLoop: createAutoplayLoop
|
|
3500
3513
|
});
|
|
3501
3514
|
|
|
3515
|
+
Object.defineProperty(exports, "PixiRenderer", {
|
|
3516
|
+
enumerable: true,
|
|
3517
|
+
get: function () { return pixi.PixiRenderer; }
|
|
3518
|
+
});
|
|
3519
|
+
Object.defineProperty(exports, "createPixiShell", {
|
|
3520
|
+
enumerable: true,
|
|
3521
|
+
get: function () { return pixi.createPixiShell; }
|
|
3522
|
+
});
|
|
3523
|
+
Object.defineProperty(exports, "createShell", {
|
|
3524
|
+
enumerable: true,
|
|
3525
|
+
get: function () { return pixi.createShell; }
|
|
3526
|
+
});
|
|
3502
3527
|
Object.defineProperty(exports, "socialize", {
|
|
3503
3528
|
enumerable: true,
|
|
3504
3529
|
get: function () { return shell.socialize; }
|