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
|
@@ -0,0 +1,386 @@
|
|
|
1
|
+
# Nova64 Voxel Engine - Quick Reference
|
|
2
|
+
|
|
3
|
+
## 🎮 Getting Started (3 lines)
|
|
4
|
+
|
|
5
|
+
```javascript
|
|
6
|
+
export function init() {
|
|
7
|
+
updateVoxelWorld(0, 0); // Generate world
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export function update(dt) {
|
|
11
|
+
if (Math.random() < 0.1) updateVoxelWorld(playerX, playerZ);
|
|
12
|
+
}
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## 📦 Block Types
|
|
16
|
+
|
|
17
|
+
```javascript
|
|
18
|
+
BLOCK_TYPES.AIR; // 0 - Empty
|
|
19
|
+
BLOCK_TYPES.GRASS; // 1 - Green grass
|
|
20
|
+
BLOCK_TYPES.DIRT; // 2 - Brown dirt
|
|
21
|
+
BLOCK_TYPES.STONE; // 3 - Gray stone
|
|
22
|
+
BLOCK_TYPES.SAND; // 4 - Yellow sand
|
|
23
|
+
BLOCK_TYPES.WATER; // 5 - Blue water (transparent)
|
|
24
|
+
BLOCK_TYPES.WOOD; // 6 - Tree trunk
|
|
25
|
+
BLOCK_TYPES.LEAVES; // 7 - Green leaves
|
|
26
|
+
BLOCK_TYPES.COBBLESTONE; // 8 - Gray cobble
|
|
27
|
+
BLOCK_TYPES.PLANKS; // 9 - Wood planks
|
|
28
|
+
BLOCK_TYPES.GLASS; // 10 - Transparent
|
|
29
|
+
BLOCK_TYPES.BRICK; // 11 - Red brick
|
|
30
|
+
BLOCK_TYPES.SNOW; // 12 - White snow
|
|
31
|
+
BLOCK_TYPES.ICE; // 13 - Ice
|
|
32
|
+
BLOCK_TYPES.BEDROCK; // 14 - Bottom layer
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## 🔧 Core Functions
|
|
36
|
+
|
|
37
|
+
### World Management
|
|
38
|
+
|
|
39
|
+
```javascript
|
|
40
|
+
// Load chunks around player (call in update loop)
|
|
41
|
+
updateVoxelWorld(playerX, playerZ);
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### Block Get/Set
|
|
45
|
+
|
|
46
|
+
```javascript
|
|
47
|
+
// Get block type at position
|
|
48
|
+
const block = getVoxelBlock(x, y, z);
|
|
49
|
+
|
|
50
|
+
// Place block
|
|
51
|
+
setVoxelBlock(x, y, z, BLOCK_TYPES.STONE);
|
|
52
|
+
|
|
53
|
+
// Remove block
|
|
54
|
+
setVoxelBlock(x, y, z, BLOCK_TYPES.AIR);
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### Raycasting (Mining/Building)
|
|
58
|
+
|
|
59
|
+
```javascript
|
|
60
|
+
const result = raycastVoxelBlock(
|
|
61
|
+
[playerX, playerY, playerZ], // Origin
|
|
62
|
+
[dirX, dirY, dirZ], // Direction (normalized)
|
|
63
|
+
10 // Max distance
|
|
64
|
+
);
|
|
65
|
+
|
|
66
|
+
if (result.hit) {
|
|
67
|
+
const [x, y, z] = result.position;
|
|
68
|
+
console.log(`Hit ${result.blockType} at ${x},${y},${z}`);
|
|
69
|
+
console.log(`Distance: ${result.distance}`);
|
|
70
|
+
}
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### Collision Detection
|
|
74
|
+
|
|
75
|
+
```javascript
|
|
76
|
+
const isColliding = checkVoxelCollision(
|
|
77
|
+
[x, y, z], // Center position
|
|
78
|
+
0.3 // Radius (half-size)
|
|
79
|
+
);
|
|
80
|
+
|
|
81
|
+
// Player collision example
|
|
82
|
+
const onGround = checkVoxelCollision([player.x, player.y, player.z], 0.3);
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### Structure Generation
|
|
86
|
+
|
|
87
|
+
```javascript
|
|
88
|
+
// Place a tree
|
|
89
|
+
placeVoxelTree(x, y, z);
|
|
90
|
+
|
|
91
|
+
// Forest
|
|
92
|
+
for (let i = 0; i < 20; i++) {
|
|
93
|
+
const x = Math.random() * 200 - 100;
|
|
94
|
+
const z = Math.random() * 200 - 100;
|
|
95
|
+
placeVoxelTree(x, 35, z);
|
|
96
|
+
}
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
## 💡 Common Patterns
|
|
100
|
+
|
|
101
|
+
### Mining System
|
|
102
|
+
|
|
103
|
+
```javascript
|
|
104
|
+
// In update()
|
|
105
|
+
const lookDir = getCameraDirection();
|
|
106
|
+
const eyePos = [player.x, player.y + 1.6, player.z];
|
|
107
|
+
const result = raycastVoxelBlock(eyePos, lookDir, 10);
|
|
108
|
+
|
|
109
|
+
if (result.hit && isMousePressed(0)) {
|
|
110
|
+
const [x, y, z] = result.position;
|
|
111
|
+
setVoxelBlock(x, y, z, BLOCK_TYPES.AIR);
|
|
112
|
+
console.log('Block broken!');
|
|
113
|
+
}
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
### Building System
|
|
117
|
+
|
|
118
|
+
```javascript
|
|
119
|
+
// In update()
|
|
120
|
+
const result = raycastVoxelBlock(eyePos, lookDir, 10);
|
|
121
|
+
|
|
122
|
+
if (result.hit && isMousePressed(2)) {
|
|
123
|
+
// Place adjacent to hit block
|
|
124
|
+
const [x, y, z] = result.position;
|
|
125
|
+
const placeX = x - Math.sign(lookDir[0]);
|
|
126
|
+
const placeY = y - Math.sign(lookDir[1]);
|
|
127
|
+
const placeZ = z - Math.sign(lookDir[2]);
|
|
128
|
+
|
|
129
|
+
setVoxelBlock(placeX, placeY, placeZ, selectedBlockType);
|
|
130
|
+
}
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
### Player Physics
|
|
134
|
+
|
|
135
|
+
```javascript
|
|
136
|
+
// Gravity
|
|
137
|
+
player.velY -= 20 * dt;
|
|
138
|
+
|
|
139
|
+
// Apply movement
|
|
140
|
+
player.y += player.velY * dt;
|
|
141
|
+
|
|
142
|
+
// Ground collision
|
|
143
|
+
const onGround = checkVoxelCollision([player.x, player.y, player.z], 0.3);
|
|
144
|
+
if (onGround && player.velY <= 0) {
|
|
145
|
+
player.y = Math.floor(player.y) + 1;
|
|
146
|
+
player.velY = 0;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
// Jump
|
|
150
|
+
if (isKeyPressed('Space') && onGround) {
|
|
151
|
+
player.velY = 8.0;
|
|
152
|
+
}
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
### Find Ground Height
|
|
156
|
+
|
|
157
|
+
```javascript
|
|
158
|
+
function getGroundHeight(x, z) {
|
|
159
|
+
for (let y = 63; y >= 0; y--) {
|
|
160
|
+
const block = getVoxelBlock(x, y, z);
|
|
161
|
+
if (block !== BLOCK_TYPES.AIR && block !== BLOCK_TYPES.WATER) {
|
|
162
|
+
return y + 1;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
return 0;
|
|
166
|
+
}
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
### Build Structure
|
|
170
|
+
|
|
171
|
+
```javascript
|
|
172
|
+
// Simple house
|
|
173
|
+
function buildHouse(x, y, z) {
|
|
174
|
+
// Floor (8x8)
|
|
175
|
+
for (let dx = 0; dx < 8; dx++) {
|
|
176
|
+
for (let dz = 0; dz < 8; dz++) {
|
|
177
|
+
setVoxelBlock(x + dx, y, z + dz, BLOCK_TYPES.PLANKS);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
// Walls (4 blocks high)
|
|
182
|
+
for (let dy = 1; dy <= 4; dy++) {
|
|
183
|
+
// Front and back
|
|
184
|
+
for (let dx = 0; dx < 8; dx++) {
|
|
185
|
+
setVoxelBlock(x + dx, y + dy, z, BLOCK_TYPES.WOOD);
|
|
186
|
+
setVoxelBlock(x + dx, y + dy, z + 7, BLOCK_TYPES.WOOD);
|
|
187
|
+
}
|
|
188
|
+
// Left and right
|
|
189
|
+
for (let dz = 0; dz < 8; dz++) {
|
|
190
|
+
setVoxelBlock(x, y + dy, z + dz, BLOCK_TYPES.WOOD);
|
|
191
|
+
setVoxelBlock(x + 7, y + dy, z + dz, BLOCK_TYPES.WOOD);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
// Roof
|
|
196
|
+
for (let dx = 0; dx < 8; dx++) {
|
|
197
|
+
for (let dz = 0; dz < 8; dz++) {
|
|
198
|
+
setVoxelBlock(x + dx, y + 5, z + dz, BLOCK_TYPES.BRICK);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
// Door (2 blocks high)
|
|
203
|
+
setVoxelBlock(x + 3, y + 1, z, BLOCK_TYPES.AIR);
|
|
204
|
+
setVoxelBlock(x + 3, y + 2, z, BLOCK_TYPES.AIR);
|
|
205
|
+
}
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
## 🎯 Minimal Minecraft Clone
|
|
209
|
+
|
|
210
|
+
```javascript
|
|
211
|
+
const player = {
|
|
212
|
+
pos: [8, 40, 8],
|
|
213
|
+
vel: [0, 0, 0],
|
|
214
|
+
rot: [0, 0],
|
|
215
|
+
selectedBlock: BLOCK_TYPES.GRASS,
|
|
216
|
+
};
|
|
217
|
+
|
|
218
|
+
let locked = false;
|
|
219
|
+
|
|
220
|
+
export function init() {
|
|
221
|
+
setAmbientLight(0x666666);
|
|
222
|
+
updateVoxelWorld(0, 0);
|
|
223
|
+
|
|
224
|
+
const canvas = document.getElementById('screen');
|
|
225
|
+
canvas.addEventListener('click', () => canvas.requestPointerLock());
|
|
226
|
+
document.addEventListener('pointerlockchange', () => {
|
|
227
|
+
locked = document.pointerLockElement === canvas;
|
|
228
|
+
});
|
|
229
|
+
canvas.addEventListener('mousemove', e => {
|
|
230
|
+
if (locked) {
|
|
231
|
+
player.rot[0] -= e.movementX * 0.002;
|
|
232
|
+
player.rot[1] -= e.movementY * 0.002;
|
|
233
|
+
}
|
|
234
|
+
});
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
export function update(dt) {
|
|
238
|
+
if (!locked) return;
|
|
239
|
+
|
|
240
|
+
// Movement
|
|
241
|
+
const speed = 4;
|
|
242
|
+
if (isKeyDown('KeyW')) player.vel[2] -= speed * dt;
|
|
243
|
+
if (isKeyDown('KeyS')) player.vel[2] += speed * dt;
|
|
244
|
+
if (isKeyDown('KeyA')) player.vel[0] -= speed * dt;
|
|
245
|
+
if (isKeyDown('KeyD')) player.vel[0] += speed * dt;
|
|
246
|
+
|
|
247
|
+
// Physics
|
|
248
|
+
player.vel[1] -= 20 * dt;
|
|
249
|
+
if (isKeyPressed('Space') && checkVoxelCollision(player.pos, 0.3)) {
|
|
250
|
+
player.vel[1] = 8;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
player.pos[0] += player.vel[0] * dt;
|
|
254
|
+
player.pos[1] += player.vel[1] * dt;
|
|
255
|
+
player.pos[2] += player.vel[2] * dt;
|
|
256
|
+
|
|
257
|
+
if (checkVoxelCollision(player.pos, 0.3)) {
|
|
258
|
+
player.pos[1] = Math.floor(player.pos[1]) + 1;
|
|
259
|
+
player.vel[1] = 0;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
player.vel[0] *= 0.8;
|
|
263
|
+
player.vel[2] *= 0.8;
|
|
264
|
+
|
|
265
|
+
// Camera
|
|
266
|
+
setCameraPosition(player.pos[0], player.pos[1] + 1.6, player.pos[2]);
|
|
267
|
+
const lookDir = [
|
|
268
|
+
-Math.sin(player.rot[0]) * Math.cos(player.rot[1]),
|
|
269
|
+
Math.sin(player.rot[1]),
|
|
270
|
+
-Math.cos(player.rot[0]) * Math.cos(player.rot[1]),
|
|
271
|
+
];
|
|
272
|
+
setCameraLookAt(lookDir);
|
|
273
|
+
|
|
274
|
+
// Block interaction
|
|
275
|
+
const result = raycastVoxelBlock(
|
|
276
|
+
[player.pos[0], player.pos[1] + 1.6, player.pos[2]],
|
|
277
|
+
lookDir,
|
|
278
|
+
10
|
|
279
|
+
);
|
|
280
|
+
|
|
281
|
+
if (result.hit) {
|
|
282
|
+
const [x, y, z] = result.position;
|
|
283
|
+
if (isMousePressed(0)) setVoxelBlock(x, y, z, BLOCK_TYPES.AIR);
|
|
284
|
+
if (isMousePressed(2)) setVoxelBlock(x, y, z, player.selectedBlock);
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
// World update
|
|
288
|
+
if (Math.random() < 0.1) updateVoxelWorld(player.pos[0], player.pos[2]);
|
|
289
|
+
|
|
290
|
+
// Block selection
|
|
291
|
+
for (let i = 1; i <= 9; i++) {
|
|
292
|
+
if (isKeyPressed(i.toString())) player.selectedBlock = i;
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
export function draw() {
|
|
297
|
+
cls();
|
|
298
|
+
if (locked) {
|
|
299
|
+
rectfill(318, 179, 322, 181, rgba8(1, 1, 1, 1));
|
|
300
|
+
rectfill(319, 178, 321, 182, rgba8(1, 1, 1, 1));
|
|
301
|
+
}
|
|
302
|
+
print(`FPS: ${Math.round(1 / getDeltaTime())}`, 4, 4, rgba8(1, 1, 1, 1));
|
|
303
|
+
}
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
## ⚡ Performance Tips
|
|
307
|
+
|
|
308
|
+
### ✅ DO:
|
|
309
|
+
|
|
310
|
+
```javascript
|
|
311
|
+
// Update chunks occasionally
|
|
312
|
+
if (frameCount % 10 === 0) {
|
|
313
|
+
updateVoxelWorld(playerX, playerZ);
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
// Use collision detection
|
|
317
|
+
const onGround = checkVoxelCollision(pos, 0.3);
|
|
318
|
+
|
|
319
|
+
// Batch block changes
|
|
320
|
+
for (let i = 0; i < 100; i++) {
|
|
321
|
+
setVoxelBlock(x + i, y, z, type);
|
|
322
|
+
}
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
### ❌ DON'T:
|
|
326
|
+
|
|
327
|
+
```javascript
|
|
328
|
+
// Don't update every frame
|
|
329
|
+
export function update() {
|
|
330
|
+
updateVoxelWorld(x, z); // TOO EXPENSIVE!
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
// Don't check many blocks manually
|
|
334
|
+
for (let x = -10; x < 10; x++) {
|
|
335
|
+
for (let z = -10; z < 10; z++) {
|
|
336
|
+
getVoxelBlock(x, y, z); // Use collision instead!
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
## 🌍 World Info
|
|
342
|
+
|
|
343
|
+
- **Chunk Size**: 16×64×16 blocks
|
|
344
|
+
- **Render Distance**: 4 chunks (64 blocks)
|
|
345
|
+
- **World Height**: 0-63 blocks
|
|
346
|
+
- **Bedrock Layer**: Y=0 (indestructible)
|
|
347
|
+
- **Water Level**: Y=30
|
|
348
|
+
- **Surface**: Y=20-52 (varies with noise)
|
|
349
|
+
- **Infinite**: Chunks generate on demand
|
|
350
|
+
|
|
351
|
+
## 🎨 Terrain Features
|
|
352
|
+
|
|
353
|
+
- **Height**: Multi-octave Perlin noise
|
|
354
|
+
- **Biomes**: Grass, Sand, Snow (based on temperature/moisture)
|
|
355
|
+
- **Caves**: 3D noise threshold underground
|
|
356
|
+
- **Trees**: Procedural with random height
|
|
357
|
+
- **Water**: Fills below Y=30
|
|
358
|
+
|
|
359
|
+
## 🔍 Debugging
|
|
360
|
+
|
|
361
|
+
```javascript
|
|
362
|
+
// Check block under player
|
|
363
|
+
const block = getVoxelBlock(Math.floor(player.x), Math.floor(player.y) - 1, Math.floor(player.z));
|
|
364
|
+
console.log(`Standing on: ${block}`);
|
|
365
|
+
|
|
366
|
+
// Draw debug info
|
|
367
|
+
print(`Pos: ${Math.floor(player.x)}, ${Math.floor(player.y)}, ${Math.floor(player.z)}`, 4, 4);
|
|
368
|
+
print(`Chunks loaded: ${chunkCount}`, 4, 12);
|
|
369
|
+
```
|
|
370
|
+
|
|
371
|
+
## 📊 Performance Costs
|
|
372
|
+
|
|
373
|
+
| Operation | Cost | Notes |
|
|
374
|
+
| ----------------------- | ------ | -------------------- |
|
|
375
|
+
| `updateVoxelWorld()` | High | Call every 10 frames |
|
|
376
|
+
| `setVoxelBlock()` | Medium | Auto-updates chunk |
|
|
377
|
+
| `getVoxelBlock()` | Low | Fast lookup |
|
|
378
|
+
| `raycastVoxelBlock()` | Low | <0.1ms per ray |
|
|
379
|
+
| `checkVoxelCollision()` | Low | Checks ~8 blocks |
|
|
380
|
+
| `placeVoxelTree()` | Medium | Places ~100 blocks |
|
|
381
|
+
|
|
382
|
+
## 🚀 Ready to Build!
|
|
383
|
+
|
|
384
|
+
Check out the full Minecraft demo in `examples/minecraft-demo/` for a complete working game!
|
|
385
|
+
|
|
386
|
+
See `VOXEL_ENGINE_GUIDE.md` for detailed documentation and advanced examples.
|