@energy8platform/game-engine 0.2.1 → 0.4.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.
Files changed (63) hide show
  1. package/README.md +400 -35
  2. package/dist/animation.cjs.js +191 -1
  3. package/dist/animation.cjs.js.map +1 -1
  4. package/dist/animation.d.ts +117 -1
  5. package/dist/animation.esm.js +192 -3
  6. package/dist/animation.esm.js.map +1 -1
  7. package/dist/audio.cjs.js +66 -16
  8. package/dist/audio.cjs.js.map +1 -1
  9. package/dist/audio.d.ts +4 -0
  10. package/dist/audio.esm.js +66 -16
  11. package/dist/audio.esm.js.map +1 -1
  12. package/dist/core.cjs.js +307 -85
  13. package/dist/core.cjs.js.map +1 -1
  14. package/dist/core.d.ts +60 -1
  15. package/dist/core.esm.js +308 -86
  16. package/dist/core.esm.js.map +1 -1
  17. package/dist/debug.cjs.js +36 -68
  18. package/dist/debug.cjs.js.map +1 -1
  19. package/dist/debug.d.ts +4 -6
  20. package/dist/debug.esm.js +36 -68
  21. package/dist/debug.esm.js.map +1 -1
  22. package/dist/index.cjs.js +997 -475
  23. package/dist/index.cjs.js.map +1 -1
  24. package/dist/index.d.ts +356 -79
  25. package/dist/index.esm.js +983 -478
  26. package/dist/index.esm.js.map +1 -1
  27. package/dist/ui.cjs.js +816 -529
  28. package/dist/ui.cjs.js.map +1 -1
  29. package/dist/ui.d.ts +179 -41
  30. package/dist/ui.esm.js +798 -531
  31. package/dist/ui.esm.js.map +1 -1
  32. package/dist/vite.cjs.js +85 -68
  33. package/dist/vite.cjs.js.map +1 -1
  34. package/dist/vite.d.ts +17 -23
  35. package/dist/vite.esm.js +86 -68
  36. package/dist/vite.esm.js.map +1 -1
  37. package/package.json +19 -5
  38. package/src/animation/SpriteAnimation.ts +210 -0
  39. package/src/animation/Tween.ts +27 -1
  40. package/src/animation/index.ts +2 -0
  41. package/src/audio/AudioManager.ts +64 -15
  42. package/src/core/EventEmitter.ts +7 -1
  43. package/src/core/GameApplication.ts +19 -7
  44. package/src/core/SceneManager.ts +3 -1
  45. package/src/debug/DevBridge.ts +49 -80
  46. package/src/index.ts +22 -0
  47. package/src/input/InputManager.ts +26 -0
  48. package/src/loading/CSSPreloader.ts +7 -33
  49. package/src/loading/LoadingScene.ts +17 -41
  50. package/src/loading/index.ts +1 -0
  51. package/src/loading/logo.ts +95 -0
  52. package/src/types.ts +4 -0
  53. package/src/ui/BalanceDisplay.ts +12 -1
  54. package/src/ui/Button.ts +71 -130
  55. package/src/ui/Layout.ts +286 -0
  56. package/src/ui/Modal.ts +6 -5
  57. package/src/ui/Panel.ts +52 -55
  58. package/src/ui/ProgressBar.ts +52 -57
  59. package/src/ui/ScrollContainer.ts +126 -0
  60. package/src/ui/Toast.ts +19 -13
  61. package/src/ui/index.ts +17 -0
  62. package/src/viewport/ViewportManager.ts +2 -0
  63. package/src/vite/index.ts +103 -83
package/src/vite/index.ts CHANGED
@@ -1,83 +1,96 @@
1
1
  import type { UserConfig, Plugin } from 'vite';
2
2
 
