hytopia 0.3.14 → 0.3.16

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/scripts.js CHANGED
@@ -3,10 +3,36 @@
3
3
  const { execSync } = require('child_process');
4
4
  const fs = require('fs');
5
5
  const path = require('path');
6
+ const readline = require('readline');
6
7
 
8
+ // Store command-line flags
9
+ const flags = {};
10
+
11
+ // Main function to handle command execution
7
12
  (async () => {
8
13
  const command = process.argv[2];
9
- const flags = {};
14
+
15
+ // Parse command-line flags
16
+ parseCommandLineFlags();
17
+
18
+ // Execute the appropriate command
19
+ const commandHandlers = {
20
+ 'init': init,
21
+ 'init-mcp': initMcp
22
+ };
23
+
24
+ const handler = commandHandlers[command];
25
+ if (handler) {
26
+ handler();
27
+ } else {
28
+ displayAvailableCommands(command);
29
+ }
30
+ })();
31
+
32
+ /**
33
+ * Parses command-line flags in the format --flag value
34
+ */
35
+ function parseCommandLineFlags() {
10
36
  for (let i = 3; i < process.argv.length; i += 2) {
11
37
  if (i % 2 === 1) { // Odd indices are flags
12
38
  const flag = process.argv[i].replace('--', '');
@@ -14,65 +40,202 @@ const path = require('path');
14
40
  flags[flag] = value;
15
41
  }
16
42
  }
43
+ }
17
44
 
