@omnitronix/bonnys-fortune-game-engine 1.8.0 → 1.8.2
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/__tests__/test-protocol-10000-spin.test.d.ts +1 -0
- package/dist/__tests__/test-protocol-10000-spin.test.js +456 -0
- package/dist/__tests__/test-protocol-10000-spin.test.js.map +1 -0
- package/dist/bonnys-fortune-v1.game-engine.d.ts +2 -3
- package/dist/bonnys-fortune-v1.game-engine.js +2 -2
- package/dist/bonnys-fortune-v1.game-engine.js.map +1 -1
- package/dist/index.d.ts +1 -2
- package/package.json +3 -2
- package/src/__tests__/test-protocol-10000-spin.test.ts +643 -0
- package/src/bonnys-fortune-v1.game-engine.ts +2 -6
- package/src/index.ts +1 -2
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,456 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
/**
|
|
37
|
+
* Test Protocol: 10,000-Spin Simulation -- Bonnys Fortune
|
|
38
|
+
*
|
|
39
|
+
* Extended test protocol that validates game engine integrity over 10,000 spins.
|
|
40
|
+
* Writes per-spin NDJSON results to results/ directory for offline analysis.
|
|
41
|
+
*
|
|
42
|
+
* Tests:
|
|
43
|
+
* 1. 10,000 Base Game Spins with Bonus Completion
|
|
44
|
+
* 2. RTP Validation Over 10,000 Spins (tighter bounds: 70%-130%)
|
|
45
|
+
* 3. Bonus Coverage -- Debug Trigger 200x Each Bonus Type
|
|
46
|
+
* 4. State Consistency Over 10,000 Spins
|
|
47
|
+
*/
|
|
48
|
+
const fs = __importStar(require("fs"));
|
|
49
|
+
const path = __importStar(require("path"));
|
|
50
|
+
const test_engine_factory_1 = require("./helpers/test-engine-factory");
|
|
51
|
+
// ---------------------------------------------------------------------------
|
|
52
|
+
// NDJSON Output Setup
|
|
53
|
+
// ---------------------------------------------------------------------------
|
|
54
|
+
const RESULTS_DIR = path.resolve(__dirname, '../../results');
|
|
55
|
+
function ensureResultsDir() {
|
|
56
|
+
if (!fs.existsSync(RESULTS_DIR)) {
|
|
57
|
+
fs.mkdirSync(RESULTS_DIR, { recursive: true });
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
function ndjsonPath(filename) {
|
|
61
|
+
return path.join(RESULTS_DIR, filename);
|
|
62
|
+
}
|
|
63
|
+
function appendNdjson(filepath, record) {
|
|
64
|
+
fs.appendFileSync(filepath, JSON.stringify(record) + '\n', 'utf-8');
|
|
65
|
+
}
|
|
66
|
+
// ---------------------------------------------------------------------------
|
|
67
|
+
// Helpers (same pattern as integration-1000-spin.test.ts)
|
|
68
|
+
// ---------------------------------------------------------------------------
|
|
69
|
+
/** Extract playerWinning from a command result outcome. */
|
|
70
|
+
function extractPlayerWinning(result) {
|
|
71
|
+
const outcome = result.outcome;
|
|
72
|
+
return outcome?.result?.playerWinning
|
|
73
|
+
?? outcome?.playerWinning
|
|
74
|
+
?? outcome?.result?.totalWin
|
|
75
|
+
?? outcome?.totalWin
|
|
76
|
+
?? 0;
|
|
77
|
+
}
|
|
78
|
+
/** Drain all pending bonuses, including chained ones (e.g. bonusGame3 -> bonusGame1). */
|
|
79
|
+
async function drainAllBonuses(engine, pub, priv, betAmount, tracker) {
|
|
80
|
+
let maxDepth = 10; // safety guard against infinite chaining
|
|
81
|
+
while (priv.pendingBonuses?.length > 0 && maxDepth-- > 0) {
|
|
82
|
+
const bonus = priv.pendingBonuses[0];
|
|
83
|
+
const bonusType = bonus.bonusType;
|
|
84
|
+
tracker.bonusTriggersPerType[bonusType] =
|
|
85
|
+
(tracker.bonusTriggersPerType[bonusType] ?? 0) + 1;
|
|
86
|
+
try {
|
|
87
|
+
const bonusResult = await (0, test_engine_factory_1.startBonusRound)(engine, pub, priv, bonusType, betAmount);
|
|
88
|
+
expect(bonusResult.success).toBe(true);
|
|
89
|
+
// Sum bonus winnings from results array
|
|
90
|
+
const bonusOutcome = bonusResult.outcome;
|
|
91
|
+
if (bonusOutcome?.results) {
|
|
92
|
+
for (const r of bonusOutcome.results) {
|
|
93
|
+
const win = r.result?.playerWinning ?? 0;
|
|
94
|
+
tracker.totalWon += win;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
else {
|
|
98
|
+
tracker.totalWon += extractPlayerWinning(bonusResult);
|
|
99
|
+
}
|
|
100
|
+
const finalState = (0, test_engine_factory_1.extractFinalBonusState)(bonusResult);
|
|
101
|
+
pub = finalState.publicState;
|
|
102
|
+
priv = finalState.privateState;
|
|
103
|
+
}
|
|
104
|
+
catch (error) {
|
|
105
|
+
// Prevent cascade failures: log and break out of bonus drain
|
|
106
|
+
console.warn(`[drainAllBonuses] Error draining ${bonusType}: ${error instanceof Error ? error.message : String(error)}`);
|
|
107
|
+
break;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
return { pub, priv };
|
|
111
|
+
}
|
|
112
|
+
/** Validate state consistency assertions after any command. */
|
|
113
|
+
function assertStateConsistency(pub, priv) {
|
|
114
|
+
// publicState.bonusMeters has exactly 3 keys
|
|
115
|
+
expect(pub.bonusMeters).toBeDefined();
|
|
116
|
+
expect(Object.keys(pub.bonusMeters).length).toBe(3);
|
|
117
|
+
expect(pub.bonusMeters).toHaveProperty('bonusGame1');
|
|
118
|
+
expect(pub.bonusMeters).toHaveProperty('bonusGame2');
|
|
119
|
+
expect(pub.bonusMeters).toHaveProperty('bonusGame3');
|
|
120
|
+
// privateState.nextSpinType is defined and non-empty
|
|
121
|
+
expect(priv.nextSpinType).toBeDefined();
|
|
122
|
+
expect(typeof priv.nextSpinType).toBe('string');
|
|
123
|
+
expect(priv.nextSpinType.length).toBeGreaterThan(0);
|
|
124
|
+
// privateState.pendingBonuses is an array
|
|
125
|
+
expect(Array.isArray(priv.pendingBonuses)).toBe(true);
|
|
126
|
+
}
|
|
127
|
+
// ---------------------------------------------------------------------------
|
|
128
|
+
// Test Suites
|
|
129
|
+
// ---------------------------------------------------------------------------
|
|
130
|
+
describe('Test Protocol: 10,000-Spin Simulation -- Bonnys Fortune', () => {
|
|
131
|
+
beforeEach(() => {
|
|
132
|
+
(0, test_engine_factory_1.resetCommandIdCounter)();
|
|
133
|
+
});
|
|
134
|
+
// -----------------------------------------------------------------------
|
|
135
|
+
// Test 1: 10,000 Base Game Spins with Bonus Completion
|
|
136
|
+
// -----------------------------------------------------------------------
|
|
137
|
+
describe('Test 1: 10,000 Base Game Spins with Bonus Completion', () => {
|
|
138
|
+
it('should complete 10,000 spins, handling any natural bonus triggers, writing NDJSON results', async () => {
|
|
139
|
+
ensureResultsDir();
|
|
140
|
+
const ndjsonFile = ndjsonPath('test1-10000-base-spins.ndjson');
|
|
141
|
+
// Truncate any previous run
|
|
142
|
+
fs.writeFileSync(ndjsonFile, '', 'utf-8');
|
|
143
|
+
const { engine } = (0, test_engine_factory_1.createEngineWithLcgRng)(99887);
|
|
144
|
+
const session = await (0, test_engine_factory_1.initSession)(engine, 1.0);
|
|
145
|
+
let pub = session.publicState;
|
|
146
|
+
let priv = session.privateState;
|
|
147
|
+
const betAmount = 1.0;
|
|
148
|
+
let totalWagered = 0;
|
|
149
|
+
let totalWon = 0;
|
|
150
|
+
let spinCount = 0;
|
|
151
|
+
const bonusTriggersPerType = {};
|
|
152
|
+
const tracker = { bonusTriggersPerType, totalWon };
|
|
153
|
+
for (let i = 0; i < 10000; i++) {
|
|
154
|
+
// If a bonus is pending, drain it before spinning
|
|
155
|
+
if (priv.nextSpinType &&
|
|
156
|
+
priv.nextSpinType !== 'BASE_GAME_SPIN' &&
|
|
157
|
+
priv.pendingBonuses?.length > 0) {
|
|
158
|
+
const drained = await drainAllBonuses(engine, pub, priv, betAmount, tracker);
|
|
159
|
+
pub = drained.pub;
|
|
160
|
+
priv = drained.priv;
|
|
161
|
+
}
|
|
162
|
+
// Execute base game spin
|
|
163
|
+
const spinResult = await (0, test_engine_factory_1.safeExecuteSpin)(engine, pub, priv, betAmount);
|
|
164
|
+
// safeExecuteSpin returns null if bonus state prevents spin
|
|
165
|
+
if (!spinResult) {
|
|
166
|
+
// Force drain any leftover bonus
|
|
167
|
+
if (priv.pendingBonuses?.length > 0) {
|
|
168
|
+
const drained = await drainAllBonuses(engine, pub, priv, betAmount, tracker);
|
|
169
|
+
pub = drained.pub;
|
|
170
|
+
priv = drained.priv;
|
|
171
|
+
}
|
|
172
|
+
// Retry the spin
|
|
173
|
+
const retry = await (0, test_engine_factory_1.safeExecuteSpin)(engine, pub, priv, betAmount);
|
|
174
|
+
if (!retry) {
|
|
175
|
+
// Skip this iteration if still stuck
|
|
176
|
+
continue;
|
|
177
|
+
}
|
|
178
|
+
spinCount++;
|
|
179
|
+
totalWagered += betAmount;
|
|
180
|
+
const win = extractPlayerWinning(retry);
|
|
181
|
+
totalWon += win;
|
|
182
|
+
pub = retry.publicState;
|
|
183
|
+
priv = retry.privateState;
|
|
184
|
+
// Write NDJSON record for retry
|
|
185
|
+
appendNdjson(ndjsonFile, {
|
|
186
|
+
spin: spinCount,
|
|
187
|
+
iteration: i,
|
|
188
|
+
wagered: betAmount,
|
|
189
|
+
win,
|
|
190
|
+
retried: true,
|
|
191
|
+
nextSpinType: priv.nextSpinType,
|
|
192
|
+
pendingBonuses: priv.pendingBonuses?.length ?? 0,
|
|
193
|
+
});
|
|
194
|
+
continue;
|
|
195
|
+
}
|
|
196
|
+
spinCount++;
|
|
197
|
+
totalWagered += betAmount;
|
|
198
|
+
const win = extractPlayerWinning(spinResult);
|
|
199
|
+
totalWon += win;
|
|
200
|
+
pub = spinResult.publicState;
|
|
201
|
+
priv = spinResult.privateState;
|
|
202
|
+
// Write NDJSON record
|
|
203
|
+
appendNdjson(ndjsonFile, {
|
|
204
|
+
spin: spinCount,
|
|
205
|
+
iteration: i,
|
|
206
|
+
wagered: betAmount,
|
|
207
|
+
win,
|
|
208
|
+
retried: false,
|
|
209
|
+
nextSpinType: priv.nextSpinType,
|
|
210
|
+
pendingBonuses: priv.pendingBonuses?.length ?? 0,
|
|
211
|
+
});
|
|
212
|
+
// If the spin triggered a bonus, drain it
|
|
213
|
+
if (priv.pendingBonuses?.length > 0) {
|
|
214
|
+
const drained = await drainAllBonuses(engine, pub, priv, betAmount, tracker);
|
|
215
|
+
pub = drained.pub;
|
|
216
|
+
priv = drained.priv;
|
|
217
|
+
}
|
|
218
|
+
// Log progress every 1,000 spins
|
|
219
|
+
if (spinCount % 1000 === 0) {
|
|
220
|
+
const runningTotalWon = totalWon + tracker.totalWon;
|
|
221
|
+
console.log(` [Test 1] Progress: ${spinCount} spins | Wagered: ${totalWagered.toFixed(2)} | Won: ${runningTotalWon.toFixed(2)} | RTP: ${totalWagered > 0 ? ((runningTotalWon / totalWagered) * 100).toFixed(2) : 0}%`);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
// Include bonus wins tracked separately
|
|
225
|
+
totalWon += tracker.totalWon;
|
|
226
|
+
console.log('=== Test 1: 10,000 Base Game Spins ===');
|
|
227
|
+
console.log(` Spins completed: ${spinCount}`);
|
|
228
|
+
console.log(` Total wagered: ${totalWagered.toFixed(2)}`);
|
|
229
|
+
console.log(` Total won: ${totalWon.toFixed(2)}`);
|
|
230
|
+
console.log(` RTP: ${totalWagered > 0 ? ((totalWon / totalWagered) * 100).toFixed(2) : 0}%`);
|
|
231
|
+
console.log(` Bonus triggers: ${JSON.stringify(bonusTriggersPerType)}`);
|
|
232
|
+
console.log(` NDJSON output: ${ndjsonFile}`);
|
|
233
|
+
// Assertions
|
|
234
|
+
expect(spinCount).toBeGreaterThanOrEqual(9500);
|
|
235
|
+
expect(totalWon).toBeGreaterThanOrEqual(0);
|
|
236
|
+
expect(totalWagered).toBeGreaterThan(0);
|
|
237
|
+
}, 600000);
|
|
238
|
+
});
|
|
239
|
+
// -----------------------------------------------------------------------
|
|
240
|
+
// Test 2: RTP Validation Over 10,000 Spins
|
|
241
|
+
// -----------------------------------------------------------------------
|
|
242
|
+
describe('Test 2: RTP Validation Over 10,000 Spins', () => {
|
|
243
|
+
it('should produce RTP between 0.70 and 1.30 (70%-130%) -- tighter bounds for 10,000 spins', async () => {
|
|
244
|
+
const { engine } = (0, test_engine_factory_1.createEngineWithLcgRng)(99887);
|
|
245
|
+
const session = await (0, test_engine_factory_1.initSession)(engine, 1.0);
|
|
246
|
+
let pub = session.publicState;
|
|
247
|
+
let priv = session.privateState;
|
|
248
|
+
const betAmount = 1.0;
|
|
249
|
+
let totalWagered = 0;
|
|
250
|
+
let totalWon = 0;
|
|
251
|
+
let paidSpins = 0;
|
|
252
|
+
const tracker = {
|
|
253
|
+
bonusTriggersPerType: {},
|
|
254
|
+
totalWon: 0,
|
|
255
|
+
};
|
|
256
|
+
while (paidSpins < 10000) {
|
|
257
|
+
// Drain any pending bonuses
|
|
258
|
+
if (priv.pendingBonuses?.length > 0) {
|
|
259
|
+
const drained = await drainAllBonuses(engine, pub, priv, betAmount, tracker);
|
|
260
|
+
pub = drained.pub;
|
|
261
|
+
priv = drained.priv;
|
|
262
|
+
}
|
|
263
|
+
// Ensure we're in BASE_GAME_SPIN
|
|
264
|
+
if (priv.nextSpinType !== 'BASE_GAME_SPIN') {
|
|
265
|
+
break;
|
|
266
|
+
}
|
|
267
|
+
const spinResult = await (0, test_engine_factory_1.safeExecuteSpin)(engine, pub, priv, betAmount);
|
|
268
|
+
if (!spinResult)
|
|
269
|
+
break;
|
|
270
|
+
paidSpins++;
|
|
271
|
+
totalWagered += betAmount;
|
|
272
|
+
const win = extractPlayerWinning(spinResult);
|
|
273
|
+
totalWon += win;
|
|
274
|
+
pub = spinResult.publicState;
|
|
275
|
+
priv = spinResult.privateState;
|
|
276
|
+
// Drain bonuses triggered by spin
|
|
277
|
+
if (priv.pendingBonuses?.length > 0) {
|
|
278
|
+
const drained = await drainAllBonuses(engine, pub, priv, betAmount, tracker);
|
|
279
|
+
pub = drained.pub;
|
|
280
|
+
priv = drained.priv;
|
|
281
|
+
}
|
|
282
|
+
// Log progress every 2,500 spins
|
|
283
|
+
if (paidSpins % 2500 === 0) {
|
|
284
|
+
const runningTotalWon = totalWon + tracker.totalWon;
|
|
285
|
+
console.log(` [Test 2] Progress: ${paidSpins} paid spins | RTP: ${totalWagered > 0 ? ((runningTotalWon / totalWagered) * 100).toFixed(2) : 0}%`);
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
// Combine base game wins with bonus wins
|
|
289
|
+
totalWon += tracker.totalWon;
|
|
290
|
+
const rtp = totalWagered > 0 ? totalWon / totalWagered : 0;
|
|
291
|
+
console.log('=== Test 2: RTP Validation (10,000 Spins) ===');
|
|
292
|
+
console.log(` Paid spins: ${paidSpins}`);
|
|
293
|
+
console.log(` Total wagered: ${totalWagered.toFixed(2)}`);
|
|
294
|
+
console.log(` Total won: ${totalWon.toFixed(2)}`);
|
|
295
|
+
console.log(` RTP: ${(rtp * 100).toFixed(2)}%`);
|
|
296
|
+
console.log(` Bonus triggers: ${JSON.stringify(tracker.bonusTriggersPerType)}`);
|
|
297
|
+
expect(paidSpins).toBeGreaterThanOrEqual(9500);
|
|
298
|
+
// Tighter bounds for 10,000 spins: declared RTP ~96%, SD shrinks with sqrt(n)
|
|
299
|
+
expect(rtp).toBeGreaterThanOrEqual(0.70);
|
|
300
|
+
expect(rtp).toBeLessThanOrEqual(1.30);
|
|
301
|
+
}, 600000);
|
|
302
|
+
});
|
|
303
|
+
// -----------------------------------------------------------------------
|
|
304
|
+
// Test 3: Bonus Coverage -- Debug Trigger 200x Each Bonus Type
|
|
305
|
+
// -----------------------------------------------------------------------
|
|
306
|
+
describe('Test 3: Bonus Coverage -- 200x Each Bonus Type', () => {
|
|
307
|
+
const bonusTypes = [
|
|
308
|
+
'bonusGame1',
|
|
309
|
+
'bonusGame2',
|
|
310
|
+
'bonusGame3',
|
|
311
|
+
'collectFeature',
|
|
312
|
+
];
|
|
313
|
+
for (const bonusType of bonusTypes) {
|
|
314
|
+
it(`should trigger ${bonusType} 200 times without crashes`, async () => {
|
|
315
|
+
let wins = 0;
|
|
316
|
+
let completions = 0;
|
|
317
|
+
for (let i = 0; i < 200; i++) {
|
|
318
|
+
(0, test_engine_factory_1.resetCommandIdCounter)();
|
|
319
|
+
const seed = 50000 + i * 41; // Different seed each iteration, unique from other tests
|
|
320
|
+
const { engine } = (0, test_engine_factory_1.createEngineWithLcgRng)(seed);
|
|
321
|
+
const session = await (0, test_engine_factory_1.initSession)(engine);
|
|
322
|
+
try {
|
|
323
|
+
const debugResult = await (0, test_engine_factory_1.debugTriggerBonus)(engine, session.publicState, session.privateState, bonusType);
|
|
324
|
+
expect(debugResult.success).toBe(true);
|
|
325
|
+
const bonus = debugResult.privateState.pendingBonuses[0];
|
|
326
|
+
const bonusResult = await (0, test_engine_factory_1.startBonusRound)(engine, debugResult.publicState, debugResult.privateState, bonus.bonusType);
|
|
327
|
+
expect(bonusResult.success).toBe(true);
|
|
328
|
+
completions++;
|
|
329
|
+
// Track total wins from bonus results
|
|
330
|
+
const stressOutcome = (0, test_engine_factory_1.getOutcome)(bonusResult);
|
|
331
|
+
if (stressOutcome.results) {
|
|
332
|
+
for (const r of stressOutcome.results) {
|
|
333
|
+
const w = r.result?.playerWinning ?? 0;
|
|
334
|
+
wins += w;
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
// Drain chained bonuses (bonusGame3 can chain to bonusGame1)
|
|
338
|
+
const finalState = (0, test_engine_factory_1.extractFinalBonusState)(bonusResult);
|
|
339
|
+
let pub = finalState.publicState;
|
|
340
|
+
let priv = finalState.privateState;
|
|
341
|
+
let depth = 5;
|
|
342
|
+
while (priv.pendingBonuses?.length > 0 && depth-- > 0) {
|
|
343
|
+
const chainedBonus = priv.pendingBonuses[0];
|
|
344
|
+
const chainedResult = await (0, test_engine_factory_1.startBonusRound)(engine, pub, priv, chainedBonus.bonusType);
|
|
345
|
+
expect(chainedResult.success).toBe(true);
|
|
346
|
+
const chainFinal = (0, test_engine_factory_1.extractFinalBonusState)(chainedResult);
|
|
347
|
+
pub = chainFinal.publicState;
|
|
348
|
+
priv = chainFinal.privateState;
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
catch (error) {
|
|
352
|
+
// Prevent cascade failures: log and continue to next iteration
|
|
353
|
+
console.warn(`[Test 3] ${bonusType} iteration ${i} failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
console.log(`=== Test 3: Bonus Coverage: ${bonusType} x200 ===`);
|
|
357
|
+
console.log(` Completions: ${completions}/200`);
|
|
358
|
+
console.log(` Total bonus wins: ${wins.toFixed(2)}`);
|
|
359
|
+
expect(completions).toBe(200);
|
|
360
|
+
}, 600000);
|
|
361
|
+
}
|
|
362
|
+
});
|
|
363
|
+
// -----------------------------------------------------------------------
|
|
364
|
+
// Test 4: State Consistency Over 10,000 Spins
|
|
365
|
+
// -----------------------------------------------------------------------
|
|
366
|
+
describe('Test 4: State Consistency Over 10,000 Spins', () => {
|
|
367
|
+
it('should maintain valid state after every spin and bonus round across 10,000 spins', async () => {
|
|
368
|
+
const { engine } = (0, test_engine_factory_1.createEngineWithLcgRng)(99887);
|
|
369
|
+
const session = await (0, test_engine_factory_1.initSession)(engine, 1.0);
|
|
370
|
+
let pub = session.publicState;
|
|
371
|
+
let priv = session.privateState;
|
|
372
|
+
const betAmount = 1.0;
|
|
373
|
+
let stateValidationFailures = 0;
|
|
374
|
+
let spinsCompleted = 0;
|
|
375
|
+
let bonusRoundsValidated = 0;
|
|
376
|
+
// Check initial state
|
|
377
|
+
try {
|
|
378
|
+
assertStateConsistency(pub, priv);
|
|
379
|
+
}
|
|
380
|
+
catch {
|
|
381
|
+
stateValidationFailures++;
|
|
382
|
+
}
|
|
383
|
+
for (let i = 0; i < 10000; i++) {
|
|
384
|
+
// Drain pending bonuses with consistency checks
|
|
385
|
+
if (priv.pendingBonuses?.length > 0) {
|
|
386
|
+
let depth = 10;
|
|
387
|
+
while (priv.pendingBonuses?.length > 0 && depth-- > 0) {
|
|
388
|
+
const bonus = priv.pendingBonuses[0];
|
|
389
|
+
try {
|
|
390
|
+
const bonusResult = await (0, test_engine_factory_1.startBonusRound)(engine, pub, priv, bonus.bonusType, betAmount);
|
|
391
|
+
expect(bonusResult.success).toBe(true);
|
|
392
|
+
// Check bonus winnings are non-negative
|
|
393
|
+
const consistencyOutcome = (0, test_engine_factory_1.getOutcome)(bonusResult);
|
|
394
|
+
if (consistencyOutcome.results) {
|
|
395
|
+
for (const r of consistencyOutcome.results) {
|
|
396
|
+
const w = r.result?.playerWinning ?? 0;
|
|
397
|
+
if (w < 0) {
|
|
398
|
+
stateValidationFailures++;
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
const finalState = (0, test_engine_factory_1.extractFinalBonusState)(bonusResult);
|
|
403
|
+
pub = finalState.publicState;
|
|
404
|
+
priv = finalState.privateState;
|
|
405
|
+
// Assert state consistency after every bonus round
|
|
406
|
+
try {
|
|
407
|
+
assertStateConsistency(pub, priv);
|
|
408
|
+
}
|
|
409
|
+
catch {
|
|
410
|
+
stateValidationFailures++;
|
|
411
|
+
}
|
|
412
|
+
bonusRoundsValidated++;
|
|
413
|
+
}
|
|
414
|
+
catch (error) {
|
|
415
|
+
// Prevent cascade failures: log, break bonus drain
|
|
416
|
+
console.warn(`[Test 4] Bonus drain error at spin ${i}: ${error instanceof Error ? error.message : String(error)}`);
|
|
417
|
+
break;
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
if (priv.nextSpinType !== 'BASE_GAME_SPIN') {
|
|
422
|
+
continue;
|
|
423
|
+
}
|
|
424
|
+
const spinResult = await (0, test_engine_factory_1.safeExecuteSpin)(engine, pub, priv, betAmount);
|
|
425
|
+
if (!spinResult)
|
|
426
|
+
continue;
|
|
427
|
+
spinsCompleted++;
|
|
428
|
+
// Check spin winning is non-negative
|
|
429
|
+
const spinWin = extractPlayerWinning(spinResult);
|
|
430
|
+
if (spinWin < 0) {
|
|
431
|
+
stateValidationFailures++;
|
|
432
|
+
}
|
|
433
|
+
pub = spinResult.publicState;
|
|
434
|
+
priv = spinResult.privateState;
|
|
435
|
+
// Verify state consistency after every spin
|
|
436
|
+
try {
|
|
437
|
+
assertStateConsistency(pub, priv);
|
|
438
|
+
}
|
|
439
|
+
catch {
|
|
440
|
+
stateValidationFailures++;
|
|
441
|
+
}
|
|
442
|
+
// Log progress every 2,000 spins
|
|
443
|
+
if (spinsCompleted % 2000 === 0) {
|
|
444
|
+
console.log(` [Test 4] Progress: ${spinsCompleted} spins validated | Bonus rounds: ${bonusRoundsValidated} | Failures: ${stateValidationFailures}`);
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
console.log('=== Test 4: State Consistency (10,000 Spins) ===');
|
|
448
|
+
console.log(` Spins completed: ${spinsCompleted}`);
|
|
449
|
+
console.log(` Bonus rounds validated: ${bonusRoundsValidated}`);
|
|
450
|
+
console.log(` State validation failures: ${stateValidationFailures}`);
|
|
451
|
+
// Assertions
|
|
452
|
+
expect(stateValidationFailures).toBe(0);
|
|
453
|
+
}, 600000);
|
|
454
|
+
});
|
|
455
|
+
});
|
|
456
|
+
//# sourceMappingURL=test-protocol-10000-spin.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"test-protocol-10000-spin.test.js","sourceRoot":"","sources":["../../src/__tests__/test-protocol-10000-spin.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -4,9 +4,8 @@ import { BonnysFortuneGameLogic } from './logic/bonnys-fortune.game-logic';
|
|
|
4
4
|
import { GameLogicConfigLoader } from './config/game-logic-config/game-logic-config-loader';
|
|
5
5
|
import { GameLogicConfigValidationService } from './validation/game-logic-config-validation.service';
|
|
6
6
|
import { ILogger, DebugIntrospectable, DebugCommandDefinition } from '@omnitronix/game-engine-contract';
|
|
7
|
-
import { SlotGameHandler } from '@omnitronix/game-engine-sdk
|
|
8
|
-
import type { BetConfig as SdkBetConfig, SlotState as SdkSlotState, SpinResult as SdkSpinResult, BonusTrigger as SdkBonusTrigger, BonusResult as SdkBonusResult } from '@omnitronix/game-engine-sdk
|
|
9
|
-
import type { GameTypeConfig } from '@omnitronix/game-engine-sdk/dist/game-type-config';
|
|
7
|
+
import { SlotGameHandler } from '@omnitronix/game-engine-sdk';
|
|
8
|
+
import type { BetConfig as SdkBetConfig, SlotState as SdkSlotState, SpinResult as SdkSpinResult, BonusTrigger as SdkBonusTrigger, BonusResult as SdkBonusResult, GameTypeConfig } from '@omnitronix/game-engine-sdk';
|
|
10
9
|
import { ReelStripsConfigLoader } from './config/reel-strips-config/reel-strips-config-loader';
|
|
11
10
|
import { ReelStripsConfigMapper } from './domain/mappers/reel-strips-config.mapper';
|
|
12
11
|
import { ReelStripsConfigValidationService } from './validation/reel-strips-config-validation.service';
|
|
@@ -8,7 +8,7 @@ const file_system_reel_strips_config_loader_1 = require("./config/reel-strips-co
|
|
|
8
8
|
const game_logic_config_validation_service_1 = require("./validation/game-logic-config-validation.service");
|
|
9
9
|
const game_round_types_1 = require("./domain/game-round.types");
|
|
10
10
|
const game_engine_contract_1 = require("@omnitronix/game-engine-contract");
|
|
11
|
-
const
|
|
11
|
+
const game_engine_sdk_1 = require("@omnitronix/game-engine-sdk");
|
|
12
12
|
const debug_command_definitions_1 = require("./debug/debug-command-definitions");
|
|
13
13
|
const reel_strips_config_mapper_1 = require("./domain/mappers/reel-strips-config.mapper");
|
|
14
14
|
const reel_strips_config_validation_service_1 = require("./validation/reel-strips-config-validation.service");
|
|
@@ -16,7 +16,7 @@ const rng_client_factory_1 = require("./rng/rng-client.factory");
|
|
|
16
16
|
const rng_service_1 = require("./rng/rng-service");
|
|
17
17
|
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
18
18
|
const packageJson = require('../package.json');
|
|
19
|
-
class BonnysFortuneV1GameEngine extends
|
|
19
|
+
class BonnysFortuneV1GameEngine extends game_engine_sdk_1.SlotGameHandler {
|
|
20
20
|
constructor(config = {}) {
|
|
21
21
|
super();
|
|
22
22
|
this.gameCode = 'bonnys-fortune';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bonnys-fortune-v1.game-engine.js","sourceRoot":"","sources":["../src/bonnys-fortune-v1.game-engine.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"bonnys-fortune-v1.game-engine.js","sourceRoot":"","sources":["../src/bonnys-fortune-v1.game-engine.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -3,5 +3,4 @@ export { BonnysFortuneV1GameEngine, BonnysFortuneV1GameEngineConfig, } from './b
|
|
|
3
3
|
export { GameEngine, GameEngineInfo, GameActionCommand, CommandProcessingResult, RngOutcome, RngOutcomeRecord, ILogger, DebugIntrospectable, DebugCommandDefinition, isDebugIntrospectable, } from '@omnitronix/game-engine-contract';
|
|
4
4
|
export { BONNYS_FORTUNE_BONUS_TYPES, BONNYS_FORTUNE_DEBUG_DEFINITIONS, getDebugCommandDefinitions, DebugSecurityError, } from './debug/debug-command-definitions';
|
|
5
5
|
export { GameEngineConfig, GameEngineMetricsHandlers } from './game-engine.interface';
|
|
6
|
-
export type { GameTypeConfig } from '@omnitronix/game-engine-sdk
|
|
7
|
-
export type { BonusResultDeliveryStrategy, BonusRoundResponse } from '@omnitronix/game-engine-sdk/dist/core';
|
|
6
|
+
export type { GameTypeConfig, BonusResultDeliveryStrategy, BonusRoundResponse } from '@omnitronix/game-engine-sdk';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@omnitronix/bonnys-fortune-game-engine",
|
|
3
|
-
"version": "1.8.
|
|
3
|
+
"version": "1.8.2",
|
|
4
4
|
"description": "Bonnys Fortune Game Engine",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
"license": "UNLICENSED",
|
|
21
21
|
"dependencies": {
|
|
22
22
|
"@omnitronix/game-engine-contract": "^1.4.0",
|
|
23
|
-
"@omnitronix/game-engine-sdk": "^2.
|
|
23
|
+
"@omnitronix/game-engine-sdk": "^2.5.0",
|
|
24
24
|
"@omnitronix/rng-client-core": "^1.1.1",
|
|
25
25
|
"class-transformer": "^0.5.1",
|
|
26
26
|
"class-validator": "^0.14.1",
|
|
@@ -29,6 +29,7 @@
|
|
|
29
29
|
},
|
|
30
30
|
"devDependencies": {
|
|
31
31
|
"@omnitronix/game-test-utils": "^1.1.0",
|
|
32
|
+
"@types/express": "^5.0.6",
|
|
32
33
|
"@types/jest": "^29.5.0",
|
|
33
34
|
"@types/node": "^20.0.0",
|
|
34
35
|
"@types/uuid": "^9.0.0",
|
|
@@ -0,0 +1,643 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Test Protocol: 10,000-Spin Simulation -- Bonnys Fortune
|
|
3
|
+
*
|
|
4
|
+
* Extended test protocol that validates game engine integrity over 10,000 spins.
|
|
5
|
+
* Writes per-spin NDJSON results to results/ directory for offline analysis.
|
|
6
|
+
*
|
|
7
|
+
* Tests:
|
|
8
|
+
* 1. 10,000 Base Game Spins with Bonus Completion
|
|
9
|
+
* 2. RTP Validation Over 10,000 Spins (tighter bounds: 70%-130%)
|
|
10
|
+
* 3. Bonus Coverage -- Debug Trigger 200x Each Bonus Type
|
|
11
|
+
* 4. State Consistency Over 10,000 Spins
|
|
12
|
+
*/
|
|
13
|
+
import * as fs from 'fs';
|
|
14
|
+
import * as path from 'path';
|
|
15
|
+
import {
|
|
16
|
+
createEngineWithLcgRng,
|
|
17
|
+
initSession,
|
|
18
|
+
executeSpin,
|
|
19
|
+
safeExecuteSpin,
|
|
20
|
+
startBonusRound,
|
|
21
|
+
extractFinalBonusState,
|
|
22
|
+
debugTriggerBonus,
|
|
23
|
+
resetCommandIdCounter,
|
|
24
|
+
BonnysFortuneCommandResult,
|
|
25
|
+
getOutcome,
|
|
26
|
+
} from './helpers/test-engine-factory';
|
|
27
|
+
import { BonnysFortuneV1GameEngine } from '../bonnys-fortune-v1.game-engine';
|
|
28
|
+
import {
|
|
29
|
+
BonnysFortunePublicState,
|
|
30
|
+
BonnysFortunePrivateState,
|
|
31
|
+
SpinResult,
|
|
32
|
+
BonusRoundResult,
|
|
33
|
+
} from '../logic/bonnys-fortune.types';
|
|
34
|
+
|
|
35
|
+
// ---------------------------------------------------------------------------
|
|
36
|
+
// NDJSON Output Setup
|
|
37
|
+
// ---------------------------------------------------------------------------
|
|
38
|
+
|
|
39
|
+
const RESULTS_DIR = path.resolve(__dirname, '../../results');
|
|
40
|
+
|
|
41
|
+
function ensureResultsDir(): void {
|
|
42
|
+
if (!fs.existsSync(RESULTS_DIR)) {
|
|
43
|
+
fs.mkdirSync(RESULTS_DIR, { recursive: true });
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function ndjsonPath(filename: string): string {
|
|
48
|
+
return path.join(RESULTS_DIR, filename);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function appendNdjson(filepath: string, record: Record<string, unknown>): void {
|
|
52
|
+
fs.appendFileSync(filepath, JSON.stringify(record) + '\n', 'utf-8');
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// ---------------------------------------------------------------------------
|
|
56
|
+
// Helpers (same pattern as integration-1000-spin.test.ts)
|
|
57
|
+
// ---------------------------------------------------------------------------
|
|
58
|
+
|
|
59
|
+
/** Extract playerWinning from a command result outcome. */
|
|
60
|
+
function extractPlayerWinning(result: BonnysFortuneCommandResult): number {
|
|
61
|
+
const outcome = result.outcome as unknown as {
|
|
62
|
+
result?: { playerWinning?: number; totalWin?: number };
|
|
63
|
+
playerWinning?: number;
|
|
64
|
+
totalWin?: number;
|
|
65
|
+
} | null;
|
|
66
|
+
return outcome?.result?.playerWinning
|
|
67
|
+
?? outcome?.playerWinning
|
|
68
|
+
?? outcome?.result?.totalWin
|
|
69
|
+
?? outcome?.totalWin
|
|
70
|
+
?? 0;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/** Drain all pending bonuses, including chained ones (e.g. bonusGame3 -> bonusGame1). */
|
|
74
|
+
async function drainAllBonuses(
|
|
75
|
+
engine: BonnysFortuneV1GameEngine,
|
|
76
|
+
pub: BonnysFortunePublicState,
|
|
77
|
+
priv: BonnysFortunePrivateState,
|
|
78
|
+
betAmount: number,
|
|
79
|
+
tracker: {
|
|
80
|
+
bonusTriggersPerType: Record<string, number>;
|
|
81
|
+
totalWon: number;
|
|
82
|
+
},
|
|
83
|
+
): Promise<{ pub: BonnysFortunePublicState; priv: BonnysFortunePrivateState }> {
|
|
84
|
+
let maxDepth = 10; // safety guard against infinite chaining
|
|
85
|
+
while (priv.pendingBonuses?.length > 0 && maxDepth-- > 0) {
|
|
86
|
+
const bonus = priv.pendingBonuses[0];
|
|
87
|
+
const bonusType = bonus.bonusType;
|
|
88
|
+
|
|
89
|
+
tracker.bonusTriggersPerType[bonusType] =
|
|
90
|
+
(tracker.bonusTriggersPerType[bonusType] ?? 0) + 1;
|
|
91
|
+
|
|
92
|
+
try {
|
|
93
|
+
const bonusResult = await startBonusRound(
|
|
94
|
+
engine,
|
|
95
|
+
pub,
|
|
96
|
+
priv,
|
|
97
|
+
bonusType,
|
|
98
|
+
betAmount,
|
|
99
|
+
);
|
|
100
|
+
expect(bonusResult.success).toBe(true);
|
|
101
|
+
|
|
102
|
+
// Sum bonus winnings from results array
|
|
103
|
+
const bonusOutcome = bonusResult.outcome as unknown as BonusRoundResult<SpinResult> | null;
|
|
104
|
+
if (bonusOutcome?.results) {
|
|
105
|
+
for (const r of bonusOutcome.results) {
|
|
106
|
+
const win = r.result?.playerWinning ?? 0;
|
|
107
|
+
tracker.totalWon += win;
|
|
108
|
+
}
|
|
109
|
+
} else {
|
|
110
|
+
tracker.totalWon += extractPlayerWinning(bonusResult);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
const finalState = extractFinalBonusState(bonusResult);
|
|
114
|
+
pub = finalState.publicState;
|
|
115
|
+
priv = finalState.privateState;
|
|
116
|
+
} catch (error: unknown) {
|
|
117
|
+
// Prevent cascade failures: log and break out of bonus drain
|
|
118
|
+
console.warn(
|
|
119
|
+
`[drainAllBonuses] Error draining ${bonusType}: ${error instanceof Error ? error.message : String(error)}`,
|
|
120
|
+
);
|
|
121
|
+
break;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
return { pub, priv };
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/** Validate state consistency assertions after any command. */
|
|
128
|
+
function assertStateConsistency(
|
|
129
|
+
pub: BonnysFortunePublicState,
|
|
130
|
+
priv: BonnysFortunePrivateState,
|
|
131
|
+
): void {
|
|
132
|
+
// publicState.bonusMeters has exactly 3 keys
|
|
133
|
+
expect(pub.bonusMeters).toBeDefined();
|
|
134
|
+
expect(Object.keys(pub.bonusMeters).length).toBe(3);
|
|
135
|
+
expect(pub.bonusMeters).toHaveProperty('bonusGame1');
|
|
136
|
+
expect(pub.bonusMeters).toHaveProperty('bonusGame2');
|
|
137
|
+
expect(pub.bonusMeters).toHaveProperty('bonusGame3');
|
|
138
|
+
|
|
139
|
+
// privateState.nextSpinType is defined and non-empty
|
|
140
|
+
expect(priv.nextSpinType).toBeDefined();
|
|
141
|
+
expect(typeof priv.nextSpinType).toBe('string');
|
|
142
|
+
expect(priv.nextSpinType.length).toBeGreaterThan(0);
|
|
143
|
+
|
|
144
|
+
// privateState.pendingBonuses is an array
|
|
145
|
+
expect(Array.isArray(priv.pendingBonuses)).toBe(true);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
// ---------------------------------------------------------------------------
|
|
149
|
+
// Test Suites
|
|
150
|
+
// ---------------------------------------------------------------------------
|
|
151
|
+
|
|
152
|
+
describe('Test Protocol: 10,000-Spin Simulation -- Bonnys Fortune', () => {
|
|
153
|
+
beforeEach(() => {
|
|
154
|
+
resetCommandIdCounter();
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
// -----------------------------------------------------------------------
|
|
158
|
+
// Test 1: 10,000 Base Game Spins with Bonus Completion
|
|
159
|
+
// -----------------------------------------------------------------------
|
|
160
|
+
describe('Test 1: 10,000 Base Game Spins with Bonus Completion', () => {
|
|
161
|
+
it(
|
|
162
|
+
'should complete 10,000 spins, handling any natural bonus triggers, writing NDJSON results',
|
|
163
|
+
async () => {
|
|
164
|
+
ensureResultsDir();
|
|
165
|
+
const ndjsonFile = ndjsonPath('test1-10000-base-spins.ndjson');
|
|
166
|
+
// Truncate any previous run
|
|
167
|
+
fs.writeFileSync(ndjsonFile, '', 'utf-8');
|
|
168
|
+
|
|
169
|
+
const { engine } = createEngineWithLcgRng(99887);
|
|
170
|
+
const session = await initSession(engine, 1.0);
|
|
171
|
+
|
|
172
|
+
let pub = session.publicState;
|
|
173
|
+
let priv = session.privateState;
|
|
174
|
+
const betAmount = 1.0;
|
|
175
|
+
|
|
176
|
+
let totalWagered = 0;
|
|
177
|
+
let totalWon = 0;
|
|
178
|
+
let spinCount = 0;
|
|
179
|
+
const bonusTriggersPerType: Record<string, number> = {};
|
|
180
|
+
const tracker = { bonusTriggersPerType, totalWon };
|
|
181
|
+
|
|
182
|
+
for (let i = 0; i < 10000; i++) {
|
|
183
|
+
// If a bonus is pending, drain it before spinning
|
|
184
|
+
if (
|
|
185
|
+
priv.nextSpinType &&
|
|
186
|
+
priv.nextSpinType !== 'BASE_GAME_SPIN' &&
|
|
187
|
+
priv.pendingBonuses?.length > 0
|
|
188
|
+
) {
|
|
189
|
+
const drained = await drainAllBonuses(
|
|
190
|
+
engine,
|
|
191
|
+
pub,
|
|
192
|
+
priv,
|
|
193
|
+
betAmount,
|
|
194
|
+
tracker,
|
|
195
|
+
);
|
|
196
|
+
pub = drained.pub;
|
|
197
|
+
priv = drained.priv;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
// Execute base game spin
|
|
201
|
+
const spinResult = await safeExecuteSpin(
|
|
202
|
+
engine,
|
|
203
|
+
pub,
|
|
204
|
+
priv,
|
|
205
|
+
betAmount,
|
|
206
|
+
);
|
|
207
|
+
|
|
208
|
+
// safeExecuteSpin returns null if bonus state prevents spin
|
|
209
|
+
if (!spinResult) {
|
|
210
|
+
// Force drain any leftover bonus
|
|
211
|
+
if (priv.pendingBonuses?.length > 0) {
|
|
212
|
+
const drained = await drainAllBonuses(
|
|
213
|
+
engine,
|
|
214
|
+
pub,
|
|
215
|
+
priv,
|
|
216
|
+
betAmount,
|
|
217
|
+
tracker,
|
|
218
|
+
);
|
|
219
|
+
pub = drained.pub;
|
|
220
|
+
priv = drained.priv;
|
|
221
|
+
}
|
|
222
|
+
// Retry the spin
|
|
223
|
+
const retry = await safeExecuteSpin(
|
|
224
|
+
engine,
|
|
225
|
+
pub,
|
|
226
|
+
priv,
|
|
227
|
+
betAmount,
|
|
228
|
+
);
|
|
229
|
+
if (!retry) {
|
|
230
|
+
// Skip this iteration if still stuck
|
|
231
|
+
continue;
|
|
232
|
+
}
|
|
233
|
+
spinCount++;
|
|
234
|
+
totalWagered += betAmount;
|
|
235
|
+
|
|
236
|
+
const win = extractPlayerWinning(retry);
|
|
237
|
+
totalWon += win;
|
|
238
|
+
|
|
239
|
+
pub = retry.publicState;
|
|
240
|
+
priv = retry.privateState;
|
|
241
|
+
|
|
242
|
+
// Write NDJSON record for retry
|
|
243
|
+
appendNdjson(ndjsonFile, {
|
|
244
|
+
spin: spinCount,
|
|
245
|
+
iteration: i,
|
|
246
|
+
wagered: betAmount,
|
|
247
|
+
win,
|
|
248
|
+
retried: true,
|
|
249
|
+
nextSpinType: priv.nextSpinType,
|
|
250
|
+
pendingBonuses: priv.pendingBonuses?.length ?? 0,
|
|
251
|
+
});
|
|
252
|
+
continue;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
spinCount++;
|
|
256
|
+
totalWagered += betAmount;
|
|
257
|
+
|
|
258
|
+
const win = extractPlayerWinning(spinResult);
|
|
259
|
+
totalWon += win;
|
|
260
|
+
|
|
261
|
+
pub = spinResult.publicState;
|
|
262
|
+
priv = spinResult.privateState;
|
|
263
|
+
|
|
264
|
+
// Write NDJSON record
|
|
265
|
+
appendNdjson(ndjsonFile, {
|
|
266
|
+
spin: spinCount,
|
|
267
|
+
iteration: i,
|
|
268
|
+
wagered: betAmount,
|
|
269
|
+
win,
|
|
270
|
+
retried: false,
|
|
271
|
+
nextSpinType: priv.nextSpinType,
|
|
272
|
+
pendingBonuses: priv.pendingBonuses?.length ?? 0,
|
|
273
|
+
});
|
|
274
|
+
|
|
275
|
+
// If the spin triggered a bonus, drain it
|
|
276
|
+
if (priv.pendingBonuses?.length > 0) {
|
|
277
|
+
const drained = await drainAllBonuses(
|
|
278
|
+
engine,
|
|
279
|
+
pub,
|
|
280
|
+
priv,
|
|
281
|
+
betAmount,
|
|
282
|
+
tracker,
|
|
283
|
+
);
|
|
284
|
+
pub = drained.pub;
|
|
285
|
+
priv = drained.priv;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
// Log progress every 1,000 spins
|
|
289
|
+
if (spinCount % 1000 === 0) {
|
|
290
|
+
const runningTotalWon = totalWon + tracker.totalWon;
|
|
291
|
+
console.log(
|
|
292
|
+
` [Test 1] Progress: ${spinCount} spins | Wagered: ${totalWagered.toFixed(2)} | Won: ${runningTotalWon.toFixed(2)} | RTP: ${totalWagered > 0 ? ((runningTotalWon / totalWagered) * 100).toFixed(2) : 0}%`,
|
|
293
|
+
);
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
// Include bonus wins tracked separately
|
|
298
|
+
totalWon += tracker.totalWon;
|
|
299
|
+
|
|
300
|
+
console.log('=== Test 1: 10,000 Base Game Spins ===');
|
|
301
|
+
console.log(` Spins completed: ${spinCount}`);
|
|
302
|
+
console.log(` Total wagered: ${totalWagered.toFixed(2)}`);
|
|
303
|
+
console.log(` Total won: ${totalWon.toFixed(2)}`);
|
|
304
|
+
console.log(
|
|
305
|
+
` RTP: ${totalWagered > 0 ? ((totalWon / totalWagered) * 100).toFixed(2) : 0}%`,
|
|
306
|
+
);
|
|
307
|
+
console.log(
|
|
308
|
+
` Bonus triggers: ${JSON.stringify(bonusTriggersPerType)}`,
|
|
309
|
+
);
|
|
310
|
+
console.log(` NDJSON output: ${ndjsonFile}`);
|
|
311
|
+
|
|
312
|
+
// Assertions
|
|
313
|
+
expect(spinCount).toBeGreaterThanOrEqual(9500);
|
|
314
|
+
expect(totalWon).toBeGreaterThanOrEqual(0);
|
|
315
|
+
expect(totalWagered).toBeGreaterThan(0);
|
|
316
|
+
},
|
|
317
|
+
600000,
|
|
318
|
+
);
|
|
319
|
+
});
|
|
320
|
+
|
|
321
|
+
// -----------------------------------------------------------------------
|
|
322
|
+
// Test 2: RTP Validation Over 10,000 Spins
|
|
323
|
+
// -----------------------------------------------------------------------
|
|
324
|
+
describe('Test 2: RTP Validation Over 10,000 Spins', () => {
|
|
325
|
+
it(
|
|
326
|
+
'should produce RTP between 0.70 and 1.30 (70%-130%) -- tighter bounds for 10,000 spins',
|
|
327
|
+
async () => {
|
|
328
|
+
const { engine } = createEngineWithLcgRng(99887);
|
|
329
|
+
const session = await initSession(engine, 1.0);
|
|
330
|
+
|
|
331
|
+
let pub = session.publicState;
|
|
332
|
+
let priv = session.privateState;
|
|
333
|
+
const betAmount = 1.0;
|
|
334
|
+
|
|
335
|
+
let totalWagered = 0;
|
|
336
|
+
let totalWon = 0;
|
|
337
|
+
let paidSpins = 0;
|
|
338
|
+
const tracker = {
|
|
339
|
+
bonusTriggersPerType: {} as Record<string, number>,
|
|
340
|
+
totalWon: 0,
|
|
341
|
+
};
|
|
342
|
+
|
|
343
|
+
while (paidSpins < 10000) {
|
|
344
|
+
// Drain any pending bonuses
|
|
345
|
+
if (priv.pendingBonuses?.length > 0) {
|
|
346
|
+
const drained = await drainAllBonuses(
|
|
347
|
+
engine,
|
|
348
|
+
pub,
|
|
349
|
+
priv,
|
|
350
|
+
betAmount,
|
|
351
|
+
tracker,
|
|
352
|
+
);
|
|
353
|
+
pub = drained.pub;
|
|
354
|
+
priv = drained.priv;
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
// Ensure we're in BASE_GAME_SPIN
|
|
358
|
+
if (priv.nextSpinType !== 'BASE_GAME_SPIN') {
|
|
359
|
+
break;
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
const spinResult = await safeExecuteSpin(
|
|
363
|
+
engine,
|
|
364
|
+
pub,
|
|
365
|
+
priv,
|
|
366
|
+
betAmount,
|
|
367
|
+
);
|
|
368
|
+
if (!spinResult) break;
|
|
369
|
+
|
|
370
|
+
paidSpins++;
|
|
371
|
+
totalWagered += betAmount;
|
|
372
|
+
|
|
373
|
+
const win = extractPlayerWinning(spinResult);
|
|
374
|
+
totalWon += win;
|
|
375
|
+
|
|
376
|
+
pub = spinResult.publicState;
|
|
377
|
+
priv = spinResult.privateState;
|
|
378
|
+
|
|
379
|
+
// Drain bonuses triggered by spin
|
|
380
|
+
if (priv.pendingBonuses?.length > 0) {
|
|
381
|
+
const drained = await drainAllBonuses(
|
|
382
|
+
engine,
|
|
383
|
+
pub,
|
|
384
|
+
priv,
|
|
385
|
+
betAmount,
|
|
386
|
+
tracker,
|
|
387
|
+
);
|
|
388
|
+
pub = drained.pub;
|
|
389
|
+
priv = drained.priv;
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
// Log progress every 2,500 spins
|
|
393
|
+
if (paidSpins % 2500 === 0) {
|
|
394
|
+
const runningTotalWon = totalWon + tracker.totalWon;
|
|
395
|
+
console.log(
|
|
396
|
+
` [Test 2] Progress: ${paidSpins} paid spins | RTP: ${totalWagered > 0 ? ((runningTotalWon / totalWagered) * 100).toFixed(2) : 0}%`,
|
|
397
|
+
);
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
// Combine base game wins with bonus wins
|
|
402
|
+
totalWon += tracker.totalWon;
|
|
403
|
+
|
|
404
|
+
const rtp =
|
|
405
|
+
totalWagered > 0 ? totalWon / totalWagered : 0;
|
|
406
|
+
|
|
407
|
+
console.log('=== Test 2: RTP Validation (10,000 Spins) ===');
|
|
408
|
+
console.log(` Paid spins: ${paidSpins}`);
|
|
409
|
+
console.log(` Total wagered: ${totalWagered.toFixed(2)}`);
|
|
410
|
+
console.log(` Total won: ${totalWon.toFixed(2)}`);
|
|
411
|
+
console.log(` RTP: ${(rtp * 100).toFixed(2)}%`);
|
|
412
|
+
console.log(
|
|
413
|
+
` Bonus triggers: ${JSON.stringify(tracker.bonusTriggersPerType)}`,
|
|
414
|
+
);
|
|
415
|
+
|
|
416
|
+
expect(paidSpins).toBeGreaterThanOrEqual(9500);
|
|
417
|
+
// Tighter bounds for 10,000 spins: declared RTP ~96%, SD shrinks with sqrt(n)
|
|
418
|
+
expect(rtp).toBeGreaterThanOrEqual(0.70);
|
|
419
|
+
expect(rtp).toBeLessThanOrEqual(1.30);
|
|
420
|
+
},
|
|
421
|
+
600000,
|
|
422
|
+
);
|
|
423
|
+
});
|
|
424
|
+
|
|
425
|
+
// -----------------------------------------------------------------------
|
|
426
|
+
// Test 3: Bonus Coverage -- Debug Trigger 200x Each Bonus Type
|
|
427
|
+
// -----------------------------------------------------------------------
|
|
428
|
+
describe('Test 3: Bonus Coverage -- 200x Each Bonus Type', () => {
|
|
429
|
+
const bonusTypes = [
|
|
430
|
+
'bonusGame1',
|
|
431
|
+
'bonusGame2',
|
|
432
|
+
'bonusGame3',
|
|
433
|
+
'collectFeature',
|
|
434
|
+
];
|
|
435
|
+
|
|
436
|
+
for (const bonusType of bonusTypes) {
|
|
437
|
+
it(
|
|
438
|
+
`should trigger ${bonusType} 200 times without crashes`,
|
|
439
|
+
async () => {
|
|
440
|
+
let wins = 0;
|
|
441
|
+
let completions = 0;
|
|
442
|
+
|
|
443
|
+
for (let i = 0; i < 200; i++) {
|
|
444
|
+
resetCommandIdCounter();
|
|
445
|
+
const seed = 50000 + i * 41; // Different seed each iteration, unique from other tests
|
|
446
|
+
const { engine } = createEngineWithLcgRng(seed);
|
|
447
|
+
const session = await initSession(engine);
|
|
448
|
+
|
|
449
|
+
try {
|
|
450
|
+
const debugResult = await debugTriggerBonus(
|
|
451
|
+
engine,
|
|
452
|
+
session.publicState,
|
|
453
|
+
session.privateState,
|
|
454
|
+
bonusType,
|
|
455
|
+
);
|
|
456
|
+
|
|
457
|
+
expect(debugResult.success).toBe(true);
|
|
458
|
+
|
|
459
|
+
const bonus = debugResult.privateState.pendingBonuses[0];
|
|
460
|
+
const bonusResult = await startBonusRound(
|
|
461
|
+
engine,
|
|
462
|
+
debugResult.publicState,
|
|
463
|
+
debugResult.privateState,
|
|
464
|
+
bonus.bonusType,
|
|
465
|
+
);
|
|
466
|
+
|
|
467
|
+
expect(bonusResult.success).toBe(true);
|
|
468
|
+
completions++;
|
|
469
|
+
|
|
470
|
+
// Track total wins from bonus results
|
|
471
|
+
const stressOutcome = getOutcome(bonusResult);
|
|
472
|
+
if (stressOutcome.results) {
|
|
473
|
+
for (const r of stressOutcome.results) {
|
|
474
|
+
const w =
|
|
475
|
+
r.result?.playerWinning ?? 0;
|
|
476
|
+
wins += w;
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
// Drain chained bonuses (bonusGame3 can chain to bonusGame1)
|
|
481
|
+
const finalState = extractFinalBonusState(bonusResult);
|
|
482
|
+
let pub = finalState.publicState;
|
|
483
|
+
let priv = finalState.privateState;
|
|
484
|
+
let depth = 5;
|
|
485
|
+
while (priv.pendingBonuses?.length > 0 && depth-- > 0) {
|
|
486
|
+
const chainedBonus = priv.pendingBonuses[0];
|
|
487
|
+
const chainedResult = await startBonusRound(
|
|
488
|
+
engine,
|
|
489
|
+
pub,
|
|
490
|
+
priv,
|
|
491
|
+
chainedBonus.bonusType,
|
|
492
|
+
);
|
|
493
|
+
expect(chainedResult.success).toBe(true);
|
|
494
|
+
const chainFinal = extractFinalBonusState(chainedResult);
|
|
495
|
+
pub = chainFinal.publicState;
|
|
496
|
+
priv = chainFinal.privateState;
|
|
497
|
+
}
|
|
498
|
+
} catch (error: unknown) {
|
|
499
|
+
// Prevent cascade failures: log and continue to next iteration
|
|
500
|
+
console.warn(
|
|
501
|
+
`[Test 3] ${bonusType} iteration ${i} failed: ${error instanceof Error ? error.message : String(error)}`,
|
|
502
|
+
);
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
console.log(
|
|
507
|
+
`=== Test 3: Bonus Coverage: ${bonusType} x200 ===`,
|
|
508
|
+
);
|
|
509
|
+
console.log(` Completions: ${completions}/200`);
|
|
510
|
+
console.log(` Total bonus wins: ${wins.toFixed(2)}`);
|
|
511
|
+
|
|
512
|
+
expect(completions).toBe(200);
|
|
513
|
+
},
|
|
514
|
+
600000,
|
|
515
|
+
);
|
|
516
|
+
}
|
|
517
|
+
});
|
|
518
|
+
|
|
519
|
+
// -----------------------------------------------------------------------
|
|
520
|
+
// Test 4: State Consistency Over 10,000 Spins
|
|
521
|
+
// -----------------------------------------------------------------------
|
|
522
|
+
describe('Test 4: State Consistency Over 10,000 Spins', () => {
|
|
523
|
+
it(
|
|
524
|
+
'should maintain valid state after every spin and bonus round across 10,000 spins',
|
|
525
|
+
async () => {
|
|
526
|
+
const { engine } = createEngineWithLcgRng(99887);
|
|
527
|
+
const session = await initSession(engine, 1.0);
|
|
528
|
+
|
|
529
|
+
let pub = session.publicState;
|
|
530
|
+
let priv = session.privateState;
|
|
531
|
+
const betAmount = 1.0;
|
|
532
|
+
|
|
533
|
+
let stateValidationFailures = 0;
|
|
534
|
+
let spinsCompleted = 0;
|
|
535
|
+
let bonusRoundsValidated = 0;
|
|
536
|
+
|
|
537
|
+
// Check initial state
|
|
538
|
+
try {
|
|
539
|
+
assertStateConsistency(pub, priv);
|
|
540
|
+
} catch {
|
|
541
|
+
stateValidationFailures++;
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
for (let i = 0; i < 10000; i++) {
|
|
545
|
+
// Drain pending bonuses with consistency checks
|
|
546
|
+
if (priv.pendingBonuses?.length > 0) {
|
|
547
|
+
let depth = 10;
|
|
548
|
+
while (priv.pendingBonuses?.length > 0 && depth-- > 0) {
|
|
549
|
+
const bonus = priv.pendingBonuses[0];
|
|
550
|
+
|
|
551
|
+
try {
|
|
552
|
+
const bonusResult = await startBonusRound(
|
|
553
|
+
engine,
|
|
554
|
+
pub,
|
|
555
|
+
priv,
|
|
556
|
+
bonus.bonusType,
|
|
557
|
+
betAmount,
|
|
558
|
+
);
|
|
559
|
+
|
|
560
|
+
expect(bonusResult.success).toBe(true);
|
|
561
|
+
|
|
562
|
+
// Check bonus winnings are non-negative
|
|
563
|
+
const consistencyOutcome = getOutcome(bonusResult);
|
|
564
|
+
if (consistencyOutcome.results) {
|
|
565
|
+
for (const r of consistencyOutcome.results) {
|
|
566
|
+
const w = r.result?.playerWinning ?? 0;
|
|
567
|
+
if (w < 0) {
|
|
568
|
+
stateValidationFailures++;
|
|
569
|
+
}
|
|
570
|
+
}
|
|
571
|
+
}
|
|
572
|
+
|
|
573
|
+
const finalState = extractFinalBonusState(bonusResult);
|
|
574
|
+
pub = finalState.publicState;
|
|
575
|
+
priv = finalState.privateState;
|
|
576
|
+
|
|
577
|
+
// Assert state consistency after every bonus round
|
|
578
|
+
try {
|
|
579
|
+
assertStateConsistency(pub, priv);
|
|
580
|
+
} catch {
|
|
581
|
+
stateValidationFailures++;
|
|
582
|
+
}
|
|
583
|
+
bonusRoundsValidated++;
|
|
584
|
+
} catch (error: unknown) {
|
|
585
|
+
// Prevent cascade failures: log, break bonus drain
|
|
586
|
+
console.warn(
|
|
587
|
+
`[Test 4] Bonus drain error at spin ${i}: ${error instanceof Error ? error.message : String(error)}`,
|
|
588
|
+
);
|
|
589
|
+
break;
|
|
590
|
+
}
|
|
591
|
+
}
|
|
592
|
+
}
|
|
593
|
+
|
|
594
|
+
if (priv.nextSpinType !== 'BASE_GAME_SPIN') {
|
|
595
|
+
continue;
|
|
596
|
+
}
|
|
597
|
+
|
|
598
|
+
const spinResult = await safeExecuteSpin(
|
|
599
|
+
engine,
|
|
600
|
+
pub,
|
|
601
|
+
priv,
|
|
602
|
+
betAmount,
|
|
603
|
+
);
|
|
604
|
+
if (!spinResult) continue;
|
|
605
|
+
|
|
606
|
+
spinsCompleted++;
|
|
607
|
+
|
|
608
|
+
// Check spin winning is non-negative
|
|
609
|
+
const spinWin = extractPlayerWinning(spinResult);
|
|
610
|
+
if (spinWin < 0) {
|
|
611
|
+
stateValidationFailures++;
|
|
612
|
+
}
|
|
613
|
+
|
|
614
|
+
pub = spinResult.publicState;
|
|
615
|
+
priv = spinResult.privateState;
|
|
616
|
+
|
|
617
|
+
// Verify state consistency after every spin
|
|
618
|
+
try {
|
|
619
|
+
assertStateConsistency(pub, priv);
|
|
620
|
+
} catch {
|
|
621
|
+
stateValidationFailures++;
|
|
622
|
+
}
|
|
623
|
+
|
|
624
|
+
// Log progress every 2,000 spins
|
|
625
|
+
if (spinsCompleted % 2000 === 0) {
|
|
626
|
+
console.log(
|
|
627
|
+
` [Test 4] Progress: ${spinsCompleted} spins validated | Bonus rounds: ${bonusRoundsValidated} | Failures: ${stateValidationFailures}`,
|
|
628
|
+
);
|
|
629
|
+
}
|
|
630
|
+
}
|
|
631
|
+
|
|
632
|
+
console.log('=== Test 4: State Consistency (10,000 Spins) ===');
|
|
633
|
+
console.log(` Spins completed: ${spinsCompleted}`);
|
|
634
|
+
console.log(` Bonus rounds validated: ${bonusRoundsValidated}`);
|
|
635
|
+
console.log(` State validation failures: ${stateValidationFailures}`);
|
|
636
|
+
|
|
637
|
+
// Assertions
|
|
638
|
+
expect(stateValidationFailures).toBe(0);
|
|
639
|
+
},
|
|
640
|
+
600000,
|
|
641
|
+
);
|
|
642
|
+
});
|
|
643
|
+
});
|
|
@@ -32,21 +32,17 @@ import {
|
|
|
32
32
|
} from '@omnitronix/game-engine-contract';
|
|
33
33
|
import {
|
|
34
34
|
SlotGameHandler,
|
|
35
|
-
} from '@omnitronix/game-engine-sdk
|
|
35
|
+
} from '@omnitronix/game-engine-sdk';
|
|
36
36
|
import type {
|
|
37
37
|
BetConfig as SdkBetConfig,
|
|
38
38
|
SlotState as SdkSlotState,
|
|
39
39
|
SpinResult as SdkSpinResult,
|
|
40
40
|
BonusTrigger as SdkBonusTrigger,
|
|
41
41
|
BonusResult as SdkBonusResult,
|
|
42
|
-
} from '@omnitronix/game-engine-sdk/dist/handlers';
|
|
43
|
-
import type {
|
|
44
42
|
GameTypeConfig,
|
|
45
|
-
} from '@omnitronix/game-engine-sdk/dist/game-type-config';
|
|
46
|
-
import type {
|
|
47
43
|
BonusResultDeliveryStrategy,
|
|
48
44
|
BonusRoundResponse,
|
|
49
|
-
} from '@omnitronix/game-engine-sdk
|
|
45
|
+
} from '@omnitronix/game-engine-sdk';
|
|
50
46
|
import { getDebugCommandDefinitions } from './debug/debug-command-definitions';
|
|
51
47
|
import { ReelStripsConfig } from './domain/reel-strips-config';
|
|
52
48
|
import { ReelStripsConfigLoader } from './config/reel-strips-config/reel-strips-config-loader';
|
package/src/index.ts
CHANGED
|
@@ -31,5 +31,4 @@ export {
|
|
|
31
31
|
export { GameEngineConfig, GameEngineMetricsHandlers } from './game-engine.interface';
|
|
32
32
|
|
|
33
33
|
// Re-export SDK types for consumers
|
|
34
|
-
export type { GameTypeConfig } from '@omnitronix/game-engine-sdk
|
|
35
|
-
export type { BonusResultDeliveryStrategy, BonusRoundResponse } from '@omnitronix/game-engine-sdk/dist/core';
|
|
34
|
+
export type { GameTypeConfig, BonusResultDeliveryStrategy, BonusRoundResponse } from '@omnitronix/game-engine-sdk';
|