Looping a certain set of events may be a tricky move to master, and most known ways to do this are by using multi managers that contact each other to complete these looping functions. But as we know, to successfully loop a set of multi managers, you will need to enable its "multithreaded" flag in the flag options. By doing this your map is on an immanent course of crashing itself.
This tutorial will show you a few tricks you can use, and in what conditions. Also it will point you to some things you will need to pay attention to to make your loops function as correctly as possible.
1. What are "Multi managers"?
Multi managers are entities in Half Life engine (Gold Source) games that when called/requested call upon other entities you placed in the multi manager. By doing this you are able to activate a set of entities at once, or control their behaviour in a looping sequence.
Multi managers can activate/deactivate/set any type of entity that can be controlled this way. Here is an example picture of what a multi manager entity does: An other entity requests/calls a multi manager, after which the multi manager starts to call upon entities you have set into the multi manager. These entities can be Sprites/Sounds/Other point - solid entities. More info about multi manager and how do they work can be found here:
2. Information on this technique
What we know
As some of you may know, looping a certain set of events can be done by using multi managers. For example, two multi managers will contact each other at the end of the sequence list you've made and loop a certain set of entities. But, for this we need to enable the "Multi-Threaded" flag, which will cause problems
over time, depending on complexity of the loop and the number of entities in the map.
As you know, multi managers will ignore any request call until they are finished with the sequence they are going trough. So in order to make them work the way we want to we need to enable the multi threaded flag. This causes the multi manager to create a copy of it self, and the entities used in the loop sequence, after which it starts to loop again with out problems. BUT, doing this, the multi manager will continue to copy it self over and over until the total amount of entities goes over the 512 engine limit and the map crashes.
We do not want our maps to crash.
What should we do
To prevent crashing, we must use some kind of a way to loop our multi managers with out them bugging out.
The trick is to contact an other entity which will than contact the starting multi manager and start the loop all over. Here is an example picture of how does it work: As you see on the image, all we do is ask the multi manager #1 to start all over. As you can see, in this set up, after a set number of requests multi manager #1 is finished, and asks multi manager #2 to start its cycle, which than contacts other multi managers in the set up to finish their cycle.
When the final multi manager is finished it calls upon an entity which reactivates the first multi manager.
This was an example, of course, in case you used them to make a set of events, activate sprites and trigger hurts at a sequenced interval for example.
As you know the maximum number of targets in an multi manager is 16, but its best to keep it safe and use maximum of 8 targets per multi manager (at once).
3. Looping it right
Note #1: Its all about timing
Note #2: I don't know of a way can multi manager loops be stopped each round, for needs in Counter Strike. I am still working around that, maybe some one will find a way after reading this tutorial.
Types of loops:
- Timed loop - Normal setup that finished after all multi managers in the sequence are done
- Not much is to be said here, just normal linking of multi managers which do not loop after they are done
- Always loop - Begin ON map start or trigger and loop till the map is finished
- What is essential for this one is the triggering mechanism. Knowing what I said in section 2, I have constructed mine out of
func_button. What I did is take advantage of
env_beam's Start ON flag and
func_button's shootable function.
What we do here is place our button in the path of the
, which will then damage the
and cause it to activate: What we need to set is:env_beam
Start on" so the loop begins on map start.
We set "Toggle" so we can start it again once its done and "
We set "Do not move" so it doesn't move out of position.
Once we have set the triggers we will make sure it loops properly. Set the final multi manager in the looping sequence to target the
entity. Once it targets the
entity it will activate and trigger the
entity which will start the loop from 0 once more. This will assure your looping will be complete every time.
Note: You can also activate it with an button if you wish, you can use the same
set up and target it with a button, or you can just use jsut the button and target that button with an other button. It should loop with out problems.
Multi managers can be linked in a long line and they need to be let to finish their original sequence. Dont forget to check the map example for more information.
There should be no problems with using this type of technique and it should not bug as long as you pay attention to timing and setting the whole ting up right. You can probably combine to achieve other ways of looping or getting what you want.
Remember to pay attention to multi manager limits and entity names. Do not make loops too complex. Keep it as simple as possible, and work out the sequence on paper first.
Remember to check all the values and in case of sprites and sounds, check how long they are and build your time list accordingly.
Do not rush.
5. Additional information
You can see in the file archive how I made my sprites loop, with a bit of bugs though, but nothing a little editing cant fix.
What id like to do here is write how I plan my loops. Since they can not be controlled fully (as far as I know), aka can not be stopped each round, I always use this only when I want to make something that will always loop.
First thing before we start planning, we need to know what desired effect do we want to achieve and we need to know some information about the sprites and sounds we use.
Some sprites are looped and you can hardly notice when do they start and when do they end, such sprite is, for example, "fire.spr". Others do not loop like that and you can clearly see when they are starting and when they are ending, example of such sprite is "blast.spr".
When it comes to sprites that are looped and we cant notice much difference between start and end, we don't have to worry about the time value
we will use. But, when it comes to sprites that are clearly noticeable we need to calculate and set a time value
When we take a look at the blast.spr sprite file with out handy sprite explorer we can see that it has a total 13 frames
from beginning to end. This means, by using the default 10 frames per second
value in Env_sprite entity, it will take 1.3 seconds
for this sprite to complete its cycle. When making our entity set up we must take this value into count, because we want it to look as realistic as possible, we cant have our sprite ending too early. So, when setting up our time line we will take these 1.3 seconds into count.
Second, sounds. Some sounds are looped, some aren't. Most atmospheric sounds are, and ending them at any time usually isn't noticeable. Here its really about sync-in the sound and sprite time value
Once we know what are we dealing with, and that we prepared everything, we need to plan out our sequence. I will demonstrate a simple sequence of sprite and sound:
Lets say we have a machine that bursts steam and a steam sound.
We will call the spots where steam appears A and B.
I have decided this to be the pattern:
Where we have:
- 1: steam and sound will play,
- 0: nothing will happen.
So, I named them:
And I have planned them to fire for 2 seconds, and wait for 1.5 seconds:Mmanager1
Sound1 0.1 //Starting value of 0.1 so we avoid bugs
Sound1#1 2.1 //Ending after 2 seconds of being activated
WAIT //1.5 seconds wait time
GO TO //Since we reached the maximum for one multi manager, we go to 2nd one
Mmanager2 10 //Call manager 2 after which manager 1 finished its function
Sound1 0.1 // We continue in manager 2, since we waited 2 seconds to call manager 2, we can start this ones functions at 0.1 again
GO TO // Managers did their purpose, time to call them again
Activator // Activates manager 1
That was an example of how to plan everything out and input it correctly.
Times will usually be in pattern, making your job easier, so just stay focused and work it out all with understanding and don't rush.
Hope this helped, and happy mapping!