• Stars
    star
    1,269
  • Rank 37,079 (Top 0.8 %)
  • Language
    JavaScript
  • License
    BSD 3-Clause "New...
  • Created almost 12 years ago
  • Updated almost 7 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

3D HTML5 voxel game engine

voxel-engine

A voxel engine in javascript using three.js

Learn more at http://voxeljs.com

hello world template repo: http://github.com/maxogden/voxel-hello-world

example

var createGame = require('voxel-engine')
var game = createGame()
game.appendTo(document.body)

contributing

voxel-engine is an OPEN Open Source Project. This means that:

Individuals making significant and valuable contributions are given commit-access to the project to contribute as they see fit. This project is more like an open wiki than a standard guarded open source project.

See the CONTRIBUTING.md file for more details.

contributors

multiplex is only possible due to the excellent work of the following contributors:

Max OgdenGitHub/maxogdenTwitter/@maxogden
KumavisGitHub/kumavis
DeathcapGitHub/deathcap

API

require('voxel-engine')(options)

Returns a new game instance. options defaults to:

{
  texturePath: './textures/',
  generate: function(x,y,z) {
    return x*x+y*y+z*z <= 15*15 ? 1 : 0 // sphere world
  },
  materials: [['grass', 'dirt', 'grass_dirt'], 'brick', 'dirt'],
  materialFlatColor: false,
  chunkSize: 32,
  chunkDistance: 2,
  worldOrigin: [0, 0, 0],
  controls: { discreteFire: false },
  lightsDisabled: false,
  fogDisabled: false,
  generateChunks: true,
  mesher: voxel.meshers.culled,
  playerHeight: 1.62
}

Defaults

Player Size

Default 'player size' is a 1/2 block long/wide and 1.5 blocks high:

game.playerAABB().width() // => 12.5
game.playerAABB().height() // => 37.5

See implementation of Game.prototype.playerAABB for more details.

Terminology

  • block/voxel/cube -> mostly interchangeable. The minecrafty blocks you see on the screen.
  • chunk: is a piece of the world that contains voxels. try to pretend that these don't exist
  • AABB: bounding volume
  • voxeljs: not 100% consistent yet, 'voxel.js' also acceptable, but definitely not 'VoxelJS'.
  • dims: short for 'dimensions'. Perhaps obvious to some.
  • yaw: rotation around the vertical axis.
  • pitch: rotation around a horizontal axis.

Positions

  • x, z: horizontal plane
  • y: vertical plane

We try to always use arrays to represent vectors (aka positions)

  • [x, y, z]

Sometimes you may also see objects used, e.g. {x: 0, y: 0, z: 0}, this is because three.js uses objects for vectors.

Generating voxel worlds

Worlds have many chunks and chunks have many voxels. Chunks are cube shaped and are chunkSize x/y/z (default 32/32/32 - 32768 voxels per chunk). When the game starts it takes the worldOrigin and generates chunkDistance chunks in every x/y/z dimension (chunkDistance default of 2 means the game will render 2 chunks behind you, 2 in front etc for a total of 16 chunks.).

There is one major coordinate system in voxel.js: "game coordinates" (aka world coordinates)

  • every object added to a three.js scene gets a x/y/z position in game coordinates. in voxel-engine 1 game coordinate is the width of 1 voxel. when generating the world or interacting with individual voxels you can refer to voxels by coordinates. an example coordinate might be [34, -50, 302] which would mean starting from the worldOrigin 34 voxels over, 50 down and 302 forward

There are also some other less used coordinate systems that you should be aware of:

  • chunk coordinates: logically the same as voxel coordinates but for chunks. you probably won't need to use these as they are just used internally for rendering the world but it is good to know they exist.
  • local object coordinates: when you add items and other things to the game that aren't voxel terrain you introduce a new relative coordinate system inside each thing. so if you add a player 3d model body and you want to put a hat on the body you could position the hat relative to the body coordinates, etc

When you create a game you can also pass functions that the game will ask for voxel data. Here is an example generate function that makes a randomly textured cube world with a diameter of 20 voxels:

function generator(x, y, z) {
  if (x*x + y*y + z*z > 20*20) return 0
  return Math.floor(Math.random() * 4) + 1
}

The generate function will be called once for each voxel in the world. x, y and z will be values in game coordinates.

Generate a flat world 1 block high

