How you trigger and release your events is very important.
Your view of the game structure is inexorably tied to this.
Ideally, you do not want to have each and every object
carrying a heavy cargo of if statements on their backs;
not only does this use up cpu, but it makes the outcome
of actions unpredictable.
It is better to use bookends - a start and a stop to
actions, with blank space in between. Much like a wormholes
work with spaceship travel.
Lets say we have a world full of green mushrooms, and red
mushrooms. The red mushrooms are incredibly rare, only one
for every 1000 of the green mushrooms. Now if we have a
mushroom detector that detects red mushrooms, should we have
the dectector check
if (redmushroomexists == true){
//trigger alarm script;
}
In the draw actor of the detector?
Consider how many seconds it will take you on average to find
a red mushroom; lets say 10 at least?
At 30 fps that's 300 checks for a red mushroom. Yet the red
mushroom only appeared once in that time. 299/300 of your
computations are redundant. In other words, 99.6% of your
code is useless.
One solution to this problem is to control the appearance of the
red mushroom alltogether; decide at the beginning of the level
where the red mushroom will appear, and set a timer for it.
Trigger the detector when the timer goes off, because you already
know that's when the mushroom will appear. The controller randomly
decides the answer once, and waits for the timer to roll around.
You can use a built in timer, or better yet you can build a
master timer that has the needed timer structures already in
place; If soldiers wait x time before attacking again, you
can simply have a controller constantly counting down and
resetting a single timer for this; and soldier units merely
query the time and add themselves to the next trigger list;
The soldier reports itself ONCE to the
master counter, and the counter sends the trigger ONCE to
all the soldiers on its list when the trigger comes around;
thus if the timer is 10 frames long, that's 8 frames the
soldiers DON'T HAVE TO CALCULATE ANYTHING OR ASK ANY IF'S!
This is one purpose of inheritance. You see the 'inherit
events from' button there on the actor panel? This allows
you to condense actions for actors that share some of the
same actions. If missiles, bullets, and flames all have
the same effect on the enemy, why make them act as though
they weren't? Just make a bullet, and add a collision with
enemy; then create missile and have it inherit the collision
event from bullet; then simply have a different destroy
actor script for missile, which gives it a different explosion
than bullet; And set the damage at startup; so that when
bullet collides with enemy, it does the proper damage to
the enemy with only ONE collision script for ALL weapon types.
Adding new weapons becomes much easier. And the weapon
doesn't have to make a lot of decisions as it flies; it doesn't
need to ponder whether it is a bullet or missile when it collides
with something; it has inherited the behaviour, and there is
only one set of actions for it to take.
Creating a tree that takes in all the numbers and intelligently
sorts the data is key to making efficient games.
The smaller and more relevant the individual ticks can
be, the more they can lend themselves to a structured sorting
of the data, using complex functions only when absolutely
necessary, and never wasting unecessary cpu. You can then use
that cpu for other things.