Closed Nesh108 closed 7 years ago
Hey, thanks for the kind words! I also started out by trying to use voxel.js, but I had similar issues and wound up rolling up my own engine.
As for the demo - wow, I had completely forgotten about that! And now that I look, I'm not sure where the source is. Instead though, check out this presentation world that I used for a talk. It was a fork of the live demo world, and I think it has all the same features - fluid blocks, mobs, etc.
Note that it will take a few edits to make that world run with the current engine though, as a couple of APIs have changed signature since then. The /examples/ demos are current, though.
If you want to hack on any engine features feel free to ask whatever!
Great to hear from you!
That's pretty nice, I was interested in getting into the mob part, as I'd love to work on having some flexibility on the AI for the different mobs.
I will definitely be in touch soon :)
Btw, is there any reason why you picked Babylon over, say, Three.js? I did some research myself and, although Babylon seems to be more suitable for games and has better performances, Three.js is much more popular, especially with voxel stuff. I am asking because I started with Three.js but since you are using Babylon, I don't mind too much switching :)
Great! Regarding Babylon, I always found Three's API confusing, so I went looking for an alternative and once I tried Babylon I've had no reason to try anything else. It's powerful, the API is intuitive, and the community is super-responsive. There's an active forum where the devs answer questions, which makes it really easy to learn.
Ok, you convinced me :D
Heya Andy!
I am currently working on switching the engine of my project to yours and I am struggling with some things:
this.noa.inputs.down.on('fire', function () {
if (this.noa.targetedBlock)
this.noa.setBlock(0, this.noa.targetedBlock.position);
}.bind(this));
// on right mouse, place some grass
this.noa.inputs.down.on('alt-fire', function () {
if (this.noa.targetedBlock)
this.noa.addBlock(1, this.noa.targetedBlock.adjacent);
}.bind(this));
or using the event:
this.noa.on('targetBlockChanged', function(tb) {
console.log(tb);
if(tb) {
console.log("Got it!");
this.highlight_block_position = tb.position;
this.highlight_adjacent_block_position = tb.position.adjacent;
console.log("Highlighting");
}
}.bind(this));
Is there something I need to do to enable it?
this.noa.world.on('worldDataNeeded', function (id, data, x, y, z) {
if(Math.max(Math.abs(x),Math.abs(y),Math.abs(z)) <= MAX_N_BLOCKS){
for (let i = 0; i < data.shape[0]; ++i) {
for (let k = 0; k < data.shape[2]; ++k) {
let height = get_height_map(x + i, z + k);
for (let j = 0; j < data.shape[1]; ++j) {
if (y + j < height) {
if (y + j < 0) {
data.set(i, j, k, dirtID);
} else if (y + j == 0) {
data.set(i, j, k, waterID);
}
else {
data.set(i, j, k, grassID);
}
}
}
}
}
}
this.noa.world.setChunkData(id, data);
}.bind(this));
Once I manage to update my project, I am sure I will know your engine much better and I will be able to contribute with some cool new things :D
/N.
Hey, thanks for further looking at the engine!
Regarding target blocks, both of your first two code samples worked perfectly for me - I just copied them into the test world and they worked as written. So I think that either there's a problem somewhere else in your code, or maybe I have some discrepancy between my test environment and what's in the github repo. I can't find anything though. Does the test world run for you? (the one you get by doing npm test
in the noa
folder and then browsing to localhost:8080
?
I tried it and got sh: webpack-dev-server: command not found
EDIT: Forgot to run npm install
, duh. Test world works on my side.
For the question about world extents, basically this engine doesn't know anything about how your world is shaped - it just asks for data within the visible radius and displays whatever you send it. So if you want the world to be empty beyond some point you can return empty data like you're doing, or if you want the world to "wrap around", you can return data that way, etc.
Eventually I should maybe think about what happens when the coordinates overrun JS's max number values, but I haven't thought about it. :)
I think the coordinates should wrap around after you reach JS's max number, in that way you can keep going north and end up south :D
I tried it and got sh: webpack-dev-server: command not found
Did you do npm install
in the noa
directory? Webpack and webpack-dev-server should be listed as dev dependencies. Or you could install them globally, or use some other method of packing if you like. webpack-dev-server
basically runs webpack to build the project, then runs a small webserver that serves to localhost:8080, with some wrappers that make the page reload when the source files get changed.
Yeah, I posted and realized that. The test world works just fine. :)
Regarding final questions:
Is there a way to find if the player is out of bounds? (I am not sure if this would make sense if your map is just endless)
Nothing right now, there's no handling for extreme numbers. Mind you, the JS number limits are very large compared to voxel world sizes.
Do you have some 'fly' option for the player? Like to go in creative mode for building.
Nothing is built-in. The quickest hack would be to let the player have infinite air jumps, so you can move around easier:
noa.ents.getMovement(noa.playerEntity).airJumps = 9999
You could also make the player float by turning off his gravity:
noa.ents.getPhysicsBody(noa.playerEntity).gravityMultiplier = 0
But you'd need to then add some ways of moving up and down, and maybe change the physics module's air friction so that you don't keep flying forever, etc.
By the way, I'm happy to answer questions like this, but maybe better to enter each question as a separate issue, so that if anyone else comes along with the same question they'll find it easily. Then one of these days I'll look at the past issues and know what I need to write documentation for. ;)
Yeah, if you don't have map bounds then it makes no sense for you to have it. My maps are limited in size (128x128), so the player is able to fall off the world.
And for the missing stuff, I will look into it and add them to the engine :D
Now I am still figuring out the targetedBlock
issue :/
Ok, good luck! Note that if the player falls off the world you'll need to detect it somehow, since by default they'll just fall forever (and noa
will keep requesting new chunks faster and faster as they fall).
There used to be a "player-changed-chunks" event that the engine emitted when the player crossed a chunk border. I'm not sure why I removed it but I should add that back in, since it's the easiest way to check stuff like this.
I think I know why it happened, I am using npm install
and apparently over there the latest version is 0.15.0. But here on github is v0.20.1.
So, the old code didn't have 'targetBlockChanged' :D
Ahhhh, sorry about that, I had not published to npm in a while. I just pushed v0.20.2 there. Sorry about that!
You can overwrite what you have by doing npm i noa-engine@latest
.
No problem! I enjoy these small hiccups, they make me learn your engine even more :D
By the way, do you know if anything changed between 0.15 and the current version regarding the world creation? Now the targetBlockChanged
works like a charm but the world is completely empty (but you can still see that there is something). Maybe how the textures are loaded?
Yes, check the repo README for a summary of changes in recent versions. The important one here is probably a change in 0.16 or so, that changed block registration from being a function that takes a long list of arguments to a function that takes an object full of settings.
The registration works, it just doesn't show neither the textures nor the plain colours. I think I followed the hello-world example almost to the letter.
let brownish = [0.45, 0.36, 0.22];
let greenish = [0.1, 0.8, 0.2];
let blueish = [0.20, 0.85, 0.95, 0.5];
this.noa.registry.registerMaterial('dirt', brownish, null);
this.noa.registry.registerMaterial('grass', greenish, null);
this.noa.registry.registerMaterial('grass_side', greenish, 'grass/grass_side.png');
this.noa.registry.registerMaterial('water', blueish, null);
// register block types and their material name
let dirtID = this.noa.registry.registerBlock(1, 'dirt' );
let grassID = this.noa.registry.registerBlock(2, ['grass', 'dirt', 'grass_side']);
let waterID = this.noa.registry.registerBlock(3, 'water', { fluidDensity: 1, viscosity: 0.8 }, false, false, true);
this.noa.world.on('worldDataNeeded', function (id, data, x, y, z) {
// populate ndarray with world data (block IDs or 0 for air)
if(Math.max(Math.abs(x),Math.abs(y),Math.abs(z)) <= MAX_N_BLOCKS){
for (let i = 0; i < data.shape[0]; ++i) {
for (let k = 0; k < data.shape[2]; ++k) {
let height = get_height_map(x + i, z + k);
for (let j = 0; j < data.shape[1]; ++j) {
if (y + j < height) {
if (y + j < 0) {
data.set(i, j, k, dirtID);
} else if (y + j == 0) {
data.set(i, j, k, waterID);
}
else {
data.set(i, j, k, grassID);
}
}
}
}
}
}
// pass the finished data back to the game engine
this.noa.world.setChunkData(id, data);
}.bind(this));
I can break the blocks, I simply can't see them.
The problem is the registerBlock arguments, which changed sometime after the old live demo was made. You've almost changed it right, but the materials array goes in the options object along with the other options. So the signature should look like:
let someID = noa.registry.registerBlock( 1, {
material: 'matName', // or [ 'mat1', 'mat2', .... ]
solid: false,
fluid: true,
fluidDensity: 1.0,
// ...
})
Since I haven't found a good way of generating JSdocs, the documentation for this stuff basically lives in the source files - e.g. a full list of what options that function recognizes can be found commented right above the function itself:
https://github.com/andyhall/noa/blob/master/lib/registry.js#L91-L109
Hope this helps!
Woah, how did I miss that?! Thanks a lot dude :D
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
andthree.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.