@energy8platform/platform-core 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 +482 -0
- package/bin/simulate.ts +139 -0
- package/dist/dev-bridge.cjs.js +237 -0
- package/dist/dev-bridge.cjs.js.map +1 -0
- package/dist/dev-bridge.d.ts +141 -0
- package/dist/dev-bridge.esm.js +235 -0
- package/dist/dev-bridge.esm.js.map +1 -0
- package/dist/index.cjs.js +569 -0
- package/dist/index.cjs.js.map +1 -0
- package/dist/index.d.ts +439 -0
- package/dist/index.esm.js +560 -0
- package/dist/index.esm.js.map +1 -0
- package/dist/loading.cjs.js +190 -0
- package/dist/loading.cjs.js.map +1 -0
- package/dist/loading.d.ts +86 -0
- package/dist/loading.esm.js +185 -0
- package/dist/loading.esm.js.map +1 -0
- package/dist/lua.cjs.js +1129 -0
- package/dist/lua.cjs.js.map +1 -0
- package/dist/lua.d.ts +319 -0
- package/dist/lua.esm.js +1119 -0
- package/dist/lua.esm.js.map +1 -0
- package/dist/simulation.cjs.js +374 -0
- package/dist/simulation.cjs.js.map +1 -0
- package/dist/simulation.d.ts +190 -0
- package/dist/simulation.esm.js +368 -0
- package/dist/simulation.esm.js.map +1 -0
- package/dist/vite.cjs.js +179 -0
- package/dist/vite.cjs.js.map +1 -0
- package/dist/vite.d.ts +13 -0
- package/dist/vite.esm.js +176 -0
- package/dist/vite.esm.js.map +1 -0
- package/package.json +100 -0
- package/scripts/install-simulate.mjs +101 -0
- package/src/EventEmitter.ts +55 -0
- package/src/PlatformSession.ts +156 -0
- package/src/dev-bridge/DevBridge.ts +305 -0
- package/src/dev-bridge/index.ts +2 -0
- package/src/index.ts +98 -0
- package/src/loading/CSSPreloader.ts +129 -0
- package/src/loading/index.ts +3 -0
- package/src/loading/logo.ts +95 -0
- package/src/lua/ActionRouter.ts +132 -0
- package/src/lua/LuaEngine.ts +412 -0
- package/src/lua/LuaEngineAPI.ts +314 -0
- package/src/lua/PersistentState.ts +80 -0
- package/src/lua/SessionManager.ts +227 -0
- package/src/lua/SimulationRunner.ts +192 -0
- package/src/lua/fengari.d.ts +10 -0
- package/src/lua/index.ts +28 -0
- package/src/lua/types.ts +149 -0
- package/src/simulation/NativeSimulationRunner.ts +367 -0
- package/src/simulation/ParallelSimulationRunner.ts +156 -0
- package/src/simulation/SimulationWorker.ts +44 -0
- package/src/simulation/index.ts +21 -0
- package/src/types.ts +85 -0
- package/src/vite/index.ts +196 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,439 @@
|
|
|
1
|
+
import { SessionData, GameConfigData, PlayParams, PlayResultData, BalanceData, CasinoGameSDK, InitData } from '@energy8platform/game-sdk';
|
|
2
|
+
export { AnywhereWinData, BalanceData, GameConfigData, InitData, PaylineData, PlayParams, PlayResultData, SessionData, SymbolData, WinLineData } from '@energy8platform/game-sdk';
|
|
3
|
+
|
|
4
|
+
interface GameDefinition {
|
|
5
|
+
id: string;
|
|
6
|
+
type: 'SLOT' | 'TABLE';
|
|
7
|
+
actions: Record<string, ActionDefinition>;
|
|
8
|
+
bet_levels?: number[] | BetLevelsConfig;
|
|
9
|
+
max_win?: MaxWinConfig;
|
|
10
|
+
buy_bonus?: BuyBonusConfig;
|
|
11
|
+
ante_bet?: AnteBetConfig;
|
|
12
|
+
persistent_state?: PersistentStateConfig;
|
|
13
|
+
}
|
|
14
|
+
interface BetLevelsConfig {
|
|
15
|
+
levels?: number[];
|
|
16
|
+
min?: number;
|
|
17
|
+
max?: number;
|
|
18
|
+
}
|
|
19
|
+
interface MaxWinConfig {
|
|
20
|
+
multiplier?: number;
|
|
21
|
+
fixed?: number;
|
|
22
|
+
}
|
|
23
|
+
interface BuyBonusConfig {
|
|
24
|
+
modes: Record<string, BuyBonusMode>;
|
|
25
|
+
}
|
|
26
|
+
interface BuyBonusMode {
|
|
27
|
+
cost_multiplier: number;
|
|
28
|
+
/** Distribution of forced scatter counts. Optional — if omitted, Lua script handles bonus setup itself. */
|
|
29
|
+
scatter_distribution?: Record<string, number>;
|
|
30
|
+
/** Optional description */
|
|
31
|
+
description?: string;
|
|
32
|
+
}
|
|
33
|
+
interface AnteBetConfig {
|
|
34
|
+
cost_multiplier: number;
|
|
35
|
+
}
|
|
36
|
+
interface PersistentStateConfig {
|
|
37
|
+
vars: string[];
|
|
38
|
+
exposed_vars: string[];
|
|
39
|
+
}
|
|
40
|
+
interface ActionDefinition {
|
|
41
|
+
stage: string;
|
|
42
|
+
debit: 'bet' | 'buy_bonus_cost' | 'ante_bet_cost' | 'none';
|
|
43
|
+
credit?: 'win' | 'none' | 'defer';
|
|
44
|
+
requires_session?: boolean;
|
|
45
|
+
buy_bonus_mode?: string;
|
|
46
|
+
transitions: TransitionRule[];
|
|
47
|
+
input_schema?: Record<string, unknown>;
|
|
48
|
+
}
|
|
49
|
+
interface TransitionRule {
|
|
50
|
+
condition: string;
|
|
51
|
+
creates_session?: boolean;
|
|
52
|
+
complete_session?: boolean;
|
|
53
|
+
credit_override?: 'defer';
|
|
54
|
+
next_actions: string[];
|
|
55
|
+
session_config?: SessionConfig;
|
|
56
|
+
add_spins_var?: string;
|
|
57
|
+
}
|
|
58
|
+
interface SessionConfig {
|
|
59
|
+
total_spins_var: string;
|
|
60
|
+
persistent_vars?: string[];
|
|
61
|
+
}
|
|
62
|
+
interface LuaEngineConfig {
|
|
63
|
+
/** Lua script source code */
|
|
64
|
+
script: string;
|
|
65
|
+
/** Platform game definition (actions, transitions, bet levels, etc.) */
|
|
66
|
+
gameDefinition: GameDefinition;
|
|
67
|
+
/** Seed for deterministic RNG (for simulation/replay) */
|
|
68
|
+
seed?: number;
|
|
69
|
+
/** Custom logger function */
|
|
70
|
+
logger?: (level: string, msg: string) => void;
|
|
71
|
+
/** Skip marshalling data fields (matrix, wins, etc.) for faster simulation */
|
|
72
|
+
simulationMode?: boolean;
|
|
73
|
+
}
|
|
74
|
+
interface LuaPlayResult {
|
|
75
|
+
totalWin: number;
|
|
76
|
+
data: Record<string, unknown>;
|
|
77
|
+
nextActions: string[];
|
|
78
|
+
session: SessionData | null;
|
|
79
|
+
variables: Record<string, number>;
|
|
80
|
+
creditDeferred: boolean;
|
|
81
|
+
}
|
|
82
|
+
interface SimulationConfig {
|
|
83
|
+
/** Lua script source code */
|
|
84
|
+
script: string;
|
|
85
|
+
/** Platform game definition */
|
|
86
|
+
gameDefinition: GameDefinition;
|
|
87
|
+
/** Number of iterations to run */
|
|
88
|
+
iterations: number;
|
|
89
|
+
/** Bet amount per spin */
|
|
90
|
+
bet: number;
|
|
91
|
+
/** RNG seed for deterministic results */
|
|
92
|
+
seed?: number;
|
|
93
|
+
/** Which action to simulate (default: 'spin') */
|
|
94
|
+
action?: string;
|
|
95
|
+
/** Params for the action (buy_bonus mode, ante_bet, etc.) */
|
|
96
|
+
params?: Record<string, unknown>;
|
|
97
|
+
/** Report progress every N iterations (default: 100_000) */
|
|
98
|
+
progressInterval?: number;
|
|
99
|
+
/** Progress callback */
|
|
100
|
+
onProgress?: (completed: number, total: number) => void;
|
|
101
|
+
/** Number of worker threads for parallel simulation (default: os.cpus().length) */
|
|
102
|
+
workerCount?: number;
|
|
103
|
+
}
|
|
104
|
+
interface SimulationResult {
|
|
105
|
+
gameId: string;
|
|
106
|
+
action: string;
|
|
107
|
+
iterations: number;
|
|
108
|
+
durationMs: number;
|
|
109
|
+
totalRtp: number;
|
|
110
|
+
baseGameRtp: number;
|
|
111
|
+
bonusRtp: number;
|
|
112
|
+
hitFrequency: number;
|
|
113
|
+
maxWin: number;
|
|
114
|
+
maxWinHits: number;
|
|
115
|
+
bonusTriggered: number;
|
|
116
|
+
bonusSpinsPlayed: number;
|
|
117
|
+
/** Raw accumulators for aggregation across workers */
|
|
118
|
+
_raw?: SimulationRawAccumulators;
|
|
119
|
+
}
|
|
120
|
+
interface SimulationRawAccumulators {
|
|
121
|
+
totalWagered: number;
|
|
122
|
+
totalWon: number;
|
|
123
|
+
baseGameWin: number;
|
|
124
|
+
bonusWin: number;
|
|
125
|
+
hits: number;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
interface DevBridgeConfig {
|
|
129
|
+
/** Mock initial balance */
|
|
130
|
+
balance?: number;
|
|
131
|
+
/** Mock currency */
|
|
132
|
+
currency?: string;
|
|
133
|
+
/** Game config */
|
|
134
|
+
gameConfig?: Partial<GameConfigData>;
|
|
135
|
+
/** Base URL for assets (default: '/assets/') */
|
|
136
|
+
assetsUrl?: string;
|
|
137
|
+
/** Active session to resume (null = no active session) */
|
|
138
|
+
session?: SessionData | null;
|
|
139
|
+
/** Custom play result handler — return mock result data */
|
|
140
|
+
onPlay?: (params: PlayParams) => Partial<PlayResultData>;
|
|
141
|
+
/** Simulated network delay in ms */
|
|
142
|
+
networkDelay?: number;
|
|
143
|
+
/** Enable debug logging */
|
|
144
|
+
debug?: boolean;
|
|
145
|
+
/** Lua script source code. When set, play requests are routed to the Vite dev server's LuaEngine. */
|
|
146
|
+
luaScript?: string;
|
|
147
|
+
/** Game definition for Lua engine (actions, transitions, etc.) */
|
|
148
|
+
gameDefinition?: GameDefinition;
|
|
149
|
+
/** RNG seed for deterministic Lua execution */
|
|
150
|
+
luaSeed?: number;
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Mock host bridge for local development.
|
|
154
|
+
*
|
|
155
|
+
* Uses the SDK's `Bridge` class in `devMode` to communicate with
|
|
156
|
+
* `CasinoGameSDK` via a shared in-memory `MemoryChannel`, removing
|
|
157
|
+
* the need for postMessage and iframes.
|
|
158
|
+
*
|
|
159
|
+
* When `luaScript` is set, play requests are sent to the Vite dev server
|
|
160
|
+
* which runs LuaEngine in Node.js — no fengari in the browser.
|
|
161
|
+
*
|
|
162
|
+
* @example
|
|
163
|
+
* ```ts
|
|
164
|
+
* import { DevBridge } from '@energy8platform/platform-core/dev-bridge';
|
|
165
|
+
*
|
|
166
|
+
* const devBridge = new DevBridge({
|
|
167
|
+
* balance: 5000,
|
|
168
|
+
* currency: 'EUR',
|
|
169
|
+
* gameConfig: { id: 'my-slot', type: 'slot', betLevels: [0.2, 0.5, 1, 2] },
|
|
170
|
+
* onPlay: ({ action, bet }) => ({
|
|
171
|
+
* totalWin: Math.random() > 0.5 ? bet * (Math.random() * 20) : 0,
|
|
172
|
+
* data: { matrix: [[1,2,3],[4,5,6],[7,8,9]] },
|
|
173
|
+
* }),
|
|
174
|
+
* });
|
|
175
|
+
* devBridge.start();
|
|
176
|
+
* ```
|
|
177
|
+
*/
|
|
178
|
+
declare class DevBridge {
|
|
179
|
+
private _config;
|
|
180
|
+
private _balance;
|
|
181
|
+
private _roundCounter;
|
|
182
|
+
private _bridge;
|
|
183
|
+
private _useLuaServer;
|
|
184
|
+
constructor(config?: DevBridgeConfig);
|
|
185
|
+
/** Current mock balance */
|
|
186
|
+
get balance(): number;
|
|
187
|
+
/** Start listening for SDK messages */
|
|
188
|
+
start(): void;
|
|
189
|
+
/** Stop listening */
|
|
190
|
+
stop(): void;
|
|
191
|
+
/** Set mock balance */
|
|
192
|
+
setBalance(balance: number): void;
|
|
193
|
+
/** Destroy the dev bridge */
|
|
194
|
+
destroy(): void;
|
|
195
|
+
private handleGameReady;
|
|
196
|
+
private handlePlayRequest;
|
|
197
|
+
private executeLuaOnServer;
|
|
198
|
+
private buildFallbackResult;
|
|
199
|
+
private handlePlayAck;
|
|
200
|
+
private handleGetBalance;
|
|
201
|
+
private handleGetState;
|
|
202
|
+
private handleOpenDeposit;
|
|
203
|
+
private delayedSend;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
/**
|
|
207
|
+
* Minimal typed event emitter — internal utility for platform-core.
|
|
208
|
+
*
|
|
209
|
+
* Supports `void` event types — events that carry no data can be emitted
|
|
210
|
+
* without arguments: `emitter.emit('eventName')`.
|
|
211
|
+
*
|
|
212
|
+
* Mirrors the EventEmitter shipped from game-engine's core, copied here
|
|
213
|
+
* so platform-core has no upward dependency on game-engine.
|
|
214
|
+
*/
|
|
215
|
+
declare class EventEmitter<TEvents extends {}> {
|
|
216
|
+
private listeners;
|
|
217
|
+
on<K extends keyof TEvents>(event: K, handler: (data: TEvents[K]) => void): this;
|
|
218
|
+
once<K extends keyof TEvents>(event: K, handler: (data: TEvents[K]) => void): this;
|
|
219
|
+
off<K extends keyof TEvents>(event: K, handler: (data: TEvents[K]) => void): this;
|
|
220
|
+
emit<K extends keyof TEvents>(...args: TEvents[K] extends void ? [event: K] : [event: K, data: TEvents[K]]): void;
|
|
221
|
+
removeAllListeners(event?: keyof TEvents): this;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
/**
|
|
225
|
+
* Options for {@link createPlatformSession}.
|
|
226
|
+
*/
|
|
227
|
+
interface PlatformSessionConfig {
|
|
228
|
+
/**
|
|
229
|
+
* Optional DevBridge mock-host config. When provided, a DevBridge is started
|
|
230
|
+
* in-process and the SDK connects to it via in-memory channel — no real
|
|
231
|
+
* casino backend required. Use this for local development and offline
|
|
232
|
+
* testing.
|
|
233
|
+
*/
|
|
234
|
+
dev?: DevBridgeConfig;
|
|
235
|
+
/**
|
|
236
|
+
* SDK configuration. Pass an options object, or `false` to skip SDK
|
|
237
|
+
* initialization entirely (no host communication, used by tests and
|
|
238
|
+
* head-less simulation).
|
|
239
|
+
*/
|
|
240
|
+
sdk?: SDKOptions | false;
|
|
241
|
+
}
|
|
242
|
+
interface SDKOptions {
|
|
243
|
+
parentOrigin?: string;
|
|
244
|
+
timeout?: number;
|
|
245
|
+
debug?: boolean;
|
|
246
|
+
/** Use in-memory channel instead of postMessage (no iframe required) */
|
|
247
|
+
devMode?: boolean;
|
|
248
|
+
}
|
|
249
|
+
/**
|
|
250
|
+
* Events forwarded from the underlying SDK by the PlatformSession.
|
|
251
|
+
*/
|
|
252
|
+
interface PlatformSessionEvents {
|
|
253
|
+
/** Player balance changed (forwarded from CasinoGameSDK) */
|
|
254
|
+
balanceUpdate: BalanceData;
|
|
255
|
+
/** SDK or transport error */
|
|
256
|
+
error: Error;
|
|
257
|
+
}
|
|
258
|
+
/**
|
|
259
|
+
* Lifecycle wrapper around CasinoGameSDK + (optional) DevBridge.
|
|
260
|
+
*
|
|
261
|
+
* Use `createPlatformSession()` to construct one. The session owns the SDK
|
|
262
|
+
* handshake, optional in-process dev host, and a typed event bus that
|
|
263
|
+
* forwards SDK events upward.
|
|
264
|
+
*
|
|
265
|
+
* Phaser/Three/custom-engine consumers use this directly:
|
|
266
|
+
*
|
|
267
|
+
* ```ts
|
|
268
|
+
* const session = await createPlatformSession({
|
|
269
|
+
* dev: { luaScript, gameDefinition, balance: 10000, currency: 'EUR' },
|
|
270
|
+
* });
|
|
271
|
+
*
|
|
272
|
+
* session.on('balanceUpdate', ({ balance }) => updateHud(balance));
|
|
273
|
+
* const result = await session.play({ action: 'spin', bet: 1 });
|
|
274
|
+
* ```
|
|
275
|
+
*/
|
|
276
|
+
declare class PlatformSession extends EventEmitter<PlatformSessionEvents> {
|
|
277
|
+
/** SDK instance, or null when `sdk: false` was passed. */
|
|
278
|
+
readonly sdk: CasinoGameSDK | null;
|
|
279
|
+
/** Data returned by the SDK handshake, or null in offline mode. */
|
|
280
|
+
readonly initData: InitData | null;
|
|
281
|
+
/** DevBridge mock host, or null when `dev` was not provided. */
|
|
282
|
+
readonly devBridge: DevBridge | null;
|
|
283
|
+
constructor(opts: {
|
|
284
|
+
sdk: CasinoGameSDK | null;
|
|
285
|
+
initData: InitData | null;
|
|
286
|
+
devBridge: DevBridge | null;
|
|
287
|
+
});
|
|
288
|
+
/** Current player balance from the SDK (0 if no SDK). */
|
|
289
|
+
get balance(): number;
|
|
290
|
+
/** Current currency from the SDK ('USD' fallback). */
|
|
291
|
+
get currency(): string;
|
|
292
|
+
/**
|
|
293
|
+
* Send a play request through the SDK and resolve with the host result.
|
|
294
|
+
* Throws if the session was constructed with `sdk: false`.
|
|
295
|
+
*/
|
|
296
|
+
play(params: PlayParams): Promise<PlayResultData>;
|
|
297
|
+
/** Tear down the SDK, DevBridge, and clear listeners. */
|
|
298
|
+
destroy(): void;
|
|
299
|
+
}
|
|
300
|
+
/**
|
|
301
|
+
* Build a PlatformSession.
|
|
302
|
+
*
|
|
303
|
+
* Steps performed:
|
|
304
|
+
* 1. If `config.dev` is set → start a DevBridge with those options
|
|
305
|
+
* 2. Unless `config.sdk === false` → construct CasinoGameSDK and await its handshake
|
|
306
|
+
* 3. Forward `error` and `balanceUpdate` events from the SDK
|
|
307
|
+
*/
|
|
308
|
+
declare function createPlatformSession(config?: PlatformSessionConfig): Promise<PlatformSession>;
|
|
309
|
+
|
|
310
|
+
interface AssetEntry {
|
|
311
|
+
alias: string;
|
|
312
|
+
src: string | string[];
|
|
313
|
+
/** Optional loader-specific data (e.g. parser hints) */
|
|
314
|
+
data?: Record<string, unknown>;
|
|
315
|
+
}
|
|
316
|
+
interface AssetBundle {
|
|
317
|
+
name: string;
|
|
318
|
+
assets: AssetEntry[];
|
|
319
|
+
}
|
|
320
|
+
interface AssetManifest {
|
|
321
|
+
bundles: AssetBundle[];
|
|
322
|
+
}
|
|
323
|
+
interface LoadingScreenConfig {
|
|
324
|
+
/** Background color (hex number or CSS string) */
|
|
325
|
+
backgroundColor?: number | string;
|
|
326
|
+
/** Background gradient (CSS string applied to the CSS preloader) */
|
|
327
|
+
backgroundGradient?: string;
|
|
328
|
+
/** Logo texture alias (must be in 'preload' bundle — engine-specific) */
|
|
329
|
+
logoAsset?: string;
|
|
330
|
+
/** Logo scale (default: 1) */
|
|
331
|
+
logoScale?: number;
|
|
332
|
+
/** Show percentage text below the loader bar */
|
|
333
|
+
showPercentage?: boolean;
|
|
334
|
+
/** Custom progress text formatter */
|
|
335
|
+
progressTextFormatter?: (progress: number) => string;
|
|
336
|
+
/** Show "Tap to start" after loading (needed for mobile audio unlock) */
|
|
337
|
+
tapToStart?: boolean;
|
|
338
|
+
/** "Tap to start" label text */
|
|
339
|
+
tapToStartText?: string;
|
|
340
|
+
/** Minimum display time in ms (so the user sees the brand, even if loading is fast) */
|
|
341
|
+
minDisplayTime?: number;
|
|
342
|
+
/** CSS preloader custom HTML (shown before the renderer is ready) */
|
|
343
|
+
cssPreloaderHTML?: string;
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
/**
|
|
347
|
+
* Creates a lightweight CSS-only preloader that appears instantly,
|
|
348
|
+
* BEFORE PixiJS/WebGL is initialized.
|
|
349
|
+
*
|
|
350
|
+
* Displays the Energy8 logo SVG with an animated loader bar.
|
|
351
|
+
*/
|
|
352
|
+
declare function createCSSPreloader(container: HTMLElement, config?: LoadingScreenConfig): void;
|
|
353
|
+
/**
|
|
354
|
+
* Remove the CSS preloader with a smooth fade-out transition.
|
|
355
|
+
*/
|
|
356
|
+
declare function removeCSSPreloader(container: HTMLElement): void;
|
|
357
|
+
|
|
358
|
+
/**
|
|
359
|
+
* Shared Energy8 SVG logo with an embedded loader bar.
|
|
360
|
+
*
|
|
361
|
+
* The loader bar fill is controlled via a `<clipPath>` whose `<rect>` width
|
|
362
|
+
* is animatable. Different consumers customise gradient IDs and the clip
|
|
363
|
+
* element's ID/class to avoid collisions when both CSSPreloader and
|
|
364
|
+
* LoadingScene appear in the same DOM.
|
|
365
|
+
*/
|
|
366
|
+
/** Max width of the loader bar in SVG units */
|
|
367
|
+
declare const LOADER_BAR_MAX_WIDTH = 174;
|
|
368
|
+
interface LogoSVGOptions {
|
|
369
|
+
/** Prefix for gradient/clip IDs to avoid collisions (e.g. 'pl' or 'ls') */
|
|
370
|
+
idPrefix: string;
|
|
371
|
+
/** Optional CSS class on the root <svg> */
|
|
372
|
+
svgClass?: string;
|
|
373
|
+
/** Optional inline style on the root <svg> */
|
|
374
|
+
svgStyle?: string;
|
|
375
|
+
/** Optional CSS class on the clip <rect> */
|
|
376
|
+
clipRectClass?: string;
|
|
377
|
+
/** Optional id on the clip <rect> (for JS access) */
|
|
378
|
+
clipRectId?: string;
|
|
379
|
+
/** Optional id on the percentage <text> */
|
|
380
|
+
textId?: string;
|
|
381
|
+
/** Default text content */
|
|
382
|
+
textContent?: string;
|
|
383
|
+
/** Optional CSS class on the <text> */
|
|
384
|
+
textClass?: string;
|
|
385
|
+
}
|
|
386
|
+
/**
|
|
387
|
+
* Build the Energy8 SVG logo with a loader bar, using unique IDs.
|
|
388
|
+
*
|
|
389
|
+
* @param opts - Configuration to avoid element ID collisions
|
|
390
|
+
* @returns SVG markup string
|
|
391
|
+
*/
|
|
392
|
+
declare function buildLogoSVG(opts: LogoSVGOptions): string;
|
|
393
|
+
|
|
394
|
+
interface NativeSimulationConfig {
|
|
395
|
+
/** Path to native simulation binary */
|
|
396
|
+
binaryPath: string;
|
|
397
|
+
/** Lua script source code */
|
|
398
|
+
script: string;
|
|
399
|
+
/** Platform game definition */
|
|
400
|
+
gameDefinition: GameDefinition;
|
|
401
|
+
/** Number of iterations */
|
|
402
|
+
iterations: number;
|
|
403
|
+
/** Bet amount */
|
|
404
|
+
bet: number;
|
|
405
|
+
/** Action to simulate (default: auto-detect by binary) */
|
|
406
|
+
action?: string;
|
|
407
|
+
/** Action params (buy_bonus, ante_bet, etc.) */
|
|
408
|
+
params?: Record<string, unknown>;
|
|
409
|
+
/** Progress callback */
|
|
410
|
+
onProgress?: (completed: number, total: number) => void;
|
|
411
|
+
}
|
|
412
|
+
interface StageStats {
|
|
413
|
+
totalWin: number;
|
|
414
|
+
spinCount: number;
|
|
415
|
+
hitCount: number;
|
|
416
|
+
maxWin: number;
|
|
417
|
+
rtp: number;
|
|
418
|
+
perSpinRtp: number;
|
|
419
|
+
hitFrequency: number;
|
|
420
|
+
avgWin: number;
|
|
421
|
+
}
|
|
422
|
+
interface DistributionBucket {
|
|
423
|
+
label: string;
|
|
424
|
+
count: number;
|
|
425
|
+
pct: number;
|
|
426
|
+
}
|
|
427
|
+
interface NativeSimulationResult extends SimulationResult {
|
|
428
|
+
/** Iterations per second */
|
|
429
|
+
speed?: number;
|
|
430
|
+
/** Number of parallel workers used */
|
|
431
|
+
workersUsed?: number;
|
|
432
|
+
/** Per-stage breakdown */
|
|
433
|
+
perStage?: Record<string, StageStats>;
|
|
434
|
+
/** Win distribution histogram */
|
|
435
|
+
winDistribution?: DistributionBucket[];
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
export { DevBridge, EventEmitter, LOADER_BAR_MAX_WIDTH, PlatformSession, buildLogoSVG, createCSSPreloader, createPlatformSession, removeCSSPreloader };
|
|
439
|
+
export type { ActionDefinition, AnteBetConfig, AssetBundle, AssetEntry, AssetManifest, BetLevelsConfig, BuyBonusConfig, BuyBonusMode, DevBridgeConfig, DistributionBucket, GameDefinition, LoadingScreenConfig, LuaEngineConfig, LuaPlayResult, MaxWinConfig, NativeSimulationConfig, NativeSimulationResult, PersistentStateConfig, PlatformSessionConfig, PlatformSessionEvents, SDKOptions, SessionConfig, SimulationConfig, SimulationRawAccumulators, SimulationResult, StageStats, TransitionRule };
|