I have released my Perlin Noise Plugin. I still have a bit of testing to do, and of course, I'll want you guys to report any bugs you find in this thread. I'm going to use this first post as a tutorial on how to use this object, and to explain what it can do for you.
Please keep in mind this is a beta, I want to see how far you guys can push this thing, and how hard you can break it. When you do, tell me how you did so here.
So what is Perlin Noise? Well, in 1985, Ken Perlin came up with an algorithm for noise that wasn't quite so random. It had smooth transitions, and to this day that algorithm is used to generate everything from cloud textures, to detail maps on "dirty" textures, and more importantly - to generate terrain. If you use the values given by this algorithm in a grid, you can create random, persistent terrain. The algorithm is pseudo-random, and uses a seed. If you feed it the same seed, you will get the same noise out of it, which means you can generate as much noise as you need, on the fly, and if you generate it again, it will be the same as it was, without actually storing all the noise into a gigantic texture. I'm going to be using this for generating as much terrain as I need on the fly in my game, and terrain will be the focus of this tutorial, but please keep in mind that there are many applications for Perlin Noise outside of terrain.
Alright, first of all you are going to want to open the zip file you downloaded, inside you will see a folder called "Runtime", and another plugin: "PerlinNoise.csx". You are going to want to drag the contents of this zip file into your Scirra\Construct\Plugins folder. If any warnings pop up, just ignore them and continue extracting.
Now fire up Construct, and double click inside the layout to drop a new object on it. Once the dialog pops up, you should see the Perlin Noise object inside. It looks like this:
Drop one of those into the layout, and select it. You will notice that it has many properties on the left. Among these are "Width", "Height", "Octaves", "Frequency", "Amplitude", and "Seed". I will briefly explain each one of these settings for you.
Width and Height are the size of the object, but you will notice that there is not actually a physical object on the layout. That is because the noise is generated at runtime, and acts more like an array than a sprite. The size of the object is arbitrarily chosen by you, but for now let's keep it at 640x480, which by the way should be the same size of your layout and application window. This will make it easier to fill the layout with noise. If you had to generate noise on a smaller scale, say for a sprite, you might want to change these values.
Octaves are basically how many passes the Perlin algorithm makes, the less octaves you use, the cloudier the noise will look, and the more you use, the grainier it will look. For most purposes, a value of 4 to 8 is fine. For our terrain, we will keep it at 4.
Frequency is similar to the frequency of sound. If you look at a frequency wave, a higher pitched sound has the waves closer together. In our noise, the higher the frequency, the tighter the noise is going to get - there will be less whitespace and more activity. Values between 1 and 8 are fine as frequencies, and we will be using 4 for our terrain.
Amplitude is a bit easier to understand. It is simply how high and how low the noise will go. The noise at any given position on the grid is a decimal value between negative amplitude and positive amplitude. So if your amplitude is 4, you will get values between -4 and 4.
Seed is the unique identifier for the noise you are generating. If you change this, the noise will change to represent the new seed. If you go back to the original seed, the noise will return to how it was.
Alright, now create a new sprite on your layout, size 32x32, and name it Tile. Color it white, and make sure it's hotspot is centered. Now position it at position 16,16, so it is in the top left corner of the layout. Right click on the tile, and choose "Array Paste". Click on the 2D option, set the 1D field to 15, and the 2D field to 20. Now set the X Row Offset to 32, and the Y Move Transformation to 32. It should look like this:
Hit OK. You should have just filled the entire layout with white tiles, now right click the Tile object in the object list, send it to the back of the order list, and lock selection so it won't be in our way.
Now create a button named GenButton, and set it's caption to "Generate". We're now ready to generate some terrain, but first we need to set up the event sheet.
Alright, now add a condition for clicking the button, and a subcondition of that that: "For Every Object", choose the Tiles as the object. Now here's the easy part. Create two more subconditions using the Perlin Noise object "Compare Noise At", set the X and Y values of both to Tile.X and Tile.Y, and the value to 0, but make one of the conditions "Less than" and the other "Greater or equal to". What we are doing right now is checking the position of each tile against the noise map that is covering the whole layer invisibly. We are taking the value of the noise at that point, and checking to see if it is below our artificial "Water Line", which is 0. You should currently have an event sheet that looks like this:
Lastly, we want to color everything in. On the condition that says the noise is below 0, set an action to colorize the tile object as a blueish color. On the other one, do it again as a greenish color. Now the tile map can easily be rendered, but we have to do one last thing before the program is done. We want to see how random this Perlin object is, so go back up to the condition where GenButton is clicked, and on that level, add an action for the Perlin generator: SetSeed. For the value, choose Random(2000). This way, our perlin map will be updated every single time that button is clicked. This is how your final event sheet should look:
Now hit that preview button! You should end up with something like this: http://screencast.com/t/T6D9oR19 Keep in mind that the blockiness is caused by the size of our tiles, the noise map is MUCH more detailed than that. It looks a little like this:
You could make the tiles 16x16 instead for a more detailed map, and instead of checking if it was above and below zero, to check if it was BETWEEN certain values using that action to create layers for darker blues in the deep ocean, lighter blues near the shoreline, yellow sand along the shore, green hills and dark green forests in the center of the mainland. If you changed the amplitude from 1 to 10, you'd have a lot more room to add more of these layers in. The amount of detail you can generate is limited only by your creativity.
Do keep in mind that you don't want to use 16x16 tiles in a real game, that's why I didn't do it here in this tutorial. That many sprites at once would start to choke up Construct. Keep in mind that here we were generating the entire world, but your player isn't always going to see the entire world. You only need to show what is in his field of vision, so he's going to be looking at a small portion of the map at any given time. However, the noise map adds a lot of realism to the terrain that wouldn't be possible otherwise.
You will find that there are enough actions, conditions, and expressions in the plugin to do whatever you need to do.
I have a few names to drop in here at the end. I have to thank Ken Perlin for his algorithm, you will notice the default seed for a Perlin object is 1985, homage to when he made the algorithm. Secondly I have to thank John Ratcliff, as he came up with this implementation of Perlin Noise, and I am simply porting it to Construct. Lastly, I have to thank my buddy Alex for cranking out a little TV with static on it at 4AM in the morning for my stupid project.
I will be releasing the plugin very soon. You can use the plugin for whatever you want to use it for. It is my first plugin ever, so PLEASE report any inconsistencies or bugs you might encounter. And please, be on the lookout for my future projects. Anything that comes out of me will involve randomizing or procedurally generating something...