18
- /**
19
- * Init command
20
- *
21
- * Initializes a new HYTOPIA project. Accepting an optional
22
- * project name as an argument.
23
- *
24
- * @example
25
- * `bunx hytopia init my-project-name`
26
- */
27
- if (command === 'init') {
28
- const destDir = process.cwd();
29
-
30
- // Grab the latest dependencies
31
- execSync('bun init --yes');
32
- execSync('bun add hytopia@latest');
33
- execSync('bun add @hytopia.com/assets');
34
-
35
- // Initialize project with latest HYTOPIA SDK
36
- console.log('🔧 Initializing project with latest HYTOPIA SDK...');
37
-
38
- if (flags.template) {
39
- // Init from example template
40
- console.log(`🖨️ Initializing project with examples template "${flags.template}"...`);
41
-
42
- const templateDir = path.join(destDir, 'node_modules', 'hytopia', 'examples', flags.template);
43
-
44
- if (!fs.existsSync(templateDir)) {
45
- console.error(`Examples template ${flags.template} does not exist in the examples directory, could not initialize project! Tried directory: ${templateDir}`);
46
- return;
47
- }
48
-
49
- fs.cpSync(templateDir, destDir, { recursive: true });
50
-
51
- execSync('bun install');
52
- } else {
53
- // Init from boilerplate
54
- console.log('🧑‍💻 Initializing project with boilerplate...');
45
+ /**
46
+ * Displays available commands when an unknown command is entered
47
+ */
48
+ function displayAvailableCommands(command) {
49
+ console.log('Unknown command: ' + command);
50
+ console.log('Supported commands: init, init-mcp');
51
+ }
55
52
 
56
- const srcDir = path.join(__dirname, '..', 'boilerplate');
57
-
58
- fs.cpSync(srcDir, destDir, { recursive: true });
59
- }
53
+ /**
54
+ * Creates a readline interface for user input
55
+ */
56
+ function createReadlineInterface() {
57
+ return readline.createInterface({
58
+ input: process.stdin,
59
+ output: process.stdout
60
+ });
61
+ }
62
+
63
+ /**
64
+ * Init command
65
+ *
66
+ * Initializes a new HYTOPIA project. Accepting an optional
67
+ * project name as an argument.
68
+ *
69
+ * @example
70
+ * `bunx hytopia init my-project-name`
71
+ */
72
+ function init() {
73
+ const destDir = process.cwd();
74
+
75
+ // Install dependencies
76
+ installProjectDependencies();
77
+
78
+ // Initialize project with latest HYTOPIA SDK
79
+ console.log('🔧 Initializing project with latest HYTOPIA SDK...');
80
+
81
+ if (flags.template) {
82
+ initFromTemplate(destDir);
83
+ } else {
84
+ initFromBoilerplate(destDir);
85
+ }
86
+
87
+ // Copy assets into project, not overwriting existing files
88
+ copyAssets(destDir);
89
+
90
+ // Display success message
91
+ displayInitSuccessMessage();
92
+
93
+ // Prompt for MCP setup
94
+ promptForMcpSetup();
95
+
96
+ return;
97
+ }
98
+
99
+ /**
100
+ * Installs required dependencies for a new project
101
+ */
102
+ function installProjectDependencies() {
103
+ execSync('bun init --yes');
104
+ execSync('bun add hytopia@latest');
105
+ execSync('bun add @hytopia.com/assets');
106
+ }
107
+
108
+ /**
109
+ * Initializes a project from a template
110
+ */
111
+ function initFromTemplate(destDir) {
112
+ console.log(`🖨️ Initializing project with examples template "${flags.template}"...`);
113
+
114
+ const templateDir = path.join(destDir, 'node_modules', 'hytopia', 'examples', flags.template);
60
115
 
61
- // Copy assets into project, not overwriting existing files
62
- fs.cpSync(
63
- path.join(destDir, 'node_modules', '@hytopia.com', 'assets'),
64
- path.join(destDir, 'assets'),
65
- { recursive: true, force: false }
66
- );
67
-
68
- // Done, lfg!
69
- console.log('--------------------------------');
70
- console.log('🚀 Hytopia project initialized successfully!');
71
- console.log('💡 Start your development server with `bun --watch index.ts`!');
72
- console.log('🎮 After you start your development server, play by opening your browser and visiting: https://play.hytopia.com/?join=localhost:8080')
116
+ if (!fs.existsSync(templateDir)) {
117
+ console.error(`❌ Examples template ${flags.template} does not exist in the examples directory, could not initialize project!`);
118
+ console.error(` Tried directory: ${templateDir}`);
73
119
  return;
74
120
  }
121
+
122
+ fs.cpSync(templateDir, destDir, { recursive: true });
123
+ execSync('bun install');
124
+ }
125
+
126
+ /**
127
+ * Initializes a project from the default boilerplate
128
+ */
129
+ function initFromBoilerplate(destDir) {
130
+ console.log('🧑‍💻 Initializing project with boilerplate...');
131
+ const srcDir = path.join(__dirname, '..', 'boilerplate');
132
+ fs.cpSync(srcDir, destDir, { recursive: true });
133
+ }
134
+
135
+ /**
136
+ * Copies assets to the project directory
137
+ */
138
+ function copyAssets(destDir) {
139
+ fs.cpSync(
140
+ path.join(destDir, 'node_modules', '@hytopia.com', 'assets'),
141
+ path.join(destDir, 'assets'),
142
+ { recursive: true, force: false }
143
+ );
144
+ }
145
+
146
+ /**
147
+ * Displays success message after project initialization
148
+ */
149
+ function displayInitSuccessMessage() {
150
+ logDivider();
151
+ console.log('✅ HYTOPIA PROJECT INITIALIZED SUCCESSFULLY!');
152
+ console.log(' ');
153
+ console.log('💡 1. Start your development server with: bun --watch index.ts');
154
+ console.log('🎮 2. Play your game by opening: https://play.hytopia.com/?join=localhost:8080');
155
+ logDivider();
156
+ }
157
+
158
+ /**
159
+ * Prompts the user to set up MCP
160
+ */
161
+ function promptForMcpSetup() {
162
+ console.log('📋 OPTIONAL: HYTOPIA MCP SETUP');
163
+ console.log(' ');
164
+ console.log('The HYTOPIA MCP enables Cursor and Claude Code editors to access');
165
+ console.log('HYTOPIA-specific capabilities, providing significantly better AI');
166
+ console.log('assistance and development experience for this HYTOPIA project.');
167
+ console.log(' ');
168
+
169
+ const rl = createReadlineInterface();
75
170
 
76
- console.log('Unknown command: ' + command);
77
- })();
171
+ rl.question('Would you like to initialize the HYTOPIA MCP for this project? (y/n): ', (answer) => {
172
+ rl.close();
173
+
174
+ if (answer.trim().toLowerCase() === 'y') {
175
+ initMcp();
176
+ } else {
177
+ logDivider();
178
+ console.log('🎉 You\'re all set! Your HYTOPIA project is ready to use.');
179
+ logDivider();
180
+ }
181
+ });
182
+ }
183
+
184
+ /**
185
+ * Initializes the MCP for the selected editors
186
+ */
187
+ function initMcp() {
188
+ const rl = createReadlineInterface();
189
+
190
+ logDivider();
191
+ console.log('🤖 HYTOPIA MCP SETUP');
192
+ console.log('Please select your code editor:');
193
+ console.log(' 1. Cursor');
194
+ console.log(' 2. Claude Code');
195
+ console.log(' 3. Both');
196
+ console.log(' 4. None / Cancel');
197
+
198
+ rl.question('Enter your selection (1-4): ', (answer) => {
199
+ const selection = parseInt(answer.trim());
200
+
201
+ if (isNaN(selection) || selection < 1 || selection > 4) {
202
+ console.log('❌ Invalid selection. Please run `bunx hytopia init-mcp` again and select a number between 1 and 4.');
203
+ rl.close();
204
+ return;
205
+ }
206
+
207
+ if ([1, 2, 3].includes(selection)) { logDivider(); }
208
+
209
+ if (selection === 1 || selection === 3) {
210
+ initEditorMcp('Cursor', 'cursor');
211
+ }
212
+
213
+ if (selection === 2 || selection === 3) {
214
+ initEditorMcp('Claude Code', 'claude');
215
+ }
216
+
217
+ rl.close();
218
+
219
+ if ([1, 2, 3].includes(selection)) {
220
+ console.log('🎉 You\'re all set! Your HYTOPIA project is ready to use.');
221
+ logDivider();
222
+ }
223
+ });
224
+ }
225
+
226
+ /**
227
+ * Initializes MCP for a specific editor
228
+ */
229
+ function initEditorMcp(editorName, editorFlag) {
230
+ console.log(`🔧 Initializing HYTOPIA MCP for ${editorName}...`);
231
+ execSync(`bunx topia-mcp@latest init ${editorFlag}`);
232
+ console.log(`✅ ${editorName} MCP initialized successfully!`);
233
+ logDivider();
234
+ }
78
235
 
