Frame-by-frame scripting

Started by
3 comments, last by ApochPiQ 12 years, 9 months ago
I'm looking for an efficient/clean way of attaching actions to an animation timeline. For instance, if I have a character playing a walk cycle, I'd like to be able to say "FRAME 8: playSound(footstep); spawnFootprint(-5,20); if(weakFloorDetected()) { breakFloor; } "

Obviously I could do this in code and just execute actions based on the current frame value, but I'll be dealing with hundreds of different animations that all perform unique actions (in fact, the current "graphical" frame of animation may very well be manually set at each "timeline" frame), and I'd prefer to have an external script per entity type to dictate all of their animation sequences. I'd be fine with either the scripted commands having direct callbacks to functions in my code, or just parsing and interpreting the commands based on strings their. I could probably write such a system from the ground-up on my own, but the reason for this post is that I'm trying to get out of my habit of re-inventing less effective wheels, so I'm hoping there's a library that I could implement that handles exactly what I'm looking for, and is easy enough to set up on a frame by frame basis.

If I haven't been clear with what I'm looking for, please let me know. Thanks a lot in advance.
Advertisement
I'm concerned about why you want this. It seems to me like coupling all of that to something as fluid as an animation implementation is very dangerous. On the one front, it means that any time I want to change the animation, I have to change a huge number of unrelated-but-interconnected things like when sounds are played, when footstep decals are generated, and so on. Another problem is that this tightly couples animation playback rate to game logic. What happens if "frame 8" no longer means "millisecond 27" but you're actually running at 10 FPS? Worse, what if you design for 30 FPS and the game runs at 100? Now everything sounds like a videotape on fast-forward.

Last but not least, this totally breaks if you need to scale animation times. For instance, if you want to use the same animation rigging for really-slow walking and moderately-slow walking (which is not unreasonable!) then you are really screwed, because the animation is so intricately hardcoded to do very specific things at very specific times. You'd end up with a guy sneaking around a corner making really loud "footfall" sounds every 3 seconds, which would just really ruin the illusion.

So I think the first step here is to make sure you really want to do this.

Wielder of the Sacred Wands
[Work - ArenaNet] [Epoch Language] [Scribblings]

Generally speaking something like this is handled by having the animation system fire events (which are setup by the animator) which the system then reacts to.

So, to take your 'foot fall' example, when animating the animator would place events on the time line for 'left foot down' and 'right foot down' then, as the animation system runs the animation it processes those events at the correct time and passes it into the games event system which might well have listeners to play a sound, lay down a foot print and check the eniroment.
Thanks for your reply!
I didn't do a great job of conveying it, but the actual timeline of scripted events won't be dictated by the graphical animation -- quite the opposite in fact. I'm working in 2D and each entity can potentially have hundreds of frames, so I'd like this scripting system to be able to dictate what frame is currently being displayed. I guess what I'd want to do is not say "playAnimation("thisanimation")", but rather "playScript("thisanimation")", and a script would look something like this:



frame 0:
{
setFrame(1);
}
//no frame 1 defined so the character graphic would hold frame #1 again
frame 2:
{
setFrame(2);
}
//no frame 3 defined so the character graphic would hold frame #2 again
frame 4:
{
setFrame(3)
}

frame 5:
{
playSound("awesome")
}


And of course all of that syntax is made up, or I'd probably just be using whatever tool/library that lets me roll with that setup.

It might be confusing that I'm using "frame" to describe both the graphical frame of animation, and the current place along the timeline that the script is executing, but they are different. Some "animation" scripts may not actually even actually animate the character at all, but 99/100 times will. Perhaps I'd be more clear if I didn't imply that animation is actually a component of this, but rather a very prominent byproduct.

So to answer your question, I'm not entirely sure I want this. But anything that would give me the ability to start a timeline of actions (almost like adding Actionscript to a timeline for a Flash Movie) would be great. Thanks again.
Personally, I wouldn't want to write scripts like that. I'd rather see something like this:

script RunAndPanic
{
Set movement path to "towards the left"
Play frames 0 to 10 (corresponding to running leftwards animation sprites)
Set movement path to "standing still"
Start sound sample "aaaaaahhh"
Play frames 250 to 270 (corresponding to "waving arms around in the air")
Set movement path to "towards the right"
Play frames 10 to 20 (corresponding to running rightwards)
Repeat
}


Obviously there's some commenting metadata in there just to clarify the example; a more realistic data might look like:

script RunAndPanic
{
SetMovementPath(left)
FrameSequence(0, 10)
SetMovementPath(none)
StartSample("scream")
FrameSequence(250, 270)
SetMovementPath(right)
FrameSequence(10, 20)
Repeat
}


Bonus points if you don't write this by hand, but rather generate it using a GUI with a more traditional timeline editor.

At that point you can just dump your "script" into something like JSON or XML and use an off-the-shelf parser to load that into the engine and playback the sequences.

Wielder of the Sacred Wands
[Work - ArenaNet] [Epoch Language] [Scribblings]

This topic is closed to new replies.

Advertisement