The third of three articles gleaned from http://www.klikacademy.com ...

Noodle's Guide to...
Random Stuff in TGF/MMF

If you're serious about doing higher-level functions in a click product, you're basically going to have to learn about the Random function. The random function is a base for many things, mainly A.I, random events and other assorted goodies. This article will hopefully give you some idea of how to use it.

Basic Random
Lets say you are making a new game, a game which needs to make a random number every 3 seconds. How would you do this? Well, first of all create a counter, just a simple default counter. Go to the event editor and create the event:

- Every 3 seconds

Now go to the actions column under the Counter a select Set counter to.... In the edit box, type:

random (5)

This will create a random number every three seconds. But in what range will this number be? It is important to note that in random terms, zero counts as a number. Random (5) will thus create either 0, 1, 2, 3, or 4, because these are the first five numbers. Note that the numbers 0-5 will only be created using random (6). An easy way to think about it is that it will choose a range of 0 to the number one less than the number in the bracket. Thus:

-random (7) makes 012345 or 6.
-random (10) makes 012345678 or 9.
-random (2) makes 0 or 1.

Get it? But what if you want to make a random number range which starts at 1?

Intermediate Random
Random (8 ) will choose 0123456 or 7, we've established that, but what will random (8 ) + 1 make? Lets think about it:
The random function will make a number from 0 to 7. This is always the case. But the +1 part will add one to the generated number. So in effect:

-random (8 ) + 1 makes 1234567 or 8.
-random (4) + 1 makes 123 or 4.
-random (6) + 2 makes 23456 or 7.

Understand? The random generated number always starts at 0, but what you do to this number afterwards can make it start at whatever you want it to.

Random Positioning
A common effect seen in side-scrollers is the generation of enemies at random points which then move onto the visible playfield. How would you go about this? For this example, the object will come in from the right of the screen, but it is easily edittable. Make the object have some sort of movement which comes onto the screen from the right for this particular example to work. For example, Set X Position to X (Enemy) - 2.

First, make your active object, with all animations and movements set beforehand. Make it's hotspot as close to the middle as you can get it. Now, go to the event editor and set:

- Every 3 seconds.

Move over to the Create Object column and put Create Enemy at: (580, 0). Please note that this is assuming that the width of the playfield is 520. This creates the active object at 60 pixels to the right of the visible edge. If your playfield width was 640, you might want to set the object at (700, 0), which would place the newly created objects 60 pixels to the right of the playfield. We do this so that you cannot see the newly generated enemies, until their full position is set.

Now, if you ran the level now you would get an Enemy created every 3 seconds in exactly the same place. These enemies move onto the screen from the right, yes? If they don't, alter their movement. Now, obviously we don't want the enemies to come along the same line every time do we? We need to alter their Y positions. Go to event editor and in the same row as the Every 3 seconds event and under the Enemy column, put:

Set Y Position to: random (Frame Height)

This means every 3 seconds the Y position of the newly created Enemy will be set to a random number, which is the same as the Frame Height. For example:

-640x480 Screen Size, Random (Frame Height) would be Random (480). So in effect numbers 0 to 479
-520x340 Screen Size, Random (Frame Height) would be Random (340). So in effect numbers 0 to 339.

This means your Enemy object will be placed at any pixel that is along the Frame Height. If you run the level now, you will get many enemies randomly placed going along the screen. Nice isn't it? Maybe not actually. You may notice some enemies are nearly all the way off the screen, and only a slight part of the object is visible. We need to create a buffer zone at the top and bottom so that enemies are always fully visible.

Go to event editor, and edit the Set Y Position action. Change it to:

- Set Y Position to: Random (Frame Height - 80) + 40.

Lets think about the consequences of this. First of all the Random function creates a number from 0 to 439. This is assuming the frame height is 520. This is because 519 - 80 is 439. The random number always creates a number from 0 to whatever is inside the bracket. Next, the number has 40 added to it, making the number range 40 - 479. This means the Enemy's Y position will be from 40-479, meaning that there is a nice gap at the top and bottom which the object will never be created in. Understand? I hope so. The next bit is harder...it involves fractions!

Weighted Random
Say, just for arguments sake, that you wanted to create an enemy every 3 seconds out of 3 possible types. You might say you could use random (3) to do this, and set an event compared to what the number is. But what if you wanted a particular enemy to appear more than an other?

Lets say there are 3 enemies, blue, red and yellow. You want blue to come up about half the time, red a quarter and yellow a quarter. How do you do this? A simple random function doesn't allow you to. What you need to do is a weighted random.

Same as the simple random function, set a counter every 3 seconds, all the anims and movement. But this time set the number on the counter to 4. This number is very important in weighted random numbers (we'll come on to why later).

Now, put a new event saying:

- Every 3 seconds AND counter is equal to or less than 1.

This means that this event will only be triggered if the counter has a value of 0 or 1. This means out of the possible counter range (0,1,2,3) the event will only be triggered by half the values. Do you see where this is going?

Now, create the object Blue Enemy in the same way as before, setting it to an area outside the field and then having it put at a random position. If you ran the level now, only half the time would this enemy appear.

Now make a new event:

- Every 3 seconds AND counter is equal to 2.

Create the Red Enemy this time. Do the same things as with the blue one, and hey presto, you get 2 different enemies coming in in different amounts. Half the time it will be a Blue Enemy, and a quarter of the time it will be Red. Do the same with counter equals 3 and the yellow enemy and you're done. 3 different enemies that come up at different amounts. This is especially useful for difficult enemies that you don't want a lot of to come up.

I said before that the number you set the random to in a weighted random is very important. It is. For example, if you want the Blue enemy quarter the time, the red a third and the yellow the rest, you need to find a number which is divisible by both 4 and 3. 12 is the obvious choice. Examples below:

- Blue 1/4, red 1/3, yellow 5/12: Random (12), Blue = 0.1.2, Red = 3.4.5.6, Yellow = 7.8.9.10.11.

- Blue 1/6, red a 3/5, yellow 7/30: Random (30), Blue = 0-4, Red = 5-22, Yellow = 23-29.

- Blue 1/2, red 1/6, yellow 2/3: Random (6), Blue = 0.1.2, Red = 3, Yellow = 4.5.

Now obviously this is all very precise fractions, but you don't have to be, you can just play it by ear, especially if you aren't good at maths.

Prologue
Wow, that has the be the biggest article I ever wrote, and now it's available on TDC too! Please comment.