Code Monkey home page Code Monkey logo

noa's Introduction

noa-engine

An experimental voxel game engine.

Some projects using noa:


Usage

The easiest way to start building a game with noa is to clone the examples repo and start hacking on the code there. The comments in the hello-world example source walk through how to instantiate the engine, define world geometry, and so forth. The example repo also shows the intended way to import noa's peer dependencies, test a world, build for production, etc.

Docs

See the API reference for engine classes and methods.

Documentation PRs are welcome! See the source for details, API docs are generated automatically via npm run docs.

Status, contributing, etc.

This engine is under active development and contributions are welcome. Please open a discussion issue before submitting large changes. PRs should be sent against the develop branch!

Code style/formatting are set up with config files and dev dependencies, if you use VSCode most of it should work automatically. If you send PRs, please try to be sorta-kinda consistent with what's already there.

Change logs

See history.md for full changes and migration for each version.

Recent changes:

  • v0.33:

    • Much improved API docs
    • Terrain now supports texture atlases! See registry.registerMaterial.
    • Added a fast way to specify that a worldgen chunk is entirely air/dirt/etc.
    • Modernized keybinds to use KeyboardEvent.code strings, and changed several binding state properties
    • Bunch of internal improvements to support shadows - see examples
  • v0.32: Fixes npm versioning issue - no code changes.

  • v0.31:

    • Change the speed of the world! See noa.timeScale
    • Now possible to control chunk processing order: noa.world.chunkSortingDistFn
    • Much improved type exports and API docs
  • v0.30:

    • Engine now a named export, use import {Engine} from 'noa-engine'
    • many performance and size optimizations
    • now generates proper type declarations and API references!
    • can now configure separate vert/horiz values for chunk load distance
    • core option tickRate is now in ticks per second, not ms per tick
    • adds several init options, e.g. maxRenderRate, stickyFullscreen
  • v0.29:

    • maximum voxel ID is now 65535
    • adds option worldGenWhilePaused
    • adds option manuallyControlChunkLoading and related APIs
    • performance and bug fixes

Credits

Made with ๐Ÿบ by @fenomas, license is MIT.

Uses Babylon.js for 3D rendering.

noa's People

Contributors

alvrs avatar codevuk avatar codezilluh avatar dependabot[bot] avatar fenomas avatar heath123 avatar jarred-sumner avatar mcarth avatar n4o847 avatar nesh108 avatar rasmuserik avatar terrac avatar thetoto avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

noa's Issues

Material name

Hey!

What are the opportunities to
a, store addition block data and retrieve by block id
b, get the name of block material ?

Fix render events to pass correct `dt` values

beforeRender and afterRender events (from noa object) currently pass a dt argument equal to the number of ms elapsed since the last tick. This was done because the physics system needs that info, but general event consumers would expect dt to be the ms since the previous event.

As part of fix, add new noa.positionInCurrentTick property, which gets updated before each tick. That is, if noa.positionInCurrentTick is 0.25, then at the time of that render event the time since the last tick would be 1/4 of the noa._tickRate.

Optimizations for chunk building

One thing I've been thinking about is how to optimize chunk building for specific types of maps based on a formula

Could there be an "optimization hook" which allows you to take the queue of chunks and prioritize them? Eg for example if you wanted to make a large 2d level, or an infinitely falling level you would tell it to prioritize building chunks in a certain order.

Preload all block textures at startup?

Hello there!

Would it be possible to preload the textures at startup?
I am asking because I have noticed that if a new block texture is used, then the engine will try to fetch it, meaning that it can show an empty hole while retrieving it.

If it could just fetch and cache all the textures, it wouldn't matter much as it is expected to have some loading but at least it would have a better overall feel when playing the game.

How could one go about doing that in noa?

Player's body cutoff

Is there a way to set the value of state.cutoff in fadeOnZoom.js?

At the moment I changed that value directly on the code but I would like to have more control over it. In many cases, having a very low cutoff (I set it to 0, with minimum zoom being 0.1) is needed in order to be able to see the player's hands while being in first person.

Browsers Supported?

Hello, I'm on Mac OSX 10.6.8 Chrome Version 49.0.2623.112 (64-bit) and the screen moves wildly when I allow pointer lock. In addition the block selection is not where my cursor is. (same in Firefox) It all performs well in terms of speed, its just very hard to control.

