@energy8platform/game-engine 0.29.0 → 0.31.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.
@@ -13,6 +13,10 @@ export interface RenderContext {
13
13
  formatAmount(value: number): string;
14
14
  /** LIVE turbo level (0 = off, 1..3 = escalating speed). Read at access. */
15
15
  readonly turbo: number;
16
+ /** Only meaningful in `onEnterMode`: true when RETURNING to a suspended parent bonus after a
17
+ * nested sub-bonus finished (e.g. back to free spins after an adventure), false on a fresh
18
+ * entry. Lets a scene restore vs rebuild. Undefined outside `onEnterMode`. */
19
+ resumed?: boolean;
16
20
  /** Aborted when the player skips this segment (double-tap). The scene's async pacing can race or
17
21
  * cancel on it; on abort the scene must collapse to the segment's final visual state. */
18
22
  signal: AbortSignal;
@@ -82,9 +86,13 @@ export interface SlotSceneController<T extends SlotSpinResultBase = SlotSpinResu
82
86
  onSpinStart(): void;
83
87
  /** Render ONE segment (a spin or one free spin). Await your own pacing. */
84
88
  onSpin(result: T, ctx: RenderContext): Promise<void>;
85
- /** Fires when ctx.mode changes between segments (entering a non-BASE mode/bonus). */
89
+ /** Fires when a bonus LEVEL begins. With nested bonuses this fires once per level (free spins,
90
+ * then adventure, …) — check `ctx.mode` for which. `ctx.resumed` is true when returning to a
91
+ * suspended parent after a nested sub-bonus finished, so a scene can restore instead of rebuild.
92
+ * A single-bonus round fires it exactly once (as before). */
86
93
  onEnterMode(result: T, ctx: RenderContext): Promise<void>;
87
- /** Fires when leaving a mode (back toward BASE). */
94
+ /** Fires when a bonus LEVEL ends — popping a nested sub-bonus back to its parent, or unwinding
95
+ * the last level back to BASE. `ctx.mode` is the level being left. Fires once per level. */
88
96
  onExitMode(result: T, ctx: RenderContext): Promise<void>;
89
97
  /** Fires once per round after the full drain (controls unlocked). */
90
98
  onSpinEnd(result: T, ctx: RenderContext): void;
package/src/host/types.ts CHANGED
@@ -7,7 +7,27 @@ import type { AudioConfig, ScaleMode, Orientation, SceneConstructor } from '../t
7
7
  import type { BookAdapter, AdapterModule, StakeBridge } from '@energy8platform/stake-bridge';
8
8
  import type { GameApplication } from '../core';
9
9
  import type { SlotShellOptions } from './shellConfig';
10
- import type { SlotSpinResultBase, SlotResultNormalizer } from '@energy8platform/platform-core/slot-result';
10
+ import type {
11
+ SlotSpinResultBase,
12
+ SlotResultNormalizer,
13
+ } from '@energy8platform/platform-core/slot-result';
14
+ import type { FreeSpinsView } from './freeSpinsCounter';
15
+
16
+ /** Turns a bonus segment into the bar readout for games whose bonus ISN'T a plain free-spins
17
+ * counter (adventure, hold-and-spin, respins). The shell shows a host-driven hero + Total Win in
18
+ * ANY bonus; this only customises the label + counter VALUE. Omit `bonus` entirely and the host
19
+ * falls back to the free-spins default (label 'Free spins', value current/total, retrigger-aware). */
20
+ export interface BonusReadoutConfig<T extends SlotSpinResultBase = SlotSpinResultBase> {
21
+ /** Bar label (localized by the shell, so a game i18n entry is honoured). A string, or a function
22
+ * of the current mode (e.g. `m => m === 'ADVENTURE' ? 'Adventure' : 'Free spins'`).
23
+ * Default: 'Free spins'. */
24
+ label?: string | ((mode: string) => string);
25
+ /** Format the counter VALUE string from the settled segment. `view` is the host's default
26
+ * free-spins counter (current/total, retrigger-aware) — use it for the common case, or ignore it
27
+ * and read your own fields off `result` (respins left, coins collected, a multiplier).
28
+ * Default: `view.current == null ? String(view.total) : `${view.current} / ${view.total}``. */
29
+ readout?: (result: T, ctx: { view: FreeSpinsView; mode: string }) => string;
30
+ }
11
31
 
12
32
  export interface StakeIntegration {
13
33
  /** The game's BookAdapter (or its module). modeMap + gameId come from the model. */
@@ -58,6 +78,9 @@ export interface CreateSlotGameOptions<T extends SlotSpinResultBase = SlotSpinRe
58
78
  dev?: boolean;
59
79
  stake?: StakeIntegration;
60
80
  shell?: SlotShellOptions;
81
+ /** Customise the bonus bar readout for games whose bonus isn't plain free spins (adventure,
82
+ * hold-and-spin, respins). Omit for the free-spins default. See `BonusReadoutConfig`. */
83
+ bonus?: BonusReadoutConfig<T>;
61
84
  /** Override how the control-bar shell is built. The host resolves the full shell config (theme,
62
85
  * features, gameInfo, currency, balance) and the Pixi mount (`app`/`parent`) and hands it to this
63
86
  * factory; return any `Shell` — e.g. `createShell({ renderer: new MyRenderer(...), ...config })`