@energy8platform/game-engine 0.10.1 → 0.10.3
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/bin/simulate.ts +0 -0
- package/dist/debug.cjs.js +64 -882
- package/dist/debug.cjs.js.map +1 -1
- package/dist/debug.d.ts +7 -9
- package/dist/debug.esm.js +64 -882
- package/dist/debug.esm.js.map +1 -1
- package/dist/index.cjs.js +64 -889
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +8 -165
- package/dist/index.esm.js +65 -883
- package/dist/index.esm.js.map +1 -1
- package/dist/lua.cjs.js +4 -4
- package/dist/lua.cjs.js.map +1 -1
- package/dist/lua.esm.js +4 -4
- package/dist/lua.esm.js.map +1 -1
- package/dist/vite.cjs.js +81 -17
- package/dist/vite.cjs.js.map +1 -1
- package/dist/vite.esm.js +81 -17
- package/dist/vite.esm.js.map +1 -1
- package/package.json +1 -1
- package/src/debug/DevBridge.ts +71 -54
- package/src/index.ts +3 -8
- package/src/lua/LuaEngine.ts +2 -3
- package/src/lua/LuaEngineAPI.ts +1 -4
- package/src/lua/fengari.d.ts +10 -0
- package/src/vite/index.ts +89 -19
package/dist/vite.esm.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vite.esm.js","sources":["../src/vite/index.ts"],"sourcesContent":[null],"names":[],"mappings":"AAkBA;AAEA;;;;AAIG;AACH,MAAM,UAAU,GAAG,uBAAuB;AAE1C,SAAS,eAAe,CAAC,UAAkB,EAAA;IACzC,IAAI,QAAQ,GAAG,EAAE;IACjB,IAAI,QAAQ,GAAG,EAAE;IACjB,IAAI,kBAAkB,GAAG,UAAU;IAEnC,OAAO;AACL,QAAA,IAAI,EAAE,wBAAwB;QAC9B,KAAK,EAAE,OAAO;AACd,QAAA,OAAO,EAAE,KAAK;AAEd,QAAA,cAAc,CAAC,MAAM,EAAA;AACnB,YAAA,QAAQ,GAAG,MAAM,CAAC,IAAI;;;AAGtB,YAAA,IAAI,UAAU,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE;AAC9B,gBAAA,kBAAkB,GAAG,MAAM,CAAC,IAAI,GAAG,GAAG,GAAG,UAAU,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC;YAC1E;QACF,CAAC;AAED,QAAA,SAAS,CAAC,EAAE,EAAA;YACV,IAAI,EAAE,KAAK,UAAU;AAAE,gBAAA,OAAO,EAAE;QAClC,CAAC;AAED,QAAA,IAAI,CAAC,EAAE,EAAA;AACL,YAAA,IAAI,EAAE,KAAK,UAAU,EAAE;;gBAErB,OAAO;;;;8BAIe,kBAAkB,CAAA;;;;;;;gBAOhC,QAAQ,CAAA;CACvB;YACK;QACF,CAAC;AAED,QAAA,kBAAkB,CAAC,IAAI,EAAA;;YAErB,MAAM,WAAW,GAAG,iEAAiE;YACrF,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC;YAErC,IAAI,CAAC,KAAK,EAAE;AACV,gBAAA,OAAO,CAAC,IAAI,CAAC,8DAA8D,CAAC;AAC5E,gBAAA,OAAO,IAAI;YACb;AAEA,YAAA,QAAQ,GAAG,KAAK,CAAC,CAAC,CAAC;AACnB,YAAA,IAAI,QAAQ,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE;AAC5B,gBAAA,QAAQ,GAAG,QAAQ,GAAG,GAAG,GAAG,QAAQ,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC;YAC3D;AAAO,iBAAA,IAAI,QAAQ,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE;AACnC,gBAAA,QAAQ,GAAG,QAAQ,GAAG,QAAQ;YAChC;AACA,YAAA,OAAO,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAA,2BAAA,EAA8B,UAAU,CAAA,WAAA,CAAa,CAAC;QACtF,CAAC;KACF;AACH;AAEA;AAEA
|
|
1
|
+
{"version":3,"file":"vite.esm.js","sources":["../src/vite/index.ts"],"sourcesContent":[null],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
package/src/debug/DevBridge.ts
CHANGED
|
@@ -9,7 +9,6 @@ import {
|
|
|
9
9
|
type PlayParams,
|
|
10
10
|
} from '@energy8platform/game-sdk';
|
|
11
11
|
import type { GameDefinition } from '../lua/types';
|
|
12
|
-
import { LuaEngine } from '../lua/LuaEngine';
|
|
13
12
|
|
|
14
13
|
export interface DevBridgeConfig {
|
|
15
14
|
/** Mock initial balance */
|
|
@@ -28,7 +27,7 @@ export interface DevBridgeConfig {
|
|
|
28
27
|
networkDelay?: number;
|
|
29
28
|
/** Enable debug logging */
|
|
30
29
|
debug?: boolean;
|
|
31
|
-
/** Lua script source code. When set,
|
|
30
|
+
/** Lua script source code. When set, play requests are routed to the Vite dev server's LuaEngine. */
|
|
32
31
|
luaScript?: string;
|
|
33
32
|
/** Game definition for Lua engine (actions, transitions, etc.) */
|
|
34
33
|
gameDefinition?: GameDefinition;
|
|
@@ -60,11 +59,11 @@ const DEFAULT_CONFIG: Omit<Required<DevBridgeConfig>, 'luaScript' | 'gameDefinit
|
|
|
60
59
|
* `CasinoGameSDK` via a shared in-memory `MemoryChannel`, removing
|
|
61
60
|
* the need for postMessage and iframes.
|
|
62
61
|
*
|
|
63
|
-
*
|
|
62
|
+
* When `luaScript` is set, play requests are sent to the Vite dev server
|
|
63
|
+
* which runs LuaEngine in Node.js — no fengari in the browser.
|
|
64
64
|
*
|
|
65
65
|
* @example
|
|
66
66
|
* ```ts
|
|
67
|
-
* // In your dev entry point or vite plugin
|
|
68
67
|
* import { DevBridge } from '@energy8platform/game-engine/debug';
|
|
69
68
|
*
|
|
70
69
|
* const devBridge = new DevBridge({
|
|
@@ -73,10 +72,7 @@ const DEFAULT_CONFIG: Omit<Required<DevBridgeConfig>, 'luaScript' | 'gameDefinit
|
|
|
73
72
|
* gameConfig: { id: 'my-slot', type: 'slot', betLevels: [0.2, 0.5, 1, 2] },
|
|
74
73
|
* onPlay: ({ action, bet }) => ({
|
|
75
74
|
* totalWin: Math.random() > 0.5 ? bet * (Math.random() * 20) : 0,
|
|
76
|
-
* data: {
|
|
77
|
-
* matrix: generateRandomMatrix(5, 3, 10),
|
|
78
|
-
* win_lines: [],
|
|
79
|
-
* },
|
|
75
|
+
* data: { matrix: [[1,2,3],[4,5,6],[7,8,9]] },
|
|
80
76
|
* }),
|
|
81
77
|
* });
|
|
82
78
|
* devBridge.start();
|
|
@@ -87,12 +83,12 @@ export class DevBridge {
|
|
|
87
83
|
private _balance: number;
|
|
88
84
|
private _roundCounter = 0;
|
|
89
85
|
private _bridge: Bridge | null = null;
|
|
90
|
-
private
|
|
86
|
+
private _useLuaServer: boolean;
|
|
91
87
|
|
|
92
88
|
constructor(config: DevBridgeConfig = {}) {
|
|
93
89
|
this._config = { ...DEFAULT_CONFIG, ...config };
|
|
94
90
|
this._balance = this._config.balance;
|
|
95
|
-
this.
|
|
91
|
+
this._useLuaServer = !!(this._config.luaScript && this._config.gameDefinition);
|
|
96
92
|
}
|
|
97
93
|
|
|
98
94
|
/** Current mock balance */
|
|
@@ -133,7 +129,8 @@ export class DevBridge {
|
|
|
133
129
|
});
|
|
134
130
|
|
|
135
131
|
if (this._config.debug) {
|
|
136
|
-
|
|
132
|
+
const mode = this._useLuaServer ? 'Lua (server-side)' : 'onPlay callback';
|
|
133
|
+
console.log(`[DevBridge] Started — mode: ${mode}`);
|
|
137
134
|
}
|
|
138
135
|
}
|
|
139
136
|
|
|
@@ -158,24 +155,6 @@ export class DevBridge {
|
|
|
158
155
|
/** Destroy the dev bridge */
|
|
159
156
|
destroy(): void {
|
|
160
157
|
this.stop();
|
|
161
|
-
if (this._luaEngine) {
|
|
162
|
-
this._luaEngine.destroy();
|
|
163
|
-
this._luaEngine = null;
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
private initLuaEngine(): void {
|
|
168
|
-
if (!this._config.luaScript || !this._config.gameDefinition) return;
|
|
169
|
-
|
|
170
|
-
this._luaEngine = new LuaEngine({
|
|
171
|
-
script: this._config.luaScript,
|
|
172
|
-
gameDefinition: this._config.gameDefinition,
|
|
173
|
-
seed: this._config.luaSeed,
|
|
174
|
-
});
|
|
175
|
-
|
|
176
|
-
if (this._config.debug) {
|
|
177
|
-
console.log('[DevBridge] LuaEngine initialized');
|
|
178
|
-
}
|
|
179
158
|
}
|
|
180
159
|
|
|
181
160
|
// ─── Message Handling ──────────────────────────────────
|
|
@@ -202,28 +181,18 @@ export class DevBridge {
|
|
|
202
181
|
this._balance -= bet;
|
|
203
182
|
this._roundCounter++;
|
|
204
183
|
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
balanceAfter: this._balance,
|
|
218
|
-
totalWin: Math.round(luaResult.totalWin * 100) / 100,
|
|
219
|
-
data: luaResult.data,
|
|
220
|
-
nextActions: luaResult.nextActions,
|
|
221
|
-
session: luaResult.session,
|
|
222
|
-
creditPending: luaResult.creditDeferred,
|
|
223
|
-
bonusFreeSpin: null,
|
|
224
|
-
currency: this._config.currency,
|
|
225
|
-
gameId: this._config.gameConfig?.id ?? 'dev-game',
|
|
226
|
-
};
|
|
184
|
+
if (this._useLuaServer) {
|
|
185
|
+
// Send to Vite dev server for Lua execution
|
|
186
|
+
this.executeLuaOnServer({ action, bet, roundId, params })
|
|
187
|
+
.then((result) => {
|
|
188
|
+
this._bridge?.send('PLAY_RESULT', result, id);
|
|
189
|
+
})
|
|
190
|
+
.catch((err) => {
|
|
191
|
+
console.error('[DevBridge] Lua server error:', err);
|
|
192
|
+
// Refund bet on error
|
|
193
|
+
this._balance += bet;
|
|
194
|
+
this._bridge?.send('PLAY_RESULT', this.buildFallbackResult(action, bet, roundId), id);
|
|
195
|
+
});
|
|
227
196
|
} else {
|
|
228
197
|
// Fallback to onPlay callback
|
|
229
198
|
const customResult = this._config.onPlay({ action, bet, roundId, params });
|
|
@@ -231,7 +200,7 @@ export class DevBridge {
|
|
|
231
200
|
|
|
232
201
|
this._balance += totalWin;
|
|
233
202
|
|
|
234
|
-
result = {
|
|
203
|
+
const result: PlayResultData = {
|
|
235
204
|
roundId: roundId ?? `dev-round-${this._roundCounter}`,
|
|
236
205
|
action,
|
|
237
206
|
balanceAfter: this._balance,
|
|
@@ -244,9 +213,57 @@ export class DevBridge {
|
|
|
244
213
|
currency: this._config.currency,
|
|
245
214
|
gameId: this._config.gameConfig?.id ?? 'dev-game',
|
|
246
215
|
};
|
|
216
|
+
|
|
217
|
+
this.delayedSend('PLAY_RESULT', result, id);
|
|
247
218
|
}
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
private async executeLuaOnServer(params: PlayParams): Promise<PlayResultData> {
|
|
222
|
+
const response = await fetch('/__lua-play', {
|
|
223
|
+
method: 'POST',
|
|
224
|
+
headers: { 'Content-Type': 'application/json' },
|
|
225
|
+
body: JSON.stringify(params),
|
|
226
|
+
});
|
|
248
227
|
|
|
249
|
-
|
|
228
|
+
if (!response.ok) {
|
|
229
|
+
const err = await response.json().catch(() => ({ error: 'Unknown error' }));
|
|
230
|
+
throw new Error(err.error ?? `HTTP ${response.status}`);
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
const luaResult = await response.json();
|
|
234
|
+
|
|
235
|
+
const totalWin = luaResult.creditDeferred ? 0 : luaResult.totalWin;
|
|
236
|
+
this._balance += totalWin;
|
|
237
|
+
|
|
238
|
+
return {
|
|
239
|
+
roundId: params.roundId ?? `dev-round-${this._roundCounter}`,
|
|
240
|
+
action: params.action,
|
|
241
|
+
balanceAfter: this._balance,
|
|
242
|
+
totalWin: Math.round(luaResult.totalWin * 100) / 100,
|
|
243
|
+
data: luaResult.data,
|
|
244
|
+
nextActions: luaResult.nextActions,
|
|
245
|
+
session: luaResult.session,
|
|
246
|
+
creditPending: luaResult.creditDeferred,
|
|
247
|
+
bonusFreeSpin: null,
|
|
248
|
+
currency: this._config.currency,
|
|
249
|
+
gameId: this._config.gameConfig?.id ?? 'dev-game',
|
|
250
|
+
};
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
private buildFallbackResult(action: string, bet: number, roundId?: string): PlayResultData {
|
|
254
|
+
return {
|
|
255
|
+
roundId: roundId ?? `dev-round-${this._roundCounter}`,
|
|
256
|
+
action,
|
|
257
|
+
balanceAfter: this._balance,
|
|
258
|
+
totalWin: 0,
|
|
259
|
+
data: { error: 'Lua execution failed' },
|
|
260
|
+
nextActions: ['spin'],
|
|
261
|
+
session: null,
|
|
262
|
+
creditPending: false,
|
|
263
|
+
bonusFreeSpin: null,
|
|
264
|
+
currency: this._config.currency,
|
|
265
|
+
gameId: this._config.gameConfig?.id ?? 'dev-game',
|
|
266
|
+
};
|
|
250
267
|
}
|
|
251
268
|
|
|
252
269
|
private handlePlayAck(_payload: PlayResultAckPayload): void {
|
|
@@ -265,7 +282,7 @@ export class DevBridge {
|
|
|
265
282
|
|
|
266
283
|
private handleOpenDeposit(): void {
|
|
267
284
|
if (this._config.debug) {
|
|
268
|
-
console.log('[DevBridge]
|
|
285
|
+
console.log('[DevBridge] Open deposit requested (mock: adding 1000)');
|
|
269
286
|
}
|
|
270
287
|
this._balance += 1000;
|
|
271
288
|
this._bridge?.send('BALANCE_UPDATE', { balance: this._balance });
|
package/src/index.ts
CHANGED
|
@@ -101,14 +101,9 @@ export type { DevBridgeConfig } from './debug/DevBridge';
|
|
|
101
101
|
export { FPSOverlay } from './debug/FPSOverlay';
|
|
102
102
|
|
|
103
103
|
// ─── Lua ────────────────────────────────────────────────
|
|
104
|
-
//
|
|
105
|
-
//
|
|
106
|
-
//
|
|
107
|
-
export { LuaEngine } from './lua/LuaEngine';
|
|
108
|
-
export { LuaEngineAPI, createSeededRng } from './lua/LuaEngineAPI';
|
|
109
|
-
export { ActionRouter, evaluateCondition } from './lua/ActionRouter';
|
|
110
|
-
export { SessionManager } from './lua/SessionManager';
|
|
111
|
-
export { PersistentState } from './lua/PersistentState';
|
|
104
|
+
// Lua module is Node.js only (fengari). Use the sub-path import:
|
|
105
|
+
// import { LuaEngine } from '@energy8platform/game-engine/lua'
|
|
106
|
+
// Re-export only types (zero runtime cost, no fengari in browser bundle).
|
|
112
107
|
export type {
|
|
113
108
|
GameDefinition,
|
|
114
109
|
ActionDefinition,
|
package/src/lua/LuaEngine.ts
CHANGED
|
@@ -6,9 +6,8 @@ import { SessionManager } from './SessionManager';
|
|
|
6
6
|
import { PersistentState } from './PersistentState';
|
|
7
7
|
|
|
8
8
|
// fengari — Lua 5.3 in pure JavaScript
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
const fengari = require('fengari');
|
|
9
|
+
import fengari from 'fengari';
|
|
10
|
+
|
|
12
11
|
const { lua, lauxlib, lualib } = fengari;
|
|
13
12
|
const { to_luastring, to_jsstring } = fengari;
|
|
14
13
|
|
package/src/lua/LuaEngineAPI.ts
CHANGED
|
@@ -1,9 +1,6 @@
|
|
|
1
1
|
import type { GameDefinition } from './types';
|
|
2
|
+
import fengari from 'fengari';
|
|
2
3
|
|
|
3
|
-
// fengari is a CJS module — use dynamic import workaround for ESM compatibility
|
|
4
|
-
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
5
|
-
declare const require: (module: string) => any;
|
|
6
|
-
const fengari = require('fengari');
|
|
7
4
|
const { lua, lauxlib } = fengari;
|
|
8
5
|
const { to_luastring, to_jsstring } = fengari;
|
|
9
6
|
|
package/src/vite/index.ts
CHANGED
|
@@ -91,14 +91,94 @@ await import('${entrySrc}');
|
|
|
91
91
|
// ─── Lua Plugin ─────────────────────────────────────────
|
|
92
92
|
|
|
93
93
|
/**
|
|
94
|
-
* Vite plugin that
|
|
95
|
-
*
|
|
94
|
+
* Vite plugin that:
|
|
95
|
+
* 1. Enables importing `.lua` files as raw strings with HMR
|
|
96
|
+
* 2. Runs a LuaEngine on the Vite dev server (Node.js) via `POST /__lua-play`
|
|
97
|
+
*
|
|
98
|
+
* fengari runs server-side only — no browser shims needed.
|
|
96
99
|
*/
|
|
97
|
-
function luaPlugin(): Plugin {
|
|
100
|
+
function luaPlugin(configPath: string): Plugin {
|
|
101
|
+
let luaEngine: any = null;
|
|
102
|
+
let viteServer: any = null;
|
|
103
|
+
|
|
104
|
+
async function initEngine() {
|
|
105
|
+
if (!viteServer) return;
|
|
106
|
+
|
|
107
|
+
try {
|
|
108
|
+
// Use Vite's SSR module loader to handle .ts config files
|
|
109
|
+
const resolvedPath = configPath.startsWith('.')
|
|
110
|
+
? '/' + configPath.replace(/^\.\//, '')
|
|
111
|
+
: configPath;
|
|
112
|
+
|
|
113
|
+
// ssrLoadModule transpiles TS and resolves imports (including ?raw)
|
|
114
|
+
const mod = await viteServer.ssrLoadModule(resolvedPath);
|
|
115
|
+
const config = mod.default ?? mod.config ?? mod;
|
|
116
|
+
|
|
117
|
+
if (!config.luaScript || !config.gameDefinition) {
|
|
118
|
+
console.log('[LuaPlugin] No luaScript/gameDefinition in config — Lua server disabled');
|
|
119
|
+
luaEngine = null;
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// Load LuaEngine via SSR too (handles the fengari CJS import in Node.js)
|
|
124
|
+
const luaMod = await viteServer.ssrLoadModule('@energy8platform/game-engine/lua');
|
|
125
|
+
const { LuaEngine } = luaMod;
|
|
126
|
+
|
|
127
|
+
if (luaEngine) luaEngine.destroy();
|
|
128
|
+
luaEngine = new LuaEngine({
|
|
129
|
+
script: config.luaScript,
|
|
130
|
+
gameDefinition: config.gameDefinition,
|
|
131
|
+
seed: config.luaSeed,
|
|
132
|
+
});
|
|
133
|
+
console.log('[LuaPlugin] LuaEngine initialized (server-side)');
|
|
134
|
+
} catch (e: any) {
|
|
135
|
+
console.warn('[LuaPlugin] Failed to initialize LuaEngine:', e.message);
|
|
136
|
+
luaEngine = null;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
98
140
|
return {
|
|
99
141
|
name: 'game-engine:lua',
|
|
100
142
|
apply: 'serve',
|
|
101
143
|
|
|
144
|
+
async configureServer(server) {
|
|
145
|
+
viteServer = server;
|
|
146
|
+
await initEngine();
|
|
147
|
+
|
|
148
|
+
// POST /__lua-play — execute Lua on the server
|
|
149
|
+
server.middlewares.use('/__lua-play', (req: any, res: any) => {
|
|
150
|
+
if (req.method !== 'POST') {
|
|
151
|
+
res.statusCode = 405;
|
|
152
|
+
res.end('Method Not Allowed');
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
let body = '';
|
|
157
|
+
req.on('data', (chunk: string) => { body += chunk; });
|
|
158
|
+
req.on('end', () => {
|
|
159
|
+
try {
|
|
160
|
+
if (!luaEngine) {
|
|
161
|
+
res.statusCode = 503;
|
|
162
|
+
res.setHeader('Content-Type', 'application/json');
|
|
163
|
+
res.end(JSON.stringify({ error: 'LuaEngine not initialized' }));
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
const params = JSON.parse(body);
|
|
168
|
+
const result = luaEngine.execute(params);
|
|
169
|
+
|
|
170
|
+
res.statusCode = 200;
|
|
171
|
+
res.setHeader('Content-Type', 'application/json');
|
|
172
|
+
res.end(JSON.stringify(result));
|
|
173
|
+
} catch (e: any) {
|
|
174
|
+
res.statusCode = 500;
|
|
175
|
+
res.setHeader('Content-Type', 'application/json');
|
|
176
|
+
res.end(JSON.stringify({ error: e.message }));
|
|
177
|
+
}
|
|
178
|
+
});
|
|
179
|
+
});
|
|
180
|
+
},
|
|
181
|
+
|
|
102
182
|
transform(code: string, id: string) {
|
|
103
183
|
if (id.endsWith('.lua')) {
|
|
104
184
|
return {
|
|
@@ -108,8 +188,10 @@ function luaPlugin(): Plugin {
|
|
|
108
188
|
}
|
|
109
189
|
},
|
|
110
190
|
|
|
111
|
-
handleHotUpdate({ file, server }: { file: string; server: any }) {
|
|
112
|
-
if (file.endsWith('.lua')) {
|
|
191
|
+
async handleHotUpdate({ file, server }: { file: string; server: any }) {
|
|
192
|
+
if (file.endsWith('.lua') || file.includes('dev.config')) {
|
|
193
|
+
console.log('[LuaPlugin] Reloading LuaEngine...');
|
|
194
|
+
await initEngine();
|
|
113
195
|
server.ws.send({ type: 'full-reload' });
|
|
114
196
|
return [];
|
|
115
197
|
}
|
|
@@ -145,19 +227,11 @@ export function defineGameConfig(config: GameConfig = {}): UserConfig {
|
|
|
145
227
|
if (config.devBridge) {
|
|
146
228
|
const configPath = config.devBridgeConfig ?? './dev.config';
|
|
147
229
|
plugins.push(devBridgePlugin(configPath));
|
|
148
|
-
plugins.push(luaPlugin());
|
|
230
|
+
plugins.push(luaPlugin(configPath));
|
|
149
231
|
}
|
|
150
232
|
|
|
151
233
|
const userVite = config.vite ?? {};
|
|
152
234
|
|
|
153
|
-
// fengari (Lua 5.3 in JS) is a CJS Node.js package that references `process`
|
|
154
|
-
// and `require('os')` at module level. Provide shims so it works in the browser.
|
|
155
|
-
const fengariShims: Record<string, string> = config.devBridge ? {
|
|
156
|
-
'process.versions.node': 'undefined',
|
|
157
|
-
'process.env': '({})',
|
|
158
|
-
'process.platform': '"browser"',
|
|
159
|
-
} : {};
|
|
160
|
-
|
|
161
235
|
return {
|
|
162
236
|
base: config.base ?? '/',
|
|
163
237
|
|
|
@@ -166,11 +240,6 @@ export function defineGameConfig(config: GameConfig = {}): UserConfig {
|
|
|
166
240
|
...((userVite.plugins as Plugin[]) ?? []),
|
|
167
241
|
],
|
|
168
242
|
|
|
169
|
-
define: {
|
|
170
|
-
...fengariShims,
|
|
171
|
-
...(userVite as Record<string, any>).define,
|
|
172
|
-
},
|
|
173
|
-
|
|
174
243
|
build: {
|
|
175
244
|
target: 'esnext',
|
|
176
245
|
assetsInlineLimit: 8192,
|
|
@@ -218,6 +287,7 @@ export function defineGameConfig(config: GameConfig = {}): UserConfig {
|
|
|
218
287
|
],
|
|
219
288
|
exclude: [
|
|
220
289
|
'yoga-layout',
|
|
290
|
+
'fengari',
|
|
221
291
|
],
|
|
222
292
|
esbuildOptions: {
|
|
223
293
|
target: 'esnext',
|