Updated: 18/02/2010

Duplicates & Clones

When you create a duplicate, you are simply adding another of the same object, to the frame.
Duplicates of an object are sometimes referred to as instances - the two terms are interchangeable.
Quick Tip: Hold Ctrl while dragging an object to create a duplicate.

A clone is something a bit different. When you clone an object, you are creating a whole new object type. It will inherit the same animations, alterable values, behaviours etc, but in all other respects, it is a completely separate object.
Any subsequent changes made to the clone will not be automatically applied to the cloned object, and vice versa.


Qualifiers

By giving several objects the same qualifier, you are grouping them together. When you refer to an object group in the event editor, all members of that group are effectively treated as if they are duplicates of the same Group Member object.


Object Matching

One of MMFs useful features is its ability to match duplicates of different objects.
For example, you could have several tanks, each comprising separate chassis and turret objects.

+ Always
-> Turret: Set position to 0,0 from Chassis

This will automatically position each turret on a different chassis.

You can do the same with alterable vales, angle, etc.

Note that objects are matched according to when they were created - the newest instances of each object type being paired.
A lot of the time you can use this simple technique instead of using spread values and fastloops (which I will come onto in a moment).


Object Focus

The biggest problem with using duplicates, is that it can be tricky to control them all separately.

It's important to understand that the way in which you order your conditions, is very important.

+ If Value("Counter") = X("Object")
-> Destroy "Object"

is NOT the same as;

+ If X("Object") = Value("Counter")
-> Destroy "Object"

The first example will find the value of the counter. It will then compare this to the X coordinate of the most recently created instance of "Object". If they are the same, it will destroy all instances of "Object".

The second example, in most cases, is what you actually should do. It will individually compare the X coordinate of each instance of "Object", to the value of the counter. Only those instances of "Object" whose X coordinate is equal to the value of the counter, are destroyed.

Be particularly careful of using the "compare two general values" condition, as this will always retrieve the value of the most recently created instance of an object, regardless of what other conditions are present.

A more practical example:

Suppose you are making a platformer and have multiple "Enemy" objects, which you want to attack when the player gets close (within 100 horizontal pixels).

This won't work (because it uses compare two general values):
+ If Abs(X("Enemy") - X("Player")) < 100
+ Restrict actions for 20 milliseconds
-> Enemy: shoot bullet at player...

This won't work either (because of the expression order - see below):
+ If X("Player") < X("Enemy") + 100
+ If X("Player") > X("Enemy") - 100
+ Restrict actions for 20 milliseconds
-> Enemy: shoot bullet at player...

In both cases, only the newest instance of the Enemy object will function properly.

This will work:
+ If X("Enemy") < X("Player") + 100
+ If X("Enemy") > X("Player") - 100
+ Restrict actions for 20 milliseconds
-> Enemy: shoot bullet at player...

In most cases though, you will need to use an alterable value aswell.

+ Always
-> Enemy: Set "Distance" to Abs(X("Enemy") - X("Player"))

+ If Distance("Enemy") < 100
+ Restrict actions for 20 milliseconds
-> Enemy: shoot bullet at player...


Object IDs & Spread Values

Sometimes it's useful to be able to assign each instance of an object, a unique ID.

MMF's built-in solution to this is a "Fixed Value". As the name suggests, this value can't be changed, and it's unique to a specific instance of a specific object. In many cases, this is good enough, but it's not ideal - fixed values aren't assigned sequentially, and as previously stated, you have no control over them.

MMF has another useful feature - the "Spread value" action. This can be used to assign each instance of an object, a different value (stored in the alterable value you specify). These are assigned sequentially, starting with the most recently created instance, which is set to the value you choose to spread; older instances are set to progressively higher values.

eg. Spread Value 3 in Alterable Value A("Object")

3 <- most recently created instance
4
5
6 <- first created instance

You can combine this function with other conditions, so for example, you could spread a value only in those instances of an object which are visible.
A useful example of this would be for checking which objects are colliding:

+ Always
-> Ball: Set "Colliding" to 0

+ "Ball" collides with "Ball"
-> Ball: Spread value 1 in "Colliding"

Now, the two balls which are colliding will have "Colliding" values of 1 and 2, while all other instances will have a value of 0.


Spread Values & Fastloops

Sometimes we're forced to deal with each instance of an object one at a time.
Fastloops can really help speed up this process.

Always
-> Spread Value 0 in ID("Object")

Always
-> Start Fastloop "MyLoop", NCount("Object") times

On Loop "MyLoop"
+ ID("Object") = LoopIndex("MyLoop")
-> >insert action here<

This will simply perform the specified action on each instance separately, but all within a single frame.
Note that you should not spread a value and start the fastloop in the same line, due to a bug in MMF.


The Select Object Extension

Basically, it's an extension (made by Dynasoft), which is very useful for handling multiple instances of the same object.
Among other things, it can select the instances with the lowest and highest alterable values.
I won't go into any more detail than that because it's quite straight-forward, and well-documentated, but I strongly recommend you use it.


Further Reading

Here are some other articles you may find relevant and useful:

Advanced Fastlooping by Tigerworks
http://www.create-games.com/article.asp?id=1399

Everything Has Gone Loopy by Tigerworks
http://www.create-games.com/article.asp?id=106

How Spread Value Works by DeadmanDines
http://www.create-games.com/article.asp?id=1798

Handling Multiple Objects by DeadmanDines
http://www.create-games.com/article.asp?id=1960