3
- export interface GameViteConfig {
4
- /** Base path for production builds (e.g., '/games/my-slot/') */
3
+ // ─── Types ───────────────────────────────────────────────
4
+
5
+ export interface GameConfig {
6
+ /** Vite `base` path for deployment (default: '/') */
5
7
  base?: string;
6
- /** Output directory (default: 'dist') */
7
- outDir?: string;
8
- /** Enable DevBridge auto-injection in dev mode */
8
+
9
+ /** Enable DevBridge mock server in dev mode (default: false) */
9
10
  devBridge?: boolean;
10
- /** Asset file extensions to include */
11
- assetExtensions?: string[];
12
- /** Additional Vite config overrides */
11
+
12
+ /** Path to DevBridge config file (default: './dev.config.ts') */
13
+ devBridgeConfig?: string;
14
+
15
+ /** Additional Vite config to merge */
13
16
  vite?: UserConfig;
14
17
  }
15
18
 
19
+ // ─── DevBridge Plugin ────────────────────────────────────
20
+
16
21
  /**
17
- * Vite plugin that injects the DevBridge mock host in development mode.
18
- *
19
- * In dev mode, wraps the game page to simulate the casino host environment,
20
- * allowing SDK communication to work without a real backend.
22
+ * Vite plugin that auto-injects the DevBridge script into the
23
+ * HTML during development, so the game can communicate with a
24
+ * mock casino host without manual setup.
21
25
  */
22
- const VIRTUAL_DEV_BRIDGE_ID = 'virtual:game-engine-dev-bridge';
23
- const RESOLVED_VIRTUAL_ID = '\0' + VIRTUAL_DEV_BRIDGE_ID;
26
+ const VIRTUAL_ID = '/@dev-bridge-entry.js';
27
+
28
+ function devBridgePlugin(configPath: string): Plugin {
29
+ let entrySrc = '';
30
+ let resolvedConfigPath = configPath;
24
31
 
25
- function gameEngineDevPlugin(options: { devBridge?: boolean } = {}): Plugin {
26
32
  return {
27
- name: 'game-engine-dev',
28
- apply: 'serve',
33
+ name: 'game-engine:dev-bridge',
34
+ apply: 'serve', // dev only
35
+ enforce: 'pre',
36
+
37
+ configResolved(config) {
38
+ // Resolve relative config path against Vite root so the virtual
39
+ // module can import it with an absolute path.
40
+ if (configPath.startsWith('.')) {
41
+ resolvedConfigPath = config.root + '/' + configPath.replace(/^\.\//, '');
42
+ }
43
+ },
29
44
 
30
45
  resolveId(id) {
31
- if (id === VIRTUAL_DEV_BRIDGE_ID) return RESOLVED_VIRTUAL_ID;
46
+ if (id === VIRTUAL_ID) return id;
32
47
  },
33
48
 
34
49
  load(id) {
35
- if (id === RESOLVED_VIRTUAL_ID) {
36
- // This module goes through Vite's transform pipeline,
37
- // so bare specifiers like '@energy8platform/game-engine/debug' resolve correctly.
50
+ if (id === VIRTUAL_ID) {
51
+ // This goes through Vite's pipeline so bare imports are resolved
38
52
  return `
39
53
  import { DevBridge } from '@energy8platform/game-engine/debug';
40
54
 
41
- async function initDevBridge() {
42
- let config = {};
43
- try {
44
- const mod = await import('/dev.config.ts');
45
- config = mod.default || mod.devBridgeConfig || {};
46
- } catch {
47
- // No dev config — use defaults
48
- }
49
-
50
- const bridge = new DevBridge(config);
51
- bridge.start();
52
- window.__devBridge = bridge;
53
- console.log('[GameEngine] DevBridge started in development mode');
55
+ try {
56
+ const mod = await import('${resolvedConfigPath}');
57
+ const config = mod.default ?? mod.config ?? mod;
58
+ new DevBridge(config).start();
59
+ } catch (e) {
60
+ console.warn('[DevBridge] Failed to load config:', e);
54
61
  }
55
62
 
56
- initDevBridge();
63
+ await import('${entrySrc}');
57
64
  `;
58
65
  }
59
66
  },
60
67
 
61
68
  transformIndexHtml(html) {
62
- if (options.devBridge === false) return html;
69
+ // Find the app's entry module script (skip Vite internal /@... scripts)
70
+ const scriptRegex = /<script\s+type="module"\s+src="((?!\/@)[^"]+)"\s*>\s*<\/script>/;
71
+ const match = html.match(scriptRegex);
63
72
 
64
- // Inject a script that imports the virtual module — Vite resolves it properly
65
- const devScript = `<script type="module" src="/${VIRTUAL_DEV_BRIDGE_ID}"></script>`;
73
+ if (!match) {
74
+ console.warn('[DevBridge] Could not find entry module script in index.html');
75
+ return html;
76
+ }
66
77
 
67
- return html.replace('</head>', `${devScript}\n</head>`);
78
+ entrySrc = match[1];
79
+ return html.replace(match[0], `<script type="module" src="${VIRTUAL_ID}"></script>`);
68
80
  },
69
81
  };
70
82
  }
71
83
 
84
+ // ─── defineGameConfig ────────────────────────────────────
85
+
72
86
  /**
73
- * Create a pre-configured Vite config for game projects.
87
+ * Define a Vite configuration tailored for Energy8 casino games.
74
88
  *
75
- * Includes:
76
- * - PixiJS optimization (exclude from dep optimization)
77
- * - DevBridge injection in dev mode
78
- * - HTML minification
79
- * - Gzip-friendly output
80
- * - Configurable base path for S3/CDN deploy
89
+ * Merges sensible defaults for iGaming projects:
90
+ * - Build target: ESNext (required for yoga-layout WASM top-level await)
91
+ * - Asset inlining threshold: 8KB
92
+ * - Source maps for dev, none for prod
93
+ * - Optional DevBridge auto-injection in dev mode
81
94
  *
82
95
  * @example
83
96
  * ```ts
@@ -85,69 +98,76 @@ initDevBridge();
85
98
  * import { defineGameConfig } from '@energy8platform/game-engine/vite';
86
99
  *
87
100
  * export default defineGameConfig({
88
- * base: '/games/my-slot/',
101
+ * base: '/',
89
102
  * devBridge: true,
90
103
  * });
91
104
  * ```
92
105
  */
93
- export function defineGameConfig(config: GameViteConfig = {}): UserConfig {
94
- const assetExtensions = config.assetExtensions ?? [
95
- 'png', 'jpg', 'jpeg', 'gif', 'webp', 'avif', 'svg',
96
- 'mp3', 'ogg', 'wav', 'webm',
97
- 'json', 'atlas', 'skel',
98
- 'fnt', 'ttf', 'otf', 'woff', 'woff2',
99
- 'mp4', 'm4v',
100
- ];
106
+ export function defineGameConfig(config: GameConfig = {}): UserConfig {
107
+ const plugins: Plugin[] = [];
108
+
109
+ if (config.devBridge) {
110
+ const configPath = config.devBridgeConfig ?? './dev.config';
111
+ plugins.push(devBridgePlugin(configPath));
112
+ }
113
+
114
+ const userVite = config.vite ?? {};
101
115
 
102
116
  return {
103
117
  base: config.base ?? '/',
104
118
 
105
119
  plugins: [
106
- gameEngineDevPlugin({ devBridge: config.devBridge ?? true }),
107
- ...(config.vite?.plugins ?? []) as Plugin[],
120
+ ...plugins,
121
+ ...((userVite.plugins as Plugin[]) ?? []),
108
122
  ],
109
123
 
110
124
  build: {
111
- outDir: config.outDir ?? 'dist',
112
- target: 'es2022',
113
- minify: 'terser',
125
+ target: 'esnext',
126
+ assetsInlineLimit: 8192,
114
127
  sourcemap: false,
115
- assetsInlineLimit: 4096,
116
128
  rollupOptions: {
117
129
  output: {
118
- assetFileNames: 'assets/[name]-[hash][extname]',
119
- chunkFileNames: 'js/[name]-[hash].js',
120
- entryFileNames: 'js/[name]-[hash].js',
130
+ manualChunks: {
131
+ pixi: ['pixi.js'],
132
+ },
121
133
  },
122
134
  },
123
- ...(config.vite?.build ?? {}),
124
- },
125
-
126
- optimizeDeps: {
127
- // Pre-bundle libs for fast dev startup
128
- include: ['pixi.js'],
129
- exclude: ['@esotericsoftware/spine-pixi-v8'],
135
+ ...userVite.build,
130
136
  },
131
137
 
132
- assetsInclude: assetExtensions.map((ext) => `**/*.${ext}`),
133
-
134
138
  server: {
135
139
  port: 3000,
136
140
  open: true,
137
- ...(config.vite?.server ?? {}),
141
+ ...userVite.server,
138
142
  },
139
143
 
140
144
  resolve: {
141
- ...(config.vite?.resolve ?? {}),
145
+ dedupe: [
146
+ 'pixi.js',
147
+ '@pixi/layout',
148
+ '@pixi/layout/components',
149
+ '@pixi/ui',
150
+ 'yoga-layout',
151
+ 'yoga-layout/load',
152
+ ],
153
+ ...userVite.resolve,
142
154
  },
143
155
 
144
- // Spread any additional user overrides
145
- ...Object.fromEntries(
146
- Object.entries(config.vite ?? {}).filter(
147
- ([key]) => !['plugins', 'build', 'server', 'resolve'].includes(key),
148
- ),
149
- ),
156
+ optimizeDeps: {
157
+ include: [
158
+ 'pixi.js',
159
+ '@pixi/layout',
160
+ '@pixi/layout/components',
161
+ '@pixi/ui',
162
+ 'yoga-layout/load',
163
+ ],
164
+ exclude: [
165
+ 'yoga-layout',
166
+ ],
167
+ esbuildOptions: {
168
+ target: 'esnext',
169
+ },
170
+ ...userVite.optimizeDeps,
171
+ },
150
172
  };
151
173
  }
152
-
153
- export { gameEngineDevPlugin };