-
Notifications
You must be signed in to change notification settings - Fork 0
/
package.json
48 lines (48 loc) · 13.8 KB
/
package.json
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
{
"name": "voxel-engine",
"description": "make games with voxel.js",
"version": "0.18.4",
"repository": {
"type": "git",
"url": "git@github.com:maxogden/voxel-engine.git"
},
"dependencies": {
"voxel": "0.3.1",
"voxel-mesh": "0.2.1",
"voxel-view": "0.0.6",
"voxel-raycast": "0.2.1",
"voxel-control": "0.0.7",
"voxel-texture": "0.5.6",
"voxel-physical": "0.0.10",
"voxel-region-change": "0.1.0",
"raf": "0.0.1",
"three": "0.56.0",
"pin-it": "0.0.1",
"aabb-3d": "0.0.0",
"inherits": "1.0.0",
"interact": "0.0.2",
"gl-matrix": "2.0.0",
"kb-controls": "0.0.2",
"spatial-events": "0.0.1",
"spatial-trigger": "0.0.0",
"collide-3d-tilemap": "0.0.1",
"tic": "0.2.1"
},
"devDependencies": {
"tape": "0.2.2"
},
"scripts": {
"test": "node test.js"
},
"readme": "# voxel-engine\n\n## A voxel engine in javascript using three.js\n\nLearn more at http://voxeljs.com\n\nWrite a voxel.js game in browser: http://voxel-creator.jit.su\n\nhello world template repo: http://github.com/maxogden/voxel-hello-world\n\n# example\n\n``` js\nvar createGame = require('voxel-engine')\nvar game = createGame()\ngame.appendTo(document.body)\n```\n\n# API\n\n## require('voxel-engine')(options)\n\nReturns a new game instance. `options` defaults to:\n\n```javascript\n{\n texturePath: './textures/',\n generate: function(x,y,z) {\n return x*x+y*y+z*z <= 20*20 ? 1 : 0 // sphere world\n },\n materials: [['grass', 'dirt', 'grass_dirt'], 'brick', 'dirt'],\n materialFlatColor: false,\n chunkSize: 32,\n chunkDistance: 2,\n worldOrigin: [0, 0, 0],\n controls: { discreteFire: false },\n lightsDisabled: false,\n fogDisabled: false,\n generateChunks: true,\n mesher: voxel.meshers.greedy,\n playerHeight: 1.62\n}\n```\n\n### Defaults\n\n#### Player Size\nDefault 'player size' is a 1/2 block long/wide and 1.5 blocks high:\n\n```js\ngame.playerAABB().width() // => 12.5\ngame.playerAABB().height() // => 37.5\n```\nSee implementation of `Game.prototype.playerAABB` for more details.\n\n## Terminology\n\n* block/voxel/cube -> mostly interchangeable. The minecrafty blocks you see on the screen.\n* chunk: is a piece of the world that contains voxels. try to pretend that these don't exist\n* AABB: [bounding volume](http://en.wikipedia.org/wiki/Bounding_volume)\n* voxeljs: not 100% consistent yet, 'voxel.js' also acceptable, but definitely not 'VoxelJS'.\n* dims: short for 'dimensions'. Perhaps obvious to some.\n* yaw: rotation around the vertical axis.\n* pitch: rotation around a horizontal axis.\n\n## Positions\n\n* `x`, `z`: horizontal plane\n* `y`: vertical plane\n\nWe try to always use arrays to represent vectors (aka positions)\n\n* `[x, y, z]`\n\nSometimes you may also see objects used, e.g. `{x: 0, y: 0, z: 0}`, this is because three.js uses objects for vectors.\n\n## Generating voxel worlds\n\nWorlds 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.). \n\nThere is one major coordinate system in voxel.js: \"game coordinates\" (aka world coordinates)\n\n- 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\n\nThere are also some other less used coordinate systems that you should be aware of:\n\n- 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.\n- 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\n\nWhen 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:\n\n```javascript\nfunction generator(x, y, z) {\n if (x*x + y*y + z*z > 20*20) return 0\n return Math.floor(Math.random() * 4) + 1\n}\n```\n\nThe `generate` function will be called once for each voxel in the world. `x`, `y` and `z` will be values in game coordinates.\n\n### Generate a flat world 1 block high\n\nFlat world is a nicer way to start (at least you can't fall off the edge).\nThis places the player just above the ground.\n\n```js\nvar game = createGame({\n generate: function(x, y, z) {\n return y === 1 ? 1 : 0\n }\n})\n\n```\n\n## Interacting with the voxel world\n\n### Get current player position\n\n```js\ngame.controls.target().avatar.position()\n```\n\nThis returns a THREE.js Vector3 object (which just means an object with 'x', 'y', and 'z').\n\n### Toggle a block on/off\n\n```js\ngame.setBlock(pos, 0) // off\ngame.setBlock(pos, 1) // on\ngame.setBlock(pos, 2) // on, with another material\n```\n\n### Get the chunk at some world coordinates:\n\n`gameInstance.voxels.chunkAtPosition(position)`\n\n### Get the voxel coordinates at some position (relative to that voxels chunk):\n\n`gameInstance.voxels.voxelVector(position)`\n\n### Create a brand new voxel at some position. \n\nIntended 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`:\n\n`gameInstance.createBlock(pos, val)`\n\n`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.\n\n### Set the value of a voxel at some position:\n\n`gameInstance.setBlock(pos, val)`\n\n### Get the value of a voxel at some position:\n\n`gameInstance.getBlock(pos)`\n\nIf you wanna see the lower level API for voxel data manipulation look at `chunker.js` inside the voxel module.\n\n### Raycast\n\nshoots a ray and collides with voxels\n\n`gameInstance.raycastVoxels(start, position, distance)`\n\nif you just type `gameInstance.raycastVoxels()` it will default to using the current main camera position and direction, and default distance of 10, and epilson of `1e-8`\n\nyou 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\n\n### Create a new voxel adjacent to an existing voxel\n\nfirst do a `.raycastVoxels()` then do `gameInstance.createAdjacent(raycastResults, materialIndex)`\n\n## Game events\n\nThere 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:\n\n`emitter.on('eventname', function(arg1, arg2, etc) {})`\n\n### `game.on('mouseup', function(pos) {})`, `game.on('mousedown', function(pos) {})`\n\nCaptures mouse activity. `pos` is the game coordinate of the intersection of the voxel that you clicked on (if any)\n\n### `game.on('tick', function(delta) {})`\n\nemits 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\n\n### `game.on('collision', function(item) {})`\n\nCalled every tick when an item is colliding with the player. Callback is passed the item that is colliding.\n\n### `game.voxelRegion.on('change', function(pos) {})`\n\nemits when you move between voxels. pos has x, y, and z voxel coordinates of the voxel you just entered\n\n### `game.chunkRegion.on('change', function(pos) {})``\n\nemits when you move between chunks. pos has x, y, and z chunk coordinates of the chunk you just entered\n\n### `game.on('renderChunk, function(chunk) {})`\n\nemits 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`\n\n### `game.on('missingChunk', function(chunkPosition) {})`\n\nemits 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.\n\n### `game.on('dirtyChunkUpdate', function(chunk) {})`\n\nemits 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 the chunk that gets updated\n\n### `game.on('setBlock', function(pos, val, old) {})`\n\nemits whenever `game.setBlock` gets called\n\n### Collisions\n\n#### Check for collisions between an item and other 'things'\n\nDetects collisions between an item and other items, or voxels.\n\n```js\ngame.getCollisions(item.mesh.position, item)\n```\n\nThis 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.\n\nFor example, here we have 4 faces colliding with the bottom of our object:\n\n```js\n{\n back: Array[0]\n bottom: Array[4]\n down: Array[1]\n forward: Array[0]\n left: Array[0]\n middle: Array[0]\n right: Array[0]\n top: Array[0]\n up: Array[0]\n}\n```\n\n### Textures\n\nLoading textures onto the texture atlas.\n\n```game.materials.load(['obsidian', 'dirt'], function(textures) { })```\n\nBoth of these textures will be loaded into the texture atlas and expanded creating 2 voxel block types.\n\n### Texture-less worlds with flat colors\n\nYou can specify hex colors to use as materials, just pass these options when creating a game:\n\n```js\n{\n materials: [\"#fff\", \"#000\", \"#ff0000\"],\n materialFlatColor: true\n}\n```\n\n### Items\n\n* Items are non-voxel objects you can add to your game. e.g. Monsters/Players, Powerups, etc.\n* Items currently implement their own physics, which is calculated every 'tick' by running an items' item.tick function. It's not very sophisticated.\n* 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.\n* Using the current item physics system, setting item.resting to false will force an item to recalculate it's position.\n\n#### Example: Creating an Item\n\n```js\n// create a mesh and use the internal game material (texture atlas)\nvar mesh = new game.THREE.Mesh(\n new game.THREE.CubeGeometry(1, 3, 1), // width, height, depth\n game.materials.material\n)\n\n// paint the mesh with a specific texture in the atlas\ngame.materials.paint(mesh, 'obsidian')\n\n// move the item to some location\nmesh.position.set(0, 3, -5)\n\nvar item = game.addItem({\n mesh: mesh,\n size: 1,\n velocity: { x: 0, y: 0, z: 0 } // initial velocity\n})\n// use `game.removeItem(item)` to remove\n```\n\n## voxel interchange format\n\n```js\n{\n \"voxels\": [packed 1D array of voxels],\n \"dimensions\": [2, 2, 2],\n \"position\": [10, 10, 10]\n}\n```\n\nthis should be generated by something like this:\n\n```js\n var length = 5, width = 5, depth = 5\n var start = [10, 10, 10]\n var voxels = new Int8Array(length * width * depth)\n var idx = \n for(var z = start[2]; z < depth[2]; ++z)\n for(var y = start[1]; y < height[1]; ++y)\n for(var x = start[0]; x < length[0]; ++x, ++idx) {\n voxels[idx] = getVoxelDataFor(x, y, z)\n }\n return {voxels: voxels, dimensions: [length, width, height], position: start}\n```\n\n### Timing\n`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.\n\n`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.\n\nAn example is we want our object to jump every 2 seconds. Normally we'd just do:\n\n```js\nsetInterval(function() {\n jump()\n}, 2000)\n```\n\nBut 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.\n\n```js\nvar clearInterval = game.setInterval(function() {\n jump()\n}, 2000)\n// later we can stop the interval by calling clearInterval()\n```\n\nWill achieve the same thing although now when the game's frame rate drops the `jump()` funciton won't be called repeatedly and the object will jump at the desired frequency.\n\n## style guide\n\nbasically https://github.com/felixge/node-style-guide#nodejs-style-guide with a couple of minor changes:\n\n- no semicolons\n- single line ifs/fors when appropriate for terseness\n- no hard to understand for n00bs 'tricks' unless they are faster\n\nany contributions (pull requests) in any style are welcome, as long as:\n\n- they are written in javascript\n- they merge cleanly\n\nif 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\n\n## license\n\nBSD (see LICENSE)\n",
"readmeFilename": "README.md",
"bugs": {
"url": "https://github.com/maxogden/voxel-engine/issues"
},
"_id": "voxel-engine@0.18.4",
"dist": {
"shasum": "6f293aa1df31fef6e004f1fc3dce9a8d6c49f7e6"
},
"_from": "voxel-engine@~0.18.0",
"_resolved": "https://registry.npmjs.org/voxel-engine/-/voxel-engine-0.18.4.tgz"
}