Animation format I would love to see

Ideas and suggestions for how to improve the Warzone 2100 base game only. Ideas for mods go in Mapping/Modding instead. Read sticky posts first!
Post Reply
User avatar
Stratadrake
Trained
Trained
Posts: 197
Joined: 07 Sep 2008, 09:43
Location: Pacific NW
Contact:

Animation format I would love to see

Post by Stratadrake »

Because customizable animations would open up a whole new world of graphical improvements in WZ.

Currently all the animations WZ uses are hard-wired one way or another. Specifically, they're listed in a file called "anim.cfg" that looks like this (the following was extracted from base.wz, e.g. the campaign):

Code: Select all

anim_module
{
	/* anim format: [filename] [id] */
	"walkanim.ani"		 0
	"fireknee.ani"		 1
	"runanim.ani"		 2
	"runflame.ani"		 3
	"flamfall.ani"		 4
	"blderik.ani"		 5
	"cybd_run.ani"		 6
	"cybdpjmp.ani"		 7
	"cybdplnd.ani"		 8
	"cybdprun.ani"		 9
}
Pretty boring, right? It's basically just a map of animation id numbers and what .ani file (and by extension, .pie) file each animation id maps out to. The actual animations themselves are handled internally, by non-customizable game code.

Where are the super cyborgs? They are also stored in the anim.cfg file, but the one in mp.wz, which has this extra line:

Code: Select all

	"scbd_run.ani"		10
And it, too, is handled internally by non-customizable game code and numeric ID.

It doesn't have to be this way; it would be a lot more customizable if we could assign animation files on a per-component, per-event basis. Of course, this requires an overhaul of how WZ handles the animations... the broad details of which, IMHO, could be:

0 - How animations actually work

Each .ani file represents only one animation. There are two methods used: the "frames" method and "transform" method. The frames method is what you see on all scavenger infantry; it's also used to animate the basic cyborg legs. It looks like this:

Code: Select all

ANIM3DFRAMES "cybd_run.pie" 6 7
{
	  0	0 0 0 0 0 0 1000 1000 1000
	  1	0 0 0 0 0 0 1000 1000 1000
	  2	0 0 0 0 0 0 1000 1000 1000
	  3	0 0 0 0 0 0 1000 1000 1000
	  4	0 0 0 0 0 0 1000 1000 1000
	  5	0 0 0 0 0 0 1000 1000 1000
}
It's basically just a reference to a PIE file and the number of frames to use. If you look at the PIE file itself, you'll see several submodels, where each submodel is a complete frame of animation. (A lot like an animated GIF, really.)

Then there's the transform method, which is what animates super-cyborg legs. And the oil derrick:

Code: Select all

