@energy8platform/game-engine 0.34.2 → 0.35.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/audio.cjs.js +114 -59
- package/dist/audio.cjs.js.map +1 -1
- package/dist/audio.d.ts +25 -0
- package/dist/audio.esm.js +114 -59
- package/dist/audio.esm.js.map +1 -1
- package/dist/core.cjs.js +222 -66
- package/dist/core.cjs.js.map +1 -1
- package/dist/core.d.ts +25 -0
- package/dist/core.esm.js +223 -67
- package/dist/core.esm.js.map +1 -1
- package/dist/flow.cjs.js +246 -0
- package/dist/flow.cjs.js.map +1 -1
- package/dist/flow.d.ts +192 -33
- package/dist/flow.esm.js +238 -1
- package/dist/flow.esm.js.map +1 -1
- package/dist/host.cjs.js +343 -82
- package/dist/host.cjs.js.map +1 -1
- package/dist/host.d.ts +82 -2
- package/dist/host.esm.js +344 -83
- package/dist/host.esm.js.map +1 -1
- package/dist/index.cjs.js +222 -66
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +72 -0
- package/dist/index.esm.js +223 -67
- package/dist/index.esm.js.map +1 -1
- package/dist/scene-devtools.cjs.js +529 -115
- package/dist/scene-devtools.cjs.js.map +1 -1
- package/dist/scene-devtools.d.ts +187 -34
- package/dist/scene-devtools.esm.js +529 -115
- package/dist/scene-devtools.esm.js.map +1 -1
- package/dist/scene.cjs.js +704 -46
- package/dist/scene.cjs.js.map +1 -1
- package/dist/scene.d.ts +228 -41
- package/dist/scene.esm.js +698 -47
- package/dist/scene.esm.js.map +1 -1
- package/package.json +2 -2
- package/src/audio/AudioManager.ts +111 -53
- package/src/core/GameApplication.ts +47 -5
- package/src/host/buildConfig.ts +17 -4
- package/src/host/createSlotGame.ts +114 -12
- package/src/host/index.ts +3 -0
- package/src/host/types.ts +58 -0
- package/src/loading/LoadingScene.ts +76 -2
- package/src/loading/index.ts +6 -0
- package/src/types.ts +2 -0
package/dist/host.d.ts
CHANGED
|
@@ -337,6 +337,12 @@ declare class AudioManager {
|
|
|
337
337
|
private _categories;
|
|
338
338
|
private _masterGain;
|
|
339
339
|
private _currentMusic;
|
|
340
|
+
/** Duck factor (0..1) from duckMusic/unduckMusic. A presentation state, not a player setting. */
|
|
341
|
+
private _musicDuck;
|
|
342
|
+
/** Crossfade ramp (0..1) for the track that is fading IN. 1 whenever no fade is running. */
|
|
343
|
+
private _musicFade;
|
|
344
|
+
/** Generation counter so a superseded crossfade ramp stops writing over the new track's. */
|
|
345
|
+
private _musicFadeToken;
|
|
340
346
|
private _unlocked;
|
|
341
347
|
private _unlockHandler;
|
|
342
348
|
constructor(config?: AudioConfig);
|
|
@@ -430,6 +436,25 @@ declare class AudioManager {
|
|
|
430
436
|
* Smoothly fade a sound's volume from `fromVol` to `toVol` over `durationMs`.
|
|
431
437
|
*/
|
|
432
438
|
private fadeVolume;
|
|
439
|
+
/**
|
|
440
|
+
* The SOUND-layer gain for the running music track.
|
|
441
|
+
*
|
|
442
|
+
* @pixi/sound resolves a playing instance as `instance × sound × global` (WebAudioInstance.
|
|
443
|
+
* refresh). Each of those three has exactly ONE owner here, which is what keeps the mixer honest:
|
|
444
|
+
* global — the master gain (`applyVolumes`)
|
|
445
|
+
* sound — music: this function. sfx: untouched, left at 1.
|
|
446
|
+
* instance — sfx: the per-call volume × the sfx category. music: always 1.
|
|
447
|
+
* Everything that can move music volume — the player's slider, the category mute, a big-win duck,
|
|
448
|
+
* a crossfade — is a term below, so they compose instead of overwriting each other.
|
|
449
|
+
*/
|
|
450
|
+
private musicGain;
|
|
451
|
+
/** Push `musicGain()` at the current track. Safe before it starts playing and with none playing. */
|
|
452
|
+
private applyMusicGain;
|
|
453
|
+
/** Current SOUND-layer volume of `alias`, or 0 when it cannot be read. */
|
|
454
|
+
private soundVolumeOf;
|
|
455
|
+
/** Ramp the crossfade term 0 → 1 over `durationMs`, recomposing the gain each frame so a slider
|
|
456
|
+
* drag or a duck landing mid-fade is honoured rather than overwritten when the fade ends. */
|
|
457
|
+
private rampMusicFade;
|
|
433
458
|
private applyVolumes;
|
|
434
459
|
private setupMobileUnlock;
|
|
435
460
|
private removeMobileUnlock;
|
|
@@ -871,6 +896,55 @@ interface StakeIntegration {
|
|
|
871
896
|
/** The game's BookAdapter (or its module). modeMap + gameId come from the model. */
|
|
872
897
|
adapter: BookAdapter | AdapterModule;
|
|
873
898
|
}
|
|
899
|
+
/** The live Artube bridge, structurally. Kept minimal so game-engine never has to import
|
|
900
|
+
* `@energy8platform/artube-bridge` — see `ArtubeIntegration.load`. */
|
|
901
|
+
interface ArtubeBridgeLike {
|
|
902
|
+
/** Resolves once the backend has sent its init. */
|
|
903
|
+
ready(): Promise<void>;
|
|
904
|
+
destroy(): void;
|
|
905
|
+
}
|
|
906
|
+
/** What `ArtubeIntegration.load()` must resolve to. `@energy8platform/artube-bridge`'s own entry
|
|
907
|
+
* satisfies this structurally, so `load: () => import('@energy8platform/artube-bridge')` typechecks
|
|
908
|
+
* with no adapter. The launch CLASSIFIER comes from the same module as the bridge: one import, and
|
|
909
|
+
* no chicken-and-egg where the host would have to load something to decide whether to load. */
|
|
910
|
+
interface ArtubeModule {
|
|
911
|
+
classifyArtubeLaunch: (url: string) => 'artube' | 'blocked' | 'offline';
|
|
912
|
+
ArtubeBridge: new (options: {
|
|
913
|
+
devMode?: boolean;
|
|
914
|
+
gameId?: string;
|
|
915
|
+
url?: string;
|
|
916
|
+
apiBase?: string;
|
|
917
|
+
demoBalance?: number;
|
|
918
|
+
}) => ArtubeBridgeLike;
|
|
919
|
+
}
|
|
920
|
+
/** Artube host integration. There is no per-game artifact to pass: the game's own BACKEND
|
|
921
|
+
* (`@energy8platform/artube-server`) owns the round shape, so the bridge is a pure protocol
|
|
922
|
+
* translator — `load` is the only required field. `gameId` comes from the model, the launch params
|
|
923
|
+
* from the URL. */
|
|
924
|
+
interface ArtubeIntegration {
|
|
925
|
+
/** REQUIRED. How the host reaches the bridge:
|
|
926
|
+
* `load: () => import('@energy8platform/artube-bridge')`.
|
|
927
|
+
*
|
|
928
|
+
* Why the GAME supplies this instead of the host importing the package itself: a bare
|
|
929
|
+
* `import('@energy8platform/artube-bridge')` inside this always-shipped `/host` entry is resolved
|
|
930
|
+
* STATICALLY by every bundler, so it would have to resolve in games that never opted into Artube
|
|
931
|
+
* and therefore never installed the package — esbuild/webpack fail the build outright, and Vite
|
|
932
|
+
* silently substitutes an empty module (it stubs uninstalled optional peers), which is worse:
|
|
933
|
+
* the game builds and then dies at runtime. With the loader, the specifier only ever appears in
|
|
934
|
+
* the bundle of a game that took the dependency.
|
|
935
|
+
*
|
|
936
|
+
* The loaded chunk is fetched on every launch of such a game (the classifier lives in it), which
|
|
937
|
+
* is the point of the split: only Artube-targeted builds pay for it. */
|
|
938
|
+
load: () => Promise<ArtubeModule>;
|
|
939
|
+
/** Starting virtual balance for a DEMO session (the platform doesn't keep one — the bridge does,
|
|
940
|
+
* client-side). Default: the backend's own configured demo balance. Ignored for real sessions. */
|
|
941
|
+
demoBalance?: number;
|
|
942
|
+
/** Origin of the game's backend. Default (and the only supported PRODUCTION value) is the launch
|
|
943
|
+
* URL's own origin: Artube serves frontend and backend on one domain, split by path (`/api/**`).
|
|
944
|
+
* Override only for local dev against a backend on another port — prefer proxying `/api` from the
|
|
945
|
+
* dev server (what the `BUILD_TARGET=artube` target does) so dev matches production. */
|
|
946
|
+
apiBase?: string;
|
|
947
|
+
}
|
|
874
948
|
/** One scene registered with the host: a key + its constructor. The list order matters — the
|
|
875
949
|
* first scene that is eligible for the current launch mode is the start scene (unless an explicit
|
|
876
950
|
* `startScene` overrides it). */
|
|
@@ -915,6 +989,10 @@ interface CreateSlotGameOptions<T extends SlotSpinResultBase = SlotSpinResultBas
|
|
|
915
989
|
textureDefaults?: boolean;
|
|
916
990
|
dev?: boolean;
|
|
917
991
|
stake?: StakeIntegration;
|
|
992
|
+
/** Run on Artube when the launch URL says so (`?sessionId=…`):
|
|
993
|
+
* `artube: { load: () => import('@energy8platform/artube-bridge') }`. See `ArtubeIntegration`
|
|
994
|
+
* for why the game supplies the loader. Build with `BUILD_TARGET=artube`. */
|
|
995
|
+
artube?: ArtubeIntegration;
|
|
918
996
|
shell?: SlotShellOptions;
|
|
919
997
|
/** Customise the bonus bar readout for games whose bonus isn't plain free spins (adventure,
|
|
920
998
|
* hold-and-spin, respins). Omit for the free-spins default. See `BonusReadoutConfig`. */
|
|
@@ -937,11 +1015,13 @@ type ShellFactory = (config: PixiShellConfig) => Shell;
|
|
|
937
1015
|
interface SlotGameHandle {
|
|
938
1016
|
game: GameApplication;
|
|
939
1017
|
stakeBridge: StakeBridge | null;
|
|
1018
|
+
/** The live Artube bridge — non-null only on a real Artube launch (`opts.artube` + `?sessionId=…`). */
|
|
1019
|
+
artubeBridge: ArtubeBridgeLike | null;
|
|
940
1020
|
shell: Shell | null;
|
|
941
1021
|
}
|
|
942
1022
|
|
|
943
1023
|
/**
|
|
944
|
-
* One-call slot bootstrap: preboot → (optional Stake bridge) → GameApplication
|
|
1024
|
+
* One-call slot bootstrap: preboot → (optional Stake / Artube bridge) → GameApplication
|
|
945
1025
|
* → register scene → start. Collapses the per-game main.ts boilerplate.
|
|
946
1026
|
*
|
|
947
1027
|
* Not unit-tested: GameApplication.init() drives Pixi, which hangs in headless
|
|
@@ -1136,4 +1216,4 @@ interface SlotSceneController<T extends SlotSpinResultBase = SlotSpinResultBase>
|
|
|
1136
1216
|
}
|
|
1137
1217
|
|
|
1138
1218
|
export { buildShellConfig, createSlotGame, createWinReporter, resolveReplayBonusId, resolveStartScene, stakeForAction };
|
|
1139
|
-
export type { AutoplaySceneState, CreateSlotGameOptions, OverlayShowOptions, RenderContext, SceneApi, SceneAudio, SceneNavData, SceneOverlay, SceneRegistration, SceneShell, ShellFactory, SlotGameHandle, SlotSceneController, SlotShellOptions, StakeIntegration, WinReportOptions, WinReporter };
|
|
1219
|
+
export type { ArtubeBridgeLike, ArtubeIntegration, ArtubeModule, AutoplaySceneState, CreateSlotGameOptions, OverlayShowOptions, RenderContext, SceneApi, SceneAudio, SceneNavData, SceneOverlay, SceneRegistration, SceneShell, ShellFactory, SlotGameHandle, SlotSceneController, SlotShellOptions, StakeIntegration, WinReportOptions, WinReporter };
|