Minecraft-style voxel world with greedy meshing, lighting, fluids, entities, ECS, schematics, and custom block shapes
The Nova64 Voxel Engine provides a complete block-world system rivaling noa-engine, with 50+ API functions.
| Constant | ID | Description |
|---|---|---|
BLOCK_TYPES.AIR | 0 | Empty space |
BLOCK_TYPES.GRASS | 1 | Grass block |
BLOCK_TYPES.DIRT | 2 | Dirt |
BLOCK_TYPES.STONE | 3 | Stone |
BLOCK_TYPES.SAND | 4 | Sand |
BLOCK_TYPES.WATER | 5 | Water (transparent, fluid) |
BLOCK_TYPES.WOOD | 6 | Wood log |
BLOCK_TYPES.LEAVES | 7 | Leaves (transparent) |
BLOCK_TYPES.COBBLESTONE | 8 | Cobblestone |
BLOCK_TYPES.PLANKS | 9 | Wooden planks |
BLOCK_TYPES.GLASS | 10 | Glass (transparent) |
BLOCK_TYPES.BRICK | 11 | Brick |
BLOCK_TYPES.SNOW | 12 | Snow |
BLOCK_TYPES.ICE | 13 | Ice (transparent) |
BLOCK_TYPES.BEDROCK | 14 | Bedrock (indestructible) |
BLOCK_TYPES.COAL_ORE | 15 | Coal ore |
BLOCK_TYPES.IRON_ORE | 16 | Iron ore |
BLOCK_TYPES.GOLD_ORE | 17 | Gold ore |
BLOCK_TYPES.DIAMOND_ORE | 18 | Diamond ore |
BLOCK_TYPES.GRAVEL | 19 | Gravel |
BLOCK_TYPES.CLAY | 20 | Clay |
BLOCK_TYPES.TORCH | 21 | Torch (light emitter, non-solid) |
BLOCK_TYPES.GLOWSTONE | 22 | Glowstone (max light) |
BLOCK_TYPES.LAVA | 23 | Lava (fluid, light emitter) |
BLOCK_TYPES.OBSIDIAN | 24 | Obsidian |
BLOCK_TYPES.MOSSY_COBBLESTONE | 25 | Mossy cobblestone |
| Constant | ID | Shape | Description |
|---|---|---|---|
BLOCK_TYPES.STONE_SLAB | 26 | slab_bottom | Half-height stone slab |
BLOCK_TYPES.STONE_SLAB_TOP | 27 | slab_top | Upper half stone slab |
BLOCK_TYPES.PLANK_SLAB | 28 | slab_bottom | Half-height plank slab |
BLOCK_TYPES.STONE_STAIR | 29 | stair | Stone staircase |
BLOCK_TYPES.PLANK_STAIR | 30 | stair | Plank staircase |
BLOCK_TYPES.FENCE | 31 | fence | Thin fence post |
BLOCK_TYPES.FLOWER | 32 | cross | Flower (non-solid) |
BLOCK_TYPES.TALL_GRASS | 33 | cross | Tall grass (non-solid) |
BLOCK_TYPES.BRICK_SLAB | 34 | slab_bottom | Half-height brick slab |
BLOCK_TYPES.BRICK_STAIR | 35 | stair | Brick staircase |
Configure world generation parameters. Call before generating chunks.
configureVoxelWorld({
seed: 42,
renderDistance: 6,
seaLevel: 62,
lodLevels: [4, 8],
generateTerrain: (chunk, ctx) => {
// Custom flat world
for (let x = 0; x < ctx.CHUNK_SIZE; x++)
for (let z = 0; z < ctx.CHUNK_SIZE; z++)
for (let y = 0; y < 60; y++)
chunk.setBlock(x, y, z, ctx.BLOCK_TYPES.STONE);
},
});
Load/unload chunks around the player. Call periodically in update().
if (frameCount % 10 === 0) updateVoxelWorld(player.x, player.z);
Synchronously load all chunks in render distance. Useful for initial world setup in init().
Clear all chunks, entities, and meshes. Resets world to empty state.
Returns the current world configuration object.
Get the block type at world coordinates.
Place or remove a block. Automatically updates chunk meshes and propagates lighting.
setVoxelBlock(10, 65, 10, BLOCK_TYPES.STONE); // Place stone
setVoxelBlock(10, 65, 10, BLOCK_TYPES.AIR); // Remove block
setVoxelBlock(5, 60, 5, BLOCK_TYPES.STONE_SLAB); // Place slab
Returns the Y of the highest non-air, non-water block at (x, z). Useful for spawning.
Returns the biome name at world position. One of: "Frozen Tundra", "Taiga", "Desert", "Jungle", "Savanna", "Forest", "Snowy Hills", "Plains".
Register a custom block type for your cart.
registerVoxelBlock(100, {
name: 'crystal',
color: 0xff00ff,
solid: true,
transparent: true,
lightEmit: 10,
shape: 'slab_bottom',
});
Blocks can have non-cube shapes. Non-cube shapes skip greedy mesh merging and emit custom geometry. They do not occlude neighboring cube faces. Collision uses shape-specific bounding boxes.
| Shape | Geometry | Bounding Box |
|---|---|---|
cube | Full block (default) | [0,0,0, 1,1,1] |
slab_bottom | Half-height box, bottom | [0,0,0, 1,0.5,1] |
slab_top | Half-height box, top | [0,0.5,0, 1,1,1] |
stair | Bottom slab + back upper half | [0,0,0, 1,1,1] |
fence | Thin centered post | [0.375,0,0.375, 0.625,1,0.625] |
cross | Two diagonal X-quads | [0.15,0,0.15, 0.85,1,0.85] |
Returns the shape string for a block type.
Returns the collision bounding box [minX, minY, minZ, maxX, maxY, maxZ] relative to block origin (0–1 range).
Returns true if the block shape is 'cube'. Non-cube blocks don't occlude neighbor faces.
DDA voxel traversal — pixel-perfect block targeting. Returns hit info with block position, face normal, and adjacent block for placing.
const result = raycastVoxelBlock([px, py+1.6, pz], lookDir, 10);
if (result.hit) {
// Break block
setVoxelBlock(...result.position, BLOCK_TYPES.AIR);
// Place block on adjacent face
setVoxelBlock(...result.adjacent, BLOCK_TYPES.STONE);
}
AABB collision check against solid blocks (excluding fluids). Uses shape-aware bounding boxes for non-cube blocks.
Check if position is inside a fluid block (water/lava).
Swept AABB physics with per-axis resolution, auto-step (0.6 blocks), water drag, and ground detection.
const result = moveVoxelEntity(
player.pos,
player.vel,
[0.6, 1.8, 0.6], // width, height, depth
dt
);
player.pos = result.position;
player.vel = result.velocity;
player.grounded = result.grounded;
BFS flood-fill light propagation with sky light (downward) and block light (torches, glowstone, lava). Smooth per-vertex interpolation combined with ambient occlusion.
Returns the light level (0–15) at a position. Max of sky light and block light.
Set time of day (0.0–1.0). Sky light brightness scales with time for day/night cycle.
let time = 0;
export function update(dt) {
time = (time + dt * 0.01) % 1;
setVoxelDayTime(time); // Smooth day/night
}
Water spreads 7 blocks horizontally with BFS flow. Lava spreads 3 blocks. Fluids retract when source is removed.
Place a fluid source block. Flow propagation begins automatically.
setVoxelFluidSource(10, 70, 10, BLOCK_TYPES.WATER); // Water source
setVoxelFluidSource(20, 70, 20, BLOCK_TYPES.LAVA); // Lava source
Remove a fluid source. Flowing blocks retract via BFS.
Returns the fluid level at a position (0 = full, 7 = thinnest, -1 = no fluid).
Spawn entities with physics, AI, health, and spatial hashing for efficient radius queries.
Spawn a new entity in the voxel world.
Remove entity and its mesh from the world.
Retrieve an entity by ID.
Modify entity health. Entity removed when health reaches 0.
Tick all entity AI callbacks and physics. Call in update().
Find all entities within radius using spatial hash (O(1) bucket lookup).
Query entities by type or get total count.
Attach arbitrary components to entities for flexible game logic. Query by component sets. Spawn from predefined archetypes.
Attach or update a component on an entity.
setVoxelEntityComponent(id, 'inventory', { slots: 10, items: [] });
setVoxelEntityComponent(id, 'hostile', { aggroRange: 16 });
Get component data. Returns undefined if not present.
Check if entity has a specific component.
Remove a component from an entity.
Find all entities that have all required components, with optional filter function.
// All entities with 'hostile' and 'ai' components
const enemies = queryVoxelEntities(['hostile', 'ai']);
// With filter
const nearbyEnemies = queryVoxelEntities(['hostile'], e =>
dist(e.position, player.pos) < 32
);
Define a reusable entity template with default components.
Spawn an entity from a registered archetype. Built-in archetypes: mob, item, projectile, npc, vehicle.
const zombie = spawnVoxelEntityFromArchetype('mob', [10, 65, 10], {
health: 20,
});
setVoxelEntityComponent(zombie.id, 'hostile', { damage: 3 });
A* pathfinding on the voxel grid. Returns an array of [x, y, z] positions, or null if no path found.
Export a rectangular region as an RLE-compressed ArrayBuffer. Header: [version, sizeX, sizeY, sizeZ] + RLE body.
Import a schematic at the given position.
Export the entire world (all loaded chunks) as a JSON object with seed, config, and chunk data.
Import a world from a previously exported JSON object. Replaces current world state.
// Export a 10x10x10 building
const schematic = exportVoxelRegion(0, 60, 0, 9, 69, 9);
// Paste it somewhere else
importVoxelRegion(schematic, 100, 60, 100);
// Paste without overwriting existing blocks
importVoxelRegion(schematic, 200, 60, 200, { skipAir: true });
Save all modified chunks to IndexedDB under the given name.
Load a previously saved world from IndexedDB.
List all saved world names in IndexedDB.
Delete a saved world from IndexedDB.
Toggle the procedural texture atlas (27 pixel-art tiles). Enabled: textured blocks. Disabled: vertex-color blocks.
Load a custom texture atlas image. Mapping defines which tile index goes to which block face.
Multi-octave 2D fractal simplex noise. Returns 0–1.
Multi-octave 3D fractal simplex noise. Returns 0–1. Use for caves, ore veins, 3D effects.
Generate a tree (wood trunk + leaf canopy) at the specified base position. Biome-appropriate variety: oak, birch, spruce, jungle, acacia.
| Category | Functions |
|---|---|
| World | configureVoxelWorld, updateVoxelWorld, forceLoadVoxelChunks, resetVoxelWorld, getVoxelConfig |
| Blocks | getVoxelBlock, setVoxelBlock, getVoxelHighestBlock, getVoxelBiome, registerVoxelBlock |
| Shapes | getVoxelBlockShape, getVoxelBlockBoundingBox, isVoxelBlockFullCube, VOXEL_SHAPE_BBOXES |
| Raycast & Collision | raycastVoxelBlock, checkVoxelCollision, checkVoxelFluid, moveVoxelEntity |
| Lighting | getVoxelLightLevel, setVoxelDayTime |
| Fluids | setVoxelFluidSource, removeVoxelFluidSource, getVoxelFluidLevel |
| Entities | spawnVoxelEntity, removeVoxelEntity, getVoxelEntity, damageVoxelEntity, healVoxelEntity, updateVoxelEntities, getVoxelEntitiesInRadius, getVoxelEntitiesByType, getVoxelEntityCount, cleanupVoxelEntities |
| ECS | setVoxelEntityComponent, getVoxelEntityComponent, hasVoxelEntityComponent, removeVoxelEntityComponent, queryVoxelEntities, createVoxelEntityArchetype, spawnVoxelEntityFromArchetype, findVoxelPath |
| Schematics | exportVoxelRegion, importVoxelRegion, exportVoxelWorldJSON, importVoxelWorldJSON |
| Persistence | saveVoxelWorld, loadVoxelWorld, listVoxelWorlds, deleteVoxelWorld |
| Textures | enableVoxelTextures, loadVoxelTextureAtlas |
| Noise | simplexNoise2D, simplexNoise3D |
| Structures | placeVoxelTree |