User Guide: Effects Choreographers
From AFXWiki
Contents |
In AFX, high level special effects are created and coordinated using effects choreographers. Different effects choreographers are provided for designing different categories of effects. Currently AFX provides choreographers for magic spell effects, selection effects, and simple single-phrase effects. Future versions may contain additional choreographers.
Choreographer Phrases
Before delving deeper into the details of effects choreographers, it's helpful to understand how choreographers organize effects into groupings called phrases. In AFX, a phrase is simply a list of effects that share a common span of time. If a phrase slides to a different time, all of its effects move with it to the new time. A phrase can have a predetermined duration or it can have a length of infinite time. It can also have a predetermined duration that loops a fixed or infinite number of times.
Most effects choreographers work by organizing phrases into a logical framework that depends on what the choreographer is trying to do. As a choreographer executes, it is in turn executing its phrases at logically appropriate times. (For example, effects in afxMagicSpell are placed in one of five different phrases: casting, launch, delivery, impact, and linger. afxSelectron has three phrases to choose from: select, main, and deselect.)
Effects in a phrase are updated in the order in which they were added to the phrase, and sometimes ordering is important. (For example, if you are layering Zodiac effects, you should take into account that they are drawn in the order they are added to their containing phrase.)
Choreographer Base - afxChoreographer
Although it is not directly used for creating effects, Choreographer Base contains the common functionality shared by all other effects choreographers. It handles user-defined constraint source declaration, and also provides several mechanisms for managing conditional execution of effects.
Ranking and LevelOfDetail
These are two identical but independent ways for determining if certain effects are conditionally executed. Choreographers can be assigned a ranking value and individual effects can be assigned a rankingRange. If the choreographer's ranking falls within an effect's rankingRange, the effect is executed, otherwise it is ignored. LevelOfDetail works the same using a choreographer's assigned levelOfDetail and an effect's levelOfDetailRange. The differences are a matter of convention. Ranking is intended for configuring effect variations that may be determined by a player's experience level, while levelOfDetail should be used to tune effects to a user's hardware capabilities.
Execute Conditions
A mask of conditions is assigned at runtime to a choreographer, and individual effects can test this mask to determine if they should execute. There are some predefined execute conditions, but many bits are available for user-defined conditions.
New in AFX 2
There are some new features that need to be described here... Client-side scripting support, network packet size tracking, and trigger-bit management.
Magic Spell - afxMagicSpell
The Magic Spell choreographer is the original AFX effects choreographer and it specializes in magic spell effects. It represents a three-staged magic spell structure beginning with a casting stage, followed by a delivery stage, and then a linger stage. The start of the delivery stage is punctuated by a launch event and the linger stage starts with an impact event. Each of these events and stages has an effects phrase associated with it, for a total of five phrases: casting, launch, delivery, impact, and linger.
Casting
The portion of spellcasting where the spellcaster prepares to cast a spell. This period of spellcasting may be interrupted by movement or damage to the spellcaster. The casting phrase executes during this stage.
Delivery
The part of spellcasting where the magic is carried from the spellcaster to a target. This can happen instantaneously (instant spells), or the magic can be delivered by a projectile which might fizzle or hit something other than the intended target. The delivery phrase executes during this stage and the launch phrase is triggered at the start of it.
Linger
The time in which a spell's effect remains active after the spell has hit a target. Enchantments, buff, and debuff spells may have a lengthy linger stage. The linger phrase executes during this stage and the impact phrase is triggered at the start of it.
Magic Missile
Magic spells often utilize an afxMagicMissile type of projectile for the delivery stage which lasts as long as the missile does. Magic Spell tracks the location of the Magic Missile projectile which can be used as a constraint source for layered effects. The tornado projectile featured in the spell, Mapleleaf Frag (AFX:SpellPack1), is put together in this manner.
New in AFX 2
Spell instances can be created using TorqueScript's new operator as an alternative to the castSpell() console-method.
Note: A Magic Spell's launch and impact phrases have some limitations that the casting, delivery, and linger phrases don't have. Unlike the others, launch and impact do not correspond to one of the spell's stages and therefore have no natural stopping time. Because of this, only effects with explicit lifetimes and one-shot effects like Explosion can be added to the launch and impact phrases. Effects with infinite lifetimes will be ignored.
Effectron - afxEffectron
An Effectron is a very simple single-phrase choreographer useful for creating a single cluster of combined effects. For compound effects with a simple structure, an Effectron may be all that you need.
Don't underestimate the usefulness of Effectrons. They work well for explosions, melee effects, weapon decorations, environment effects, and many other kinds of effects.
New in AFX 2
Effectron instances can be created using TorqueScript's new operator as an alternative to the startEffectron() console-method. Effectrons can now inflict damage.
Selectron - afxSelectron
A Selectron is an effects choreographer specifically designed for client-side highlighting of selected objects and characters. Selectrons are a key component of the selection system AFX adds to Torque. When a scene object is selected, the system looks for a Selectron corresponding to the selected object's type. If found, the Selectron is executed to indicate the selected status of the object. Because Selectrons are tied to specific object types, you can have one kind of Selectron for players, another for items, yet another for vehicles, etc.
A unique aspect of selectrons is that they run on a single client, the one belonging to the user who made the selection. This is because an object's selection state is really part of a client's user interface and should only be seen by the user making the selection.
Selectrons have three phrases: select, deselect, and main.
Select
Effects in the select phrase are executed when an object is freshly selected and the Selectron appears.
Main
Any continuous effects that are active throughout the life of the selection belong in the Selectron's main phrase.
Deselect
Those effects that occur when a selected object is deselected, or when a different object is selected, go in the deselect phrase.
Building Choreographer Effects
Building a compound effect is basically the same for all choreographer types. First you define the building-block effects to be used. Each type of building-block effect is defined by a corresponding datablock type. So, if you want to use a Particle Emitter, you define it using a ParticleEmitterData datablock, which in turn will point to ParticleData datablocks.
Once you have some building-block effect datablocks defined, you then create an effect wrapper for each one. This is done by specifying an afxEffectWrapperData datablock and assigning one of the building-block effect datablock names to the afxEffectWrapperData effect field. Within each effect wrapper you define more parameters that further describe the behavior of the enclosed effect. These include timing parameters, constraints, and execution conditions.
Next you add effect wrappers to your choreographer, which is done by adding them to one of the choreographer's phrases. Each phrase in a choreographer is really just an ordered dynamic array of effect wrappers.
Unfortunately, datablocks in TorqueScript lack a means for representing dynamically sized arrays. Datablocks can contain arrays, but their size must be predetermined and fixed. Since choreographer phrases may contain anywhere from zero to hundreds of effects, using fixed-size arrays for phrases would be very inefficient. Also, keeping track of indices for large arrays is tedious and error prone for script writers.
To get around the datablock array limitations, choreographers use an unusual syntax for adding effects to dynamic phrase arrays. Here is an example:
datablock afxMagicSpellData(ExampleSpellEffect)
{
addCastingEffect = Zodiac_EW;
addCastingEffect = CastingAnim_EW;
addCastingEffect = CastingSound_EW;
};
In this example, three effect wrapper references are assigned to the addCastingEffect field, which corresponds to the casting phrase of a Magic Spell. The usual interpretation of this code would be that each successive assignment to addCastingEffect is replacing the previous value. This is basically true, but as each assignment is made to addCastingEffect, the new value is appended to an internal dynamic array. Think of addCastingEffect as a special macro for appending effect wrappers to a phrase array.
This special syntax has an upside and a downside. On the downside, the syntax is not strictly well-behaved TorqueScript. The phrase arrays are not shown when the dump() method is called, and phrase arrays are not copied when the colon operator is used to initialize a datablock by copying fields from an existing datablock. The upside is that the special syntax allows the use of efficiently-sized phrase arrays and makes it easier for users to add, delete, and rearrange the effects in each list.
Once one or more of a choreographer's phrases contain some effect wrappers, the basic construction of a choreographer effect is complete. To summarize:
- Specify building-block effects by defining appropriate building-block effect datablocks.
- Enclose each building-block effect datablock in an afxEffectWrapperData datablock.
- Add timing, constraint, and conditional execution parameters to each effect wrapper.
- Add each effect wrapper to one of the phrase arrays in a choreographer.
Previous: User Guide: Effect Wrappers
