@iruka-edu/create-iruka-game 1.0.9 → 1.1.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.
- package/dist/index.cjs +1 -0
- package/package.json +35 -35
- package/templates/basic-phaser/package.json +1 -1
- package/templates/basic-phaser/src/game/MyGame.ts +49 -0
- package/templates/basic-phaser/src/main.ts +4 -19
- package/templates/basic-phaser/src/scenes/Play.ts +39 -19
- package/templates/basic-phaser/src/scenes/Preloader.ts +26 -11
- package/templates/basic-phaser/src/config.ts +0 -28
- package/templates/basic-phaser/src/iruka/adapter.ts +0 -121
package/dist/index.cjs
CHANGED
|
@@ -202,6 +202,7 @@ dist
|
|
|
202
202
|
}
|
|
203
203
|
console.log(`
|
|
204
204
|
\u{1F389} Project \u0111\xE3 s\u1EB5n s\xE0ng t\u1EA1i: ${import_picocolors.default.cyan(root)}`);
|
|
205
|
+
console.log(import_picocolors.default.green(`\u2728 Game c\u1EE7a b\u1EA1n \u0111\xE3 \u0111\u01B0\u1EE3c t\xEDch h\u1EE3p s\u1EB5n Iruka SDK v0.4. Safe & Ready!`));
|
|
205
206
|
console.log(`\u{1F449} C\xE1c b\u01B0\u1EDBc ti\u1EBFp theo:`);
|
|
206
207
|
console.log(` cd ${projectName}`);
|
|
207
208
|
const userAgent = process.env.npm_config_user_agent || "";
|
package/package.json
CHANGED
|
@@ -1,35 +1,35 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@iruka-edu/create-iruka-game",
|
|
3
|
-
"version": "1.0
|
|
4
|
-
"description": "Create Iruka mini game (React + Phaser template)",
|
|
5
|
-
"license": "MIT",
|
|
6
|
-
"type": "module",
|
|
7
|
-
"bin": {
|
|
8
|
-
"create-iruka-game": "dist/index.cjs"
|
|
9
|
-
},
|
|
10
|
-
"scripts": {
|
|
11
|
-
"build": "tsup src/index.ts --format cjs --clean",
|
|
12
|
-
"dev": "tsup src/index.ts --format cjs --watch"
|
|
13
|
-
},
|
|
14
|
-
"dependencies": {
|
|
15
|
-
"fs-extra": "^11.3.3",
|
|
16
|
-
"picocolors": "^1.1.1",
|
|
17
|
-
"prompts": "^2.4.2"
|
|
18
|
-
},
|
|
19
|
-
"devDependencies": {
|
|
20
|
-
"@types/fs-extra": "^11.0.4",
|
|
21
|
-
"@types/prompts": "^2.4.9",
|
|
22
|
-
"terser": "^5.44.1",
|
|
23
|
-
"tsup": "^8.0.0",
|
|
24
|
-
"typescript": "^5.5.0"
|
|
25
|
-
},
|
|
26
|
-
"files": [
|
|
27
|
-
"dist",
|
|
28
|
-
"templates",
|
|
29
|
-
"README.md"
|
|
30
|
-
],
|
|
31
|
-
"publishConfig": {
|
|
32
|
-
"access": "public",
|
|
33
|
-
"registry": "https://registry.npmjs.org/"
|
|
34
|
-
}
|
|
35
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "@iruka-edu/create-iruka-game",
|
|
3
|
+
"version": "1.1.0",
|
|
4
|
+
"description": "Create Iruka mini game (React + Phaser template)",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"bin": {
|
|
8
|
+
"create-iruka-game": "dist/index.cjs"
|
|
9
|
+
},
|
|
10
|
+
"scripts": {
|
|
11
|
+
"build": "tsup src/index.ts --format cjs --clean",
|
|
12
|
+
"dev": "tsup src/index.ts --format cjs --watch"
|
|
13
|
+
},
|
|
14
|
+
"dependencies": {
|
|
15
|
+
"fs-extra": "^11.3.3",
|
|
16
|
+
"picocolors": "^1.1.1",
|
|
17
|
+
"prompts": "^2.4.2"
|
|
18
|
+
},
|
|
19
|
+
"devDependencies": {
|
|
20
|
+
"@types/fs-extra": "^11.0.4",
|
|
21
|
+
"@types/prompts": "^2.4.9",
|
|
22
|
+
"terser": "^5.44.1",
|
|
23
|
+
"tsup": "^8.0.0",
|
|
24
|
+
"typescript": "^5.5.0"
|
|
25
|
+
},
|
|
26
|
+
"files": [
|
|
27
|
+
"dist",
|
|
28
|
+
"templates",
|
|
29
|
+
"README.md"
|
|
30
|
+
],
|
|
31
|
+
"publishConfig": {
|
|
32
|
+
"access": "public",
|
|
33
|
+
"registry": "https://registry.npmjs.org/"
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { BaseGame, type LaunchContext, createIrukaPluginConfig } from "@iruka-edu/mini-game-sdk";
|
|
2
|
+
import Phaser from "phaser";
|
|
3
|
+
import { PreloadScene } from "../scenes/Preloader";
|
|
4
|
+
import { PlayScene } from "../scenes/Play";
|
|
5
|
+
|
|
6
|
+
export class MyGame extends BaseGame {
|
|
7
|
+
private game: Phaser.Game | null = null;
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* This function runs only after:
|
|
11
|
+
* 1. Hub connection is successful
|
|
12
|
+
* 2. Context validation passes
|
|
13
|
+
*/
|
|
14
|
+
protected async onInit(context: LaunchContext): Promise<void> {
|
|
15
|
+
console.log("🎮 Initializing Game with Context:", context);
|
|
16
|
+
|
|
17
|
+
const config: Phaser.Types.Core.GameConfig = {
|
|
18
|
+
type: Phaser.AUTO,
|
|
19
|
+
width: 800,
|
|
20
|
+
height: 600,
|
|
21
|
+
parent: "game-container",
|
|
22
|
+
backgroundColor: "#2c3e50",
|
|
23
|
+
scale: {
|
|
24
|
+
mode: Phaser.Scale.FIT,
|
|
25
|
+
autoCenter: Phaser.Scale.CENTER_BOTH,
|
|
26
|
+
},
|
|
27
|
+
scene: [PreloadScene, PlayScene],
|
|
28
|
+
// Register Iruka plugin
|
|
29
|
+
plugins: {
|
|
30
|
+
global: [createIrukaPluginConfig()]
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
this.game = new Phaser.Game(config);
|
|
35
|
+
|
|
36
|
+
// Make game globally accessible for plugin initialization
|
|
37
|
+
(window as any).phaserGame = this.game;
|
|
38
|
+
|
|
39
|
+
// Inject SDK into Registry for Scenes to access (legacy support)
|
|
40
|
+
this.game.registry.set("iruka-context", context);
|
|
41
|
+
// this.bridge is available from BaseGame
|
|
42
|
+
this.game.registry.set("iruka-bridge", this.bridge);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
protected async onStart(): Promise<void> {
|
|
46
|
+
console.log("🚀 Game Started Lifecycle");
|
|
47
|
+
// Optional: Tracking logic or additional setup
|
|
48
|
+
}
|
|
49
|
+
}
|
|
@@ -1,21 +1,6 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { MyGame } from "./game/MyGame";
|
|
2
2
|
import "./style.css";
|
|
3
|
-
import { GameConfig } from "./config";
|
|
4
|
-
import { Iruka } from "./iruka/adapter";
|
|
5
3
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
(async () => {
|
|
10
|
-
try {
|
|
11
|
-
// 1. Connect to Hub (or fallback to mock mode)
|
|
12
|
-
await Iruka.init();
|
|
13
|
-
console.log("✅ SDK Ready:", Iruka.isMock ? "Mock Mode" : "Connected to Hub");
|
|
14
|
-
|
|
15
|
-
// 2. Start Phaser game
|
|
16
|
-
new Phaser.Game(GameConfig);
|
|
17
|
-
} catch (error) {
|
|
18
|
-
console.error("❌ Failed to initialize:", error);
|
|
19
|
-
Iruka.error("INIT_FAILED", error);
|
|
20
|
-
}
|
|
21
|
-
})();
|
|
4
|
+
// Launch Game
|
|
5
|
+
// BaseGame handles Handshake, Validation, and Loading UI automatically
|
|
6
|
+
new MyGame();
|
|
@@ -1,14 +1,12 @@
|
|
|
1
1
|
import { Scene } from "phaser";
|
|
2
|
-
import { Iruka } from "../iruka/adapter";
|
|
3
|
-
import { GAME_WIDTH, GAME_HEIGHT } from "../config";
|
|
4
2
|
|
|
5
3
|
/**
|
|
6
4
|
* PlayScene - Main gameplay scene
|
|
7
5
|
*
|
|
8
|
-
* Access SDK
|
|
9
|
-
* -
|
|
10
|
-
* -
|
|
11
|
-
* -
|
|
6
|
+
* Access SDK via this.iruka (Phaser Plugin):
|
|
7
|
+
* - this.iruka.submitScore(100)
|
|
8
|
+
* - this.iruka.completeGame({score, timeMs})
|
|
9
|
+
* - this.iruka.getContext() for sessionId, difficulty, etc.
|
|
12
10
|
*/
|
|
13
11
|
export class PlayScene extends Scene {
|
|
14
12
|
private score = 0;
|
|
@@ -23,8 +21,10 @@ export class PlayScene extends Scene {
|
|
|
23
21
|
this.startTime = Date.now();
|
|
24
22
|
this.score = 0;
|
|
25
23
|
|
|
26
|
-
// Get context from SDK
|
|
27
|
-
const
|
|
24
|
+
// Get context from SDK plugin
|
|
25
|
+
const context = (this as any).iruka?.getContext();
|
|
26
|
+
const { difficulty, player, seed } = context || {};
|
|
27
|
+
const profile = player || {};
|
|
28
28
|
console.log(`🎮 Starting game | Difficulty: ${difficulty} | Seed: ${seed}`);
|
|
29
29
|
|
|
30
30
|
this.setupUI(profile?.name || "Player");
|
|
@@ -32,20 +32,34 @@ export class PlayScene extends Scene {
|
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
private setupUI(playerName: string) {
|
|
35
|
+
const width = this.scale.width;
|
|
36
|
+
const height = this.scale.height;
|
|
37
|
+
|
|
35
38
|
// Header
|
|
36
|
-
this.add.text(20, 20, `Player: ${playerName}`, {
|
|
39
|
+
this.add.text(20, 20, `Player: ${playerName}`, {
|
|
40
|
+
fontSize: "18px",
|
|
41
|
+
color: "#fff",
|
|
42
|
+
});
|
|
37
43
|
|
|
38
44
|
// Score
|
|
39
45
|
this.scoreText = this.add
|
|
40
|
-
.text(
|
|
46
|
+
.text(width - 20, 20, "Score: 0", {
|
|
47
|
+
fontSize: "20px",
|
|
48
|
+
color: "#2ecc71",
|
|
49
|
+
})
|
|
41
50
|
.setOrigin(1, 0);
|
|
42
51
|
|
|
43
52
|
// Instructions
|
|
44
53
|
this.add
|
|
45
|
-
.text(
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
54
|
+
.text(
|
|
55
|
+
width / 2,
|
|
56
|
+
height - 40,
|
|
57
|
+
"Click anywhere to score | Press SPACE to finish",
|
|
58
|
+
{
|
|
59
|
+
fontSize: "14px",
|
|
60
|
+
color: "#aaa",
|
|
61
|
+
}
|
|
62
|
+
)
|
|
49
63
|
.setOrigin(0.5);
|
|
50
64
|
}
|
|
51
65
|
|
|
@@ -63,16 +77,22 @@ export class PlayScene extends Scene {
|
|
|
63
77
|
private addScore(points: number) {
|
|
64
78
|
this.score += points;
|
|
65
79
|
this.scoreText.setText(`Score: ${this.score}`);
|
|
66
|
-
|
|
80
|
+
|
|
81
|
+
// Use Iruka plugin to submit score
|
|
82
|
+
(this as any).iruka?.submitScore(this.score, points);
|
|
67
83
|
}
|
|
68
84
|
|
|
69
85
|
private endGame() {
|
|
70
86
|
const timeMs = Date.now() - this.startTime;
|
|
71
87
|
|
|
72
|
-
// Submit result to Hub
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
88
|
+
// Submit result to Hub using Iruka plugin
|
|
89
|
+
(this as any).iruka?.completeGame({
|
|
90
|
+
score: this.score,
|
|
91
|
+
timeMs,
|
|
92
|
+
extras: {
|
|
93
|
+
maxScore: 100,
|
|
94
|
+
accuracy: Math.min(1, this.score / 100),
|
|
95
|
+
},
|
|
76
96
|
});
|
|
77
97
|
|
|
78
98
|
console.log(`🏁 Game Over | Score: ${this.score} | Time: ${timeMs}ms`);
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { Scene } from "phaser";
|
|
2
|
-
|
|
2
|
+
// Removed Iruka adapter import
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
|
-
* PreloadScene - Load assets
|
|
5
|
+
* PreloadScene - Load assets and report progress to Hub
|
|
6
6
|
*/
|
|
7
7
|
export class PreloadScene extends Scene {
|
|
8
8
|
constructor() {
|
|
@@ -12,10 +12,15 @@ export class PreloadScene extends Scene {
|
|
|
12
12
|
preload() {
|
|
13
13
|
this.createLoadingUI();
|
|
14
14
|
|
|
15
|
-
//
|
|
15
|
+
// Report progress to Hub
|
|
16
16
|
this.load.on("progress", (value: number) => {
|
|
17
17
|
this.updateProgress(value);
|
|
18
|
-
|
|
18
|
+
const bridge = this.registry.get("iruka-bridge");
|
|
19
|
+
bridge?.loading(value * 100); // SDK expects 0-100? or 0-1? IframeBridge says loading(progress: number)
|
|
20
|
+
// IframeBridge documentation should be checked. Usually 0-100 for UI.
|
|
21
|
+
// Wait, let's check game-core/bridge.ts or iframeBridge.ts.
|
|
22
|
+
// iframeBridge.ts: loading: (progress: number) => post("LOADING", { progress })
|
|
23
|
+
// Usually standard is 0-100.
|
|
19
24
|
});
|
|
20
25
|
|
|
21
26
|
// Load game assets
|
|
@@ -24,7 +29,9 @@ export class PreloadScene extends Scene {
|
|
|
24
29
|
|
|
25
30
|
create() {
|
|
26
31
|
// Báo Hub game đã sẵn sàng
|
|
27
|
-
Iruka.ready(["score", "progress"]);
|
|
32
|
+
// Iruka.ready(["score", "progress"]);
|
|
33
|
+
const bridge = this.registry.get("iruka-bridge");
|
|
34
|
+
bridge?.ready(["score", "progress"]);
|
|
28
35
|
|
|
29
36
|
// Chuyển sang màn chơi
|
|
30
37
|
this.scene.start("Play");
|
|
@@ -34,17 +41,25 @@ export class PreloadScene extends Scene {
|
|
|
34
41
|
const { width, height } = this.cameras.main;
|
|
35
42
|
|
|
36
43
|
// Background
|
|
37
|
-
this.add
|
|
44
|
+
this.add
|
|
45
|
+
.graphics()
|
|
46
|
+
.fillStyle(0x222222, 0.8)
|
|
47
|
+
.fillRect(width / 2 - 160, height / 2 - 25, 320, 50);
|
|
38
48
|
|
|
39
49
|
// Progress bar
|
|
40
50
|
const bar = this.add.graphics();
|
|
41
|
-
const text = this.add
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
51
|
+
const text = this.add
|
|
52
|
+
.text(width / 2, height / 2, "0%", {
|
|
53
|
+
fontSize: "18px",
|
|
54
|
+
color: "#ffffff",
|
|
55
|
+
})
|
|
56
|
+
.setOrigin(0.5);
|
|
45
57
|
|
|
46
58
|
this.load.on("progress", (value: number) => {
|
|
47
|
-
bar
|
|
59
|
+
bar
|
|
60
|
+
.clear()
|
|
61
|
+
.fillStyle(0x3498db, 1)
|
|
62
|
+
.fillRect(width / 2 - 150, height / 2 - 15, 300 * value, 30);
|
|
48
63
|
text.setText(`${Math.round(value * 100)}%`);
|
|
49
64
|
});
|
|
50
65
|
}
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import Phaser from "phaser";
|
|
2
|
-
import { PreloadScene } from "./scenes/Preloader";
|
|
3
|
-
import { PlayScene } from "./scenes/Play";
|
|
4
|
-
|
|
5
|
-
export const GAME_WIDTH = 800;
|
|
6
|
-
export const GAME_HEIGHT = 600;
|
|
7
|
-
|
|
8
|
-
export const GameConfig: Phaser.Types.Core.GameConfig = {
|
|
9
|
-
type: Phaser.AUTO,
|
|
10
|
-
width: GAME_WIDTH,
|
|
11
|
-
height: GAME_HEIGHT,
|
|
12
|
-
parent: "app",
|
|
13
|
-
|
|
14
|
-
scale: {
|
|
15
|
-
mode: Phaser.Scale.FIT,
|
|
16
|
-
autoCenter: Phaser.Scale.CENTER_BOTH,
|
|
17
|
-
},
|
|
18
|
-
|
|
19
|
-
backgroundColor: "#2c3e50",
|
|
20
|
-
|
|
21
|
-
// Disable physics if not needed (better performance)
|
|
22
|
-
// physics: {
|
|
23
|
-
// default: 'arcade',
|
|
24
|
-
// arcade: { gravity: { x: 0, y: 300 }, debug: false }
|
|
25
|
-
// },
|
|
26
|
-
|
|
27
|
-
scene: [PreloadScene, PlayScene],
|
|
28
|
-
};
|
|
@@ -1,121 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
createIframeBridge,
|
|
3
|
-
type IframeBridge,
|
|
4
|
-
type LaunchContext,
|
|
5
|
-
type HubCommand,
|
|
6
|
-
} from "@iruka-edu/mini-game-sdk";
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* IrukaAdapter - Cầu nối giữa Phaser Game và Iruka Hub
|
|
10
|
-
*
|
|
11
|
-
* Sử dụng SDK để giao tiếp với Hub:
|
|
12
|
-
* - await Iruka.init() - Khởi tạo và chờ INIT từ Hub
|
|
13
|
-
* - Iruka.context - Lấy thông tin session/user
|
|
14
|
-
* - Iruka.submit() - Gửi kết quả cuối game
|
|
15
|
-
*/
|
|
16
|
-
class IrukaAdapter {
|
|
17
|
-
private static instance: IrukaAdapter;
|
|
18
|
-
|
|
19
|
-
public context!: LaunchContext;
|
|
20
|
-
public isMock = false;
|
|
21
|
-
private bridge!: IframeBridge;
|
|
22
|
-
private initResolver?: (ctx: LaunchContext) => void;
|
|
23
|
-
|
|
24
|
-
public static get use(): IrukaAdapter {
|
|
25
|
-
return this.instance || (this.instance = new IrukaAdapter());
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* Khởi tạo SDK và chờ INIT command từ Hub
|
|
30
|
-
* Timeout 3s sẽ fallback sang Mock mode cho development
|
|
31
|
-
*/
|
|
32
|
-
public async init(): Promise<LaunchContext> {
|
|
33
|
-
return new Promise((resolve) => {
|
|
34
|
-
// Tạo bridge với handler
|
|
35
|
-
this.bridge = createIframeBridge(this.handleCommand.bind(this));
|
|
36
|
-
|
|
37
|
-
// Timeout -> Mock mode
|
|
38
|
-
const timeout = setTimeout(() => {
|
|
39
|
-
console.warn("⚠️ Hub timeout, using Mock mode");
|
|
40
|
-
this.context = this.createMockContext();
|
|
41
|
-
this.isMock = true;
|
|
42
|
-
resolve(this.context);
|
|
43
|
-
}, 3000);
|
|
44
|
-
|
|
45
|
-
// Lưu resolver để gọi khi nhận INIT
|
|
46
|
-
this.initResolver = (ctx: LaunchContext) => {
|
|
47
|
-
clearTimeout(timeout);
|
|
48
|
-
this.context = ctx;
|
|
49
|
-
this.isMock = false;
|
|
50
|
-
resolve(ctx);
|
|
51
|
-
};
|
|
52
|
-
});
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
/** Báo Hub game đã sẵn sàng */
|
|
56
|
-
public ready(capabilities: string[] = ["score", "progress"]) {
|
|
57
|
-
this.bridge.ready(capabilities);
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
/** Cập nhật điểm */
|
|
61
|
-
public updateScore(score: number, delta?: number) {
|
|
62
|
-
this.bridge.score(score, delta);
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
/** Cập nhật tiến độ loading */
|
|
66
|
-
public updateProgress(data: unknown) {
|
|
67
|
-
this.bridge.progress(data);
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
/** Gửi kết quả cuối game */
|
|
71
|
-
public submit(score: number, timeMs: number, extras?: unknown) {
|
|
72
|
-
this.bridge.complete({ score, timeMs, extras });
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
/** Báo lỗi cho Hub */
|
|
76
|
-
public error(message: string, detail?: unknown) {
|
|
77
|
-
this.bridge.error(message, detail);
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
/** Cleanup khi game kết thúc */
|
|
81
|
-
public dispose() {
|
|
82
|
-
this.bridge.dispose();
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
// === Private ===
|
|
86
|
-
|
|
87
|
-
private handleCommand(cmd: HubCommand) {
|
|
88
|
-
switch (cmd.type) {
|
|
89
|
-
case "INIT":
|
|
90
|
-
this.initResolver?.(cmd.payload);
|
|
91
|
-
break;
|
|
92
|
-
case "START":
|
|
93
|
-
console.log("🎮 Hub: START");
|
|
94
|
-
break;
|
|
95
|
-
case "PAUSE":
|
|
96
|
-
console.log("⏸️ Hub: PAUSE");
|
|
97
|
-
break;
|
|
98
|
-
case "RESUME":
|
|
99
|
-
console.log("▶️ Hub: RESUME");
|
|
100
|
-
break;
|
|
101
|
-
case "QUIT":
|
|
102
|
-
console.log("🛑 Hub: QUIT");
|
|
103
|
-
this.dispose();
|
|
104
|
-
break;
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
private createMockContext(): LaunchContext {
|
|
109
|
-
return {
|
|
110
|
-
sessionId: "mock-" + Date.now(),
|
|
111
|
-
gameId: "{{GAME_ID}}",
|
|
112
|
-
locale: "vi",
|
|
113
|
-
difficulty: "medium",
|
|
114
|
-
playerId: "dev-player",
|
|
115
|
-
profile: { name: "Developer" },
|
|
116
|
-
seed: Math.floor(Math.random() * 1000000),
|
|
117
|
-
};
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
export const Iruka = IrukaAdapter.use;
|