nova64 0.2.5 → 0.2.7

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.
Files changed (185) hide show
  1. package/README.md +25 -8
  2. package/bin/nova64.js +165 -0
  3. package/dist/assets/console-CY_kygm3.js +14 -0
  4. package/dist/assets/console-CY_kygm3.js.map +1 -0
  5. package/dist/assets/main-l0sNRNKZ.js.map +1 -0
  6. package/dist/assets/sky/studio/nx.png +0 -0
  7. package/dist/assets/sky/studio/ny.png +0 -0
  8. package/dist/assets/sky/studio/nz.png +0 -0
  9. package/dist/assets/sky/studio/px.png +0 -0
  10. package/dist/assets/sky/studio/py.png +0 -0
  11. package/dist/assets/sky/studio/pz.png +0 -0
  12. package/dist/assets/vanilla-Dcuy32gi.js +2 -0
  13. package/dist/assets/vanilla-Dcuy32gi.js.map +1 -0
  14. package/dist/console.html +899 -0
  15. package/dist/docs/BENCHMARK.md +77 -0
  16. package/dist/docs/CHEATSHEET.md +255 -0
  17. package/dist/docs/EFFECTS_API_GUIDE.md +577 -0
  18. package/dist/docs/EFFECTS_QUICK_REFERENCE.md +331 -0
  19. package/dist/docs/FONT_CHARACTER_REFERENCE.md +219 -0
  20. package/dist/docs/FREE_GLB_ASSETS.md +330 -0
  21. package/dist/docs/FULLSCREEN_BUTTON_FEATURE.md +296 -0
  22. package/dist/docs/GAMEPAD_SUPPORT.md +348 -0
  23. package/dist/docs/GAME_IMPROVEMENTS.md +278 -0
  24. package/dist/docs/GAME_QUALITY_STATUS.md +300 -0
  25. package/dist/docs/MIGRATION_GUIDE.md +553 -0
  26. package/dist/docs/NOVA64_3D_API.md +356 -0
  27. package/dist/docs/NOVA64_API_REFERENCE.md +1406 -0
  28. package/dist/docs/NOVA64_UI_API.md +503 -0
  29. package/dist/docs/UI_SYSTEM_SUMMARY.md +445 -0
  30. package/dist/docs/VOXEL_ENGINE_GUIDE.md +662 -0
  31. package/dist/docs/VOXEL_QUICK_REFERENCE.md +386 -0
  32. package/dist/docs/api-3d.html +750 -0
  33. package/dist/docs/api-effects.html +385 -0
  34. package/dist/docs/api-improvements.md +121 -0
  35. package/dist/docs/api-skybox.html +407 -0
  36. package/dist/docs/api-sprites.html +321 -0
  37. package/dist/docs/api-voxel.html +337 -0
  38. package/dist/docs/api.html +543 -0
  39. package/dist/docs/assets.html +306 -0
  40. package/dist/docs/audio.html +340 -0
  41. package/dist/docs/blogs.html +286 -0
  42. package/dist/docs/collision.html +316 -0
  43. package/dist/docs/console.html +247 -0
  44. package/dist/docs/editor.html +297 -0
  45. package/dist/docs/font.html +247 -0
  46. package/dist/docs/framebuffer.html +247 -0
  47. package/dist/docs/fullscreen-button.html +297 -0
  48. package/dist/docs/gpu-systems.html +247 -0
  49. package/dist/docs/index.html +580 -0
  50. package/dist/docs/input.html +491 -0
  51. package/dist/docs/physics.html +311 -0
  52. package/dist/docs/screens.html +311 -0
  53. package/dist/docs/storage.html +311 -0
  54. package/dist/docs/textinput.html +332 -0
  55. package/dist/docs/ui.html +488 -0
  56. package/dist/examples/3d-advanced/code.js +695 -0
  57. package/dist/examples/adventure-comic-3d/code.js +342 -0
  58. package/dist/examples/audio-lab/code.js +150 -0
  59. package/dist/examples/boids-flocking/code.js +270 -0
  60. package/dist/examples/crystal-cathedral-3d/code.js +706 -0
  61. package/dist/examples/cyberpunk-city-3d/code.js +1383 -0
  62. package/dist/examples/demoscene/README.md +192 -0
  63. package/dist/examples/demoscene/code.js +1081 -0
  64. package/dist/examples/demoscene/meta.json +21 -0
  65. package/dist/examples/dungeon-crawler-3d/code.js +1117 -0
  66. package/dist/examples/f-zero-nova-3d/code.js +865 -0
  67. package/dist/examples/f-zero-nova-3d/code_old.js +1555 -0
  68. package/dist/examples/fps-demo-3d/code.js +744 -0
  69. package/dist/examples/game-of-life-3d/code.js +338 -0
  70. package/dist/examples/generative-art/code.js +632 -0
  71. package/dist/examples/hello-3d/code.js +325 -0
  72. package/dist/examples/hello-skybox/code.js +183 -0
  73. package/dist/examples/hello-world/code.js +19 -0
  74. package/dist/examples/input-showcase/code.js +109 -0
  75. package/dist/examples/instancing-demo/code.js +315 -0
  76. package/dist/examples/minecraft-demo/code.js +387 -0
  77. package/dist/examples/model-viewer-3d/code.js +114 -0
  78. package/dist/examples/mystical-realm-3d/code.js +1203 -0
  79. package/dist/examples/nature-explorer-3d/code.js +1318 -0
  80. package/dist/examples/particles-demo/code.js +522 -0
  81. package/dist/examples/pbr-showcase/code.js +140 -0
  82. package/dist/examples/physics-demo-3d/code.js +948 -0
  83. package/dist/examples/screen-demo/code.js +267 -0
  84. package/dist/examples/shooter-demo-3d/code.js +1286 -0
  85. package/dist/examples/space-combat-3d/IMPLEMENTATION_SUMMARY.md +109 -0
  86. package/dist/examples/space-combat-3d/README.md +135 -0
  87. package/dist/examples/space-combat-3d/code.js +1332 -0
  88. package/dist/examples/space-harrier-3d/code.js +923 -0
  89. package/dist/examples/star-fox-nova-3d/code.js +1116 -0
  90. package/dist/examples/star-fox-nova-3d/code_backup.js +410 -0
  91. package/dist/examples/star-fox-nova-3d/code_broken.js +1821 -0
  92. package/dist/examples/storage-quest/code.js +209 -0
  93. package/dist/examples/strider-demo-3d/IMPROVEMENT_OPTIONS.md +285 -0
  94. package/dist/examples/strider-demo-3d/cache-test.html +132 -0
  95. package/dist/examples/strider-demo-3d/code-fixed.js +582 -0
  96. package/dist/examples/strider-demo-3d/code-old.js +1537 -0
  97. package/dist/examples/strider-demo-3d/code.js +1462 -0
  98. package/dist/examples/strider-demo-3d/code.js.bak2 +1169 -0
  99. package/dist/examples/strider-demo-3d/fix-game.sh +53 -0
  100. package/dist/examples/super-plumber-64/README.md +128 -0
  101. package/dist/examples/super-plumber-64/code.js +1185 -0
  102. package/dist/examples/super-plumber-64/index.html +88 -0
  103. package/dist/examples/test-2d-overlay/code.js +32 -0
  104. package/dist/examples/test-font/code.js +51 -0
  105. package/dist/examples/test-minimal/code.js +21 -0
  106. package/dist/examples/ui-demo/code.js +306 -0
  107. package/dist/examples/wing-commander-space/README.md +180 -0
  108. package/dist/examples/wing-commander-space/code.js +1285 -0
  109. package/dist/examples/wizardry-3d/CHANGELOG.md +366 -0
  110. package/dist/examples/wizardry-3d/code.js +3928 -0
  111. package/dist/index.html +666 -0
  112. package/dist/os9-shell/assets/index-DIHfrTaW.css +1 -0
  113. package/dist/os9-shell/assets/index-KchE_ngx.js +483 -0
  114. package/dist/os9-shell/assets/index-KchE_ngx.js.map +1 -0
  115. package/dist/os9-shell/index.html +23 -0
  116. package/dist/os9-shell/nova-icon.svg +12 -0
  117. package/dist/runtime/api-2d.js +1158 -0
  118. package/dist/runtime/api-3d/camera.js +73 -0
  119. package/dist/runtime/api-3d/instancing.js +180 -0
  120. package/dist/runtime/api-3d/lights.js +51 -0
  121. package/dist/runtime/api-3d/materials.js +47 -0
  122. package/dist/runtime/api-3d/models.js +84 -0
  123. package/dist/runtime/api-3d/particles.js +296 -0
  124. package/dist/runtime/api-3d/pbr.js +113 -0
  125. package/dist/runtime/api-3d/primitives.js +304 -0
  126. package/dist/runtime/api-3d/scene.js +169 -0
  127. package/dist/runtime/api-3d/transforms.js +161 -0
  128. package/dist/runtime/api-3d.js +166 -0
  129. package/dist/runtime/api-effects.js +840 -0
  130. package/dist/runtime/api-gameutils.js +476 -0
  131. package/dist/runtime/api-generative.js +610 -0
  132. package/dist/runtime/api-presets.js +85 -0
  133. package/dist/runtime/api-skybox.js +232 -0
  134. package/dist/runtime/api-sprites.js +100 -0
  135. package/dist/runtime/api-voxel.js +712 -0
  136. package/dist/runtime/api.js +201 -0
  137. package/dist/runtime/assets.js +27 -0
  138. package/dist/runtime/audio.js +114 -0
  139. package/dist/runtime/collision.js +47 -0
  140. package/dist/runtime/console.js +101 -0
  141. package/dist/runtime/editor.js +233 -0
  142. package/dist/runtime/font.js +233 -0
  143. package/dist/runtime/framebuffer.js +28 -0
  144. package/dist/runtime/fullscreen-button.js +185 -0
  145. package/dist/runtime/gpu-canvas2d.js +47 -0
  146. package/dist/runtime/gpu-threejs.js +643 -0
  147. package/dist/runtime/gpu-webgl2.js +310 -0
  148. package/dist/runtime/index.d.ts +682 -0
  149. package/dist/runtime/index.js +22 -0
  150. package/dist/runtime/input.js +225 -0
  151. package/dist/runtime/logger.js +60 -0
  152. package/dist/runtime/physics.js +101 -0
  153. package/dist/runtime/screens.js +213 -0
  154. package/dist/runtime/storage.js +38 -0
  155. package/dist/runtime/store.js +151 -0
  156. package/dist/runtime/textinput.js +68 -0
  157. package/dist/runtime/ui/buttons.js +124 -0
  158. package/dist/runtime/ui/panels.js +105 -0
  159. package/dist/runtime/ui/text.js +86 -0
  160. package/dist/runtime/ui/widgets.js +141 -0
  161. package/dist/runtime/ui.js +111 -0
  162. package/index.html +6 -1
  163. package/package.json +9 -2
  164. package/public/assets/sky/studio/nx.png +0 -0
  165. package/public/assets/sky/studio/ny.png +0 -0
  166. package/public/assets/sky/studio/nz.png +0 -0
  167. package/public/assets/sky/studio/px.png +0 -0
  168. package/public/assets/sky/studio/py.png +0 -0
  169. package/public/assets/sky/studio/pz.png +0 -0
  170. package/public/os9-shell/assets/index-KchE_ngx.js +483 -0
  171. package/public/os9-shell/assets/index-KchE_ngx.js.map +1 -0
  172. package/public/os9-shell/index.html +10 -1
  173. package/runtime/api-2d.js +301 -21
  174. package/runtime/api-3d/pbr.js +45 -1
  175. package/runtime/api-3d.js +1 -0
  176. package/runtime/api-effects.js +90 -3
  177. package/runtime/api-gameutils.js +476 -0
  178. package/runtime/api-generative.js +610 -0
  179. package/runtime/api-skybox.js +54 -0
  180. package/runtime/api-voxel.js +139 -28
  181. package/runtime/gpu-threejs.js +13 -9
  182. package/runtime/ui.js +2 -2
  183. package/src/main.js +20 -0
  184. package/public/os9-shell/assets/index-B1Uvacma.js +0 -32825
  185. package/public/os9-shell/assets/index-B1Uvacma.js.map +0 -1