Flat world is a nicer way to start (at least you can't fall off the edge). This places the player just above the ground.

var game = createGame({
  generate: function(x, y, z) {
    return y === 1 ? 1 : 0
  }
})

Interacting with the voxel world

Get current player position

game.controls.target().avatar.position()

This returns a THREE.js Vector3 object (which just means an object with 'x', 'y', and 'z').

Toggle a block on/off

game.setBlock(pos, 0) // off
game.setBlock(pos, 1) // on
game.setBlock(pos, 2) // on, with another material

Get the chunk at some world coordinates:

gameInstance.voxels.chunkAtPosition(position)

Get the voxel coordinates at some position (relative to that voxels chunk):

gameInstance.voxels.voxelVector(position)

Create a brand new voxel at some position.

Intended for use in first player contexts as it checks if a player is standing in the way of the new voxel. If you don't care about that then just use setBlock:

gameInstance.createBlock(pos, val)

val can be 0 or you can also use any single digit integer 0-9. These correspond to the materials array that you pass in to the game.

Set the value of a voxel at some position:

gameInstance.setBlock(pos, val)

Get the value of a voxel at some position:

gameInstance.getBlock(pos)

If you wanna see the lower level API for voxel data manipulation look at chunker.js inside the voxel module.

Raycast

shoots a ray and collides with voxels

gameInstance.raycastVoxels(start, position, distance)

if you just type gameInstance.raycastVoxels() it will default to using the current main camera position and direction, and default distance of 10, and epsilon of 1e-8

you will get back an object with the precise position, voxel position, direction, face normal and voxel value of the voxel that you intersected, or false if there was no collision

Create a new voxel adjacent to an existing voxel

first do a .raycastVoxels() then do gameInstance.createAdjacent(raycastResults, materialIndex)

Game events

There are a number of events you can listen to once you've instantiated a game. we use the node.js event emitter library which uses the following syntax for subscribing:

emitter.on('eventname', function(arg1, arg2, etc) {})

game.on('mouseup', function(pos) {}), game.on('mousedown', function(pos) {})

Captures mouse activity. pos is the game coordinate of the intersection of the voxel that you clicked on (if any)

game.on('tick', function(delta) {})

emits every time the game renders (usually no more than 60 times a second). delta is the time in milliseconds between this render and the last render

game.on('collision', function(item) {})

Called every tick when an item is colliding with the player. Callback is passed the item that is colliding.

game.voxelRegion.on('change', function(pos) {})

emits when you move between voxels. pos has x, y, and z voxel coordinates of the voxel you just entered

`game.chunkRegion.on('change', function(pos) {})``

emits when you move between chunks. pos has x, y, and z chunk coordinates of the chunk you just entered

game.on('renderChunk', function(chunk) {})

emits when a chunk is drawn (using the showChunk method). chunk is the full chunk object, which has the voxel data and a .position and .dims

game.on('missingChunk', function(chunkPosition) {})

emits when the player moves into range of a chunk that isn't loaded yet. if your game has generateChunks set to true it will automatically create the chunk and render it but if you are providing your own chunk generation then you can use this to hook into the game.

game.on('dirtyChunkUpdate', function(chunk) {})

emits when game updates a chunk, this is usually triggered when a chunk gets edited. if game.setBlock were to get called 50 times on one chunk in between renders, dirtyChunkUpdate will emit once with the chunk that gets updated

game.on('setBlock', function(pos, val, old) {})

emits whenever game.setBlock gets called

Collisions

Check for collisions between an item and other 'things'

Detects collisions between an item and other items, or voxels.

game.getCollisions(item.mesh.position, item)

This will give you back a 'collisions object' whose keys are positions on the object and values are arrays of the positions of faces that are colliding.

For example, here we have 4 faces colliding with the bottom of our object:

{
  back: Array[0]
  bottom: Array[4]
  down: Array[1]
  forward: Array[0]
  left: Array[0]
  middle: Array[0]
  right: Array[0]
  top: Array[0]
  up: Array[0]
}

Textures

Loading textures onto the texture atlas.

game.materials.load(['obsidian', 'dirt'], function(textures) { })

Both of these textures will be loaded into the texture atlas and expanded creating 2 voxel block types.

Texture-less worlds with flat colors

You can specify hex colors to use as materials, just pass these options when creating a game:

{
  materials: ["#fff", "#000", "#ff0000"],
  materialFlatColor: true
}

Items

  • Items are non-voxel objects you can add to your game. e.g. Monsters/Players, Powerups, etc.
  • Items currently implement their own physics, which is calculated every 'tick' by running an items' item.tick function. It's not very sophisticated.
  • Items .mesh property is the thing that's actually processed by the THREE.js engine. Other properties of item are used in voxel.js to update the mesh, e.g. item.velocity.y is used every tick to calculate the next position the mesh should be in.
  • Using the current item physics system, setting item.resting to false will force an item to recalculate it's position.

Example: Creating an Item

// create a mesh and use the internal game material (texture atlas)
var mesh = new game.THREE.Mesh(
  new game.THREE.CubeGeometry(1, 3, 1), // width, height, depth
  game.materials.material
)

// paint the mesh with a specific texture in the atlas
game.materials.paint(mesh, 'obsidian')

// move the item to some location
mesh.position.set(0, 3, -5)

var item = game.addItem({
  mesh: mesh,
  size: 1,
  velocity: { x: 0, y: 0, z: 0 } // initial velocity
})
// use `game.removeItem(item)` to remove

voxel interchange format

{
  "voxels": [packed 1D array of voxels],
  "dimensions": [2, 2, 2],
  "position": [10, 10, 10]
}

this should be generated by something like this:

  var length = 5, width = 5, depth = 5
  var start = [10, 10, 10]
  var voxels = new Int8Array(length * width * depth)
  var idx = 0
  for(var z = start[2]; z < depth; ++z)
  for(var y = start[1]; y < height; ++y)
  for(var x = start[0]; x < length; ++x, ++idx) {
    voxels[idx] = getVoxelDataFor(x+start[0], y+start[1], z+start[2])
  }
  return {voxels: voxels, dimensions: [length, width, height], position: start}

Timing

setTimeout and setInterval work fine when timing things against the computer's clock but what about staying in sync with the game's clock? When the game lags, is paused or hasn't begun you probably don't want your timed operations firing.

game.setInterval(fn, duration[, args]) and game.setTimeout(fn, duration[, args]) are available and similar to the built in interval functions but stay in sync with the game's clock.

An example is we want our object to jump every 2 seconds. Normally we'd just do:

setInterval(function() {
  jump()
}, 2000)

But if the game's frame rate drops or the game hasn't begun the computer will still fire the jump() function every 2 seconds. Thus causing the object to fly way up into the air.

var clearInterval = game.setInterval(function() {
  jump()
}, 2000)
// later we can stop the interval by calling clearInterval()

Will achieve the same thing although now when the game's frame rate drops the jump() function won't be called repeatedly and the object will jump at the desired frequency.

style guide

basically https://github.com/felixge/node-style-guide#nodejs-style-guide with a couple of minor changes:

  • no semicolons
  • single line ifs/fors when appropriate for terseness
  • no hard to understand for n00bs 'tricks' unless they are faster

any contributions (pull requests) in any style are welcome, as long as:

  • they are written in javascript
  • they merge cleanly

if you send a pull request and you use, for example, 4 space indents it will not be rejected but please try to follow conventions when you can

license

BSD (see LICENSE)

More Repositories

1

art-of-node

❄️ a short introduction to node.js
JavaScript
9,640
star
2

menubar

βž– high level way to create menubar desktop applications with electron
TypeScript
6,673
star
3

screencat

🐈 webrtc screensharing electron app for mac os (Alpha)
CSS
3,014
star
4

cool-ascii-faces

α•™ΰΌΌΰΊˆΩ„ΝœΰΊˆΰΌ½α•—
JavaScript
1,753
star
5

yo-yo

A tiny library for building modular UI components using DOM diffing and ES6 tagged template literals
JavaScript
1,326
star
6

monu

menubar process monitor mac app [ALPHA]
CSS
1,111
star
7

mississippi

A collection of useful stream utility modules for writing better code using streams
JavaScript
1,084
star
8

callback-hell

information about async javascript programming
JavaScript
815
star
9

javascript-for-cats

an introduction to the javascript programming language. intended audience: cats
JavaScript
775
star
10

websocket-stream

websockets with the node stream API
JavaScript
665
star
11

torrent

download torrents with node from the CLI
JavaScript
637
star
12

concat-stream

writable stream that concatenates strings or data and calls a callback with the result
JavaScript
570
star
13

hexbin

community curated list of hexagon logos
JavaScript
526
star
14

linux

run Linux on Yosemite easily from the CLI
JavaScript
457
star
15

geojson-js-utils

JavaScript helper functions for manipulating GeoJSON
JavaScript
403
star
16

requirebin

write browser JavaScript programs using modules from NPM
JavaScript
391
star
17

extract-zip

Zip extraction written in pure JavaScript. Extracts a zip into a directory.
JavaScript
391
star
18

maintenance-modules

a list of modules that are useful for maintaining or developing modules
348
star
19

tabby

a browser with almost no UI
JavaScript
345
star
20

ndjson

streaming line delimited json parser + serializer
JavaScript
294
star
21

abstract-blob-store

A test suite and interface you can use to implement streaming file (blob) storage modules for various storage backends and platforms
JavaScript
266
star
22

standard-format

converts your code into Standard JavaScript Format
JavaScript
265
star
23

wzrd

Super minimal browserify development server
JavaScript
248
star
24

elementary-electron

NodeSchool workshop for learning Electron
JavaScript
228
star
25

gh-pages-template

free hosting on github! fork this to get a repo with only a gh-pages branch that is easy to edit
CSS
221
star
26

taco

a modular deployment system for unix
215
star
27

toiletdb

flushes an object to a JSON file. lets you do simple CRUD with async safely with the backend being a flat JSON file
JavaScript
215
star
28

bytewiser

a nodeschool workshop that teaches you the fundamentals of working with binary data in node.js and HTML5 browsers
HTML
208
star
29

csv-write-stream

A CSV encoder stream that produces properly escaped CSVs
JavaScript
204
star
30

electron-spawn

easy way to run code inside of a headless electron window from the CLI
JavaScript
198
star
31

voxel

tools to work with voxel generation and meshing in javascript
JavaScript
186
star
32

monocles

[NOT MAINTAINED] diaspora... as a couchapp! in pure javascript and fully OStatus compliant (almost)
JavaScript
180
star
33

simplify-geojson

apply the ramer-douglas-peucker line simplification to geojson features or feature collections in JS or on the CLI
JavaScript
170
star
34

nugget

minimalist wget clone written in node. HTTP GET files and downloads them into the current directory
JavaScript
162
star
35

electron-microscope

use electron-microscope to inspect websites and extract data
JavaScript
157
star
36

domnode

node style streams for HTML5 APIs
JavaScript
154
star
37

voxel-builder

build stuff with blocks in the browser, export for papercraft or 3d printing
CSS
149
star
38

multiplex

A binary stream multiplexer
JavaScript
141
star
39

gifify-docker

docker container for the gifify utility
135
star
40

csv-spectrum

A variety of CSV files to serve as an acid test for CSV parsing libraries
JavaScript
134
star
41

async-team

Documentation about how to run an async team (e.g. a remote team in different places)
132
star
42

node-repl

run a node program but also attach a repl to the same context that your code runs in so you can inspect + mess with stuff as your program is running. node 0.12/iojs and above only
JavaScript
129
star
43

datacouch

[ON HIATUS] distributed, collaborative dataset sharing
JavaScript
122
star
44

HyperOS

A 50MB linux distribution that has dat-container for booting live containers on mac OS
Shell
119
star
45

couchpubtato

use Node.js to make CouchDB eat feeds like potato chips
JavaScript
116
star
46

voxel-mesh

generate a three.js mesh from voxel data
JavaScript
109
star
47

browser-locale

normalizes weird cross browser issues and tries to return the users selected language in 100% client side JS by looking at various properties on the `window.navigator` object
JavaScript
106
star
48

binary-csv

A fast, streaming CSV binary parser written in javascript
JavaScript
105
star
49

cats

BSD licensed cat photos that I've taken
103
star
50

filereader-stream

Read an HTML5 File object (from e.g. HTML5 drag and drops) as a stream.
JavaScript
102
star
51

nets

nothing but nets. http client that works in node and browsers
JavaScript
101
star
52

javascript-editor

codemirror + esprima powered html5 javascript editor component
JavaScript
99
star
53

adventure-time

a web based environment for doing nodeschool adventures
JavaScript
97
star
54

workerstream

use HTML5 web workers with the node stream API
JavaScript
92
star
55

tree-view

tree viewer UI widget made with react
JavaScript
91
star
56

packify

packs up browserify apps by inlining all assets into one html file
JavaScript
89
star
57

ViewKit

UI library designed for WebKit/Mobile Safari/Android WebViews
JavaScript
87
star
58

gut

hosted open data filet knives
JavaScript
86
star
59

conversationThreading-js

javascript port of JWZ email conversation threading
JavaScript
83
star
60

refine-python

Python client library for controlling Google Refine
Python
83
star
61

require-times

find out how long require calls take in your program. this is a debugging tool for figuring out why apps load slowly
JavaScript
77
star
62

binary-split

a fast newline (or any delimiter) splitter stream - like require('split') but specific for binary data
JavaScript
77
star
63

commonjs-html-prettyprinter

easy HTML pretty printing in commonJS
JavaScript
76
star
64

voxel-server

multiplayer server for voxel-engine
JavaScript
74
star
65

nginx-vhosts

Programmatically add or remove vhosts to a running Nginx instance
JavaScript
71
star
66

github-oauth

simple node.js functions for doing oauth login with github
JavaScript
71
star
67

get-dat

A command line tutorial to learn dat
HTML
69
star
68

docker-stream

CLI tool for automating the use of docker containers in streaming data processing pipelines. Works on Windows, Mac and Linux.
JavaScript
68
star
69

ogmail

minimalist gmail cli client
JavaScript
63
star
70

dhtkv

CLI for storing arbitrary key/value data in the bittorrent mainline DHT
JavaScript
63
star
71

voxel-hello-world

a template voxel game repo you can use to build your own voxel games
JavaScript
62
star
72

browser-module-sandbox

browser editor for code that gets 'compiled' on the server with node and run on the client
JavaScript
61
star
73

minecraft-skin

load minecraft skins as meshes in three.js applications
JavaScript
58
star
74

atomic-queue

a crash friendly queue that persists queue state and can restart. uses a worker pool and has configurable concurrency
JavaScript
57
star
75

PDXAPI

JSON API for CivicApps.org datasets for Portland, OR
JavaScript
53
star
76

googleauth

Create and load persistent Google authentication tokens for command-line apps
JavaScript
52
star
77

joinopenwifi

automatically join open and internet connect wireless networks on linux
JavaScript
51
star
78

superlevel

a minimalist cli utility for leveldb databases
JavaScript
51
star
79

ble-stream

experimental duplex stream api over bluetooth low energy connections (BLE)
JavaScript
50
star
80

json-merge

given two streams of newline delimited JSON data perform a merge/extend on each object in the stream
JavaScript
49
star
81

haraka-couchdb

a real time email server using nodejs, haraka and couchdb
JavaScript
49
star
82

multirepo

a power tool for batch processing multiple github repositories
JavaScript
49
star
83

mount-url

mount a http file as if it was a local file using fuse
JavaScript
48
star
84

dat-editor

web app console/dashboard/spreadsheet thingy for dat
CSS
47
star
85

csv2html

CSV to HTML command line utility
JavaScript
47
star
86

collaborator

easily add new collaborators to your github repos from the CLI
JavaScript
46
star
87

subcommand

Create CLI tools with subcommands. A minimalist CLI router
JavaScript
44
star
88

blockplot

[alpha] explore minecraft worlds in your browser
JavaScript
44
star
89

refine-ruby

Ruby client library for controlling Google Refine
Ruby
43
star
90

element-class

exactly like .addClass and .removeClass from jquery but without dependencies
JavaScript
42
star
91

biofabric

a client side module for generating biofabric graphs in svg using d3
JavaScript
42
star
92

dat-core

low level implementation of the dat data version graph
JavaScript
42
star
93

kawaii

kawaii face detection
JavaScript
41
star
94

doorknob

convenience module for adding Mozilla Persona user login + LevelDB based session storage to node web apps
JavaScript
38
star
95

stl-obj-viewer

super simple viewer for .stl or .obj files powered by three.js
JavaScript
38
star
96

ftpfs

an ftp client that expose the node fs API
JavaScript
38
star
97

xml-json

convert xml to json on the command line. not streaming, pure javascript
JavaScript
37
star
98

ndarray-stl

convert voxels into 3D printable .stl files
JavaScript
37
star
99

masseuse.js

a (now deprecated) library for fast taps on mobile browsers
JavaScript
37
star
100

current-location

Get your current location (latitude, longitude) on the command line as JSON
JavaScript
37
star