nova64 0.2.5 → 0.2.6

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 (140) 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/index.html +6 -1
  118. package/package.json +37 -32
  119. package/public/assets/sky/studio/nx.png +0 -0
  120. package/public/assets/sky/studio/ny.png +0 -0
  121. package/public/assets/sky/studio/nz.png +0 -0
  122. package/public/assets/sky/studio/px.png +0 -0
  123. package/public/assets/sky/studio/py.png +0 -0
  124. package/public/assets/sky/studio/pz.png +0 -0
  125. package/public/os9-shell/assets/index-KchE_ngx.js +483 -0
  126. package/public/os9-shell/assets/index-KchE_ngx.js.map +1 -0
  127. package/public/os9-shell/index.html +10 -1
  128. package/runtime/api-2d.js +301 -21
  129. package/runtime/api-3d/pbr.js +45 -1
  130. package/runtime/api-3d.js +1 -0
  131. package/runtime/api-effects.js +90 -3
  132. package/runtime/api-gameutils.js +476 -0
  133. package/runtime/api-generative.js +610 -0
  134. package/runtime/api-skybox.js +54 -0
  135. package/runtime/api-voxel.js +139 -28
  136. package/runtime/gpu-threejs.js +13 -9
  137. package/runtime/ui.js +2 -2
  138. package/src/main.js +20 -0
  139. package/public/os9-shell/assets/index-B1Uvacma.js +0 -32825
  140. package/public/os9-shell/assets/index-B1Uvacma.js.map +0 -1