236
+ /**
237
+ * Prints a divider line for better console output readability
238
+ */
239
+ function logDivider() {
240
+ console.log('--------------------------------');
241
+ }
@@ -34,9 +34,9 @@ and also configure additional buttons for mobile compatibility.
34
34
  </script>
35
35
 
36
36
  <!--
37
- HYTOPIA allows you to build completely custom UI uses HTML, CSS and Javascript.
37
+ HYTOPIA allows you to build completely custom UI using HTML, CSS and Javascript.
38
38
  You can build simple UIs, to highly complex ones. UI capabilities are as powerful
39
- as building a regaulr web page - there are no limitations on what you can do.
39
+ as building a regular web page - there are close to no limitations on what is possible.
40
40
 
41
41
  Remember, HYTOPIA sandboxes your UI & UI scripts, so external network requests or
42
42
  other unsafe actions likely won't work as you expect in production.
@@ -60,7 +60,7 @@ and also configure additional buttons for mobile compatibility.
60
60
 
61
61
  /*
62
62
  We can use the body.mobile class to detect if we're on a mobile device.
63
- HYTOPIA will always add this class to the body element when running on a mobile device.
63
+ The HYTOPIA game client will always add this class to the body element when running on a mobile device.
64
64
  */
65
65
  body.mobile .mobile-controls { /* If this css selector matches because we're on mobile, show the mobile controls */
66
66
  display: flex;
@@ -99,7 +99,7 @@ export default class ItemEntity extends Entity {
99
99
  }
100
100
 
101
101
  (new Audio({
102
- attachedToEntity: this.parent,
102
+ attachedToEntity: this,
103
103
  uri: this.consumeAudioUri,
104
104
  volume: 0.5,
105
105
  referenceDistance: 5,
@@ -34,9 +34,9 @@ and also configure additional buttons for mobile compatibility.
34
34
  </script>
35
35
 
36
36
  <!--
37
- HYTOPIA allows you to build completely custom UI uses HTML, CSS and Javascript.
37
+ HYTOPIA allows you to build completely custom UI using HTML, CSS and Javascript.
38
38
  You can build simple UIs, to highly complex ones. UI capabilities are as powerful
39
- as building a regaulr web page - there are no limitations on what you can do.
39
+ as building a regular web page - there are close to no limitations on what is possible.
40
40
 
41
41
  Remember, HYTOPIA sandboxes your UI & UI scripts, so external network requests or
42
42
  other unsafe actions likely won't work as you expect in production.
@@ -60,7 +60,7 @@ and also configure additional buttons for mobile compatibility.
60
60
 
61
61
  /*
62
62
  We can use the body.mobile class to detect if we're on a mobile device.
63
- HYTOPIA will always add this class to the body element when running on a mobile device.
63
+ The HYTOPIA game client will always add this class to the body element when running on a mobile device.
64
64
  */
65
65
  body.mobile .mobile-controls { /* If this css selector matches because we're on mobile, show the mobile controls */
66
66
  display: flex;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hytopia",
3
- "version": "0.3.14",
3
+ "version": "0.3.16",
4
4
  "description": "The HYTOPIA SDK makes it easy for developers to create massively multiplayer games using JavaScript or TypeScript.",
5
5
  "main": "server.js",
6
6
  "bin": {