create-remix-game 1.1.14 ā 1.2.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/bin/auth.js +2 -0
- package/bin/link.js +2 -0
- package/dist/auth.d.ts +2 -0
- package/dist/auth.js +84 -0
- package/dist/cli.js +130 -0
- package/dist/link.d.ts +2 -0
- package/dist/link.js +111 -0
- package/dist/scaffold.d.ts +2 -0
- package/dist/scaffold.js +4 -1
- package/package.json +5 -2
- package/templates/base/package.json.template +2 -2
- package/templates/base/remix.config.ts.template +34 -0
- package/templates/base/vite.config.ts +2 -10
package/bin/auth.js
ADDED
package/bin/link.js
ADDED
package/dist/auth.d.ts
ADDED
package/dist/auth.js
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import chalk from 'chalk';
|
|
3
|
+
import fs from 'fs';
|
|
4
|
+
import os from 'os';
|
|
5
|
+
import path from 'path';
|
|
6
|
+
import prompts from 'prompts';
|
|
7
|
+
import { pathToFileURL } from 'url';
|
|
8
|
+
export async function auth() {
|
|
9
|
+
console.log(chalk.bold('\nš Remix API Key Setup\n'));
|
|
10
|
+
// 1. Check if already configured
|
|
11
|
+
if (process.env.REMIX_API_KEY) {
|
|
12
|
+
console.log(chalk.green('ā API key already configured'));
|
|
13
|
+
console.log(chalk.gray(` Current key: ${process.env.REMIX_API_KEY.slice(0, 15)}...`));
|
|
14
|
+
const { reconfigure } = await prompts({
|
|
15
|
+
type: 'confirm',
|
|
16
|
+
name: 'reconfigure',
|
|
17
|
+
message: 'Reconfigure with a new key?',
|
|
18
|
+
initial: false,
|
|
19
|
+
});
|
|
20
|
+
if (!reconfigure) {
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
// 2. Detect shell config file
|
|
25
|
+
const homeDir = os.homedir();
|
|
26
|
+
const shellFiles = ['.zshrc', '.bashrc', '.bash_profile', '.profile'];
|
|
27
|
+
let shellConfig = null;
|
|
28
|
+
for (const file of shellFiles) {
|
|
29
|
+
const filePath = path.join(homeDir, file);
|
|
30
|
+
if (fs.existsSync(filePath)) {
|
|
31
|
+
shellConfig = filePath;
|
|
32
|
+
break;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
if (!shellConfig) {
|
|
36
|
+
// Default to .zshrc on macOS, .bashrc elsewhere
|
|
37
|
+
shellConfig = path.join(homeDir, process.platform === 'darwin' ? '.zshrc' : '.bashrc');
|
|
38
|
+
}
|
|
39
|
+
console.log(chalk.cyan(`Using shell config: ${shellConfig}`));
|
|
40
|
+
console.log(chalk.gray('Get your API key at: https://remix.gg/api-keys\n'));
|
|
41
|
+
// 3. Prompt for API key
|
|
42
|
+
const { apiKey } = await prompts({
|
|
43
|
+
type: 'password',
|
|
44
|
+
name: 'apiKey',
|
|
45
|
+
message: 'Paste your API key (starts with sk_live_):',
|
|
46
|
+
validate: (value) => {
|
|
47
|
+
const apiKeyRegex = /^sk_live_[A-Za-z0-9_]{43}$/;
|
|
48
|
+
if (!apiKeyRegex.test(value)) {
|
|
49
|
+
return 'Invalid API key format. Should be sk_live_ followed by 43 characters.';
|
|
50
|
+
}
|
|
51
|
+
return true;
|
|
52
|
+
},
|
|
53
|
+
}, {
|
|
54
|
+
onCancel: () => {
|
|
55
|
+
console.log(chalk.yellow('\nCancelled'));
|
|
56
|
+
process.exit(0);
|
|
57
|
+
},
|
|
58
|
+
});
|
|
59
|
+
if (!apiKey) {
|
|
60
|
+
console.log(chalk.yellow('Cancelled'));
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
// 4. Append to shell config
|
|
64
|
+
const configLine = `\n# Remix API Key (added by create-remix-game)\nexport REMIX_API_KEY="${apiKey}"\n`;
|
|
65
|
+
try {
|
|
66
|
+
fs.appendFileSync(shellConfig, configLine);
|
|
67
|
+
console.log(chalk.green('\nā API key saved to'), chalk.cyan(shellConfig));
|
|
68
|
+
console.log(chalk.yellow('\nTo activate in this terminal:'));
|
|
69
|
+
console.log(chalk.cyan(` source ${shellConfig}`));
|
|
70
|
+
console.log(chalk.yellow('\nOr restart your terminal\n'));
|
|
71
|
+
}
|
|
72
|
+
catch (error) {
|
|
73
|
+
console.error(chalk.red('Failed to write to shell config:'), error);
|
|
74
|
+
console.log(chalk.yellow('\nManually add this line to your shell config:'));
|
|
75
|
+
console.log(chalk.cyan(`export REMIX_API_KEY="${apiKey}"`));
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
// If run directly (use pathToFileURL for Windows compatibility)
|
|
79
|
+
if (import.meta.url === pathToFileURL(process.argv[1]).href) {
|
|
80
|
+
auth().catch((error) => {
|
|
81
|
+
console.error(chalk.red('Error:'), error);
|
|
82
|
+
process.exit(1);
|
|
83
|
+
});
|
|
84
|
+
}
|
package/dist/cli.js
CHANGED
|
@@ -1,10 +1,88 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import chalk from 'chalk';
|
|
3
|
+
import { randomUUID } from 'crypto';
|
|
4
|
+
import fs from 'fs';
|
|
5
|
+
import os from 'os';
|
|
3
6
|
import path from 'path';
|
|
4
7
|
import prompts from 'prompts';
|
|
5
8
|
import { initGitRepo } from './git.js';
|
|
6
9
|
import { installDependencies, installLatestPackages } from './install.js';
|
|
7
10
|
import { scaffold } from './scaffold.js';
|
|
11
|
+
/**
|
|
12
|
+
* Extracts game ID from a Remix URL or returns the input if already a UUID
|
|
13
|
+
* Supports any remix.gg URL format (games, preview, play.remix.gg, etc.)
|
|
14
|
+
*/
|
|
15
|
+
function extractGameId(input) {
|
|
16
|
+
// Match UUID v4 pattern anywhere in the string
|
|
17
|
+
const uuidPattern = /[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}/i;
|
|
18
|
+
const match = input.match(uuidPattern);
|
|
19
|
+
if (match) {
|
|
20
|
+
return match[0];
|
|
21
|
+
}
|
|
22
|
+
return input.trim();
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Generates a new UUID v4 for local game ID
|
|
26
|
+
*/
|
|
27
|
+
function generateUUID() {
|
|
28
|
+
return randomUUID();
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Sets up the Remix API key in the user's shell config
|
|
32
|
+
*/
|
|
33
|
+
async function setupApiKey() {
|
|
34
|
+
// Detect shell config file
|
|
35
|
+
const homeDir = os.homedir();
|
|
36
|
+
const shellFiles = ['.zshrc', '.bashrc', '.bash_profile', '.profile'];
|
|
37
|
+
let shellConfig = null;
|
|
38
|
+
for (const file of shellFiles) {
|
|
39
|
+
const filePath = path.join(homeDir, file);
|
|
40
|
+
if (fs.existsSync(filePath)) {
|
|
41
|
+
shellConfig = filePath;
|
|
42
|
+
break;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
if (!shellConfig) {
|
|
46
|
+
// Default to .zshrc on macOS, .bashrc elsewhere
|
|
47
|
+
shellConfig = path.join(homeDir, process.platform === 'darwin' ? '.zshrc' : '.bashrc');
|
|
48
|
+
}
|
|
49
|
+
console.log(chalk.cyan(`\nShell config: ${shellConfig}`));
|
|
50
|
+
console.log(chalk.gray('Get your API key at: https://remix.gg/api-keys\n'));
|
|
51
|
+
const { apiKey } = await prompts({
|
|
52
|
+
type: 'password',
|
|
53
|
+
name: 'apiKey',
|
|
54
|
+
message: 'Paste your API key (starts with sk_live_):',
|
|
55
|
+
validate: (value) => {
|
|
56
|
+
const apiKeyRegex = /^sk_live_[A-Za-z0-9_]{43}$/;
|
|
57
|
+
if (!apiKeyRegex.test(value)) {
|
|
58
|
+
return 'Invalid API key format. Should be sk_live_ followed by 43 characters.';
|
|
59
|
+
}
|
|
60
|
+
return true;
|
|
61
|
+
},
|
|
62
|
+
}, {
|
|
63
|
+
onCancel: () => {
|
|
64
|
+
return false;
|
|
65
|
+
},
|
|
66
|
+
});
|
|
67
|
+
if (!apiKey) {
|
|
68
|
+
return false;
|
|
69
|
+
}
|
|
70
|
+
// Append to shell config
|
|
71
|
+
const configLine = `\n# Remix API Key (added by create-remix-game)\nexport REMIX_API_KEY="${apiKey}"\n`;
|
|
72
|
+
try {
|
|
73
|
+
fs.appendFileSync(shellConfig, configLine);
|
|
74
|
+
console.log(chalk.green('\nā API key saved to'), chalk.cyan(shellConfig));
|
|
75
|
+
console.log(chalk.yellow("\nNote: You'll need to restart your terminal or run:"));
|
|
76
|
+
console.log(chalk.cyan(` source ${shellConfig}\n`));
|
|
77
|
+
return true;
|
|
78
|
+
}
|
|
79
|
+
catch (error) {
|
|
80
|
+
console.error(chalk.red('Failed to write to shell config:'), error);
|
|
81
|
+
console.log(chalk.yellow('\nManually add this line to your shell config:'));
|
|
82
|
+
console.log(chalk.cyan(`export REMIX_API_KEY="${apiKey}"\n`));
|
|
83
|
+
return false;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
8
86
|
async function main() {
|
|
9
87
|
console.log(chalk.greenBright(`
|
|
10
88
|
|
|
@@ -51,6 +129,30 @@ async function main() {
|
|
|
51
129
|
return true;
|
|
52
130
|
},
|
|
53
131
|
},
|
|
132
|
+
{
|
|
133
|
+
type: 'confirm',
|
|
134
|
+
name: 'hasRemixGame',
|
|
135
|
+
message: 'Do you have a game from Remix to link?\nCreate one at: https://remix.gg',
|
|
136
|
+
initial: false,
|
|
137
|
+
},
|
|
138
|
+
{
|
|
139
|
+
type: (prev) => (prev ? 'text' : null),
|
|
140
|
+
name: 'remixGameInput',
|
|
141
|
+
message: 'Enter your game URL or ID:',
|
|
142
|
+
validate: (input) => {
|
|
143
|
+
if (!input || !input.trim()) {
|
|
144
|
+
return 'Game URL or ID is required';
|
|
145
|
+
}
|
|
146
|
+
// Accept any format - just need to find a UUID v4 in the string
|
|
147
|
+
// Works with: remix.gg/games/{uuid}, play.remix.gg/{uuid}, or just {uuid}
|
|
148
|
+
const uuidPattern = /[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}/i;
|
|
149
|
+
const match = input.match(uuidPattern);
|
|
150
|
+
if (!match) {
|
|
151
|
+
return 'No valid game ID found. Expected a UUID v4 or Remix URL.';
|
|
152
|
+
}
|
|
153
|
+
return true;
|
|
154
|
+
},
|
|
155
|
+
},
|
|
54
156
|
{
|
|
55
157
|
type: 'confirm',
|
|
56
158
|
name: 'multiplayer',
|
|
@@ -85,6 +187,29 @@ async function main() {
|
|
|
85
187
|
console.log('Cancelled');
|
|
86
188
|
process.exit(0);
|
|
87
189
|
}
|
|
190
|
+
// If user is linking a Remix game, check for API key
|
|
191
|
+
if (config.remixGameInput) {
|
|
192
|
+
if (!process.env.REMIX_API_KEY) {
|
|
193
|
+
console.log(chalk.cyan('\nš” Want to publish your game updates with one click?'));
|
|
194
|
+
console.log(chalk.gray('Add an API key to deploy and update your game directly from your local dev environment.\n'));
|
|
195
|
+
const { setupKey } = await prompts({
|
|
196
|
+
type: 'confirm',
|
|
197
|
+
name: 'setupKey',
|
|
198
|
+
message: 'Set up your API key now?',
|
|
199
|
+
initial: true,
|
|
200
|
+
});
|
|
201
|
+
if (setupKey) {
|
|
202
|
+
await setupApiKey();
|
|
203
|
+
}
|
|
204
|
+
else {
|
|
205
|
+
console.log(chalk.gray('\nNo problem! You can add it anytime by running:'));
|
|
206
|
+
console.log(chalk.cyan(' npx create-remix-game auth\n'));
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
else {
|
|
210
|
+
console.log(chalk.green('\nā API key found - one-click publishing enabled!'));
|
|
211
|
+
}
|
|
212
|
+
}
|
|
88
213
|
// Generate a safe package name from the game name
|
|
89
214
|
const projectName = targetDir ||
|
|
90
215
|
config.gameName
|
|
@@ -92,11 +217,16 @@ async function main() {
|
|
|
92
217
|
.replace(/[^a-z0-9]+/g, '-')
|
|
93
218
|
.replace(/^-+|-+$/g, '');
|
|
94
219
|
const projectPath = path.resolve(process.cwd(), projectName);
|
|
220
|
+
// Generate or extract game ID
|
|
221
|
+
const gameId = config.remixGameInput ? extractGameId(config.remixGameInput) : generateUUID();
|
|
222
|
+
const isRemixGame = !!config.remixGameInput;
|
|
95
223
|
console.log(chalk.cyan(`\nā Creating project in ${projectPath}`));
|
|
96
224
|
// Scaffold the project
|
|
97
225
|
await scaffold(projectPath, {
|
|
98
226
|
...config,
|
|
99
227
|
projectName,
|
|
228
|
+
gameId,
|
|
229
|
+
isRemixGame,
|
|
100
230
|
});
|
|
101
231
|
// Install dependencies
|
|
102
232
|
console.log(chalk.cyan('ā Installing dependencies...'));
|
package/dist/link.d.ts
ADDED
package/dist/link.js
ADDED
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import chalk from 'chalk';
|
|
3
|
+
import fs from 'fs';
|
|
4
|
+
import path from 'path';
|
|
5
|
+
import prompts from 'prompts';
|
|
6
|
+
import { pathToFileURL } from 'url';
|
|
7
|
+
export async function link() {
|
|
8
|
+
console.log(chalk.bold('\nš Remix Game Linking\n'));
|
|
9
|
+
// 1. Find remix.config.js or remix.config.ts
|
|
10
|
+
const configPathJs = path.resolve(process.cwd(), 'remix.config.js');
|
|
11
|
+
const configPathTs = path.resolve(process.cwd(), 'remix.config.ts');
|
|
12
|
+
const configPath = fs.existsSync(configPathJs) ? configPathJs : configPathTs;
|
|
13
|
+
if (!fs.existsSync(configPath)) {
|
|
14
|
+
console.error(chalk.red('ā Error: No remix.config.js or remix.config.ts found'));
|
|
15
|
+
console.log(chalk.yellow(' Run this command from your Remix project root\n'));
|
|
16
|
+
process.exit(1);
|
|
17
|
+
}
|
|
18
|
+
// 2. Read current config
|
|
19
|
+
let currentConfig;
|
|
20
|
+
try {
|
|
21
|
+
// Dynamic import to read TypeScript config (use pathToFileURL for Windows compatibility)
|
|
22
|
+
const configModule = await import(pathToFileURL(configPath).href);
|
|
23
|
+
currentConfig = configModule.default;
|
|
24
|
+
}
|
|
25
|
+
catch (error) {
|
|
26
|
+
console.error(chalk.red('Failed to read remix.config.ts:'), error);
|
|
27
|
+
process.exit(1);
|
|
28
|
+
}
|
|
29
|
+
// 3. Check if already linked
|
|
30
|
+
if (currentConfig.isRemixGame) {
|
|
31
|
+
console.log(chalk.yellow(`ā Project already linked to: ${currentConfig.gameId}`));
|
|
32
|
+
const { replace } = await prompts({
|
|
33
|
+
type: 'confirm',
|
|
34
|
+
name: 'replace',
|
|
35
|
+
message: 'Replace with new game ID?',
|
|
36
|
+
initial: false,
|
|
37
|
+
});
|
|
38
|
+
if (!replace) {
|
|
39
|
+
console.log(chalk.gray('Cancelled\n'));
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
// 4. Prompt for game URL or ID
|
|
44
|
+
console.log(chalk.gray('Create a game at: https://remix.gg\n'));
|
|
45
|
+
const { gameInput } = await prompts({
|
|
46
|
+
type: 'text',
|
|
47
|
+
name: 'gameInput',
|
|
48
|
+
message: 'Paste your game URL or ID:',
|
|
49
|
+
validate: (input) => {
|
|
50
|
+
if (!input.trim()) {
|
|
51
|
+
return 'Game URL or ID is required';
|
|
52
|
+
}
|
|
53
|
+
return true;
|
|
54
|
+
},
|
|
55
|
+
}, {
|
|
56
|
+
onCancel: () => {
|
|
57
|
+
console.log(chalk.yellow('\nCancelled'));
|
|
58
|
+
process.exit(0);
|
|
59
|
+
},
|
|
60
|
+
});
|
|
61
|
+
// 5. Extract and validate game ID
|
|
62
|
+
let gameId = gameInput.trim();
|
|
63
|
+
// Extract UUID from various URL formats
|
|
64
|
+
const urlPatterns = [
|
|
65
|
+
/remix\.gg\/games\/([0-9a-f-]{36})/i, // /games/{uuid}
|
|
66
|
+
/remix\.gg\/preview\/([0-9a-f-]{36})/i, // /preview/{uuid}
|
|
67
|
+
/remix\.gg\/game\/([0-9a-f-]{36})/i, // /game/{uuid}
|
|
68
|
+
];
|
|
69
|
+
for (const pattern of urlPatterns) {
|
|
70
|
+
const match = gameInput.match(pattern);
|
|
71
|
+
if (match) {
|
|
72
|
+
gameId = match[1];
|
|
73
|
+
break;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
// Validate UUID v4 format
|
|
77
|
+
const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
|
|
78
|
+
if (!uuidRegex.test(gameId)) {
|
|
79
|
+
console.error(chalk.red('\nā Invalid game ID or URL'));
|
|
80
|
+
console.log(chalk.yellow(' Expected: https://remix.gg/games/{uuid}'));
|
|
81
|
+
console.log(chalk.yellow(' Or just the UUID (e.g., 45b7d6db-94f4-4c2d-b5d7-7501d10a3b70)\n'));
|
|
82
|
+
process.exit(1);
|
|
83
|
+
}
|
|
84
|
+
console.log(chalk.green(`ā Extracted game ID: ${gameId}`));
|
|
85
|
+
// 6. Update remix.config.ts
|
|
86
|
+
try {
|
|
87
|
+
let configContent = fs.readFileSync(configPath, 'utf-8');
|
|
88
|
+
// Replace gameId
|
|
89
|
+
configContent = configContent.replace(/gameId:\s*['"][^'"]*['"]/, `gameId: '${gameId}'`);
|
|
90
|
+
// Replace isRemixGame
|
|
91
|
+
configContent = configContent.replace(/isRemixGame:\s*(true|false)/, 'isRemixGame: true');
|
|
92
|
+
fs.writeFileSync(configPath, configContent, 'utf-8');
|
|
93
|
+
console.log(chalk.green('ā Updated remix.config.ts'));
|
|
94
|
+
console.log(chalk.green('ā Project linked to Remix!\n'));
|
|
95
|
+
console.log(chalk.bold('Next steps:'));
|
|
96
|
+
console.log(chalk.cyan(' 1. Set up API key: npx create-remix-game auth'));
|
|
97
|
+
console.log(chalk.cyan(' 2. Build and deploy: pnpm deploy\n'));
|
|
98
|
+
console.log(chalk.gray(`View your game: https://remix.gg/games/${gameId}\n`));
|
|
99
|
+
}
|
|
100
|
+
catch (error) {
|
|
101
|
+
console.error(chalk.red('Failed to update remix.config.ts:'), error);
|
|
102
|
+
process.exit(1);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
// If run directly (use pathToFileURL for Windows compatibility)
|
|
106
|
+
if (import.meta.url === pathToFileURL(process.argv[1]).href) {
|
|
107
|
+
link().catch((error) => {
|
|
108
|
+
console.error(chalk.red('Error:'), error);
|
|
109
|
+
process.exit(1);
|
|
110
|
+
});
|
|
111
|
+
}
|
package/dist/scaffold.d.ts
CHANGED
|
@@ -4,6 +4,8 @@ export interface ScaffoldConfig {
|
|
|
4
4
|
multiplayer: boolean;
|
|
5
5
|
packageManager: string;
|
|
6
6
|
initGit: boolean;
|
|
7
|
+
gameId: string;
|
|
8
|
+
isRemixGame: boolean;
|
|
7
9
|
useLocalDeps?: boolean;
|
|
8
10
|
}
|
|
9
11
|
export declare function scaffold(targetPath: string, config: ScaffoldConfig): Promise<void>;
|
package/dist/scaffold.js
CHANGED
|
@@ -62,6 +62,7 @@ async function processTemplates(targetPath, config) {
|
|
|
62
62
|
'src/config/GameSettings.ts.template',
|
|
63
63
|
'README.md.template',
|
|
64
64
|
'index.html.template',
|
|
65
|
+
'remix.config.ts.template',
|
|
65
66
|
];
|
|
66
67
|
// Get remix-dev version for dependency injection
|
|
67
68
|
const remixDevVersion = config.useLocalDeps ? 'workspace:*' : `^${getRemixDevVersion()}`;
|
|
@@ -74,7 +75,9 @@ async function processTemplates(targetPath, config) {
|
|
|
74
75
|
.replace(/\{\{PROJECT_NAME\}\}/g, config.projectName)
|
|
75
76
|
.replace(/\{\{MULTIPLAYER\}\}/g, String(config.multiplayer))
|
|
76
77
|
.replace(/\{\{PACKAGE_MANAGER\}\}/g, config.packageManager)
|
|
77
|
-
.replace(/\{\{REMIX_DEV_VERSION\}\}/g, remixDevVersion)
|
|
78
|
+
.replace(/\{\{REMIX_DEV_VERSION\}\}/g, remixDevVersion)
|
|
79
|
+
.replace(/\{\{GAME_ID\}\}/g, config.gameId)
|
|
80
|
+
.replace(/\{\{IS_REMIX_GAME\}\}/g, String(config.isRemixGame));
|
|
78
81
|
// Write to actual file (remove .template)
|
|
79
82
|
const outputPath = filePath.replace('.template', '');
|
|
80
83
|
await fs.writeFile(outputPath, processed);
|
package/package.json
CHANGED
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-remix-game",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.2",
|
|
4
4
|
"description": "CLI for scaffolding Remix games",
|
|
5
5
|
"license": "SEE LICENSE IN LICENSE",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"bin": {
|
|
8
|
-
"remix-game": "./bin/remix-game.js"
|
|
8
|
+
"remix-game": "./bin/remix-game.js",
|
|
9
|
+
"create-remix-game": "./bin/remix-game.js",
|
|
10
|
+
"create-remix-game-auth": "./bin/auth.js",
|
|
11
|
+
"create-remix-game-link": "./bin/link.js"
|
|
9
12
|
},
|
|
10
13
|
"files": [
|
|
11
14
|
"bin",
|
|
@@ -3,11 +3,11 @@
|
|
|
3
3
|
"version": "1.0.0",
|
|
4
4
|
"description": "{{GAME_NAME}} game for Remix platform",
|
|
5
5
|
"type": "module",
|
|
6
|
-
"multiplayer": {{MULTIPLAYER}},
|
|
7
6
|
"scripts": {
|
|
8
7
|
"dev": "remix-dev dev",
|
|
9
8
|
"build": "remix-dev build",
|
|
10
|
-
"preview": "remix-dev preview"
|
|
9
|
+
"preview": "remix-dev preview",
|
|
10
|
+
"deploy": "remix-dev deploy"
|
|
11
11
|
},
|
|
12
12
|
"keywords": [
|
|
13
13
|
"game",
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Remix Game Configuration
|
|
3
|
+
*
|
|
4
|
+
* This file contains your game's configuration for the Remix framework.
|
|
5
|
+
*
|
|
6
|
+
* Getting Started:
|
|
7
|
+
* 1. This gameId is auto-generated for local save states (localStorage)
|
|
8
|
+
* 2. To publish your game to Remix:
|
|
9
|
+
* - Run: npx create-remix-game link
|
|
10
|
+
* - This will authenticate and link your game to Remix
|
|
11
|
+
* - Your gameId will be updated automatically
|
|
12
|
+
*
|
|
13
|
+
* API Key (for publishing):
|
|
14
|
+
* - Set REMIX_API_KEY environment variable in your .env file
|
|
15
|
+
* - Get your API key from: https://remix.gg/dashboard
|
|
16
|
+
* - Example: REMIX_API_KEY=your_api_key_here
|
|
17
|
+
*
|
|
18
|
+
* Publishing your game:
|
|
19
|
+
* - Run: npx remix-dev deploy
|
|
20
|
+
* - This uploads your game to Remix (requires auth via link command)
|
|
21
|
+
*/
|
|
22
|
+
export default {
|
|
23
|
+
// Unique identifier for your game
|
|
24
|
+
gameId: '{{GAME_ID}}', // UUID format - auto-generated or linked to Remix
|
|
25
|
+
|
|
26
|
+
// Whether this game is linked to Remix (true after running link command)
|
|
27
|
+
isRemixGame: {{IS_REMIX_GAME}},
|
|
28
|
+
|
|
29
|
+
// Display name for your game
|
|
30
|
+
gameName: '{{GAME_NAME}}',
|
|
31
|
+
|
|
32
|
+
// Multiplayer mode (true = multiplayer, false = singleplayer)
|
|
33
|
+
multiplayer: {{MULTIPLAYER}},
|
|
34
|
+
}
|
|
@@ -1,15 +1,7 @@
|
|
|
1
1
|
import { remixPlugin } from '@insidethesim/remix-dev/vite'
|
|
2
|
-
import fs from 'fs'
|
|
3
2
|
import { defineConfig } from 'vite'
|
|
4
|
-
|
|
5
|
-
// Read multiplayer setting from package.json
|
|
6
|
-
const packageJson = JSON.parse(fs.readFileSync('./package.json', 'utf-8'))
|
|
7
|
-
const isMultiplayer = packageJson.multiplayer === true
|
|
3
|
+
import remixConfig from './remix.config'
|
|
8
4
|
|
|
9
5
|
export default defineConfig({
|
|
10
|
-
plugins: [
|
|
11
|
-
remixPlugin({
|
|
12
|
-
multiplayer: isMultiplayer,
|
|
13
|
-
}),
|
|
14
|
-
],
|
|
6
|
+
plugins: [remixPlugin(remixConfig)],
|
|
15
7
|
})
|