What OS/Browser does this work properly in? Thanks, Joel

How to retrieve the mesh of a block from the registry?

Hey!

I am making the player carry some items and I would like to know how to retrieve the base mesh of a specific block from the registry?

Something like:

let water_mesh = noa.rendering.makeMeshInstance(noa.registry.getBlockMesh(WaterId), false)
let flower_mesh = noa.rendering.makeMeshInstance(noa.registry.getBlockMesh(FlowerId), false);

In this way I can resize it and attach it to the player's hand.

controls through buttons

Hi,

I would like to control the direction of the player through up, down, left and right.
The movements work with keyboard bindings and I just don't get a coupling with html buttons to work (for mobile).

My alternative solution would be sending my flask server (python on android) the keyboard simulation command (get call), but that is overkill!?

I am aware client side js (key sim) is not allowed in browsers.

Please help with how I can make directional movement to work. In expanse a babylon gamepad could also be configured this way.

Thanks in advance!

Changing skybox

I couldn't find this in the engine, is this a feature which would be interesting for you?

It would be something like:

opts = { ...., skyboxTextureFolder: night_skybox}

And then one would be able to set one by simply using:

noa.world.setSkybox(skyboxTop, skyboxSide1, skyboxSide2, skyboxSide3, skyboxSide4, skyboxBottom);

EDIT:

I tried adding a skybox to the scene but it just didn't work, does this work for you? (https://doc.babylonjs.com/tutorials/environment)

    public init_skybox() {
    	this.skybox = BABYLON.Mesh.CreateBox("skyBox", 100.0, this.stage, true);
		this.skybox_material = new BABYLON.StandardMaterial("skyBox", this.stage);
		this.skybox_material.backFaceCulling = false;
		this.skybox_material.disableLighting = true;
		this.skybox.material = this.skybox_material;
		this.skybox.infiniteDistance = true;
		this.skybox_material.diffuseColor = new BABYLON.Color3(0, 0, 0);
		this.skybox_material.specularColor = new BABYLON.Color3(0, 0, 0);
		this.skybox_material.reflectionTexture = new BABYLON.CubeTexture(this.opts.texturePath + this.opts.skyboxStart, this.stage);
		this.skybox_material.reflectionTexture.coordinatesMode = BABYLON.Texture.SKYBOX_MODE;
		this.skybox.renderingGroupId = 0;
    }

Semi transparent material

I have some textures (such as glass) that have alpha channel. But if I make a block with it then the parts with alpha become full transparent. I did a little research on this and it seems babylon standard material does alpha testing instead of alpha blending, so any pixel with alpha < 0.5 becomes fully transparent. To support alpha channel, opacityTexture needs to be set on the material. But after looking through the code it's not obvious where to set this.

Click on costum mesh

I have added a entity via .add(...) with custom mesh, how can i get a callback if the player clicks on it?

Rotate blocks (0, 90, 180, 270 degrees)

Hey @andyhall,

Is there any way to be able to rotate a specific block (either before or after being placed) by 0, 90, 180, 270 degrees (x, y or z)?

The idea would be to reuse blocks without having to re-create them X times just to add different rotations.

How to store chunk data in memory for reuse?

I've been messing around with the library off and on for the last few days and was curious, I've been wanting to attempt to build out some multiplayer functionality to the engine using sockets.io but noticed that the voxel engine is generating chunks in a predefined manner and wiping from memory previous chunks once they are out of range, how difficult would it be to add functionality to the engine to save chunks to memory after they've been generated and reuse them once the player entity returns to the chunk?

Babylon.js tree shaking

The distribution size is reduced significantly when loading the babylon modules individually, rather than including the entire babylon.js. For a production build of docs/hello-world the total size reduces from 2.5MB to 1MB.

Would you like a pull-request to noa, where it depends on @babylonjs/core, and imports that with import instead of require?

Otherwise I'll just continue as I do now by creating a custom window.BABYLON in my code, โ€“ and I might add some notes here about how to do that, in case others want to do the same.

Z-fighting in entity shadows

Drawing entity shadows at a fixed offset leads to z-fighting in distant entities, or nearby shadows being drawn noticeably off the ground.

Reset chunks

Hey!

I'm about to install portals, and I'm interested in if I can reset the whole world/chunk/block data thing? like pressing f5 in the browser, which methods should I call in what order?