@@ -0,0 +1,553 @@
1
+ # 🚀 Ultimate 3D Migration Guide for Nova64
2
+
3
+ Transform your Nova64 experiences into **spectacular 3D fantasy console adventures** with advanced materials, cinematic lighting, and Nintendo 64/PlayStation aesthetics!
4
+
5
+ ## 🌟 **Migration to v0.2.0**
6
+
7
+ ### 🎯 **Breaking Changes**
8
+
9
+ - **Three.js Only**: Nova64 now exclusively uses Three.js for maximum 3D performance
10
+ - **Enhanced API**: New 3D functions with improved parameter structure
11
+ - **Material System**: Advanced material options with new configuration format
12
+ - **Camera Controls**: Improved camera system with smooth interpolation
13
+
14
+ ### ✅ **Backward Compatibility**
15
+
16
+ - **100% 2D Compatibility**: All existing 2D carts work without modification
17
+ - **Gradual Migration**: Add 3D elements incrementally to existing projects
18
+ - **API Preservation**: Core 2D functions remain unchanged
19
+
20
+ ## 🌟 **Revolutionary 3D Transformation**
21
+
22
+ ### 🎪 **Advanced Rendering Pipeline**
23
+
24
+ 1. **🎯 3D Scene Rendering**: Automatic Three.js rendering with advanced materials and lighting
25
+ 2. **🎨 2D Overlay Compositing**: High-precision transparent overlay for HUD and UI elements
26
+ 3. **✅ 100% Backward Compatibility**: All existing 2D carts work flawlessly with zero changes
27
+ 4. **⚡ Hot Reloading**: Instant updates without losing game state during development
28
+
29
+ ### 📐 **Coordinate Systems**
30
+
31
+ - **🌍 3D World Space**: Standard 3D coordinates (Y-up) with perspective projection
32
+ - **🖥️ 2D Screen Space**: 320×180 pixel overlay coordinates (Y-down) for UI elements
33
+ - **🎯 Hybrid Mapping**: Seamless conversion between 2D screen and 3D world positions
34
+
35
+ ## 🎯 **Spectacular Migration Steps**
36
+
37
+ ### 🌟 **Step 1: Advanced 3D Scene Setup**
38
+
39
+ Transform your cart into a cinematic 3D experience:
40
+
41
+ ```javascript
42
+ // ❌ Before (Basic 2D)
43
+ export function init() {
44
+ cls();
45
+ // Basic 2D initialization...
46
+ }
47
+
48
+ // ✅ After (Ultimate 3D Fantasy Console)
49
+ export function init() {
50
+ console.log('🚀 Initializing spectacular 3D world...');
51
+
52
+ // 🎪 Advanced 3D scene setup
53
+ setCameraPosition(0, 5, 10); // Cinematic camera position
54
+ setCameraTarget(0, 0, 0); // Look at world origin
55
+ setCameraFOV(75); // Wide-angle perspective
56
+
57
+ // 🌫️ Atmospheric effects for depth and mood
58
+ setFog(0x1a1a2e, 8, 25); // Mysterious purple fog
59
+
60
+ // 💡 Enhanced lighting system
61
+ setAmbientLight(0x404060, 0.3); // Subtle ambient lighting
62
+ setDirectionalLight(0xffffff, 0.8); // Strong directional light
63
+
64
+ // ✨ Visual enhancement effects
65
+ enablePostProcessing(true); // ACES tone mapping + bloom
66
+ setRenderQuality('high'); // 4K shadows, full effects
67
+
68
+ // 🎨 Existing 2D initialization (still works!)
69
+ cls();
70
+ // ... your existing 2D setup
71
+ }
72
+ ```
73
+
74
+ ### 🎨 **Step 2: Advanced 3D Object Creation**
75
+
76
+ Add spectacular 3D objects with professional materials:
77
+
78
+ ```javascript
79
+ let player2D = { x: 160, y: 90 }; // Existing 2D player
80
+ let player3D,
81
+ worldObjects = []; // New 3D representations
82
+ let particleEffects = []; // Dynamic particle systems
83
+
84
+ export function init() {
85
+ // Previous 3D setup...
86
+
87
+ // 👤 Create spectacular 3D player with advanced materials
88
+ player3D = createCube(0, 1, 0, 1, {
89
+ material: 'metallic', // Professional metallic surface
90
+ color: 0x0088ff, // Bright blue primary color
91
+ emissive: 0x002244, // Subtle blue glow
92
+ metalness: 0.8, // High metallic reflection
93
+ roughness: 0.2, // Smooth, polished surface
94
+ });
95
+
96
+ // 🌍 Create immersive world environment
97
+ const ground = createPlane(0, -1, 0, 30, 30, {
98
+ material: 'standard',
99
+ color: 0x2a4d3a, // Forest green ground
100
+ roughness: 0.8, // Natural rough surface
101
+ });
102
+ rotateMesh(ground, -Math.PI / 2, 0, 0); // Make horizontal
103
+
104
+ // ✨ Add magical floating crystals
105
+ for (let i = 0; i < 8; i++) {
106
+ const crystal = createCube(
107
+ Math.cos((i * Math.PI) / 4) * 5, // Circular arrangement
108
+ 2 + Math.sin(i * 0.5), // Varied heights
109
+ Math.sin((i * Math.PI) / 4) * 5,
110
+ 0.6,
111
+ {
112
+ material: 'holographic', // Ultimate visual effect
113
+ color: 0xff0088,
114
+ emissive: 0x440022,
115
+ }
116
+ );
117
+ worldObjects.push({ mesh: crystal, spin: i * 0.1 });
118
+ }
119
+ }
120
+ ```
121
+
122
+ ### 📐 **Step 3: Advanced Coordinate Transformation**
123
+
124
+ Seamlessly convert between 2D screen and 3D world coordinates:
125
+
126
+ ```javascript
127
+ // 🎯 Professional coordinate mapping with perspective correction
128
+ function screen2DToWorld3D(screenX, screenY, depth = 0) {
129
+ // Advanced mapping with camera-relative positioning
130
+ const worldX = (screenX - 160) / 32; // Center and scale X
131
+ const worldZ = (screenY - 90) / 32 + depth; // Y becomes Z with depth
132
+ const worldY = 0; // Ground level default
133
+ return { x: worldX, y: worldY, z: worldZ };
134
+ }
135
+
136
+ function world3DToScreen2D(worldX, worldY, worldZ) {
137
+ // Project 3D world coordinates to 2D screen space
138
+ const screenX = worldX * 32 + 160;
139
+ const screenY = worldZ * 32 + 90;
140
+ return { x: screenX, y: screenY };
141
+ }
142
+
143
+ // 🎪 Advanced raycasting for precise 3D interaction
144
+ function screenToWorldRay(mouseX, mouseY) {
145
+ // Cast ray from camera through screen point for object picking
146
+ const ray = raycastFromCamera(mouseX, mouseY);
147
+ if (ray && ray.object) {
148
+ console.log(`Hit 3D object: ${ray.object.uuid} at distance ${ray.distance}`);
149
+ return ray;
150
+ }
151
+ return null;
152
+ }
153
+
154
+ // 🌍 Convert 2D game coordinates to immersive 3D positions
155
+ function enhance2DWith3D(gameObject2D) {
156
+ const world3D = screen2DToWorld3D(gameObject2D.x, gameObject2D.y);
157
+
158
+ // Create spectacular 3D representation
159
+ const mesh3D = createCube(world3D.x, world3D.y + 1, world3D.z, 0.8, {
160
+ material: 'emissive',
161
+ color: gameObject2D.color || 0xff4488,
162
+ emissive: 0x220011,
163
+ });
164
+
165
+ return { ...gameObject2D, mesh3D, world3D };
166
+ }
167
+ ```
168
+
169
+ ### ⚡ **Step 4: Enhanced Update System**
170
+
171
+ Create smooth, responsive hybrid 2D/3D gameplay:
172
+
173
+ ```javascript
174
+ export function update() {
175
+ // 🎮 Enhanced input system with WASD + arrows support
176
+ const moveSpeed = 0.12;
177
+ const rotationSpeed = 0.05;
178
+
179
+ // Modern WASD movement (enhanced input system)
180
+ if (key('KeyW') || btn(2)) {
181
+ // W or Up
182
+ player2D.y -= 2;
183
+ player3D.velocity.z = -moveSpeed;
184
+ }
185
+ if (key('KeyS') || btn(3)) {
186
+ // S or Down
187
+ player2D.y += 2;
188
+ player3D.velocity.z = moveSpeed;
189
+ }
190
+ if (key('KeyA') || btn(0)) {
191
+ // A or Left
192
+ player2D.x -= 2;
193
+ player3D.velocity.x = -moveSpeed;
194
+ }
195
+ if (key('KeyD') || btn(1)) {
196
+ // D or Right
197
+ player2D.x += 2;
198
+ player3D.velocity.x = moveSpeed;
199
+ }
200
+ if (key('Space') || btn(4)) {
201
+ // Space or Z button
202
+ player3D.velocity.y = 0.08; // Jump with physics
203
+ }
204
+
205
+ // 🎯 Advanced 3D physics and positioning
206
+ const world3D = screen2DToWorld3D(player2D.x, player2D.y);
207
+
208
+ // Smooth 3D positioning with interpolation
209
+ const currentPos = getMeshPosition(player3D);
210
+ const targetX = lerp(currentPos.x, world3D.x, 0.1);
211
+ const targetZ = lerp(currentPos.z, world3D.z, 0.1);
212
+ setPosition(player3D, targetX, currentPos.y, targetZ);
213
+
214
+ // Apply physics (gravity, ground collision)
215
+ player3D.velocity.y -= 0.01; // Gravity
216
+ if (currentPos.y <= 1) {
217
+ // Ground collision
218
+ setPosition(player3D, targetX, 1, targetZ);
219
+ player3D.velocity.y = 0;
220
+ }
221
+
222
+ // 🎪 Spectacular world object animations
223
+ worldObjects.forEach((obj, i) => {
224
+ obj.spin += rotationSpeed;
225
+ rotateMesh(obj.mesh, obj.spin, obj.spin * 1.3, obj.spin * 0.7);
226
+
227
+ // Dynamic floating motion
228
+ const floatY = 2 + Math.sin(time * 0.02 + i) * 0.4;
229
+ const pos = getMeshPosition(obj.mesh);
230
+ setPosition(obj.mesh, pos.x, floatY, pos.z);
231
+ });
232
+
233
+ // 📷 Cinematic camera following
234
+ setCameraPosition(world3D.x + 4, world3D.y + 3, world3D.z + 6);
235
+ setCameraTarget(world3D.x, world3D.y + 1, world3D.z);
236
+ }
237
+ ```
238
+
239
+ ### 🎨 **Step 5: Professional Hybrid Rendering**
240
+
241
+ Create stunning 3D scenes with polished 2D HUD overlays:
242
+
243
+ ```javascript
244
+ export function draw() {
245
+ // 🎪 Advanced 3D rendering with cinematic effects
246
+ draw3d(() => {
247
+ // 3D scene renders automatically with all objects
248
+ // Advanced lighting, materials, and post-processing active
249
+
250
+ // 🌟 Optional: Add dynamic lighting effects
251
+ const lightIntensity = 0.8 + Math.sin(time * 0.05) * 0.2;
252
+ setDirectionalLight(0xffffff, lightIntensity);
253
+
254
+ // 💫 Optional: Dynamic atmospheric effects
255
+ const fogColor = Math.floor(Math.sin(time * 0.03) * 20 + 40);
256
+ setFog((fogColor << 16) + (fogColor << 8) + (fogColor + 20), 8, 25);
257
+ });
258
+
259
+ // 📊 Professional HUD system (rendered over 3D)
260
+ cls(); // Clear 2D overlay (transparent background)
261
+
262
+ // 🏆 Game statistics with modern styling
263
+ print('🏆 SCORE: 1,337', 10, 10, 0xffffff);
264
+ print('❤️ HEALTH: ██████████', 10, 26, 0xff4444);
265
+ print('💎 CRYSTALS: ' + collectedCrystals, 10, 42, 0x44ff88);
266
+ print('⚡ ENERGY: ' + Math.floor(playerEnergy), 10, 58, 0x4488ff);
267
+
268
+ // 🗺️ Advanced minimap with 3D awareness
269
+ const mapX = 240,
270
+ mapY = 10,
271
+ mapSize = 70;
272
+ rect(mapX, mapY, mapSize, mapSize, 0x333333, true); // Map background
273
+ rect(mapX, mapY, mapSize, mapSize, 0x888888, false); // Map border
274
+
275
+ // Draw 3D objects on minimap
276
+ worldObjects.forEach(obj => {
277
+ const pos = getMeshPosition(obj.mesh);
278
+ const mapPosX = mapX + (pos.x + 10) * (mapSize / 20);
279
+ const mapPosY = mapY + (pos.z + 10) * (mapSize / 20);
280
+ pset(mapPosX, mapPosY, 0xff0088); // Crystal positions
281
+ });
282
+
283
+ // Player position on minimap
284
+ const playerPos = getMeshPosition(player3D);
285
+ const playerMapX = mapX + (playerPos.x + 10) * (mapSize / 20);
286
+ const playerMapY = mapY + (playerPos.z + 10) * (mapSize / 20);
287
+ rect(playerMapX - 1, playerMapY - 1, 3, 3, 0x00ff00, true); // Player dot
288
+
289
+ // 🎮 Control instructions
290
+ print('WASD: Move • Space: Jump • Mouse: Look', 10, 165, 0x888888);
291
+
292
+ // 📈 Performance overlay (optional debug info)
293
+ if (showDebug) {
294
+ const stats = get3DStats();
295
+ print(`FPS: ${Math.round(1000 / deltaTime)}`, 270, 10, 0x88ff88);
296
+ print(`Triangles: ${stats.triangles}`, 270, 26, 0x88ff88);
297
+ print(`Objects: ${stats.objects}`, 270, 42, 0x88ff88);
298
+ }
299
+ }
300
+ ```
301
+
302
+ ## Common Patterns
303
+
304
+ ### Camera Following 2D Character
305
+
306
+ ```js
307
+ export function update(dt) {
308
+ // Update 2D player...
309
+
310
+ // Make 3D camera follow 2D position
311
+ const [worldX, , worldZ] = screen2DToWorld3D(player2D.x, player2D.y);
312
+ setCameraPosition(worldX, 5, worldZ + 5);
313
+ setCameraTarget(worldX, 0, worldZ);
314
+ }
315
+ ```
316
+
317
+ ### 3D Background with 2D Gameplay
318
+
319
+ Perfect for platformers or shoot-em-ups:
320
+
321
+ ```js
322
+ let terrain3D = [];
323
+ let enemies2D = [];
324
+
325
+ export function init() {
326
+ // Create 3D terrain
327
+ for (let x = -10; x <= 10; x += 2) {
328
+ terrain3D.push(createCube(2, 0x336633, [x, -2, 0]));
329
+ }
330
+
331
+ // Traditional 2D enemies
332
+ enemies2D.push({ x: 200, y: 100, vx: -1 });
333
+ }
334
+
335
+ export function update(dt) {
336
+ // Update 2D gameplay
337
+ enemies2D.forEach(enemy => {
338
+ enemy.x += enemy.vx;
339
+ });
340
+
341
+ // Animate 3D background
342
+ terrain3D.forEach((cube, i) => {
343
+ rotateMesh(cube, 0, dt * 0.1, 0);
344
+ });
345
+ }
346
+
347
+ export function draw() {
348
+ cls();
349
+
350
+ // Draw 2D gameplay elements
351
+ enemies2D.forEach(enemy => {
352
+ rect(enemy.x, enemy.y, 16, 16, rgba8(255, 0, 0, 255), true);
353
+ });
354
+ }
355
+ ```
356
+
357
+ ### Mixed 2D/3D Particles
358
+
359
+ ```js
360
+ let particles2D = [];
361
+ let particles3D = [];
362
+
363
+ function spawnExplosion(x, y) {
364
+ // 2D particles for UI/effects
365
+ for (let i = 0; i < 10; i++) {
366
+ particles2D.push({
367
+ x,
368
+ y,
369
+ vx: (Math.random() - 0.5) * 4,
370
+ vy: (Math.random() - 0.5) * 4,
371
+ life: 1.0,
372
+ });
373
+ }
374
+
375
+ // 3D particles for world objects
376
+ const [worldX, , worldZ] = screen2DToWorld3D(x, y);
377
+ for (let i = 0; i < 5; i++) {
378
+ const particle = createCube(0.1, 0xffaa00, [worldX, 0, worldZ]);
379
+ particles3D.push({
380
+ mesh: particle,
381
+ vx: (Math.random() - 0.5) * 2,
382
+ vy: Math.random() * 2,
383
+ vz: (Math.random() - 0.5) * 2,
384
+ life: 1.0,
385
+ });
386
+ }
387
+ }
388
+ ```
389
+
390
+ ## Performance Tips
391
+
392
+ ### Efficient 3D Object Management
393
+
394
+ ```js
395
+ // Object pooling for frequently created/destroyed objects
396
+ let particlePool = [];
397
+
398
+ function getPooledParticle() {
399
+ if (particlePool.length > 0) {
400
+ return particlePool.pop();
401
+ }
402
+ return createCube(0.1, 0xffaa00);
403
+ }
404
+
405
+ function returnToPool(meshId) {
406
+ setPosition(meshId, 1000, 1000, 1000); // Move offscreen
407
+ particlePool.push(meshId);
408
+ }
409
+ ```
410
+
411
+ ### LOD (Level of Detail)
412
+
413
+ ```js
414
+ export function update(dt) {
415
+ const cameraPos = getCamera().position;
416
+
417
+ objects3D.forEach(obj => {
418
+ const distance = distanceTo(obj.position, cameraPos);
419
+
420
+ if (distance > 20) {
421
+ // Hide distant objects
422
+ setPosition(obj.mesh, 1000, 1000, 1000);
423
+ } else if (distance > 10) {
424
+ // Use low-detail version
425
+ setScale(obj.mesh, 0.5);
426
+ } else {
427
+ // Full detail
428
+ setScale(obj.mesh, 1);
429
+ }
430
+ });
431
+ }
432
+ ```
433
+
434
+ ## Debugging
435
+
436
+ ### Visual Debugging
437
+
438
+ ```js
439
+ export function draw() {
440
+ cls();
441
+
442
+ // Show 3D object count
443
+ print(`3D Objects: ${get3DStats().render.geometries}`, 8, 8, rgba8(255, 255, 255, 255));
444
+
445
+ // Show renderer type
446
+ const rendererInfo = typeof createCube === 'function' ? 'Three.js' : 'WebGL2';
447
+ print(`Renderer: ${rendererInfo}`, 8, 24, rgba8(200, 200, 200, 255));
448
+
449
+ // Performance overlay
450
+ const stats = get3DStats();
451
+ if (stats.render) {
452
+ print(`Triangles: ${stats.render.triangles}`, 8, 40, rgba8(150, 255, 150, 255));
453
+ print(`Draw Calls: ${stats.render.calls}`, 8, 56, rgba8(150, 255, 150, 255));
454
+ }
455
+ }
456
+ ```
457
+
458
+ ### Console Debugging
459
+
460
+ ```js
461
+ // Check if 3D features are available
462
+ if (typeof createCube === 'function') {
463
+ console.log('3D features available');
464
+ } else {
465
+ console.log('Running in 2D-only mode');
466
+ }
467
+
468
+ // Get object information
469
+ const cube = createCube(1, 0xff0000);
470
+ console.log('Cube position:', getPosition(cube));
471
+ console.log('Cube rotation:', getRotation(cube));
472
+ ```
473
+
474
+ ## Best Practices
475
+
476
+ 1. **Start Simple**: Add one 3D element at a time to existing carts
477
+ 2. **Maintain 2D Feel**: Use 3D to enhance, not replace, the 2D aesthetic
478
+ 3. **Performance First**: Monitor triangle count and draw calls
479
+ 4. **Consistent Style**: Use N64-style effects (`enablePixelation`, `enableDithering`)
480
+ 5. **Test Fallbacks**: Ensure carts work on WebGL2-only systems
481
+
482
+ ## Example: Upgrading a Shooter
483
+
484
+ ```js
485
+ // Before: Pure 2D shooter
486
+ let player = { x: 160, y: 140 };
487
+ let bullets = [];
488
+ let enemies = [];
489
+
490
+ // After: 3D background + 2D gameplay
491
+ let player = { x: 160, y: 140 };
492
+ let player3D;
493
+ let bullets = [];
494
+ let enemies = [];
495
+ let stars3D = [];
496
+
497
+ export function init() {
498
+ // 3D setup
499
+ setCameraPosition(0, 0, 5);
500
+ setFog(0x000011, 10, 50);
501
+
502
+ // Create 3D starfield
503
+ for (let i = 0; i < 50; i++) {
504
+ const star = createCube(0.1, 0xffffff, [
505
+ (Math.random() - 0.5) * 40,
506
+ (Math.random() - 0.5) * 20,
507
+ Math.random() * -30,
508
+ ]);
509
+ stars3D.push(star);
510
+ }
511
+
512
+ // 3D player ship
513
+ player3D = createCube(0.5, 0x00ff00, [0, 0, 0]);
514
+ }
515
+
516
+ export function update(dt) {
517
+ // 2D player movement
518
+ if (btn(0)) player.x -= 3;
519
+ if (btn(1)) player.x += 3;
520
+
521
+ // Mirror to 3D
522
+ const worldX = (player.x - 160) / 40;
523
+ setPosition(player3D, worldX, 0, 2);
524
+
525
+ // Animate starfield
526
+ stars3D.forEach(star => {
527
+ moveMesh(star, 0, 0, dt * 5);
528
+ const pos = getPosition(star);
529
+ if (pos[2] > 5) {
530
+ setPosition(star, pos[0], pos[1], -30);
531
+ }
532
+ });
533
+
534
+ // Standard 2D game logic...
535
+ }
536
+
537
+ export function draw() {
538
+ cls(); // Clear for 2D overlay
539
+
540
+ // 2D gameplay elements render on top of 3D
541
+ rect(player.x - 8, player.y - 8, 16, 16, rgba8(0, 255, 0, 255), true);
542
+
543
+ bullets.forEach(bullet => {
544
+ pset(bullet.x, bullet.y, rgba8(255, 255, 0, 255));
545
+ });
546
+
547
+ enemies.forEach(enemy => {
548
+ rect(enemy.x, enemy.y, 12, 12, rgba8(255, 0, 0, 255), true);
549
+ });
550
+ }
551
+ ```
552
+
553
+ This approach lets you gradually enhance existing games with 3D elements while maintaining their core 2D gameplay feel.