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.
- package/README.md +25 -8
- package/bin/nova64.js +165 -0
- package/dist/assets/console-CY_kygm3.js +14 -0
- package/dist/assets/console-CY_kygm3.js.map +1 -0
- package/dist/assets/main-l0sNRNKZ.js.map +1 -0
- package/dist/assets/sky/studio/nx.png +0 -0
- package/dist/assets/sky/studio/ny.png +0 -0
- package/dist/assets/sky/studio/nz.png +0 -0
- package/dist/assets/sky/studio/px.png +0 -0
- package/dist/assets/sky/studio/py.png +0 -0
- package/dist/assets/sky/studio/pz.png +0 -0
- package/dist/assets/vanilla-Dcuy32gi.js +2 -0
- package/dist/assets/vanilla-Dcuy32gi.js.map +1 -0
- package/dist/console.html +899 -0
- package/dist/docs/BENCHMARK.md +77 -0
- package/dist/docs/CHEATSHEET.md +255 -0
- package/dist/docs/EFFECTS_API_GUIDE.md +577 -0
- package/dist/docs/EFFECTS_QUICK_REFERENCE.md +331 -0
- package/dist/docs/FONT_CHARACTER_REFERENCE.md +219 -0
- package/dist/docs/FREE_GLB_ASSETS.md +330 -0
- package/dist/docs/FULLSCREEN_BUTTON_FEATURE.md +296 -0
- package/dist/docs/GAMEPAD_SUPPORT.md +348 -0
- package/dist/docs/GAME_IMPROVEMENTS.md +278 -0
- package/dist/docs/GAME_QUALITY_STATUS.md +300 -0
- package/dist/docs/MIGRATION_GUIDE.md +553 -0
- package/dist/docs/NOVA64_3D_API.md +356 -0
- package/dist/docs/NOVA64_API_REFERENCE.md +1406 -0
- package/dist/docs/NOVA64_UI_API.md +503 -0
- package/dist/docs/UI_SYSTEM_SUMMARY.md +445 -0
- package/dist/docs/VOXEL_ENGINE_GUIDE.md +662 -0
- package/dist/docs/VOXEL_QUICK_REFERENCE.md +386 -0
- package/dist/docs/api-3d.html +750 -0
- package/dist/docs/api-effects.html +385 -0
- package/dist/docs/api-improvements.md +121 -0
- package/dist/docs/api-skybox.html +407 -0
- package/dist/docs/api-sprites.html +321 -0
- package/dist/docs/api-voxel.html +337 -0
- package/dist/docs/api.html +543 -0
- package/dist/docs/assets.html +306 -0
- package/dist/docs/audio.html +340 -0
- package/dist/docs/blogs.html +286 -0
- package/dist/docs/collision.html +316 -0
- package/dist/docs/console.html +247 -0
- package/dist/docs/editor.html +297 -0
- package/dist/docs/font.html +247 -0
- package/dist/docs/framebuffer.html +247 -0
- package/dist/docs/fullscreen-button.html +297 -0
- package/dist/docs/gpu-systems.html +247 -0
- package/dist/docs/index.html +580 -0
- package/dist/docs/input.html +491 -0
- package/dist/docs/physics.html +311 -0
- package/dist/docs/screens.html +311 -0
- package/dist/docs/storage.html +311 -0
- package/dist/docs/textinput.html +332 -0
- package/dist/docs/ui.html +488 -0
- package/dist/examples/3d-advanced/code.js +695 -0
- package/dist/examples/adventure-comic-3d/code.js +342 -0
- package/dist/examples/audio-lab/code.js +150 -0
- package/dist/examples/boids-flocking/code.js +270 -0
- package/dist/examples/crystal-cathedral-3d/code.js +706 -0
- package/dist/examples/cyberpunk-city-3d/code.js +1383 -0
- package/dist/examples/demoscene/README.md +192 -0
- package/dist/examples/demoscene/code.js +1081 -0
- package/dist/examples/demoscene/meta.json +21 -0
- package/dist/examples/dungeon-crawler-3d/code.js +1117 -0
- package/dist/examples/f-zero-nova-3d/code.js +865 -0
- package/dist/examples/f-zero-nova-3d/code_old.js +1555 -0
- package/dist/examples/fps-demo-3d/code.js +744 -0
- package/dist/examples/game-of-life-3d/code.js +338 -0
- package/dist/examples/generative-art/code.js +632 -0
- package/dist/examples/hello-3d/code.js +325 -0
- package/dist/examples/hello-skybox/code.js +183 -0
- package/dist/examples/hello-world/code.js +19 -0
- package/dist/examples/input-showcase/code.js +109 -0
- package/dist/examples/instancing-demo/code.js +315 -0
- package/dist/examples/minecraft-demo/code.js +387 -0
- package/dist/examples/model-viewer-3d/code.js +114 -0
- package/dist/examples/mystical-realm-3d/code.js +1203 -0
- package/dist/examples/nature-explorer-3d/code.js +1318 -0
- package/dist/examples/particles-demo/code.js +522 -0
- package/dist/examples/pbr-showcase/code.js +140 -0
- package/dist/examples/physics-demo-3d/code.js +948 -0
- package/dist/examples/screen-demo/code.js +267 -0
- package/dist/examples/shooter-demo-3d/code.js +1286 -0
- package/dist/examples/space-combat-3d/IMPLEMENTATION_SUMMARY.md +109 -0
- package/dist/examples/space-combat-3d/README.md +135 -0
- package/dist/examples/space-combat-3d/code.js +1332 -0
- package/dist/examples/space-harrier-3d/code.js +923 -0
- package/dist/examples/star-fox-nova-3d/code.js +1116 -0
- package/dist/examples/star-fox-nova-3d/code_backup.js +410 -0
- package/dist/examples/star-fox-nova-3d/code_broken.js +1821 -0
- package/dist/examples/storage-quest/code.js +209 -0
- package/dist/examples/strider-demo-3d/IMPROVEMENT_OPTIONS.md +285 -0
- package/dist/examples/strider-demo-3d/cache-test.html +132 -0
- package/dist/examples/strider-demo-3d/code-fixed.js +582 -0
- package/dist/examples/strider-demo-3d/code-old.js +1537 -0
- package/dist/examples/strider-demo-3d/code.js +1462 -0
- package/dist/examples/strider-demo-3d/code.js.bak2 +1169 -0
- package/dist/examples/strider-demo-3d/fix-game.sh +53 -0
- package/dist/examples/super-plumber-64/README.md +128 -0
- package/dist/examples/super-plumber-64/code.js +1185 -0
- package/dist/examples/super-plumber-64/index.html +88 -0
- package/dist/examples/test-2d-overlay/code.js +32 -0
- package/dist/examples/test-font/code.js +51 -0
- package/dist/examples/test-minimal/code.js +21 -0
- package/dist/examples/ui-demo/code.js +306 -0
- package/dist/examples/wing-commander-space/README.md +180 -0
- package/dist/examples/wing-commander-space/code.js +1285 -0
- package/dist/examples/wizardry-3d/CHANGELOG.md +366 -0
- package/dist/examples/wizardry-3d/code.js +3928 -0
- package/dist/index.html +666 -0
- package/dist/os9-shell/assets/index-DIHfrTaW.css +1 -0
- package/dist/os9-shell/assets/index-KchE_ngx.js +483 -0
- package/dist/os9-shell/assets/index-KchE_ngx.js.map +1 -0
- package/dist/os9-shell/index.html +23 -0
- package/dist/os9-shell/nova-icon.svg +12 -0
- package/dist/runtime/api-2d.js +1158 -0
- package/dist/runtime/api-3d/camera.js +73 -0
- package/dist/runtime/api-3d/instancing.js +180 -0
- package/dist/runtime/api-3d/lights.js +51 -0
- package/dist/runtime/api-3d/materials.js +47 -0
- package/dist/runtime/api-3d/models.js +84 -0
- package/dist/runtime/api-3d/particles.js +296 -0
- package/dist/runtime/api-3d/pbr.js +113 -0
- package/dist/runtime/api-3d/primitives.js +304 -0
- package/dist/runtime/api-3d/scene.js +169 -0
- package/dist/runtime/api-3d/transforms.js +161 -0
- package/dist/runtime/api-3d.js +166 -0
- package/dist/runtime/api-effects.js +840 -0
- package/dist/runtime/api-gameutils.js +476 -0
- package/dist/runtime/api-generative.js +610 -0
- package/dist/runtime/api-presets.js +85 -0
- package/dist/runtime/api-skybox.js +232 -0
- package/dist/runtime/api-sprites.js +100 -0
- package/dist/runtime/api-voxel.js +712 -0
- package/dist/runtime/api.js +201 -0
- package/dist/runtime/assets.js +27 -0
- package/dist/runtime/audio.js +114 -0
- package/dist/runtime/collision.js +47 -0
- package/dist/runtime/console.js +101 -0
- package/dist/runtime/editor.js +233 -0
- package/dist/runtime/font.js +233 -0
- package/dist/runtime/framebuffer.js +28 -0
- package/dist/runtime/fullscreen-button.js +185 -0
- package/dist/runtime/gpu-canvas2d.js +47 -0
- package/dist/runtime/gpu-threejs.js +643 -0
- package/dist/runtime/gpu-webgl2.js +310 -0
- package/dist/runtime/index.d.ts +682 -0
- package/dist/runtime/index.js +22 -0
- package/dist/runtime/input.js +225 -0
- package/dist/runtime/logger.js +60 -0
- package/dist/runtime/physics.js +101 -0
- package/dist/runtime/screens.js +213 -0
- package/dist/runtime/storage.js +38 -0
- package/dist/runtime/store.js +151 -0
- package/dist/runtime/textinput.js +68 -0
- package/dist/runtime/ui/buttons.js +124 -0
- package/dist/runtime/ui/panels.js +105 -0
- package/dist/runtime/ui/text.js +86 -0
- package/dist/runtime/ui/widgets.js +141 -0
- package/dist/runtime/ui.js +111 -0
- package/index.html +6 -1
- package/package.json +9 -2
- package/public/assets/sky/studio/nx.png +0 -0
- package/public/assets/sky/studio/ny.png +0 -0
- package/public/assets/sky/studio/nz.png +0 -0
- package/public/assets/sky/studio/px.png +0 -0
- package/public/assets/sky/studio/py.png +0 -0
- package/public/assets/sky/studio/pz.png +0 -0
- package/public/os9-shell/assets/index-KchE_ngx.js +483 -0
- package/public/os9-shell/assets/index-KchE_ngx.js.map +1 -0
- package/public/os9-shell/index.html +10 -1
- package/runtime/api-2d.js +301 -21
- package/runtime/api-3d/pbr.js +45 -1
- package/runtime/api-3d.js +1 -0
- package/runtime/api-effects.js +90 -3
- package/runtime/api-gameutils.js +476 -0
- package/runtime/api-generative.js +610 -0
- package/runtime/api-skybox.js +54 -0
- package/runtime/api-voxel.js +139 -28
- package/runtime/gpu-threejs.js +13 -9
- package/runtime/ui.js +2 -2
- package/src/main.js +20 -0
- package/public/os9-shell/assets/index-B1Uvacma.js +0 -32825
- package/public/os9-shell/assets/index-B1Uvacma.js.map +0 -1
package/runtime/api-voxel.js
CHANGED
|
@@ -37,27 +37,28 @@ export function voxelApi(gpu) {
|
|
|
37
37
|
BEDROCK: 14,
|
|
38
38
|
};
|
|
39
39
|
|
|
40
|
-
// Block colors (for texture-less rendering)
|
|
40
|
+
// Block colors (for texture-less rendering) — tuned for visual biome distinction
|
|
41
41
|
const BLOCK_COLORS = {
|
|
42
|
-
[BLOCK_TYPES.GRASS]:
|
|
43
|
-
[BLOCK_TYPES.DIRT]:
|
|
44
|
-
[BLOCK_TYPES.STONE]:
|
|
42
|
+
[BLOCK_TYPES.GRASS]: 0x55cc33,
|
|
43
|
+
[BLOCK_TYPES.DIRT]: 0x996644,
|
|
44
|
+
[BLOCK_TYPES.STONE]: 0xaaaaaa,
|
|
45
45
|
[BLOCK_TYPES.SAND]: 0xffdd88,
|
|
46
|
-
[BLOCK_TYPES.WATER]:
|
|
46
|
+
[BLOCK_TYPES.WATER]: 0x2288dd,
|
|
47
47
|
[BLOCK_TYPES.WOOD]: 0x774422,
|
|
48
|
-
[BLOCK_TYPES.LEAVES]:
|
|
49
|
-
[BLOCK_TYPES.COBBLESTONE]:
|
|
48
|
+
[BLOCK_TYPES.LEAVES]: 0x116622,
|
|
49
|
+
[BLOCK_TYPES.COBBLESTONE]: 0x667788,
|
|
50
50
|
[BLOCK_TYPES.PLANKS]: 0xddaa55,
|
|
51
51
|
[BLOCK_TYPES.GLASS]: 0xccffff,
|
|
52
52
|
[BLOCK_TYPES.BRICK]: 0xcc4433,
|
|
53
|
-
[BLOCK_TYPES.SNOW]:
|
|
54
|
-
[BLOCK_TYPES.ICE]:
|
|
53
|
+
[BLOCK_TYPES.SNOW]: 0xeeeeff,
|
|
54
|
+
[BLOCK_TYPES.ICE]: 0x99ddff,
|
|
55
55
|
[BLOCK_TYPES.BEDROCK]: 0x333333,
|
|
56
56
|
};
|
|
57
57
|
|
|
58
58
|
// World data
|
|
59
59
|
const chunks = new Map(); // key: "x,z" -> Chunk
|
|
60
60
|
const chunkMeshes = new Map(); // key: "x,z" -> THREE.Mesh
|
|
61
|
+
let worldSeed = Math.floor(Math.random() * 50000); // random start for biome variety
|
|
61
62
|
|
|
62
63
|
// Noise function for terrain generation (simple Perlin-like)
|
|
63
64
|
function noise2D(x, z) {
|
|
@@ -160,39 +161,101 @@ export function voxelApi(gpu) {
|
|
|
160
161
|
const baseX = chunk.chunkX * CHUNK_SIZE;
|
|
161
162
|
const baseZ = chunk.chunkZ * CHUNK_SIZE;
|
|
162
163
|
|
|
164
|
+
// Pending trees to place after terrain fill (avoid overwriting terrain)
|
|
165
|
+
const pendingTrees = [];
|
|
166
|
+
|
|
163
167
|
for (let x = 0; x < CHUNK_SIZE; x++) {
|
|
164
168
|
for (let z = 0; z < CHUNK_SIZE; z++) {
|
|
165
169
|
const worldX = baseX + x;
|
|
166
170
|
const worldZ = baseZ + z;
|
|
167
171
|
|
|
168
|
-
//
|
|
169
|
-
const
|
|
172
|
+
// Biome selection via temperature + moisture noise
|
|
173
|
+
const temperature = perlinNoise(worldX * 0.5 + worldSeed, worldZ * 0.5 + worldSeed, 2, 0.5);
|
|
174
|
+
const moisture = perlinNoise(
|
|
175
|
+
worldX * 0.3 + 1000 + worldSeed,
|
|
176
|
+
worldZ * 0.3 + 1000 + worldSeed,
|
|
177
|
+
2,
|
|
178
|
+
0.5
|
|
179
|
+
);
|
|
180
|
+
|
|
181
|
+
// Per-biome height profile — each biome has unique surface, terrain shape, and density
|
|
182
|
+
let heightScale = 20;
|
|
183
|
+
let heightBase = 32;
|
|
184
|
+
let surfaceBlock = BLOCK_TYPES.GRASS;
|
|
185
|
+
let subBlock = BLOCK_TYPES.DIRT;
|
|
186
|
+
let treeChance = 0;
|
|
187
|
+
let waterLevel = 30;
|
|
188
|
+
|
|
189
|
+
if (temperature < 0.2) {
|
|
190
|
+
// ── Frozen Tundra ── flat icy plains
|
|
191
|
+
surfaceBlock = BLOCK_TYPES.SNOW;
|
|
192
|
+
subBlock = BLOCK_TYPES.ICE;
|
|
193
|
+
heightScale = 6;
|
|
194
|
+
heightBase = 33;
|
|
195
|
+
treeChance = 0;
|
|
196
|
+
} else if (temperature < 0.35 && moisture > 0.5) {
|
|
197
|
+
// ── Taiga ── gray rocky forest
|
|
198
|
+
surfaceBlock = BLOCK_TYPES.COBBLESTONE;
|
|
199
|
+
subBlock = BLOCK_TYPES.STONE;
|
|
200
|
+
heightScale = 18;
|
|
201
|
+
heightBase = 34;
|
|
202
|
+
treeChance = 0.06;
|
|
203
|
+
} else if (temperature > 0.7 && moisture < 0.25) {
|
|
204
|
+
// ── Desert ── flat sand dunes
|
|
205
|
+
surfaceBlock = BLOCK_TYPES.SAND;
|
|
206
|
+
subBlock = BLOCK_TYPES.SAND;
|
|
207
|
+
heightScale = 4;
|
|
208
|
+
heightBase = 31;
|
|
209
|
+
treeChance = 0;
|
|
210
|
+
} else if (temperature > 0.6 && moisture > 0.6) {
|
|
211
|
+
// ── Jungle ── dense dark-green valleys
|
|
212
|
+
surfaceBlock = BLOCK_TYPES.LEAVES;
|
|
213
|
+
subBlock = BLOCK_TYPES.DIRT;
|
|
214
|
+
heightScale = 22;
|
|
215
|
+
heightBase = 28;
|
|
216
|
+
treeChance = 0.15;
|
|
217
|
+
} else if (moisture < 0.3) {
|
|
218
|
+
// ── Savanna ── dry brown earth
|
|
219
|
+
surfaceBlock = BLOCK_TYPES.DIRT;
|
|
220
|
+
subBlock = BLOCK_TYPES.SAND;
|
|
221
|
+
heightScale = 5;
|
|
222
|
+
heightBase = 33;
|
|
223
|
+
treeChance = 0.005;
|
|
224
|
+
} else if (temperature > 0.4 && moisture > 0.4) {
|
|
225
|
+
// ── Forest ── classic green hills
|
|
226
|
+
surfaceBlock = BLOCK_TYPES.GRASS;
|
|
227
|
+
subBlock = BLOCK_TYPES.DIRT;
|
|
228
|
+
heightScale = 14;
|
|
229
|
+
heightBase = 32;
|
|
230
|
+
treeChance = 0.08;
|
|
231
|
+
} else if (temperature < 0.35) {
|
|
232
|
+
// ── Snowy Hills ── tall snowy mountains
|
|
233
|
+
surfaceBlock = BLOCK_TYPES.SNOW;
|
|
234
|
+
subBlock = BLOCK_TYPES.STONE;
|
|
235
|
+
heightScale = 35;
|
|
236
|
+
heightBase = 30;
|
|
237
|
+
treeChance = 0.02;
|
|
238
|
+
} else {
|
|
239
|
+
// ── Plains ── gentle rolling grassland
|
|
240
|
+
surfaceBlock = BLOCK_TYPES.GRASS;
|
|
241
|
+
subBlock = BLOCK_TYPES.DIRT;
|
|
242
|
+
heightScale = 6;
|
|
243
|
+
heightBase = 32;
|
|
244
|
+
treeChance = 0.015;
|
|
245
|
+
}
|
|
170
246
|
|
|
171
|
-
|
|
172
|
-
const temperature = perlinNoise(worldX * 0.5, worldZ * 0.5, 2, 0.5);
|
|
173
|
-
const moisture = perlinNoise(worldX * 0.3 + 1000, worldZ * 0.3 + 1000, 2, 0.5);
|
|
247
|
+
const height = Math.floor(perlinNoise(worldX, worldZ, 4, 0.5) * heightScale + heightBase);
|
|
174
248
|
|
|
175
249
|
for (let y = 0; y < CHUNK_HEIGHT; y++) {
|
|
176
250
|
if (y === 0) {
|
|
177
|
-
// Bedrock layer
|
|
178
251
|
chunk.setBlock(x, y, z, BLOCK_TYPES.BEDROCK);
|
|
179
252
|
} else if (y < height - 3) {
|
|
180
|
-
// Stone layer
|
|
181
253
|
chunk.setBlock(x, y, z, BLOCK_TYPES.STONE);
|
|
182
254
|
} else if (y < height - 1) {
|
|
183
|
-
|
|
184
|
-
chunk.setBlock(x, y, z, BLOCK_TYPES.DIRT);
|
|
255
|
+
chunk.setBlock(x, y, z, subBlock);
|
|
185
256
|
} else if (y === height - 1) {
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
chunk.setBlock(x, y, z, BLOCK_TYPES.SNOW);
|
|
189
|
-
} else if (moisture < 0.3) {
|
|
190
|
-
chunk.setBlock(x, y, z, BLOCK_TYPES.SAND);
|
|
191
|
-
} else {
|
|
192
|
-
chunk.setBlock(x, y, z, BLOCK_TYPES.GRASS);
|
|
193
|
-
}
|
|
194
|
-
} else if (y < 30 && y >= height) {
|
|
195
|
-
// Water level
|
|
257
|
+
chunk.setBlock(x, y, z, surfaceBlock);
|
|
258
|
+
} else if (y < waterLevel && y >= height) {
|
|
196
259
|
chunk.setBlock(x, y, z, BLOCK_TYPES.WATER);
|
|
197
260
|
}
|
|
198
261
|
|
|
@@ -204,6 +267,38 @@ export function voxelApi(gpu) {
|
|
|
204
267
|
}
|
|
205
268
|
}
|
|
206
269
|
}
|
|
270
|
+
|
|
271
|
+
// Random tree placement (seeded by world position)
|
|
272
|
+
if (height > waterLevel && treeChance > 0) {
|
|
273
|
+
const treeSeed = Math.sin(worldX * 12.9898 + worldZ * 78.233) * 43758.5453;
|
|
274
|
+
const treeRoll = treeSeed - Math.floor(treeSeed);
|
|
275
|
+
if (treeRoll < treeChance && x > 2 && x < CHUNK_SIZE - 3 && z > 2 && z < CHUNK_SIZE - 3) {
|
|
276
|
+
pendingTrees.push({ x, y: height, z });
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
// Place trees after terrain is fully generated
|
|
283
|
+
for (const t of pendingTrees) {
|
|
284
|
+
const trunkHeight = 4 + Math.floor(Math.abs(Math.sin(t.x * 7 + t.z * 13)) * 3);
|
|
285
|
+
for (let i = 0; i < trunkHeight; i++) {
|
|
286
|
+
chunk.setBlock(t.x, t.y + i, t.z, BLOCK_TYPES.WOOD);
|
|
287
|
+
}
|
|
288
|
+
const leafY = t.y + trunkHeight;
|
|
289
|
+
for (let dx = -2; dx <= 2; dx++) {
|
|
290
|
+
for (let dy = -2; dy <= 2; dy++) {
|
|
291
|
+
for (let dz = -2; dz <= 2; dz++) {
|
|
292
|
+
if (Math.abs(dx) + Math.abs(dy) + Math.abs(dz) < 4) {
|
|
293
|
+
const lx = t.x + dx,
|
|
294
|
+
ly = leafY + dy,
|
|
295
|
+
lz = t.z + dz;
|
|
296
|
+
if (lx >= 0 && lx < CHUNK_SIZE && lz >= 0 && lz < CHUNK_SIZE && ly < CHUNK_HEIGHT) {
|
|
297
|
+
chunk.setBlock(lx, ly, lz, BLOCK_TYPES.LEAVES);
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
}
|
|
207
302
|
}
|
|
208
303
|
}
|
|
209
304
|
}
|
|
@@ -494,6 +589,18 @@ export function voxelApi(gpu) {
|
|
|
494
589
|
keysToRemove.forEach(key => chunkMeshes.delete(key));
|
|
495
590
|
}
|
|
496
591
|
|
|
592
|
+
// Reset entire world (clear all chunks and meshes)
|
|
593
|
+
function resetWorld() {
|
|
594
|
+
for (const mesh of chunkMeshes.values()) {
|
|
595
|
+
gpu.scene.remove(mesh);
|
|
596
|
+
mesh.geometry.dispose();
|
|
597
|
+
mesh.material.dispose();
|
|
598
|
+
}
|
|
599
|
+
chunkMeshes.clear();
|
|
600
|
+
chunks.clear();
|
|
601
|
+
worldSeed += 5000 + Math.floor(Math.random() * 10000);
|
|
602
|
+
}
|
|
603
|
+
|
|
497
604
|
// Raycast to find block player is looking at
|
|
498
605
|
function raycastBlock(origin, direction, maxDistance = 10) {
|
|
499
606
|
const step = 0.1;
|
|
@@ -587,6 +694,9 @@ export function voxelApi(gpu) {
|
|
|
587
694
|
// Structures
|
|
588
695
|
placeTree,
|
|
589
696
|
|
|
697
|
+
// World reset
|
|
698
|
+
resetWorld,
|
|
699
|
+
|
|
590
700
|
// Expose to global game context
|
|
591
701
|
exposeTo: function (g) {
|
|
592
702
|
g.BLOCK_TYPES = BLOCK_TYPES;
|
|
@@ -596,6 +706,7 @@ export function voxelApi(gpu) {
|
|
|
596
706
|
g.raycastVoxelBlock = raycastBlock;
|
|
597
707
|
g.checkVoxelCollision = checkCollision;
|
|
598
708
|
g.placeVoxelTree = placeTree;
|
|
709
|
+
g.resetVoxelWorld = resetWorld;
|
|
599
710
|
},
|
|
600
711
|
};
|
|
601
712
|
}
|
package/runtime/gpu-threejs.js
CHANGED
|
@@ -29,7 +29,7 @@ export class GpuThreeJS {
|
|
|
29
29
|
|
|
30
30
|
// Dramatically enhanced visual rendering setup
|
|
31
31
|
this.renderer.toneMapping = THREE.ACESFilmicToneMapping;
|
|
32
|
-
this.renderer.toneMappingExposure = 1.
|
|
32
|
+
this.renderer.toneMappingExposure = 1.25;
|
|
33
33
|
this.renderer.shadowMap.enabled = true;
|
|
34
34
|
// Note: PCFSoftShadowMap is deprecated in r182, PCFShadowMap now provides soft shadows
|
|
35
35
|
this.renderer.shadowMap.type = THREE.PCFShadowMap;
|
|
@@ -84,11 +84,11 @@ export class GpuThreeJS {
|
|
|
84
84
|
|
|
85
85
|
setupN64Lighting() {
|
|
86
86
|
// Multi-layered ambient lighting for rich atmosphere
|
|
87
|
-
const ambientLight = new THREE.AmbientLight(
|
|
87
|
+
const ambientLight = new THREE.AmbientLight(0x606080, 0.5);
|
|
88
88
|
this.scene.add(ambientLight);
|
|
89
89
|
|
|
90
90
|
// Hemisphere light for more natural lighting
|
|
91
|
-
const hemisphereLight = new THREE.HemisphereLight(0xffffbb, 0x080820, 0.
|
|
91
|
+
const hemisphereLight = new THREE.HemisphereLight(0xffffbb, 0x080820, 0.6);
|
|
92
92
|
this.scene.add(hemisphereLight);
|
|
93
93
|
|
|
94
94
|
// Main directional light with ultra-high quality shadows
|
|
@@ -153,8 +153,8 @@ export class GpuThreeJS {
|
|
|
153
153
|
// Envmap setup is non-critical; silently skip on unsupported renderers
|
|
154
154
|
}
|
|
155
155
|
|
|
156
|
-
//
|
|
157
|
-
this.scene.fog = new THREE.FogExp2(0x202050, 0.
|
|
156
|
+
// Atmospheric fog with subtle color
|
|
157
|
+
this.scene.fog = new THREE.FogExp2(0x202050, 0.005);
|
|
158
158
|
|
|
159
159
|
// Store lights for dynamic control
|
|
160
160
|
this.lights = {
|
|
@@ -541,7 +541,11 @@ export class GpuThreeJS {
|
|
|
541
541
|
|
|
542
542
|
// N64-style post-processing
|
|
543
543
|
enablePixelation(factor = 2) {
|
|
544
|
-
|
|
544
|
+
if (factor <= 0) {
|
|
545
|
+
this.renderer.setPixelRatio(window.devicePixelRatio || 1);
|
|
546
|
+
} else {
|
|
547
|
+
this.renderer.setPixelRatio(1 / factor);
|
|
548
|
+
}
|
|
545
549
|
}
|
|
546
550
|
|
|
547
551
|
enableDithering(enabled = true) {
|
|
@@ -551,9 +555,9 @@ export class GpuThreeJS {
|
|
|
551
555
|
enableBloom(enabled = true) {
|
|
552
556
|
// For now, just increase exposure for bloom-like effect
|
|
553
557
|
if (enabled) {
|
|
554
|
-
this.renderer.toneMappingExposure = 1.
|
|
558
|
+
this.renderer.toneMappingExposure = 1.2;
|
|
555
559
|
} else {
|
|
556
|
-
this.renderer.toneMappingExposure = 1.
|
|
560
|
+
this.renderer.toneMappingExposure = 1.0;
|
|
557
561
|
}
|
|
558
562
|
}
|
|
559
563
|
|
|
@@ -621,7 +625,7 @@ export class GpuThreeJS {
|
|
|
621
625
|
|
|
622
626
|
// Fog animation for atmospheric depth
|
|
623
627
|
if (this.scene.fog && this.scene.fog.density) {
|
|
624
|
-
this.scene.fog.density = 0.
|
|
628
|
+
this.scene.fog.density = 0.005 + Math.sin(time * 0.5) * 0.001;
|
|
625
629
|
}
|
|
626
630
|
}
|
|
627
631
|
|
package/runtime/ui.js
CHANGED
|
@@ -83,8 +83,8 @@ export function uiApi(gpu, g) {
|
|
|
83
83
|
removeButton: ctx.removeButton,
|
|
84
84
|
clearButtons: ctx.clearButtons,
|
|
85
85
|
|
|
86
|
-
// Progress bars
|
|
87
|
-
|
|
86
|
+
// Progress bars (as uiProgressBar to avoid overwriting the api-2d drawProgressBar)
|
|
87
|
+
uiProgressBar: ctx.drawProgressBar,
|
|
88
88
|
|
|
89
89
|
// Advanced shapes
|
|
90
90
|
drawRoundedRect: ctx.drawRoundedRect,
|
package/src/main.js
CHANGED
|
@@ -21,6 +21,8 @@ import { createFullscreenButton } from '../runtime/fullscreen-button.js';
|
|
|
21
21
|
import { storeApi } from '../runtime/store.js';
|
|
22
22
|
import { api2d } from '../runtime/api-2d.js';
|
|
23
23
|
import { presetsApi } from '../runtime/api-presets.js';
|
|
24
|
+
import { generativeApi } from '../runtime/api-generative.js';
|
|
25
|
+
import { gameUtilsApi } from '../runtime/api-gameutils.js';
|
|
24
26
|
|
|
25
27
|
const canvas = document.getElementById('screen');
|
|
26
28
|
|
|
@@ -53,6 +55,8 @@ const vxApi = voxelApi(gpu);
|
|
|
53
55
|
const storeApiInst = storeApi();
|
|
54
56
|
const api2dInst = api2d(gpu);
|
|
55
57
|
const presetsInst = presetsApi(gpu);
|
|
58
|
+
const genArtInst = generativeApi(gpu);
|
|
59
|
+
const gameUtilsInst = gameUtilsApi();
|
|
56
60
|
|
|
57
61
|
// Create UI API - needs to be created after api is fully initialized
|
|
58
62
|
let uiApiInstance;
|
|
@@ -76,6 +80,8 @@ vxApi.exposeTo(g);
|
|
|
76
80
|
storeApiInst.exposeTo(g);
|
|
77
81
|
api2dInst.exposeTo(g);
|
|
78
82
|
presetsInst.exposeTo(g);
|
|
83
|
+
genArtInst.exposeTo(g);
|
|
84
|
+
gameUtilsInst.exposeTo(g);
|
|
79
85
|
|
|
80
86
|
// Now create UI API after g has rgba8 and other functions
|
|
81
87
|
uiApiInstance = uiApi(gpu, g);
|
|
@@ -152,6 +158,8 @@ function loop() {
|
|
|
152
158
|
storeApiInst.tick(dt);
|
|
153
159
|
// Auto-animate skybox if enabled
|
|
154
160
|
skyApi._tick(dt);
|
|
161
|
+
// Advance generative art frame counter
|
|
162
|
+
genArtInst._advanceFrame();
|
|
155
163
|
// Update post-processing shader uniforms (time, etc.)
|
|
156
164
|
fxApi.update(dt);
|
|
157
165
|
|
|
@@ -241,6 +249,11 @@ const gameMap = {
|
|
|
241
249
|
demoscene: '/examples/demoscene/code.js',
|
|
242
250
|
'space-combat': '/examples/star-fox-nova-3d/code.js',
|
|
243
251
|
minecraft: '/examples/minecraft-demo/code.js',
|
|
252
|
+
boids: '/examples/boids-flocking/code.js',
|
|
253
|
+
'game-of-life': '/examples/game-of-life-3d/code.js',
|
|
254
|
+
nature: '/examples/nature-explorer-3d/code.js',
|
|
255
|
+
dungeon: '/examples/dungeon-crawler-3d/code.js',
|
|
256
|
+
wizardry: '/examples/wizardry-3d/code.js',
|
|
244
257
|
};
|
|
245
258
|
|
|
246
259
|
// Map demo names (from ?demo= URL param) to paths
|
|
@@ -273,6 +286,13 @@ const demoMap = {
|
|
|
273
286
|
'space-combat-3d': '/examples/space-combat-3d/code.js',
|
|
274
287
|
'model-viewer-3d': '/examples/model-viewer-3d/code.js',
|
|
275
288
|
'3d-advanced': '/examples/3d-advanced/code.js',
|
|
289
|
+
'pbr-showcase': '/examples/pbr-showcase/code.js',
|
|
290
|
+
'generative-art': '/examples/generative-art/code.js',
|
|
291
|
+
'boids-flocking': '/examples/boids-flocking/code.js',
|
|
292
|
+
'game-of-life-3d': '/examples/game-of-life-3d/code.js',
|
|
293
|
+
'nature-explorer-3d': '/examples/nature-explorer-3d/code.js',
|
|
294
|
+
'dungeon-crawler-3d': '/examples/dungeon-crawler-3d/code.js',
|
|
295
|
+
'wizardry-3d': '/examples/wizardry-3d/code.js',
|
|
276
296
|
};
|
|
277
297
|
|
|
278
298
|
// default cart - load from URL param or default to space-harrier-3d
|