Been working on a new Effect System for Spellbook and Grey lately (not much time for it, though)…
For discussion purposes, an Effect System is a subsystem that will allow me to quickly build and modify effects. Effects in this context are any sequence of visual/audio items that need to do be done in a sequence to augment the animations of the characters…
For example, when Grey does a life-shaping spell, he needs to play his animation (with any sound effects needed), turn on two point lights that follow his hands, draw a beam of light from the ground to the sky, etc… When the effect ends, we need to activate whatever he life-shaped into existence (which can have any number of effects as well).
I’ve defined some goals for this effect system:
-
Independent – The system should be independent of most existing Spellbook systems, specially minimizing dependencies with the animation system (because of a point below).
-
Multithreaded – This system should be able to run in a separate thread, synchronizing only for the rendering parts. I want this so that I can do more complex effects, like physics-based cloth animation, etc, without nuking the frame rate.
-
Data-driven – I should be able to design a whole effect without doing any actual coding. For phase 1, the idea is to have a XML-driven effect, which describes the effect and the changes in properties of the entities that make up the effect, but in the future I want to build a component in SurgeEd that allows me to design the effects in a more user-friendly environment (a Flash-like timeline)
-
Jump-to-frame – Because I want one day to have a decent application to author effects, I need the effects to be capable of jumping to a specific frame (so I can implement the timeline). In most casts, it’s simple enough to do this (because the state is implicit in a formula), but cases with more random components (like particle systems), this might be more complicated.
-
Event-tracking – The effect must be capable of raising events (for example, if the spawn of the creature needs to start at a specific time in the effect)
- Time-scaling – The effects must be capable of going faster or slower, depending on the instancing of the effect: for example, if the cast time of a fireball is normally 3 seconds and I want it to be done in 2 seconds, the effect must be speeded up.
-
Hierarchy – The effects must have components that can aggregate other components (and respect the scaling/orientation/position of its parent)
-
Object reference – All effects must have a source object (that will be the target of animation controls, for example)
-
Reuse of meshes – The system must be capable of reusing meshes; for example, if I have the same effect running 10 times, I must be able to use the same mesh for all of them, so I can cut the DIP calls from 10 to 1.
Of course, some of these will clash with others; for example 9 makes it harder to implement 7, since I have to do all hierarchy calculations in the CPU, instead of going for the GPU.
Anyway, what I have for now is an Effect System, that manages Effect Instances, which contains Effect Objects. The instance is build from an Effect Declaration, which describes properties and interpolators. The Effect Instance animates the properties using the interpolators (in this context, interpolators are everything from a linear interpolator in which a value goes from A to B in C time, to random interpolators which just assign a random value A to the property). The Effect Objects then use these properties to update a renderable mesh that it requests the Effect System…
All in all, the system is becoming interesting, with a good decoupling of animation and render tasks (because of 2), and the fact that I treat everything as a function of properties and interpolators helps along with 3.
Hopefully I’ll have some more on this by the end of the week, on the Spellcaster Studios blog. Any questions/suggestions, don’t hesitate!