@@ -0,0 +1,338 @@
1
+ // GAME OF LIFE 3D — Conway's Game of Life rendered with 3D cubes
2
+ // A mesmerizing cellular automata with multiple rulesets and patterns
3
+ // Uses the Nova64 3D engine for a stunning visual twist on classic CA
4
+
5
+ const GRID_W = 40;
6
+ const GRID_H = 30;
7
+ const CELL_SIZE = 0.9;
8
+
9
+ let grid = [];
10
+ let nextGrid = [];
11
+ let meshGrid = []; // 3D cube mesh IDs
12
+ let generation = 0;
13
+ let tickTimer = 0;
14
+ let tickSpeed = 0.12; // seconds per generation
15
+ let paused = false;
16
+ let gameState = 'start';
17
+ let time = 0;
18
+ let ruleset = 0;
19
+ const RULESETS = [
20
+ { name: 'CONWAY (B3/S23)', birth: [3], survive: [2, 3] },
21
+ { name: 'HIGH LIFE (B36/S23)', birth: [3, 6], survive: [2, 3] },
22
+ { name: 'DAY & NIGHT (B3678/S34678)', birth: [3, 6, 7, 8], survive: [3, 4, 6, 7, 8] },
23
+ { name: 'SEEDS (B2/S)', birth: [2], survive: [] },
24
+ { name: 'DIAMOEBA (B35678/S5678)', birth: [3, 5, 6, 7, 8], survive: [5, 6, 7, 8] },
25
+ ];
26
+ let cameraAngle = 0;
27
+ let cameraHeight = 25;
28
+ let cameraDistance = 35;
29
+ let pattern = 0;
30
+
31
+ function createGrid() {
32
+ const g = [];
33
+ for (let y = 0; y < GRID_H; y++) {
34
+ g[y] = [];
35
+ for (let x = 0; x < GRID_W; x++) {
36
+ g[y][x] = 0;
37
+ }
38
+ }
39
+ return g;
40
+ }
41
+
42
+ function clearMeshes() {
43
+ for (let y = 0; y < GRID_H; y++) {
44
+ for (let x = 0; x < GRID_W; x++) {
45
+ if (meshGrid[y] && meshGrid[y][x]) {
46
+ destroyMesh(meshGrid[y][x]);
47
+ meshGrid[y][x] = null;
48
+ }
49
+ }
50
+ }
51
+ }
52
+
53
+ function randomize(density = 0.3) {
54
+ for (let y = 0; y < GRID_H; y++) {
55
+ for (let x = 0; x < GRID_W; x++) {
56
+ grid[y][x] = Math.random() < density ? 1 : 0;
57
+ }
58
+ }
59
+ generation = 0;
60
+ }
61
+
62
+ function placeGlider(gx, gy) {
63
+ const shape = [
64
+ [0, 1, 0],
65
+ [0, 0, 1],
66
+ [1, 1, 1],
67
+ ];
68
+ for (let dy = 0; dy < 3; dy++)
69
+ for (let dx = 0; dx < 3; dx++)
70
+ if (shape[dy][dx]) grid[(gy + dy) % GRID_H][(gx + dx) % GRID_W] = 1;
71
+ }
72
+
73
+ function placeRPentomino(gx, gy) {
74
+ const shape = [
75
+ [0, 1, 1],
76
+ [1, 1, 0],
77
+ [0, 1, 0],
78
+ ];
79
+ for (let dy = 0; dy < 3; dy++)
80
+ for (let dx = 0; dx < 3; dx++)
81
+ if (shape[dy][dx]) grid[(gy + dy) % GRID_H][(gx + dx) % GRID_W] = 1;
82
+ }
83
+
84
+ function placePulsar(gx, gy) {
85
+ const offsets = [
86
+ [2, 0],
87
+ [3, 0],
88
+ [4, 0],
89
+ [8, 0],
90
+ [9, 0],
91
+ [10, 0],
92
+ [0, 2],
93
+ [5, 2],
94
+ [7, 2],
95
+ [12, 2],
96
+ [0, 3],
97
+ [5, 3],
98
+ [7, 3],
99
+ [12, 3],
100
+ [0, 4],
101
+ [5, 4],
102
+ [7, 4],
103
+ [12, 4],
104
+ [2, 5],
105
+ [3, 5],
106
+ [4, 5],
107
+ [8, 5],
108
+ [9, 5],
109
+ [10, 5],
110
+ [2, 7],
111
+ [3, 7],
112
+ [4, 7],
113
+ [8, 7],
114
+ [9, 7],
115
+ [10, 7],
116
+ [0, 8],
117
+ [5, 8],
118
+ [7, 8],
119
+ [12, 8],
120
+ [0, 9],
121
+ [5, 9],
122
+ [7, 9],
123
+ [12, 9],
124
+ [0, 10],
125
+ [5, 10],
126
+ [7, 10],
127
+ [12, 10],
128
+ [2, 12],
129
+ [3, 12],
130
+ [4, 12],
131
+ [8, 12],
132
+ [9, 12],
133
+ [10, 12],
134
+ ];
135
+ for (const [dx, dy] of offsets) grid[(gy + dy) % GRID_H][(gx + dx) % GRID_W] = 1;
136
+ }
137
+
138
+ function loadPattern(idx) {
139
+ grid = createGrid();
140
+ clearMeshes();
141
+ meshGrid = [];
142
+ for (let y = 0; y < GRID_H; y++) meshGrid[y] = new Array(GRID_W).fill(null);
143
+
144
+ if (idx === 0) {
145
+ // Random soup
146
+ randomize(0.35);
147
+ } else if (idx === 1) {
148
+ // Glider fleet
149
+ for (let i = 0; i < 8; i++) {
150
+ placeGlider((i * 5) % GRID_W, (i * 4) % GRID_H);
151
+ }
152
+ } else if (idx === 2) {
153
+ // R-pentomino explosion
154
+ placeRPentomino(GRID_W / 2 - 1, GRID_H / 2 - 1);
155
+ } else if (idx === 3) {
156
+ // Pulsar
157
+ placePulsar(GRID_W / 2 - 6, GRID_H / 2 - 6);
158
+ }
159
+ generation = 0;
160
+ }
161
+
162
+ function countNeighbors(x, y) {
163
+ let count = 0;
164
+ for (let dy = -1; dy <= 1; dy++) {
165
+ for (let dx = -1; dx <= 1; dx++) {
166
+ if (dx === 0 && dy === 0) continue;
167
+ const nx = (x + dx + GRID_W) % GRID_W;
168
+ const ny = (y + dy + GRID_H) % GRID_H;
169
+ count += grid[ny][nx];
170
+ }
171
+ }
172
+ return count;
173
+ }
174
+
175
+ function step() {
176
+ const rules = RULESETS[ruleset];
177
+ nextGrid = createGrid();
178
+ for (let y = 0; y < GRID_H; y++) {
179
+ for (let x = 0; x < GRID_W; x++) {
180
+ const n = countNeighbors(x, y);
181
+ if (grid[y][x]) {
182
+ nextGrid[y][x] = rules.survive.includes(n) ? 1 : 0;
183
+ } else {
184
+ nextGrid[y][x] = rules.birth.includes(n) ? 1 : 0;
185
+ }
186
+ }
187
+ }
188
+ grid = nextGrid;
189
+ generation++;
190
+ }
191
+
192
+ export function init() {
193
+ grid = createGrid();
194
+ nextGrid = createGrid();
195
+ meshGrid = [];
196
+ for (let y = 0; y < GRID_H; y++) meshGrid[y] = new Array(GRID_W).fill(null);
197
+
198
+ setAmbientLight(0xffffff, 0.3);
199
+ setLightDirection(-1, -2, -1);
200
+ setFog(0x050510, 30, 80);
201
+ enableBloom(1.0, 0.4, 0.3);
202
+
203
+ loadPattern(0);
204
+ gameState = 'start';
205
+ time = 0;
206
+ }
207
+
208
+ export function update(dt) {
209
+ time += dt;
210
+
211
+ if (gameState === 'start') {
212
+ if (keyp('Space') || keyp('Enter')) {
213
+ gameState = 'running';
214
+ }
215
+ // Still animate camera on start
216
+ cameraAngle += dt * 0.2;
217
+ updateCamera();
218
+ return;
219
+ }
220
+
221
+ // Controls
222
+ if (keyp('Space')) paused = !paused;
223
+ if (keyp('ArrowRight')) {
224
+ ruleset = (ruleset + 1) % RULESETS.length;
225
+ loadPattern(pattern);
226
+ }
227
+ if (keyp('ArrowLeft')) {
228
+ ruleset = (ruleset - 1 + RULESETS.length) % RULESETS.length;
229
+ loadPattern(pattern);
230
+ }
231
+ if (keyp('ArrowUp')) {
232
+ pattern = (pattern + 1) % 4;
233
+ loadPattern(pattern);
234
+ }
235
+ if (keyp('ArrowDown')) {
236
+ tickSpeed = tickSpeed === 0.12 ? 0.04 : tickSpeed === 0.04 ? 0.25 : 0.12;
237
+ }
238
+ if (keyp('KeyR')) loadPattern(pattern);
239
+
240
+ // Simulation tick
241
+ if (!paused) {
242
+ tickTimer += dt;
243
+ if (tickTimer >= tickSpeed) {
244
+ tickTimer = 0;
245
+ step();
246
+ }
247
+ }
248
+
249
+ // Camera orbit
250
+ cameraAngle += dt * 0.15;
251
+ updateCamera();
252
+
253
+ // Sync 3D cubes with grid
254
+ syncMeshes();
255
+ }
256
+
257
+ function updateCamera() {
258
+ const cx = GRID_W * CELL_SIZE * 0.5;
259
+ const cz = GRID_H * CELL_SIZE * 0.5;
260
+ const camX = cx + Math.cos(cameraAngle) * cameraDistance;
261
+ const camZ = cz + Math.sin(cameraAngle) * cameraDistance;
262
+ setCameraPosition(camX, cameraHeight, camZ);
263
+ setCameraTarget(cx, 0, cz);
264
+ }
265
+
266
+ function syncMeshes() {
267
+ for (let y = 0; y < GRID_H; y++) {
268
+ for (let x = 0; x < GRID_W; x++) {
269
+ const alive = grid[y][x];
270
+ const hasMesh = meshGrid[y][x] != null;
271
+
272
+ if (alive && !hasMesh) {
273
+ // Birth — create a cube
274
+ const hue = ((x + y) * 7 + generation * 2) % 360;
275
+ const col = hsb(hue, 80, 90);
276
+ const px = x * CELL_SIZE;
277
+ const pz = y * CELL_SIZE;
278
+ const height = 0.5 + Math.sin(generation * 0.3 + x * 0.2 + y * 0.2) * 0.3;
279
+ meshGrid[y][x] = createCube(CELL_SIZE * 0.85, col, [px, height, pz]);
280
+ setScale(meshGrid[y][x], 1, 0.5 + height, 1);
281
+ } else if (!alive && hasMesh) {
282
+ // Death — remove the cube
283
+ destroyMesh(meshGrid[y][x]);
284
+ meshGrid[y][x] = null;
285
+ } else if (alive && hasMesh) {
286
+ // Alive — animate height and color
287
+ const hue = ((x + y) * 7 + generation * 2) % 360;
288
+ const height = 0.5 + Math.sin(generation * 0.3 + x * 0.2 + y * 0.2) * 0.3;
289
+ const px = x * CELL_SIZE;
290
+ const pz = y * CELL_SIZE;
291
+ setPosition(meshGrid[y][x], px, height, pz);
292
+ setScale(meshGrid[y][x], 1, 0.5 + height, 1);
293
+ }
294
+ }
295
+ }
296
+ }
297
+
298
+ function countAlive() {
299
+ let c = 0;
300
+ for (let y = 0; y < GRID_H; y++) for (let x = 0; x < GRID_W; x++) c += grid[y][x];
301
+ return c;
302
+ }
303
+
304
+ export function draw() {
305
+ if (gameState === 'start') {
306
+ // Dark overlay
307
+ rect(0, 0, 640, 360, rgba8(0, 0, 20, 180), true);
308
+ printCentered('GAME OF LIFE 3D', 320, 80, rgba8(100, 200, 255));
309
+ printCentered("Conway's Cellular Automata in Three Dimensions", 320, 110, rgba8(150, 150, 200));
310
+ const pulse = Math.sin(time * 3) * 0.5 + 0.5;
311
+ printCentered('PRESS SPACE TO BEGIN', 320, 180, rgba8(255, 255, 100, 100 + pulse * 155));
312
+ printCentered(
313
+ 'LEFT/RIGHT = Ruleset | UP = Pattern | R = Reset',
314
+ 320,
315
+ 240,
316
+ rgba8(120, 120, 160)
317
+ );
318
+ printCentered('DOWN = Speed | SPACE = Pause', 320, 260, rgba8(120, 120, 160));
319
+ return;
320
+ }
321
+
322
+ // Minimal HUD over 3D scene
323
+ rect(0, 0, 640, 20, rgba8(0, 0, 0, 120), true);
324
+ const alive = countAlive();
325
+ const speedLabel = tickSpeed <= 0.04 ? 'FAST' : tickSpeed >= 0.25 ? 'SLOW' : 'MED';
326
+ print(
327
+ `${RULESETS[ruleset].name} | GEN: ${generation} | ALIVE: ${alive} | SPEED: ${speedLabel}${paused ? ' [PAUSED]' : ''}`,
328
+ 10,
329
+ 6,
330
+ rgba8(180, 220, 255)
331
+ );
332
+ print(
333
+ 'LEFT/RIGHT=Rules UP=Pattern DOWN=Speed R=Reset SPACE=Pause',
334
+ 10,
335
+ 348,
336
+ rgba8(100, 100, 130, 180)
337
+ );
338
+ }