ANIM3DTRANS "BLDerik.pie" 25 15 3
{
	ANIMOBJECT 0 "DerrickBase"
	{
		  0	      0       0       0       0       0       0    1000    1000    1000
		  1	      0       0       0       0       0       0    1000    1000    1000
		  2	      0       0       0       0       0       0    1000    1000    1000
		  3	      0       0       0       0       0       0    1000    1000    1000
		  4	      0       0       0       0       0       0    1000    1000    1000
		  5	      0       0       0       0       0       0    1000    1000    1000
		  6	      0       0       0       0       0       0    1000    1000    1000
		  7	      0       0       0       0       0       0    1000    1000    1000
		  8	      0       0       0       0       0       0    1000    1000    1000
		  9	      0       0       0       0       0       0    1000    1000    1000
		 10	      0       0       0       0       0       0    1000    1000    1000
		 11	      0       0       0       0       0       0    1000    1000    1000
		 12	      0       0       0       0       0       0    1000    1000    1000
		 13	      0       0       0       0       0       0    1000    1000    1000
		 14	      0       0       0       0       0       0    1000    1000    1000
		 15	      0       0       0       0       0       0    1000    1000    1000
		 16	      0       0       0       0       0       0    1000    1000    1000
		 17	      0       0       0       0       0       0    1000    1000    1000
		 18	      0       0       0       0       0       0    1000    1000    1000
		 19	      0       0       0       0       0       0    1000    1000    1000
		 20	      0       0       0       0       0       0    1000    1000    1000
		 21	      0       0       0       0       0       0    1000    1000    1000
		 22	      0       0       0       0       0       0    1000    1000    1000
		 23	      0       0       0       0       0       0    1000    1000    1000
		 24	      0       0       0       0       0       0    1000    1000    1000
	}

	ANIMOBJECT 1 "Piston"
	{
		  0	      0       0       0       0       0       0     999    1000    1000
		  1	      0       0     544       0       0       0     999    1000    1000
		  2	      0       0    2056       0       0       0     999    1000    1000
		  3	      0       0    4349       0       0       0     999    1000    1000
		  4	      0       0    7242       0       0       0     999    1000    1000
		  5	      0       0   10548       0       0       0     999    1000    1000
		  6	      0       0   14085       0       0       0     999    1000    1000
		  7	      0       0   17668       0       0       0     999    1000    1000
		  8	      0       0   21112       0       0       0     999    1000    1000
		  9	      0       0   24235       0       0       0     999    1000    1000
		 10	      0       0   26851       0       0       0     999    1000    1000
		 11	      0       0   28776       0       0       0     999    1000    1000
		 12	      0       0   29827       0       0       0     999    1000    1000
		 13	      0       0   29827       0       0       0     999    1000    1000
		 14	      0       0   28776       0       0       0     999    1000    1000
		 15	      0       0   26851       0       0       0     999    1000    1000
		 16	      0       0   24235       0       0       0     999    1000    1000
		 17	      0       0   21112       0       0       0     999    1000    1000
		 18	      0       0   17668       0       0       0     999    1000    1000
		 19	      0       0   14085       0       0       0     999    1000    1000
		 20	      0       0   10548       0       0       0     999    1000    1000
		 21	      0       0    7242       0       0       0     999    1000    1000
		 22	      0       0    4349       0       0       0     999    1000    1000
		 23	      0       0    2056       0       0       0     999    1000    1000
		 24	      0       0     544       0       0       0     999    1000    1000
	}

	ANIMOBJECT 2 "Box03"
	{
		  0	      0       0       0       0       0       0    1000    1000    1000
		  1	   -671       0     168       0     480       0     999    1000     999
		  2	  -2680       0     707       0    1921       0     999    1000     999
		  3	  -6001       0    1720       0    4328       0     999    1000     999
		  4	 -10581       0    3374       0    7705       0     999    1000     999
		  5	 -16322       0    5895       0   12052       0     999    1000     999
		  6	 -23053       0    9556       0   17365       0    1000    1000    1000
		  7	 -29891       0   14178       0   23089       0     999    1000     999
		  8	 -35243       0   18562       0   27886       0    1000    1000    1000
		  9	 -39228       0   22361       0   31703       0    1000    1000    1000
		 10	 -42031       0   25362       0   34550       0    1000    1000    1000
		 11	 -43808       0   27430       0   36440       0    1000    1000    1000
		 12	 -44668       0   28482       0   37382       0     999    1000     999
		 13	 -44668       0   28482       0   37382       0     999    1000     999
		 14	 -43808       0   27430       0   36440       0    1000    1000    1000
		 15	 -42031       0   25362       0   34550       0    1000    1000    1000
		 16	 -39228       0   22361       0   31703       0    1000    1000    1000
		 17	 -35243       0   18562       0   27886       0    1000    1000    1000
		 18	 -29891       0   14178       0   23089       0     999    1000     999
		 19	 -23053       0    9556       0   17365       0    1000    1000    1000
		 20	 -16322       0    5895       0   12052       0     999    1000     999
		 21	 -10581       0    3374       0    7705       0     999    1000     999
		 22	  -6001       0    1720       0    4328       0     999    1000     999
		 23	  -2680       0     707       0    1921       0     999    1000     999
		 24	   -671       0     168       0     480       0     999    1000     999
	}
}
In this case, each submodel represents a portion of the figure, all rendered simultaneously using the stated rotation/offset values to orient each component.

1 - Create a new animation script format

Basically, this would be a replacement for anim.cfg and its purpose is to specify a list of in-game contexts where a given animation should be used. A quick example of cyborg legs might look like this:

Code: Select all

