@energy8platform/platform-core 0.16.2 → 0.17.1
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/README.md +41 -5
- package/bin/simulate.ts +53 -3
- package/dist/dev-bridge.cjs.js +16 -51
- package/dist/dev-bridge.cjs.js.map +1 -1
- package/dist/dev-bridge.d.ts +26 -30
- package/dist/dev-bridge.esm.js +16 -51
- package/dist/dev-bridge.esm.js.map +1 -1
- package/dist/index.cjs.js +16 -51
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +64 -31
- package/dist/index.esm.js +16 -51
- package/dist/index.esm.js.map +1 -1
- package/dist/lua.cjs.js +53 -30
- package/dist/lua.cjs.js.map +1 -1
- package/dist/lua.d.ts +24 -19
- package/dist/lua.esm.js +53 -30
- package/dist/lua.esm.js.map +1 -1
- package/dist/simulation.cjs.js +32 -1
- package/dist/simulation.cjs.js.map +1 -1
- package/dist/simulation.d.ts +55 -18
- package/dist/simulation.esm.js +32 -1
- package/dist/simulation.esm.js.map +1 -1
- package/package.json +1 -1
- package/scripts/install-simulate.mjs +1 -1
- package/src/dev-bridge/DevBridge.ts +16 -57
- package/src/index.ts +0 -3
- package/src/lua/LuaEngine.ts +40 -18
- package/src/lua/SimulationRunner.ts +12 -14
- package/src/lua/index.ts +0 -3
- package/src/lua/types.ts +17 -20
- package/src/simulation/NativeSimulationRunner.ts +87 -1
- package/src/simulation/index.ts +2 -0
- package/src/types.ts +0 -3
|
@@ -10,6 +10,19 @@ import type { GameDefinition, SimulationResult } from '../lua/types';
|
|
|
10
10
|
|
|
11
11
|
// ─── Types ──────────────────────────────────────────────
|
|
12
12
|
|
|
13
|
+
export type NativeRNGKind = 'provably-fair' | 'fast';
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Replay mode parameters. Forces single-worker deterministic execution over a
|
|
17
|
+
* specific (server_seed, client_seed, nonce-start) triple — used to reproduce a
|
|
18
|
+
* production round captured in `provably_fair_rounds`.
|
|
19
|
+
*/
|
|
20
|
+
export interface NativeReplayParams {
|
|
21
|
+
serverSeed: string;
|
|
22
|
+
clientSeed: string;
|
|
23
|
+
nonceStart: number;
|
|
24
|
+
}
|
|
25
|
+
|
|
13
26
|
export interface NativeSimulationConfig {
|
|
14
27
|
/** Path to native simulation binary */
|
|
15
28
|
binaryPath: string;
|
|
@@ -25,6 +38,20 @@ export interface NativeSimulationConfig {
|
|
|
25
38
|
action?: string;
|
|
26
39
|
/** Action params (buy_bonus, ante_bet, etc.) */
|
|
27
40
|
params?: Record<string, unknown>;
|
|
41
|
+
/**
|
|
42
|
+
* Hex-encoded master seed for reproducible runs. The binary derives per-worker
|
|
43
|
+
* server_seeds via sha256(seed || ":" || worker_idx). When omitted, the binary
|
|
44
|
+
* generates one and returns it on the result so the run can be reproduced via
|
|
45
|
+
* `seed: result.masterSeed`. Ignored when `rng === 'fast'`.
|
|
46
|
+
*/
|
|
47
|
+
seed?: string;
|
|
48
|
+
/**
|
|
49
|
+
* RNG backend: `'provably-fair'` (default, matches production) or `'fast'`
|
|
50
|
+
* (math/rand PCG — local iteration only, do NOT publish those RTP numbers).
|
|
51
|
+
*/
|
|
52
|
+
rng?: NativeRNGKind;
|
|
53
|
+
/** Replay mode: requires `rng: 'provably-fair'` (or default). */
|
|
54
|
+
replay?: NativeReplayParams;
|
|
28
55
|
/** Progress callback */
|
|
29
56
|
onProgress?: (completed: number, total: number) => void;
|
|
30
57
|
}
|
|
@@ -55,6 +82,18 @@ export interface NativeSimulationResult extends SimulationResult {
|
|
|
55
82
|
perStage?: Record<string, StageStats>;
|
|
56
83
|
/** Win distribution histogram */
|
|
57
84
|
winDistribution?: DistributionBucket[];
|
|
85
|
+
/** RNG backend that produced these numbers. */
|
|
86
|
+
rngKind?: NativeRNGKind;
|
|
87
|
+
/**
|
|
88
|
+
* Hex master seed that drove worker-seed derivation. Always set for
|
|
89
|
+
* `provably-fair` runs (supplied or auto-generated). Pass back via `seed`
|
|
90
|
+
* to reproduce the run bit-for-bit.
|
|
91
|
+
*/
|
|
92
|
+
masterSeed?: string;
|
|
93
|
+
/** Per-worker server_seed sequence (lets support reproduce any individual spin). */
|
|
94
|
+
workerSeeds?: string[];
|
|
95
|
+
/** Echo of replay params when the run was in replay mode. */
|
|
96
|
+
replay?: NativeReplayParams;
|
|
58
97
|
}
|
|
59
98
|
|
|
60
99
|
// ─── Go JSON output shape (snake_case) ──────────────────
|
|
@@ -88,6 +127,14 @@ interface GoSimulationOutput {
|
|
|
88
127
|
count: number;
|
|
89
128
|
pct: number;
|
|
90
129
|
}>;
|
|
130
|
+
rng_kind?: NativeRNGKind;
|
|
131
|
+
master_seed?: string;
|
|
132
|
+
worker_seeds?: string[];
|
|
133
|
+
replay?: {
|
|
134
|
+
server_seed: string;
|
|
135
|
+
client_seed: string;
|
|
136
|
+
nonce_start: number;
|
|
137
|
+
};
|
|
91
138
|
}
|
|
92
139
|
|
|
93
140
|
// ─── Runner ─────────────────────────────────────────────
|
|
@@ -100,7 +147,12 @@ export class NativeSimulationRunner {
|
|
|
100
147
|
}
|
|
101
148
|
|
|
102
149
|
async run(): Promise<NativeSimulationResult> {
|
|
103
|
-
const { binaryPath, script, gameDefinition, iterations, bet, action, params } = this.config;
|
|
150
|
+
const { binaryPath, script, gameDefinition, iterations, bet, action, params, seed, rng, replay } = this.config;
|
|
151
|
+
|
|
152
|
+
if (replay && rng && rng !== 'provably-fair') {
|
|
153
|
+
throw new Error(`Replay mode requires rng="provably-fair" (got rng="${rng}")`);
|
|
154
|
+
}
|
|
155
|
+
|
|
104
156
|
const id = randomBytes(8).toString('hex');
|
|
105
157
|
const tmpDir = tmpdir();
|
|
106
158
|
const luaPath = join(tmpDir, `sim-${id}.lua`);
|
|
@@ -126,6 +178,19 @@ export class NativeSimulationRunner {
|
|
|
126
178
|
if (params && Object.keys(params).length > 0) {
|
|
127
179
|
args.push('-params', JSON.stringify(params));
|
|
128
180
|
}
|
|
181
|
+
if (rng) {
|
|
182
|
+
args.push('-rng', rng);
|
|
183
|
+
}
|
|
184
|
+
if (seed) {
|
|
185
|
+
args.push('-seed', seed);
|
|
186
|
+
}
|
|
187
|
+
if (replay) {
|
|
188
|
+
args.push(
|
|
189
|
+
'-replay-server-seed', replay.serverSeed,
|
|
190
|
+
'-replay-client-seed', replay.clientSeed,
|
|
191
|
+
'-replay-nonce-start', String(replay.nonceStart),
|
|
192
|
+
);
|
|
193
|
+
}
|
|
129
194
|
|
|
130
195
|
// Execute binary
|
|
131
196
|
const output = await this.exec(binaryPath, args);
|
|
@@ -211,6 +276,16 @@ function mapGoResult(json: GoSimulationOutput): NativeSimulationResult {
|
|
|
211
276
|
workersUsed: json.workers_used,
|
|
212
277
|
perStage,
|
|
213
278
|
winDistribution: json.win_distribution,
|
|
279
|
+
rngKind: json.rng_kind,
|
|
280
|
+
masterSeed: json.master_seed,
|
|
281
|
+
workerSeeds: json.worker_seeds,
|
|
282
|
+
replay: json.replay
|
|
283
|
+
? {
|
|
284
|
+
serverSeed: json.replay.server_seed,
|
|
285
|
+
clientSeed: json.replay.client_seed,
|
|
286
|
+
nonceStart: json.replay.nonce_start,
|
|
287
|
+
}
|
|
288
|
+
: undefined,
|
|
214
289
|
_raw: {
|
|
215
290
|
totalWagered: json.total_bet,
|
|
216
291
|
totalWon: json.total_win,
|
|
@@ -311,6 +386,17 @@ export function formatNativeResult(result: NativeSimulationResult): string {
|
|
|
311
386
|
if (result.workersUsed) {
|
|
312
387
|
lines.push(`Workers: ${result.workersUsed}`);
|
|
313
388
|
}
|
|
389
|
+
if (result.rngKind) {
|
|
390
|
+
lines.push(`RNG: ${result.rngKind}`);
|
|
391
|
+
}
|
|
392
|
+
if (result.masterSeed) {
|
|
393
|
+
lines.push(`Master seed: ${result.masterSeed} (pass --seed=${result.masterSeed} to reproduce)`);
|
|
394
|
+
}
|
|
395
|
+
if (result.replay) {
|
|
396
|
+
lines.push(
|
|
397
|
+
`Replay: server_seed=${result.replay.serverSeed} client_seed=${result.replay.clientSeed} nonce_start=${result.replay.nonceStart}`,
|
|
398
|
+
);
|
|
399
|
+
}
|
|
314
400
|
|
|
315
401
|
lines.push(
|
|
316
402
|
'',
|
package/src/simulation/index.ts
CHANGED