External Library issue

0 favourites
  • 15 posts
From the Asset Store
This pack of sounds for monsters consists of 107 sounds, among which you can find different sounds of Attack, Death, Ste
  • Hi, I am trying to use the FastNoiseLite noise libray but I keep getting the error: FastNoiseLite is not a constructor or FastNoiseLite is not defined.

    In my import for events script I have:

    import * as FastNoiseLite from "./fastNoiseLite.js";
    

    The fastNoiseLite.js script is in the script folder with the correct case name

    fastNoiseLite.js has purpose 'None Set'

    fastNoiseLite.js has export set eg..

    export default class FastNoiseLite { //...code
    

    And in my function triggered by a button press I create a new instance with :

    const noise = new FastNoiseLite();
    

    which is where the error happens.

    ..Any ideas?

    Thanks

  • I can't see anything wrong in what you've described. As ever, the quickest way to get help is to share a project file demonstrating the problem so we can try it ourselves.

  • OKay. Here is the c3p file.

    Cheers

  • A couple of things to get this working.

    1) Use the import in the file you need it.

    import * as FastNoiseLite from "./fastNoiseLite.js";
    

    That creates the variable FastNoiseLite in the script where it is written. So instead of putting it in your main.js you put it at the top of importForEvents.js

    2) This part is tricky.

    The module you are using is exporting a class using the default keyword

    export default FastNoiseLite {
    	...
    }
    

    When you do

    	import * as FastNoiseLite from "./fastNoiseLite.js";
    

    What is happening is that all the things the module is exporting become part of the new FastNoiseLite variable.

    Because what you are looking for was set as the default thing to export, what you need to write to access the object you are looking for is this:

    	// Use FastNoiseLite.default to access the default export from the module
    	
    	const noise = new FastNoiseLite.default();
    	noise.SetNoiseType(FastNoiseLite.default.NoiseType.Perlin);
    

    In this particular case where the module you want to use has a default export, it is much better to use this to import:

    	import FastNoiseLite from "./fastNoiseLite.js";
    

    Doing that just places the default export of the module into the FastNoiseLite variable, and is used like you expect it should be used.

  • Thanks. using...

    import FastNoiseLite from "./fastNoiseLite.js";
    

    ...instead of...

    import * as FastNoiseLite from "./fastNoiseLite.js";
    

    ..works a treat.

    Oddly though, if I put the import in the main script it doesn't work, but if I put it in the import for events sheet it does. Is there a reason for that?

    Thanks again

  • That's because what the import keyword is doing is creating a variable, and the variable can only be seen in the scope it is created in. Just like a regular variable can not be seen outside of the function it is created in.

    There is a caveat though. If the module you are trying to use is an older one, the way they export things is by attaching properties to the global scope. So in that case, it doesn't matter were the import statement is, because the module will just add things globally.

    For example, if you take the library you are trying to use and add this to the very end:

    globalThis.FastNoiseLite = FastNoiseLite;
    

    A FastNoiseLite property will be created in the global scope, then it doesn't matter in which file you import the module, globalThis.FastNoiseLite will be available.

  • Well, after spending quite a bit of time with this I realised FastNoiseLite doesnt do 'seamless' noise ; which is really what Im after.

    So, does anyone know any library I can use to generate seamless noise in construct?

    I saw a few but tried them and they all have very weird setups that I just dont understand how to import and use in construct. I just get errors. For example, one begins like this...

    function Grad(x, y, z, t) {
     this.x = x; this.y = y; this.z = z; this.t = t;
     }
    
     Grad.prototype.dot2 = function(x, y) {
     return this.x*x + this.y*y;
     };
    

    ..which is neither a class of regular function, others have other, even weirder looking setups and I just get errors everytime I try to hook them up.

    I am well aware of using export and import but I cant get anything working.

    Does anyone have any recommendations?

    Thanks

  • That last snippet that you are not sure what it is, is what classes used to look in Javascript and they are used just like classes defined with the newer syntax.

    	let grad = new Grad(1, 2, 3, 4);
    	grad.dot2(0, 1);
    

    Maybe you can try this module github.com/jwagner/simplex-noise.js , it looks promising.

  • Try Construct 3

    Develop games in your browser. Powerful, performant & highly capable.

    Try Now Construct 3 users don't see these ads
  • The built-in advancedRandom objects scripting interface allows getting different types of noise in js. Afaik it uses a wasm module which means it should be speedy.

  • Thanks fedca, yes this was my initial approach but sadly I dont think there is a way to make the advanced Random Seamless.

    Although Im still hoping there is :)

  • Hi again, DiegoM I tried simplexnoise2d.js but surprisingly despite its name it seems to be written in typescript. This mean when I bring it into construct I just get a ton of errors.

    I always thought c3 supported typescript but it seems to rename everything to .js and also throw errors.

    I just saw the help on typescript. Seems a lot of effort just to include a library.:(

  • I didn't try it out myself and didn't notice the main file in the repo is Typescript and that the type definitions are no where to be seen. You need those so TypeScript can work.

    Anyway, it looks like you can't just copy and paste from the repo, because the code you end up using needs to be generated using a build script that is also in there.

    Instead of doing that, you should download it from from NPM. That way you get the built library in both JavaScript and TypeScript. To get this working I think it's easier to just look for the Javascript file and import that in C3.

    To load the library I did the following:

    1. Install NPM
    2. Create an empty folder somewhere, the desktop is an easy place.
    3. Open that folder
    4. Open a command line window in that folder (In Windows if you press SHIFT while right-clicking, you should see an "Open Powershell" option)
    5. In the command line type npm i -S simplex-noise
    6. That will create a node_modules folder with all the files you are looking for
    7. I took the .js file in ..\node_modules\simplex-noise\dist\esm
    8. Import that file into C3

    After all of that, I imported in the main script with:

    import { createNoise2D } from "./simplex-noise.js";
    

    I don't know if the library will be useful to you, but you can load it like this and try it out.

    I assumed you know about NPM and how to install it. If you need help with that let me know!

  • Thanks very much for this. I got the javascript implementation working in C3, but again, there seems to be no customization options or any way to make the noise seamless afaik :(

  • I don't know anything about noise, but I did a little bit of digging and found what looks like a rather elegant solution for your problem, so elegant that I wouldn't have been able to figure it out in a million years :P

    gamedev.net/blog/33/entry-2138456-seamless-noise

    Towards the end of the article there is this bit of code:

    for x=0,bufferwidth-1,1 do
    	for y=0,bufferheight-1,1 do
    		local s=x/bufferwidth
    		local t=y/bufferheight
    		local dx=x2-x1
    		local dy=y2-y1
    
    		local nx=x1+cos(s*2*pi)*dx/(2*pi)
    		local ny=y1+cos(t*2*pi)*dy/(2*pi)
    		local nz=x1+sin(s*2*pi)*dx/(2*pi)
    		local nw=y1+sin(t*2*pi)*dy/(2*pi)
    
    		buffer:set(x,y,Noise4D(nx,ny,nz,nw))
    	end
    end
    

    I am not too sure what language is that, but whatever it is, it should be easy to translate it to JavaScript using simplex-noise.js

    // Going to need 4D noise
    import { createNoise4D } from "./simplex-noise.js";
    
    const noise4D = createNoise4D();
    
    // The size of the noise data we are going to generate
    const width = 250;
    const height = 250;
    
    // Shortest way I found to declare a 2D array to store the result
    const noiseTexture = Array.from({ length: width }, () => new Array(height).fill(0));
    
    for (let x=0; width-1; x++)
    {
    	for (let y=0; height-1; y++)
    	{
    		// Do some sick math here!
    		let s = x / width;
    		let t = y / height;
    		let dx = x2-x1;
    		let dy = y2-y1;
    
    		let nx = x1 + Math.cos(s*2*Math.PI) * dx / (2*Math.PI);
    		let ny = y1 + Math.cos(t*2*Math.PI) * dy / (2*Math.PI);
    		let nz = x1 + Math.sin(s*2*Math.PI) * dx / (2*Math.PI);
    		let nw = y1 + Math.sin(t*2*Math.PI) * dy / (2*Math.PI);
    		
    		// Store the result for each coordinate
    		noiseTexture[x][y] = noise4D(nx,ny,nz,nw);
    	}
    }
    

    That should produce seamless noise data you can use elsewhere.

    I got the link to the article from one of the answers found here:

    gamedev.stackexchange.com/questions/23625/how-do-you-generate-tileable-perlin-noise

    The snippet is explained in "simple" terms in there

    Basically, map the X coordinate of your pixel to a 2D circle, and the Y coordinate of your pixel to a second 2D circle, and place those two circles orthogonal to each other in 4D space. The resulting texture is tileable, has no obvious distortion, and doesn't repeat in the way that a mirrored texture would.

    That should be obvious XD

    By the way, I haven't tried any of this, but it looks like it might just work!

  • Great Thanks. I got it working but I have no idea how. I'm going to try to implement different noise types then will update more here. Thanks again.

Jump to:
Active Users
There are 1 visitors browsing this topic (0 users and 1 guests)