MMF is a great tool that simplifies a hell of a lot of things when creating a game, I guess everybody around here knows that. But MMF also has its problems when it comes across some particular situations. One of these problems is what I call MMF's object focus: When something happens to a specific object, MMF checks if some conditions are true and then somehow performs actions that influence the object. But it's not always that easy.

ImageBut let's start with a simple example. E.g. the player's sprite... If the sprite is overlapping a background, it should stop falling. Or something like that. It's a simple cycle: Something happens to an object, MMF checks if some conditions are true and then (well, if they are actually true) performs the actions that influence the object.

ImageBut what happens if there are several instances of the same object? Everybody who uses Clickteam products usually stumbles across this question sooner or later (usually sooner, but who cares...). Usually the first time this question comes up, it's about enemies that should have several hitpoints, but that doesn't really matter. MMF has a solution for this problem: It remembers which instance of that object fulfills the conditions and performs the specified actions for that single object only. An example would be an enemy that has limited ammunition: After it has fired 20 bullets (counted by one of its alterable values), it has to reload. So if that single enemy has fired 20 bullets, that single enemy (and no other one) will reload.

ImageHowever, life wouldn't be life if everything was that easy. And a computer wouldn't be a computer if it does immediately what the user wants it to do... MMF usually becomes a nasty little bitch when it's supposed to focus on the right objects in events that have more complex conditions. Personally, I came across this problem when I wanted to do a movement for my platform game enemies: I wanted to keep the level design as simple es possible. My enemies should act like a fire and forget missile: Just put them into there and let them walk. I didn't want to do any AI masterpieces, but I wanted them to do basic stuff like firing at the player, not falling down abysses, not walking through walls etc. etc.. And I wanted them to do it without any path nodes or waypoints or dummies or whatever. MMF 1.5 has a great collision mask feature that checks (without using any active objects or something) for the level structure at a particular x-y coordinate. All I wanted the enemies to do is to check if there is an obstacle at e.g. x=128; y=192 - and if not, to turn around (because there would be an abyss or something similar). But my event (negate: collision mask at coordinates relative to enemy is an obstacle) simply didn't work as it was supposed to. The reason was simple: There aren't many conditions that make MMF remember the object it has tested. And that collision mask condition didn't do it. MMF checked for the first enemy and didn't run the actions. It checked for the second and it checked for the third and so on. And suddenly, when one enemy (be it number 13 or whatever), it had to run those actions. But it didn't know what object should be used, it couldn't focus on the right object. And therefore, the actions were run for all objects. Every last enemy in that level turned around.

ImageI was thinking and trying and thinking again. And finally found a solution that does not only work for some rare examples but one that should fix any object focus bug in MMF's games.
Alterable values are one of the few values that are checked for every single instance seperately. So if I could just run the same events for every single instance again, it should work. MMF comes with the spread value function: Every instance of an object gets a number, but unlike fixed values which are pretty much random numbers, the spread values enables you to count through the instances: The first object starts with 0, the next gets 1, then 2, 3, 4, 5, 6, 7 and so on (okay, it doesn't have to start with 0, but that doesn't matter now). All that has to be done for checking the conditions for each instance on its own is to spread a value in one of its alterable values and to add a counter that is raised one by one. Then, one more condition has to be added for the events that make MMF's object focus refuse to work: The object's alterable value has to have the same value as the counter has.
That'd be fine, but MMF is slow as hell. It only runs its code 50 times per second, so if there were 50 enemies, every enemy would only be checked once in a second which might be not enough. But there is the amazing fast loop object everybody should know how to use: It can run events several times within one single MMF-beat. So all that is left is add a new loop that runs as many times as there are instances of the object that is tested in the frame (simply select number of objects). Voilà, it works.

So what events do we have now? The first one should be a set counter event - the enemies should be checked over and over again, so the counter has to be set to 0 before MMF enters the loop.
always: Set counter to 0
Then, we start the loop.
always: Start loop number 0 for [number of object object] times
Within that loop, each object has to get its number...
loop trigger 0: Spread value 0 in alterable value a of object
... so we can check for something that should influence that particular object alone (e.g. the collision mask or whatever).
loop trigger 0 + alterable value a of object = value of counter + collision mask (x of object / y of object + 32) is an obstacle
And finally, the counter's value has to be raised... After all, all objects should be checked, not object number 0 several times while the other ones aren't checked at all
loop trigger 0: add 1 to counter
Of course, all numbers and names and whatever can be changed...


All in all, the example described here was, as the name suggests, only an example. Nothing more. MMF's focus doesn't really always work as it should, but this is a working solution for practically every problem that might come up concerning that problem - and it isn't that much work. Of course, it's a new counter and it's one more loop, but apart from that it's not that much more than before. On the other hand, this is only three more events: start the loop, spread the value and add 1 to the counter (if you put the last two actions into one event, it's even merely two events) - and you can put as many other events into that loop as you want (like checking for four points - obstacle left, obstacle right, no obstacle bottom left, no obstacle bottom right) etc. etc.. So this really keeps the code clean and enables you to do some things that MMF refused to do before.