@energy8platform/game-engine 0.15.1 → 0.16.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 +22 -12
- package/dist/assets.d.ts +2 -14
- package/dist/core.cjs.js +16 -201
- package/dist/core.cjs.js.map +1 -1
- package/dist/core.d.ts +4 -35
- package/dist/core.esm.js +12 -197
- package/dist/core.esm.js.map +1 -1
- package/dist/debug.cjs.js +5 -233
- package/dist/debug.cjs.js.map +1 -1
- package/dist/debug.d.ts +2 -140
- package/dist/debug.esm.js +2 -233
- package/dist/debug.esm.js.map +1 -1
- package/dist/index.cjs.js +36 -442
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +10 -195
- package/dist/index.esm.js +29 -439
- package/dist/index.esm.js.map +1 -1
- package/dist/lua.cjs.js +7 -1493
- package/dist/lua.cjs.js.map +1 -1
- package/dist/lua.d.ts +1 -403
- package/dist/lua.esm.js +1 -1483
- package/dist/lua.esm.js.map +1 -1
- package/dist/react.cjs.js +15 -10
- package/dist/react.cjs.js.map +1 -1
- package/dist/react.d.ts +4 -35
- package/dist/react.esm.js +15 -10
- package/dist/react.esm.js.map +1 -1
- package/dist/ui.cjs.js +15 -10
- package/dist/ui.cjs.js.map +1 -1
- package/dist/ui.esm.js +15 -10
- package/dist/ui.esm.js.map +1 -1
- package/dist/vite.cjs.js +19 -175
- package/dist/vite.cjs.js.map +1 -1
- package/dist/vite.d.ts +8 -3
- package/dist/vite.esm.js +10 -173
- package/dist/vite.esm.js.map +1 -1
- package/package.json +6 -16
- package/src/core/GameApplication.ts +14 -18
- package/src/debug/index.ts +4 -2
- package/src/index.ts +3 -3
- package/src/loading/LoadingScene.ts +1 -1
- package/src/loading/index.ts +9 -2
- package/src/lua/index.ts +3 -31
- package/src/types.ts +16 -41
- package/src/ui/FlexContainer.ts +15 -10
- package/src/vite/index.ts +13 -196
- package/bin/simulate.ts +0 -139
- package/scripts/install-simulate.mjs +0 -101
- package/src/debug/DevBridge.ts +0 -305
- package/src/loading/CSSPreloader.ts +0 -129
- package/src/loading/logo.ts +0 -95
- package/src/lua/ActionRouter.ts +0 -132
- package/src/lua/LuaEngine.ts +0 -412
- package/src/lua/LuaEngineAPI.ts +0 -314
- package/src/lua/NativeSimulationRunner.ts +0 -367
- package/src/lua/ParallelSimulationRunner.ts +0 -156
- package/src/lua/PersistentState.ts +0 -80
- package/src/lua/SessionManager.ts +0 -227
- package/src/lua/SimulationRunner.ts +0 -192
- package/src/lua/SimulationWorker.ts +0 -44
- package/src/lua/fengari.d.ts +0 -10
- package/src/lua/types.ts +0 -149
package/README.md
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
# @energy8platform/game-engine
|
|
2
2
|
|
|
3
|
-
A casino game engine built on [PixiJS v8](https://pixijs.com/) and [@energy8platform/game-sdk](https://github.com/energy8platform/game-sdk). Provides scene management, responsive scaling, audio, state machines, tweens, UI components,
|
|
3
|
+
A casino game engine built on [PixiJS v8](https://pixijs.com/) and [@energy8platform/game-sdk](https://github.com/energy8platform/game-sdk). Provides scene management, responsive scaling, audio, state machines, tweens, UI components, and React integration for developing slot machines, card games, and other iGaming titles.
|
|
4
|
+
|
|
5
|
+
> **Building on a different renderer?** The platform-specific bits (Lua engine, RTP simulation, DevBridge, branded loading screen, SDK session orchestration) live in the renderer-agnostic [`@energy8platform/platform-core`](../platform-core/README.md). `game-engine` is the Pixi front-end on top of it; Phaser, Three.js, and custom-engine consumers depend only on `platform-core`.
|
|
4
6
|
|
|
5
7
|
---
|
|
6
8
|
|
|
@@ -31,14 +33,15 @@ A casino game engine built on [PixiJS v8](https://pixijs.com/) and [@energy8plat
|
|
|
31
33
|
## Quick Start
|
|
32
34
|
|
|
33
35
|
```bash
|
|
34
|
-
# Install dependencies
|
|
36
|
+
# Install dependencies. platform-core comes in transitively as a
|
|
37
|
+
# regular dependency of game-engine — you don't list it explicitly.
|
|
35
38
|
npm install pixi.js @energy8platform/game-sdk @energy8platform/game-engine
|
|
36
39
|
|
|
37
40
|
# Optional peer dependencies
|
|
38
41
|
npm install @pixi/sound # Audio
|
|
39
42
|
npm install @esotericsoftware/spine-pixi-v8 # Spine animations
|
|
40
43
|
npm install react react-dom react-reconciler # React integration
|
|
41
|
-
npm install fengari # Lua engine
|
|
44
|
+
npm install fengari # Lua engine (in dev/sim)
|
|
42
45
|
```
|
|
43
46
|
|
|
44
47
|
```typescript
|
|
@@ -91,7 +94,9 @@ bootstrap();
|
|
|
91
94
|
| `@esotericsoftware/spine-pixi-v8` | `~4.2.0` | Optional — Spine animations |
|
|
92
95
|
| `react`, `react-dom` | `>=18.0.0` | Optional — ReactScene |
|
|
93
96
|
| `react-reconciler` | `>=0.29.0` | Optional — ReactScene (custom PixiJS reconciler) |
|
|
94
|
-
| `fengari` | `^0.1.4` | Optional — Lua engine |
|
|
97
|
+
| `fengari` | `^0.1.4` | Optional — Lua engine (peer of `platform-core`, install only if you use Lua locally) |
|
|
98
|
+
|
|
99
|
+
`@energy8platform/platform-core` is a regular dependency (not a peer) — npm pulls it in automatically when you install `game-engine`.
|
|
95
100
|
|
|
96
101
|
### Sub-path Exports
|
|
97
102
|
|
|
@@ -710,6 +715,8 @@ export default defineGameConfig({
|
|
|
710
715
|
|
|
711
716
|
Runs platform Lua game scripts in the browser via `fengari` (Lua 5.3, pure JS). Replicates server-side execution for development — no backend required.
|
|
712
717
|
|
|
718
|
+
> The Lua engine, simulation runners, and game-definition types ship from [`@energy8platform/platform-core`](../platform-core/README.md). `game-engine` re-exports them at `@energy8platform/game-engine/lua` so existing import paths keep working.
|
|
719
|
+
|
|
713
720
|
### DevBridge Integration (recommended)
|
|
714
721
|
|
|
715
722
|
```typescript
|
|
@@ -764,20 +771,20 @@ engine.destroy();
|
|
|
764
771
|
|
|
765
772
|
### RTP Simulation (CLI)
|
|
766
773
|
|
|
767
|
-
Run the same Lua script from `dev.config.ts` through millions of iterations to verify math:
|
|
774
|
+
Run the same Lua script from `dev.config.ts` through millions of iterations to verify math. The CLI ships with [`@energy8platform/platform-core`](../platform-core/README.md) (a transitive dep when you install `game-engine`):
|
|
768
775
|
|
|
769
776
|
```bash
|
|
770
777
|
# Regular spins (1M iterations, default)
|
|
771
|
-
npx
|
|
778
|
+
npx platform-core-simulate
|
|
772
779
|
|
|
773
780
|
# Buy bonus simulation
|
|
774
|
-
npx
|
|
781
|
+
npx platform-core-simulate --action buy_bonus
|
|
775
782
|
|
|
776
|
-
# Ante bet
|
|
777
|
-
npx
|
|
783
|
+
# Ante bet (v5: regular action, not a params flag)
|
|
784
|
+
npx platform-core-simulate --action ante_spin
|
|
778
785
|
|
|
779
786
|
# Custom parameters
|
|
780
|
-
npx
|
|
787
|
+
npx platform-core-simulate --iterations 5000000 --bet 1 --seed 42 --config ./dev.config.ts
|
|
781
788
|
```
|
|
782
789
|
|
|
783
790
|
Output matches the platform's server-side simulation format:
|
|
@@ -824,7 +831,7 @@ console.log(formatSimulationResult(result));
|
|
|
824
831
|
|
|
825
832
|
## DevBridge
|
|
826
833
|
|
|
827
|
-
Simulates a casino host for local development using SDK's `Bridge` in `devMode` (shared `MemoryChannel`, no iframe needed).
|
|
834
|
+
Simulates a casino host for local development using SDK's `Bridge` in `devMode` (shared `MemoryChannel`, no iframe needed). DevBridge is implemented in [`@energy8platform/platform-core`](../platform-core/README.md); the imports below resolve through the re-export shim shipped by `game-engine`.
|
|
828
835
|
|
|
829
836
|
```typescript
|
|
830
837
|
import { DevBridge } from '@energy8platform/game-engine/debug';
|
|
@@ -847,10 +854,13 @@ bridge.setBalance(5000);
|
|
|
847
854
|
bridge.destroy();
|
|
848
855
|
```
|
|
849
856
|
|
|
850
|
-
**Handled
|
|
857
|
+
**Handled (in):** `GAME_READY`, `PLAY_REQUEST`, `PLAY_RESULT_ACK`, `GET_BALANCE`, `GET_STATE`, `OPEN_DEPOSIT`.
|
|
858
|
+
**Emitted (out):** `INIT`, `PLAY_RESULT`, `PLAY_ERROR`, `BALANCE_UPDATE`, `STATE_RESPONSE`.
|
|
851
859
|
|
|
852
860
|
> With the Vite plugin (`devBridge: true`), DevBridge is injected automatically before your app entry point.
|
|
853
861
|
|
|
862
|
+
> **Error codes & session contract.** In Lua mode, DevBridge emits the same `PLAY_ERROR` codes the platform does (`INVALID_AMOUNT`, `INSUFFICIENT_FUNDS`, `ACTIVE_SESSION_EXISTS`, `NO_ACTIVE_SESSION`, `SESSION_EXPIRED`, `ENGINE_ERROR`, …) — see the [platform-core DevBridge section](../platform-core/README.md#platform-parity-behavior-lua-mode) for the full table and the contract details (server-generated round IDs, `session.history`, `STATE_RESPONSE` shape, `creditPending` semantics).
|
|
863
|
+
|
|
854
864
|
---
|
|
855
865
|
|
|
856
866
|
## React Integration
|
package/dist/assets.d.ts
CHANGED
|
@@ -1,16 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
src: string | string[];
|
|
4
|
-
/** Optional data to pass to the loader */
|
|
5
|
-
data?: Record<string, unknown>;
|
|
6
|
-
}
|
|
7
|
-
interface AssetBundle {
|
|
8
|
-
name: string;
|
|
9
|
-
assets: AssetEntry[];
|
|
10
|
-
}
|
|
11
|
-
interface AssetManifest {
|
|
12
|
-
bundles: AssetBundle[];
|
|
13
|
-
}
|
|
1
|
+
import { AssetManifest } from '@energy8platform/platform-core';
|
|
2
|
+
export { AssetBundle, AssetEntry, AssetManifest } from '@energy8platform/platform-core';
|
|
14
3
|
|
|
15
4
|
/**
|
|
16
5
|
* Manages game asset loading with progress tracking, bundle support, and
|
|
@@ -94,4 +83,3 @@ declare class AssetManager {
|
|
|
94
83
|
}
|
|
95
84
|
|
|
96
85
|
export { AssetManager };
|
|
97
|
-
export type { AssetBundle, AssetEntry, AssetManifest };
|
package/dist/core.cjs.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var pixi_js = require('pixi.js');
|
|
4
|
-
var
|
|
4
|
+
var platformCore = require('@energy8platform/platform-core');
|
|
5
|
+
var loading = require('@energy8platform/platform-core/loading');
|
|
5
6
|
|
|
6
7
|
// ─── Scale Modes ───────────────────────────────────────────
|
|
7
8
|
var ScaleMode;
|
|
@@ -1429,81 +1430,12 @@ class Scene {
|
|
|
1429
1430
|
}
|
|
1430
1431
|
}
|
|
1431
1432
|
|
|
1432
|
-
/**
|
|
1433
|
-
* Shared Energy8 SVG logo with an embedded loader bar.
|
|
1434
|
-
*
|
|
1435
|
-
* The loader bar fill is controlled via a `<clipPath>` whose `<rect>` width
|
|
1436
|
-
* is animatable. Different consumers customise gradient IDs and the clip
|
|
1437
|
-
* element's ID/class to avoid collisions when both CSSPreloader and
|
|
1438
|
-
* LoadingScene appear in the same DOM.
|
|
1439
|
-
*/
|
|
1440
|
-
/** SVG path data for the Energy8 wordmark — reused across loaders */
|
|
1441
|
-
const WORDMARK_PATHS = `
|
|
1442
|
-
<path d="m241 81.75h-19.28c-1.77 0-6.73 4.98-7.43 6.99l-4.36 12.22c-0.49 1.37 0.05 2.92 1.06 4.32-2.07 1.19-3.69 3.08-4.36 5.43l-3.25 10.41c-0.86 2.89 2.39 6.63 4.31 6.63h19.28c1.96 0 7.4-5.56 7.96-7.51l2.96-10.22c0.63-2.25 0.1-3.98-1.22-4.99 2.55-1.56 3.86-4.14 4.55-6.31l2.77-9.31c0.74-2.57-1.37-7.66-2.99-7.66zm-13.36 28.31-2.27 7.03h-8.28l2.58-8.28h8.28l-0.31 1.25zm4.06-16.97-2.11 6.7h-7.04l2.25-7.34h7.26l-0.36 0.64z" fill="url(#GID0)"/>
|
|
1443
|
-
<path d="m202.5 81.75-9.31 14.97-2.32-14.97h-11.82l4.32 25.15-0.57 4.91-8.64 26.44 15.31-12.76 5.63-16.48 19.96-27.26h-12.56z" fill="url(#GID1)"/>
|
|
1444
|
-
<path d="m174.2 81.75h-19.78l-5.75 5.16-10.79 33.2c-0.77 2.53 2.48 6.93 4.87 6.93h17.38c2.63 0 7.85-5.34 8.32-6.83l5.37-18.14h-15.17l-2.2 7.64h3.78l-2.25 7.2h-8.01l7.1-25.52h7.58l-1.48 8.4 12.78-5.98c1.28-0.63 1.97-3.99 1.61-6.61-0.36-2.34-1.64-5.45-3.36-5.45z" fill="url(#GID2)"/>
|
|
1445
|
-
<path d="m140.6 81.75h-70.6l-5.36 19.37-4.26-19.37h-46.76l2.95 5.88-10.58 39.28h26.84l2.95-9.52-15.63-0.13 2.55-8.34h8.74l8.47-9.81h-14.61l2.11-7.3h15.47l2.54-8.71 2.58 4.74-11.4 39.07h11.05l6.46-21.49 8.84 36.33 19.18-55.67-1.83-3.36 3.68 4.09-12.07 40.1h28.18l3.39-10.31h-17.01l2.67-8.03h9.98l7.58-9.52h-14.28l1.93-6.6h14.61l3.25-9.73 2.81 5.12-11.3 38.89h11.05l5.23-17.81h1.62l1.48 17.6h10.69l-1.48-16.81c4.75-1.28 7.52-5.9 8.64-9.81l2.95-11.3c0.86-2.73-1.43-6.85-3.3-6.85zm-9.8 17.3h-8.69l2.54-7.84h8.35l-2.2 7.84z" fill="url(#GID3)"/>
|
|
1446
|
-
<path d="m205.9 148.9h-122.6l-2.61-3.12h-32.4l-2.51 3.12h-1.59c-5.34 0-7.94 4.88-7.94 7.65v0.03c0 4.2 3.55 7.6 7.74 7.6h103.6l2.11 3.12h36.09l1.82-3.12h18.3c5.25 0 6.64-5.3 6.64-7.35v-0.25c0-4.23-2.9-7.68-6.64-7.68zm-0.7 12.83h-160.6c-3.69 0-6.11-2.58-6.11-5.47v-0.03c0-2.89 2.1-5.47 5.61-5.47h161.1c3.45 0 4.89 3.12 4.89 5.65v0.17c0 2.57-2.11 5.15-4.89 5.15z" fill="url(#GID4)"/>`;
|
|
1447
|
-
/** Gradient definitions template (gradient IDs are replaced per-consumer) */
|
|
1448
|
-
const GRADIENT_DEFS = `
|
|
1449
|
-
<linearGradient id="GID0" x1="223.7" x2="223.7" y1="81.75" y2="127.8" gradientUnits="userSpaceOnUse">
|
|
1450
|
-
<stop stop-color="#663BA6"/><stop stop-color="#7939C2" offset=".349"/><stop stop-color="#8A2FC0" offset=".6615"/><stop stop-color="#791BA3" offset="1"/>
|
|
1451
|
-
</linearGradient>
|
|
1452
|
-
<linearGradient id="GID1" x1="194.6" x2="194.6" y1="81.75" y2="138.3" gradientUnits="userSpaceOnUse">
|
|
1453
|
-
<stop stop-color="#663BA6"/><stop stop-color="#7939C2" offset=".349"/><stop stop-color="#8A2FC0" offset=".6615"/><stop stop-color="#791BA3" offset="1"/>
|
|
1454
|
-
</linearGradient>
|
|
1455
|
-
<linearGradient id="GID2" x1="157.8" x2="157.8" y1="81.75" y2="127" gradientUnits="userSpaceOnUse">
|
|
1456
|
-
<stop stop-color="#663BA6"/><stop stop-color="#7939C2" offset=".349"/><stop stop-color="#8A2FC0" offset=".6615"/><stop stop-color="#791BA3" offset="1"/>
|
|
1457
|
-
</linearGradient>
|
|
1458
|
-
<linearGradient id="GID3" x1="79.96" x2="79.96" y1="81.75" y2="141.8" gradientUnits="userSpaceOnUse">
|
|
1459
|
-
<stop stop-color="#663BA6"/><stop stop-color="#7939C2" offset=".349"/><stop stop-color="#8A2FC0" offset=".6615"/><stop stop-color="#791BA3" offset="1"/>
|
|
1460
|
-
</linearGradient>
|
|
1461
|
-
<linearGradient id="GID4" x1="36.18" x2="212.5" y1="156.6" y2="156.6" gradientUnits="userSpaceOnUse">
|
|
1462
|
-
<stop stop-color="#316FB0"/><stop stop-color="#1FCDE6" offset=".5"/><stop stop-color="#29FEE7" offset="1"/>
|
|
1463
|
-
</linearGradient>
|
|
1464
|
-
<linearGradient id="GID5" x1="40.27" x2="208.2" y1="156.4" y2="156.4" gradientUnits="userSpaceOnUse">
|
|
1465
|
-
<stop stop-color="#316FB0"/><stop stop-color="#1FCDE6" offset=".5"/><stop stop-color="#29FEE7" offset="1"/>
|
|
1466
|
-
</linearGradient>`;
|
|
1467
|
-
/** Max width of the loader bar in SVG units */
|
|
1468
|
-
const LOADER_BAR_MAX_WIDTH = 174;
|
|
1469
|
-
/**
|
|
1470
|
-
* Build the Energy8 SVG logo with a loader bar, using unique IDs.
|
|
1471
|
-
*
|
|
1472
|
-
* @param opts - Configuration to avoid element ID collisions
|
|
1473
|
-
* @returns SVG markup string
|
|
1474
|
-
*/
|
|
1475
|
-
function buildLogoSVG(opts) {
|
|
1476
|
-
const { idPrefix, svgClass, svgStyle, clipRectClass, clipRectId, textId, textContent, textClass } = opts;
|
|
1477
|
-
// Replace gradient ID placeholders with prefixed versions
|
|
1478
|
-
const paths = WORDMARK_PATHS.replace(/GID(\d)/g, `${idPrefix}$1`);
|
|
1479
|
-
const defs = GRADIENT_DEFS.replace(/GID(\d)/g, `${idPrefix}$1`);
|
|
1480
|
-
const clipId = `${idPrefix}-loader-clip`;
|
|
1481
|
-
const fillGradientId = `${idPrefix}5`;
|
|
1482
|
-
const classAttr = svgClass ? ` class="${svgClass}"` : '';
|
|
1483
|
-
const styleAttr = svgStyle ? ` style="${svgStyle}"` : '';
|
|
1484
|
-
const rectClassAttr = clipRectClass ? ` class="${clipRectClass}"` : '';
|
|
1485
|
-
const rectIdAttr = clipRectId ? ` id="${clipRectId}"` : '';
|
|
1486
|
-
const txtIdAttr = textId ? ` id="${textId}"` : '';
|
|
1487
|
-
const txtClassAttr = textClass ? ` class="${textClass}"` : '';
|
|
1488
|
-
return `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 250 200" fill="none"${classAttr}${styleAttr}>
|
|
1489
|
-
${paths}
|
|
1490
|
-
<clipPath id="${clipId}">
|
|
1491
|
-
<rect${rectIdAttr} x="37" y="148" width="0" height="20"${rectClassAttr}/>
|
|
1492
|
-
</clipPath>
|
|
1493
|
-
<path d="m204.5 152.6h-159.8c-2.78 0-4.45 1.69-4.45 3.99v0.11c0 2.04 1.42 3.43 3.64 3.43h160.6c2.88 0 3.67-2.07 3.67-3.43v-0.25c0-2.04-1.48-3.85-3.67-3.85z" fill="url(#${fillGradientId})" clip-path="url(#${clipId})"/>
|
|
1494
|
-
<text${txtIdAttr} x="125" y="196" text-anchor="middle" fill="rgba(255,255,255,0.6)" font-family="-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif" font-size="8" font-weight="600" letter-spacing="1.5"${txtClassAttr}>${textContent ?? 'Loading...'}</text>
|
|
1495
|
-
<defs>
|
|
1496
|
-
${defs}
|
|
1497
|
-
</defs>
|
|
1498
|
-
</svg>`;
|
|
1499
|
-
}
|
|
1500
|
-
|
|
1501
1433
|
/**
|
|
1502
1434
|
* Build the loading scene variant of the logo SVG.
|
|
1503
1435
|
* Uses unique IDs (prefixed with 'ls') to avoid collisions with CSSPreloader.
|
|
1504
1436
|
*/
|
|
1505
1437
|
function buildLoadingLogoSVG() {
|
|
1506
|
-
return buildLogoSVG({
|
|
1438
|
+
return loading.buildLogoSVG({
|
|
1507
1439
|
idPrefix: 'ls',
|
|
1508
1440
|
svgStyle: 'width:100%;height:auto;',
|
|
1509
1441
|
clipRectId: 'ge-loader-rect',
|
|
@@ -1684,7 +1616,7 @@ class LoadingScene extends Scene {
|
|
|
1684
1616
|
// ─── Progress ──────────────────────────────────────────
|
|
1685
1617
|
updateLoaderBar(progress) {
|
|
1686
1618
|
if (this._loaderRect) {
|
|
1687
|
-
this._loaderRect.setAttribute('width', String(LOADER_BAR_MAX_WIDTH * progress));
|
|
1619
|
+
this._loaderRect.setAttribute('width', String(loading.LOADER_BAR_MAX_WIDTH * progress));
|
|
1688
1620
|
}
|
|
1689
1621
|
if (this._percentEl) {
|
|
1690
1622
|
const pct = Math.round(progress * 100);
|
|
@@ -1766,120 +1698,6 @@ class LoadingScene extends Scene {
|
|
|
1766
1698
|
}
|
|
1767
1699
|
}
|
|
1768
1700
|
|
|
1769
|
-
const PRELOADER_ID = '__ge-css-preloader__';
|
|
1770
|
-
/**
|
|
1771
|
-
* Inline SVG logo with animated loader bar.
|
|
1772
|
-
* The `#loader` path acts as the progress fill — animated via clipPath.
|
|
1773
|
-
*/
|
|
1774
|
-
const LOGO_SVG = buildLogoSVG({
|
|
1775
|
-
idPrefix: 'pl',
|
|
1776
|
-
svgClass: 'ge-logo-svg',
|
|
1777
|
-
clipRectClass: 'ge-clip-rect',
|
|
1778
|
-
textClass: 'ge-preloader-svg-text',
|
|
1779
|
-
});
|
|
1780
|
-
/**
|
|
1781
|
-
* Creates a lightweight CSS-only preloader that appears instantly,
|
|
1782
|
-
* BEFORE PixiJS/WebGL is initialized.
|
|
1783
|
-
*
|
|
1784
|
-
* Displays the Energy8 logo SVG with an animated loader bar.
|
|
1785
|
-
*/
|
|
1786
|
-
function createCSSPreloader(container, config) {
|
|
1787
|
-
if (document.getElementById(PRELOADER_ID))
|
|
1788
|
-
return;
|
|
1789
|
-
const bgColor = typeof config?.backgroundColor === 'string'
|
|
1790
|
-
? config.backgroundColor
|
|
1791
|
-
: typeof config?.backgroundColor === 'number'
|
|
1792
|
-
? `#${config.backgroundColor.toString(16).padStart(6, '0')}`
|
|
1793
|
-
: '#0a0a1a';
|
|
1794
|
-
const bgGradient = config?.backgroundGradient ?? `linear-gradient(135deg, ${bgColor} 0%, #1a1a3e 100%)`;
|
|
1795
|
-
const customHTML = config?.cssPreloaderHTML ?? '';
|
|
1796
|
-
const el = document.createElement('div');
|
|
1797
|
-
el.id = PRELOADER_ID;
|
|
1798
|
-
el.innerHTML = customHTML || `
|
|
1799
|
-
<div class="ge-preloader-content">
|
|
1800
|
-
${LOGO_SVG}
|
|
1801
|
-
</div>
|
|
1802
|
-
`;
|
|
1803
|
-
const style = document.createElement('style');
|
|
1804
|
-
style.textContent = `
|
|
1805
|
-
#${PRELOADER_ID} {
|
|
1806
|
-
position: absolute;
|
|
1807
|
-
top: 0; left: 0;
|
|
1808
|
-
width: 100%; height: 100%;
|
|
1809
|
-
background: ${bgGradient};
|
|
1810
|
-
display: flex;
|
|
1811
|
-
align-items: center;
|
|
1812
|
-
justify-content: center;
|
|
1813
|
-
z-index: 10000;
|
|
1814
|
-
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
|
1815
|
-
transition: opacity 0.4s ease-out;
|
|
1816
|
-
}
|
|
1817
|
-
|
|
1818
|
-
#${PRELOADER_ID}.ge-preloader-hidden {
|
|
1819
|
-
opacity: 0;
|
|
1820
|
-
pointer-events: none;
|
|
1821
|
-
}
|
|
1822
|
-
|
|
1823
|
-
.ge-preloader-content {
|
|
1824
|
-
display: flex;
|
|
1825
|
-
flex-direction: column;
|
|
1826
|
-
align-items: center;
|
|
1827
|
-
width: 80%;
|
|
1828
|
-
max-width: 700px;
|
|
1829
|
-
}
|
|
1830
|
-
|
|
1831
|
-
.ge-logo-svg {
|
|
1832
|
-
width: 100%;
|
|
1833
|
-
height: auto;
|
|
1834
|
-
filter: drop-shadow(0 0 30px rgba(121, 57, 194, 0.4));
|
|
1835
|
-
}
|
|
1836
|
-
|
|
1837
|
-
/* Animate the loader clip-rect to shimmer while waiting */
|
|
1838
|
-
.ge-clip-rect {
|
|
1839
|
-
animation: ge-loader-fill 2s ease-in-out infinite;
|
|
1840
|
-
}
|
|
1841
|
-
|
|
1842
|
-
@keyframes ge-loader-fill {
|
|
1843
|
-
0% { width: 0; }
|
|
1844
|
-
50% { width: 174; }
|
|
1845
|
-
100% { width: 0; }
|
|
1846
|
-
}
|
|
1847
|
-
|
|
1848
|
-
/* Animate the SVG text opacity */
|
|
1849
|
-
.ge-preloader-svg-text {
|
|
1850
|
-
animation: ge-pulse 1.5s ease-in-out infinite;
|
|
1851
|
-
}
|
|
1852
|
-
|
|
1853
|
-
@keyframes ge-pulse {
|
|
1854
|
-
0%, 100% { opacity: 0.4; }
|
|
1855
|
-
50% { opacity: 1; }
|
|
1856
|
-
}
|
|
1857
|
-
`;
|
|
1858
|
-
container.style.position = container.style.position || 'relative';
|
|
1859
|
-
container.appendChild(style);
|
|
1860
|
-
container.appendChild(el);
|
|
1861
|
-
}
|
|
1862
|
-
/**
|
|
1863
|
-
* Remove the CSS preloader with a smooth fade-out transition.
|
|
1864
|
-
*/
|
|
1865
|
-
function removeCSSPreloader(container) {
|
|
1866
|
-
const el = document.getElementById(PRELOADER_ID);
|
|
1867
|
-
if (!el)
|
|
1868
|
-
return;
|
|
1869
|
-
el.classList.add('ge-preloader-hidden');
|
|
1870
|
-
// Remove after transition
|
|
1871
|
-
el.addEventListener('transitionend', () => {
|
|
1872
|
-
el.remove();
|
|
1873
|
-
// Also remove the style element
|
|
1874
|
-
const styles = container.querySelectorAll('style');
|
|
1875
|
-
for (const style of styles) {
|
|
1876
|
-
if (style.textContent?.includes(PRELOADER_ID)) {
|
|
1877
|
-
style.remove();
|
|
1878
|
-
}
|
|
1879
|
-
}
|
|
1880
|
-
});
|
|
1881
|
-
}
|
|
1882
|
-
|
|
1883
1701
|
/**
|
|
1884
1702
|
* FPS overlay for debugging performance.
|
|
1885
1703
|
*
|
|
@@ -2021,6 +1839,8 @@ class GameApplication extends EventEmitter {
|
|
|
2021
1839
|
fpsOverlay = null;
|
|
2022
1840
|
/** Data received from SDK initialization */
|
|
2023
1841
|
initData = null;
|
|
1842
|
+
/** Platform session (SDK + optional DevBridge). null until start() runs. */
|
|
1843
|
+
platformSession = null;
|
|
2024
1844
|
/** Configuration */
|
|
2025
1845
|
config;
|
|
2026
1846
|
// ─── Private state ──────────────────────────────────────
|
|
@@ -2077,7 +1897,7 @@ class GameApplication extends EventEmitter {
|
|
|
2077
1897
|
// 1. Resolve container element
|
|
2078
1898
|
this._container = this.resolveContainer();
|
|
2079
1899
|
// 2. Show CSS preloader immediately (before PixiJS)
|
|
2080
|
-
createCSSPreloader(this._container, this.config.loading);
|
|
1900
|
+
loading.createCSSPreloader(this._container, this.config.loading);
|
|
2081
1901
|
// 3. Initialize PixiJS
|
|
2082
1902
|
await this.initPixi();
|
|
2083
1903
|
// 4. Initialize SDK (if enabled)
|
|
@@ -2088,7 +1908,7 @@ class GameApplication extends EventEmitter {
|
|
|
2088
1908
|
this.initSubSystems();
|
|
2089
1909
|
this.emit('initialized');
|
|
2090
1910
|
// 7. Remove CSS preloader, show Canvas loading screen
|
|
2091
|
-
removeCSSPreloader(this._container);
|
|
1911
|
+
loading.removeCSSPreloader(this._container);
|
|
2092
1912
|
// 8. Load assets with loading screen
|
|
2093
1913
|
await this.loadAssets(firstScene, sceneData);
|
|
2094
1914
|
this.emit('loaded');
|
|
@@ -2114,7 +1934,7 @@ class GameApplication extends EventEmitter {
|
|
|
2114
1934
|
this.input?.destroy();
|
|
2115
1935
|
this.audio?.destroy();
|
|
2116
1936
|
this.viewport?.destroy();
|
|
2117
|
-
this.
|
|
1937
|
+
this.platformSession?.destroy();
|
|
2118
1938
|
this.app?.destroy(true, { children: true, texture: true });
|
|
2119
1939
|
this.emit('destroyed');
|
|
2120
1940
|
this.removeAllListeners();
|
|
@@ -2150,20 +1970,15 @@ class GameApplication extends EventEmitter {
|
|
|
2150
1970
|
this.app.canvas.style.height = '100%';
|
|
2151
1971
|
}
|
|
2152
1972
|
async initSDK() {
|
|
2153
|
-
|
|
2154
|
-
|
|
2155
|
-
|
|
2156
|
-
|
|
2157
|
-
|
|
2158
|
-
|
|
2159
|
-
this.sdk = new gameSdk.CasinoGameSDK(sdkOpts);
|
|
2160
|
-
// Perform the handshake
|
|
2161
|
-
this.initData = await this.sdk.ready();
|
|
2162
|
-
// Forward SDK events
|
|
2163
|
-
this.sdk.on('error', (err) => {
|
|
1973
|
+
// Delegate the SDK handshake (and any optional in-process DevBridge
|
|
1974
|
+
// wiring) to platform-core. The session forwards SDK events upward.
|
|
1975
|
+
this.platformSession = await platformCore.createPlatformSession({ sdk: this.config.sdk });
|
|
1976
|
+
this.sdk = this.platformSession.sdk;
|
|
1977
|
+
this.initData = this.platformSession.initData;
|
|
1978
|
+
this.platformSession.on('error', (err) => {
|
|
2164
1979
|
this.emit('error', err);
|
|
2165
1980
|
});
|
|
2166
|
-
this.
|
|
1981
|
+
this.platformSession.on('balanceUpdate', (data) => {
|
|
2167
1982
|
this.emit('balanceUpdate', data);
|
|
2168
1983
|
});
|
|
2169
1984
|
}
|