/* format: animation [animation-name] [default-animation] */
animation "cyborg_legs" "cybd_std.pie"
{
 /* format: [event-type] [anim-file] [optional-event-parameters] */
  onMove "cybd_run.ani" 1
}
Which effectively translates to "if the cyborg is walking, render cybd_run.ani. Otherwise, render cybd_std.pie." (The third parameter is specific to the onMove event, and specifies that the animation rate should be relative to movement speed.)

For a more complicated example, let's imagine scavenger infantry:

Code: Select all

animation "babaDude" "exbloke.pie"
{
  /* running animation */
  onMove "runanim.ani" 1
  
  /* Shooting animation */
  onShoot "fireknee.ani"
  
  /* Hit by a flame weapon */
  onBurn "runflame.ani" 0
  
  /* Killed by flame damage */
  onBurnDie "flamfall.ani"
}
Of course, the oil derrick uses only a simple looping animation, so its animation script would be very simple:

Code: Select all

animation "oilDerrick" "blderik.ani"
{
}
2 - Referencing animations on a per-component basis

Of course, that's only half of the equation. The other half is that once the animation event-scripts are defined and loaded by the game engine, we should be able to reference those animations anywhere a file format would normally refer to a static PIE File. For example, the cyborg legs graphic is actually specified in Body.txt, e.g:

Code: Select all

CybRotMgGrd,Level All,LIGHT,25,100,150,200,cybd_std.pie,100,1,600,12,6,0,0
So to apply the new cyborg animation script we would simply replace the PIE file reference with the animation name reference:

Code: Select all

CybRotMgGrd,Level All,LIGHT,25,100,150,200,cyborg_legs,100,1,600,12,6,0,0
Alternately, we could have a new anim.cfg file that, instead of simply mapping individual animations (.ani files) to their hardwired ID numbers, it could instead define animation names and map them to the animation scripts (with the scripts themselves mapping various events to individual .ani files). e.g:

Code: Select all

cyborg_legs,cyborgLegs.script
babaDude,babaDude.script
3 - Animation events

Of course, the biggest task is implementing the various events that power the logic of what-animation-gets-rendered-when. Some that I can think of are:
  • onMove - animation to play when the unit is moving. Framerate can either be absolute (per second) or relative (per distance moved).
  • onShoot - animation to play when an attack round is executed.
  • beforeShoot - animation to play before executing an attack round (the actual attack is delayed until this animation completes).
  • onHit - when the user is struck by any enemy attack.
  • onBurn - when the user is receiving incendiary (burn) damage (mostly scavenger infantry)
  • onBurnDie - if the user is killed by incendiary damage (mostly scavenger infantry)
  • onJump - when the user takes off into the air (e.g. jump cyborgs)
  • onFly - when the user is moving while airborne
  • onLand - when the user lands on the ground again
And these would be sufficient to accommodate all existing animations (oil derrick, scavengers, cyborgs, jump cyborgs) that we have already.

I know this is very rough and mainly conceptual, but what do you think?

For one, I believe Pumpkin clearly intended NEXUS to use flying cyborgs against you in the final campaign level (and wouldn't that be awesome?) - three NEXUS unit templates have "-JUMP" suffixed to their template ids, original warzone.wdg does include jetpack animation files, they just never got it working well enough for the final product so they decided to simply disable it.
Strata @dA, @FAC
Jorzi
Regular
Regular
Posts: 2063
Joined: 11 Apr 2010, 00:14

Re: Animation format I would love to see

Post by Jorzi »

From a graphics standpoint, this might be even more important than having new better-looking models.
Quite a bit of work, of course, but if we are ever going to see the WZM models animated, I guess this is what should be done.
ImageImage
-insert deep philosophical statement here-
User avatar
Andrie
Regular
Regular
Posts: 533
Joined: 20 Jun 2012, 14:11
Location: Suid Afrika

Re: Animation format I would love to see

Post by Andrie »

This is a brilliant idea!
Stratadrake wrote:For one, I believe Pumpkin clearly intended NEXUS to use flying cyborgs against you in the final campaign level (and wouldn't that be awesome?) - three NEXUS unit templates have "-JUMP" suffixed to their template ids, original warzone.wdg does include jetpack animation files, they just never got it working well enough for the final product so they decided to simply disable it.
And if this is true it should be added to the game! :wink:
"My IRC en multiplay naam is Andrie"

Groete Andrie
Post Reply