Adding Dynamic Meshes with collisions?

Hey there!

I am trying to add my own custom meshes but I can't seem to be able to enable the checkCollisions from Babylon, is there a special way to do it with the engine?

Basically something like:

var myMesh = createCustomMesh();
myMesh.checkCollisions = true;
this.noa.rendering.addDynamicMesh(myMesh);

Even with that, my player seems to still go through the custom meshes (not the normal blocks, though).

Lights and Shadows

Hello!

Is there a way to change the intensity of the lights in the world? I found params for the colors but nothing concerning their intensity.

Also, I found the component/shadow.js which a disc for the player's shadow, how about having some global shadows for all the blocks as well?

I tried adding some of my own lights but I didn't notice any appreciable difference (I was checking the brightness of each block).

Resetting and saving the state of the world

Hello!

I am trying to find a way to reset the world. Basically, I would like to be able to change the configuration of the world whenever I want.

I tried emitting 'worldDataNeeded' but it seems a bit overly complex. Is there a way to just invalidate the current chuck and update every block again?

Also, is there a way to retrieve the current state of the world? Something like a matrix world[x][y][z] that can be saved and restored.

Voxel Size

What should i tweak to resize voxels? (all of them, lets say make them 0.25_0.25_0.25 unit instead of 1_1_1)

Third-person camera support?

As far as I know, noa doesn't support this, so I tried to implement it myself. You can see what little progress I made on my fork: https://github.com/queer/noa. My solution was basically:

At this point, most everything works correctly execpt for raycasting to get the block the camera is pointing at. There are a few things like camera min/max angles not being exactly correct, but that was less-important than raycasting to me.

After digging into it more, the problem appears to be that Engine.getCameraVector() seemingly ends up being perpendicular to the direction the camera itself is facing in, making Engine.pick() return incorrect results. I tried to fix this by using the camera pitch/yaw (from Engine.rendering.getCameraRotation()) to construct a unit vector that faces in the correct direction, but that didn't produce the correct result either; it just gave me a vector that was still facing in the wrong direction, but with a different perpendicularity relative to the camera's actual direction. The attempts at that can be seen here: queer@43cf935#diff-1fdf421c05c1140f6d71444ea2b27638R397 (including some remnants of probably-misguided attempts at transforming the rotations / unit vector)

At this point I'm pretty lost as to what can be done to implement this correctly. I was wanting to open a PR if I managed to implement this successfully, but it doesn't seem like it's likely to happen.

Stairs

What would be the best approach to implement stairs? I mean, can it be done only by textures? 1 can imagine the top,back,and right,left sides' textures (transparent) but I cannot figure out how should I paint the front face?

Other option would be to handle all stairs/slabs as "object", and not terrain but then it'd be a pain in the ass to -lets say put a block above a stair-,or I had to rewrite the hole raycasting-block selection part, to include objects to, or to have a fully transparent block where the stair would go, and if the block is deleted then the stair is, it might be possible, due to my latest contribution (block data).

Jumping out of water

I've noticed that water is treated like air in terms of how many jumps you get. So you can't repeatedly jump out of it unless you have a bunch of air jumps. Should it be treated more like ground?

Calling game.pick in the development branch

On line 387 in index.js in the development branch it looks like an internal object is being returned from the pick function.

I think it should do something like
var result = {}
Object.assign({},_hitResult)
result.hit = hit
return result

Though I am not sure of the best optimized way to do that.

Texture backface flip

Hey!

Me again, I tried to solve this one on my own, but just cant figure it out.
Problem:

I give only 1 texture to a voxel. It displays perfectly. (I'm only interested in the side-faces (front, left, right, back, .... bottom and top doesnt matter). 3 out of 4 faces displays correctly but the back one is fliped vertically, any idea how to get rid of this?

How to lock / unlock mouse?

Hello there, I was recently thinking about working on a GUI system for the game I was making in this engine. However, I can't seem to figure out how to lock / unlock the mouse. I've done coding a lot before, but I'm fairly new to javascript so sorry if this question has a obvious answer. Thanks!

Texture/Material limit

I have a world, with 129-131 (129 which are registered by me, and plus 2 by the engine itself) and 143 materials.
My problem is, when I'm about to register/use the next texture, and place a block with the texture and it wont show up. In networking tab I cannot see the new texture it seems like babylon doesnt even try to download it (most of the time), and I get a corresponding ID and can get the material texture and etc from registry by ID, but it just does not show up. Any idea?

Strange chunk size

Hey, I'm trying to use the world generator using noa.world.on('worldDataNeeded', () => {}) but for some reason, the chunk's data object has a shape that is different than the chunkSize. In my case, I set chunkSize: 16, but the data.shape ends up being [18,18,18].

Even stranger, when I try to set a block on the corner of that chunk data.set(0, 0, 0, game.blocks.stone.id);, the block doesn't appear, I need to set it on (1,1,1) for it to work. Same thing with setting it at (data.shape[0] - 1, data.shape[1] - 1, data.shape[2] - 1), which I expected to be the opposite corner, but didn't work, that corner turned out to be at data.shape[i] - 2 for all of them.

I'm unsure if this is intended and, if so, what the purpose of having a 1 block padding all around the chunk if they're not going to be rendered anyways.

Thanks!

Andy Question

first of all amazing work , too good to be true , amazing programming , Andy Im trying to accessMeshParticleSystem library from another part of the script , to be honest with you I dont know nothing about ES6 only javascript , how do we access libraries it puzzles me ,thanks

Source code for the live test app?

Hey Andy!

First of all: great job!
I have just found this project and I find it very interesting, especially because I am working on something like this as well.
I have been using voxel-engine and three.js but the performance and the low maintenance of the engine (last update around 3/4 years ago) made me consider switching to something else.

I found your live app really interesting and that's what sold it to me but I noticed it is not available in the examples folder. Would it be possible to get it as an example?
I am mainly asking because I want to start adding things like mobs with AI and things like that (together with physics for the liquids).

Let me know!

Cheers,

/N.

Custom objects

I'd use noa engine for a personal project where I have to load more than 200-300 different textures, depending on player positions (there would be rooms, and in each room there are pictures like a galery).

My question is, does the engine only loads the textures if they are visible, or they'll load anyways? and plus question: does custom meshes only rendered/added to the scene to the position when they'd appear on the scene?

slow loading issue

Sorry to bother you Andy im using your colorfull example with the jumping slimes , im getting slow load times ,when loading new chunks , is this normal or I should upgrade to your latest build thanks , the reason i didnt upgrade is because I didnt see your updates before ,and I added so much code , it will be a pain to upgrade thanks

Great result, but ...

Please do not understand me wrong. But this code is one of the ugliest code I've ever seen.
Ok, I think you're not a professional developer. You have to learn more clean code. And how to develop correctly and responsive. It's not my intention to insult you. The truth can be hard.
Your project is great, but only the result. I'm looking for great REAL voxel engines. And your's is one of the best. But coding ...
One of the important rule for coding is: Do not code for you, Do it for others. Do not confuse the readers. Do not complicate it, to appear more intelligent.

Tip:
You could develop with typescript and build with gulp. Code with visual studio code.

Strange terrain generation

Hey, merry christmas to you!

I'm trying to create a new world generation algorithm, I'd like to have a 200*200 flat space, the rest of the world should be "air" (hence: players could fall from the edges)
My generation script is:

for(var i = 0; i < data.shape[0]; i++) {
        for(var j = 0; j < data.shape[1]; j++) {
            for(var k = 0; k < data.shape[2]; k++) {

                if((Math.abs(x) > 100) || (Math.abs(z) > 100)) {
                    data.set(i,j,k, 0);
                } else {

                    if((j >= -10) && (j < 1)) {
                        data.set(i,j,k, grassID);
                    } else {
                        data.set(i,j,k, 0);
                    }
                }

            }
        }
    }

but I get strange effects, any idea?

Solid Color Opacity

Hey!
When I'm setting [1,1,1,0.5] as a color, without texture, it will not render the neighbouring voxel's texture as would expected.

Make mesh instance name in rendering

On line 254 in rendering.js I noticed that it is passing a name mesh.createInstance(name), but that name doesn't seem to be set in the function it is being called from.

I don't know if that might have a negative side effect in some cases, but it doesn't look correct to me.

Thanks

Better way to build docs

This project needs docs! Most of the public methods have up-to-date JSDoc-style headers, and I'm pretty good about keeping them in sync with the implementations, but I never worked out a decent way of building the JSDocs into clean readable markdown or html. If anyone wants to tackle this it'd be cool ๐Ÿ˜

How to tell the engine to load textures underneath blocks with alpha

I have been playing around with the testbed and found the leaf.png, which is supposed to represent the leaves for a tree. I tried applying it to the ground and this was the result:

leaf-textures

It looks like the engine loads only 1 level of blocks (probably for optimization) but that fails when the block hasAlpha: true.

How to create emissive/lighting blocks?

Hey!

I just implemented the cloud generation but I noticed that, like all the other blocks, they are affected by the lighting.
I tried setting the clouds not opaque or making it a fluid but they still are very dark underneath:

dark_clouds

Would there be a way to create blocks with an emissive color/texture (the only problem being with emissive color, is that you would lose the alpha channel as it only accepts Color3)? Same would be interesting for blocks which actually generate light, that would be sweet to have as a parameter like being a fluid or a solid.

EDIT: I thought about it and I would probably want the clouds to be affected by lighting in general just not have such a strong dark area underneath. Otherwise they would show up even when it's pitch dark.

Any plan to support mobile VR and touch inputs (virtual joystick)?

Hey @andyhall,

I am currently looking into adding VR support for mobile headsets and some touch inputs for allowing users to play with their phones.

Are these things in your list?

It would be interesting to have them. Let's see if I can make something conclusive ๐Ÿ˜„

Adding Skybox To Scene

I realize this mostly has to do with Babylon.js and not the noa voxel engine so I understand if you'd like for me to ask this question else where but I'm curious how to add a scene to noa that is stable?? I'm very new to Babylon.js and am still learning.

I followed along with the code nesh108 wrote that sets up the skybox:

function Skybox(opts) {
  if (!(this instanceof Skybox)) return new Skybox(opts || {});
  this.scene = opts.scene;
  this.skybox_size = opts.skybox_size || 200.0;
  this.skybox_path = opts.skybox_path;
  this.skybox_name = opts.skybox_name;

  // Setup skybox
  this.skybox = BABYLON.Mesh.CreateBox("skyBox", this.skybox_size, this.scene);
  this.skybox.renderingGroupId = 0;
  this.skybox.infiniteDistance = true;

  if (this.skybox_path && this.skybox_name) {
    this.set_skybox(this.skybox_name);
  }
}

Skybox.prototype.get_skybox = function() {
  return this.skybox;
};

Skybox.prototype.set_skybox = function(skybox_name) {
  this.skybox_material = new BABYLON.StandardMaterial("skyBox", this.scene);
  this.skybox_material.backFaceCulling = false;
  this.skybox_material.disableLighting = true;
  this.skybox_material.diffuseColor = new BABYLON.Color3(0, 0, 100);
  this.skybox_material.specularColor = new BABYLON.Color3(0, 0, 100);

  this.skybox_material.reflectionTexture = new BABYLON.CubeTexture(this.skybox_path + skybox_name, this.scene);
  this.skybox_material.reflectionTexture.coordinatesMode = BABYLON.Texture.SKYBOX_MODE;

  this.skybox.material = this.skybox_material;
};


var noaEngine = __webpack_require__(20)

var opts = {
	showFPS: true,
	inverseY: false,
	chunkSize: 32,
	chunkAddDistance: 3,
	chunkRemoveDistance: 4,
	blockTestDistance: 10, //distance at which you can interact with blocks
	texturePath: 'textures/',
	playerStart: [0.5, 5, 0.5],
	playerHeight: 1.4,
	playerWidth: 0.6,
	playerAutoStep: false,
	useAO: true,
	AOmultipliers: [0.92, 0.8, 0.5],
	reverseAOmultiplier: 1.0,
}



// create engine
var noa = noaEngine(opts);

var noaScene = noa.rendering.getScene();

let skybox = new Skybox({
    // Pass it a copy of the Babylon scene
  scene: noaScene,
  // Path skybox folder
  skybox_path: 'textures/',
  // Skybox name
  skybox_name: 'TropicalSunnyDay',
  // Size skybox
  skybox_size: 1000.0,
});

// If using Noa-Engine: Tell engine to render it
noa.rendering.addMeshToScene(skybox.get_skybox());

It's rendering into the scene, however when you walk around the world, the skybox is flickering on and off randomly regardless of what skybox assets I use. Any ideas on what I should do?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.