Rob's Log - February 23, 2000


Thought I’d give you guys a little information on the AVI and things in
general.
First off, one of the major complaints about the video was the fact that the fighters passed through each other during the slow-motion sequence. Well, this may eventually be tweaked a little so it doesn’t happen as much, but it will not go away. Every solution to the problem I’ve come up with comes at a horrible price, so it’s just something we’ll have to live with.
Now, how it was made. The entire sequence is scripted, camera movement, fighter movement, everything. This sequence will also be used in the final game, of course running in the game engine. For outputting the data, we originally tried outputting to video then capturing that. Ok, that just produced bad quality stuff and we decided it was a dead-end road. So, what we have is a way to run a sequence and output the frames to an AVI at a specific frame rate, so the engine simple passes 1/30th of a second, renders a frame, and dumps it to the AVI, and repeats. This was done to an uncompressed video, which was 540 meg, then compressed into what you see now (using Adobe Premiere LE). The music was done by Saul using DirectMusic (yes, the very same DirectMusic that many of you verbally smacked us for choosing, so I’ll just assume an apology J). BTW, for anyone wanting to use our game engine to make "movies", well, I doubt you’ll be disappointed with what we allow you to do. Just so you know, besides adding features as I went, the entire Jaguar sequence only took about two days, and that’s using "unfinished" tools.
Here’s the script for the final sequence (and your first peek at our scripting language):
First off, one of the major complaints about the video was the fact that the fighters passed through each other during the slow-motion sequence. Well, this may eventually be tweaked a little so it doesn’t happen as much, but it will not go away. Every solution to the problem I’ve come up with comes at a horrible price, so it’s just something we’ll have to live with.
Now, how it was made. The entire sequence is scripted, camera movement, fighter movement, everything. This sequence will also be used in the final game, of course running in the game engine. For outputting the data, we originally tried outputting to video then capturing that. Ok, that just produced bad quality stuff and we decided it was a dead-end road. So, what we have is a way to run a sequence and output the frames to an AVI at a specific frame rate, so the engine simple passes 1/30th of a second, renders a frame, and dumps it to the AVI, and repeats. This was done to an uncompressed video, which was 540 meg, then compressed into what you see now (using Adobe Premiere LE). The music was done by Saul using DirectMusic (yes, the very same DirectMusic that many of you verbally smacked us for choosing, so I’ll just assume an apology J). BTW, for anyone wanting to use our game engine to make "movies", well, I doubt you’ll be disappointed with what we allow you to do. Just so you know, besides adding features as I went, the entire Jaguar sequence only took about two days, and that’s using "unfinished" tools.
Here’s the script for the final sequence (and your first peek at our scripting language):
interface BJaguar JaguarInterface;
int t;
final float TextStartPos=50;
final float TextSlideTime=120;
JaguarInterface=m_Jaguar.Interface(BJaguar);
m_Jaguar.SetLocalPosition(0,0,0);
// Put the fighter into the correct place.
m_Enemy.SetLocalPosition(-4,-500,-25);
// Put the enemy way off screen so he's not seen.
m_Camera.SetLocalPosition(-55,10,-55);
JaguarInterface.Stand();
BeginNewSequence();
exSleep(5); // Just waste a bit of time.
JaguarInterface.Stand.Winning2(); // Start winning animation.
m_Camera.CommandOrbitTo(m_Jaguar,-45,-5,45,CameraRange,2000);
exSleep(120);
m_Camera.CommandOrbitTo(m_Jaguar,40,-4,40,CameraRange,2000);
for (t=TextSlideTime;t>=0;t--)
{
m_Logo.LocalPosition().y=
10.0+(TextStartPos*(SmoothStopToFast((float)t/TextSlideTime)));
exEndFrame();
}
m_Camera.CommandOrbitTo(m_Jaguar,35,-3,-35,CameraRange,2000);
exSleep(120);
m_Camera.CommandOrbitTo(m_Jaguar,-30,-2,-30,CameraRange,2000);
exSleep(120);
m_Camera.CommandOrbitTo(m_Jaguar,-25,-1,25,CameraRange,2000);
exSleep(120);
int t;
final float TextStartPos=50;
final float TextSlideTime=120;
JaguarInterface=m_Jaguar.Interface(BJaguar);
m_Jaguar.SetLocalPosition(0,0,0);
// Put the fighter into the correct place.
m_Enemy.SetLocalPosition(-4,-500,-25);
// Put the enemy way off screen so he's not seen.
m_Camera.SetLocalPosition(-55,10,-55);
JaguarInterface.Stand();
BeginNewSequence();
exSleep(5); // Just waste a bit of time.
JaguarInterface.Stand.Winning2(); // Start winning animation.
m_Camera.CommandOrbitTo(m_Jaguar,-45,-5,45,CameraRange,2000);
exSleep(120);
m_Camera.CommandOrbitTo(m_Jaguar,40,-4,40,CameraRange,2000);
for (t=TextSlideTime;t>=0;t--)
{
m_Logo.LocalPosition().y=
10.0+(TextStartPos*(SmoothStopToFast((float)t/TextSlideTime)));
exEndFrame();
}
m_Camera.CommandOrbitTo(m_Jaguar,35,-3,-35,CameraRange,2000);
exSleep(120);
m_Camera.CommandOrbitTo(m_Jaguar,-30,-2,-30,CameraRange,2000);
exSleep(120);
m_Camera.CommandOrbitTo(m_Jaguar,-25,-1,25,CameraRange,2000);
exSleep(120);
That’s it, well, it’s relatively simple, but I’m sure some parts will
look a little odd. Just to let you know, you see m_Camera.CommandOrbitTo()
calls all over the place, well, this is quite simply telling the camera
where to move to in relation to a target, in this case m_Jaguar.
Now you’ll get a little taste of how cool our AI system is (and will be), the camera movement is accomplished through these Command prefixed functions. These functions can be used on m_Jaguar, as well as m_Camera. What we’ve done in our AI system is go to great lengths to separate the What, How, and Why portions of the object’s behavior. For now, we’re not going to discuss the Why, but the What and How. In the above example, commands are issued to the camera telling it What to do. As far as the object issuing the command is concerned, How it’s completed is not important. IOW, I just want to be able to tell the camera to move to a position, what it does internally to complete the task is really not my problem. This is where the AI system becomes hugely powerful, you could make a game wherein you have a fighter jet, a subterranean worm, and a normal humanoid, and have all three attack a target using the exact same command.
Another neat thing is that when you command something to perform a task, it’ll be done through the same interface a human would use. For example, the camera is controlled through a mouse axis controller (to orient the camera, like in a quake game), and three thrusters (one for up/down, one for forward/back, and one for left/right) to move the camera about the world. I’ll skip the really gory details, but ultimately the command system simply sets the controller input to the correct values to make the camera move about the world and look at it’s target. This may seem like a great deal of work just to have a camera move around, and it is, but it allowed me to really tweak out the core AI system and ultimately produced a VERY easy way to move the camera around. BTW, in other sequences to get the fighter to run across the arena, I simply commanded him to move to the other side of the arena, then he decided on his own that it was a long distance so decided to run to the position rather than walk. So he simply entered in the same input commands you would to start running.
I’m not going to discuss the AI system any more, there’s some more cool stuff, but it’ll get a little too technical and I don’t feel like getting into that (sorry).
Now you’ll get a little taste of how cool our AI system is (and will be), the camera movement is accomplished through these Command prefixed functions. These functions can be used on m_Jaguar, as well as m_Camera. What we’ve done in our AI system is go to great lengths to separate the What, How, and Why portions of the object’s behavior. For now, we’re not going to discuss the Why, but the What and How. In the above example, commands are issued to the camera telling it What to do. As far as the object issuing the command is concerned, How it’s completed is not important. IOW, I just want to be able to tell the camera to move to a position, what it does internally to complete the task is really not my problem. This is where the AI system becomes hugely powerful, you could make a game wherein you have a fighter jet, a subterranean worm, and a normal humanoid, and have all three attack a target using the exact same command.
Another neat thing is that when you command something to perform a task, it’ll be done through the same interface a human would use. For example, the camera is controlled through a mouse axis controller (to orient the camera, like in a quake game), and three thrusters (one for up/down, one for forward/back, and one for left/right) to move the camera about the world. I’ll skip the really gory details, but ultimately the command system simply sets the controller input to the correct values to make the camera move about the world and look at it’s target. This may seem like a great deal of work just to have a camera move around, and it is, but it allowed me to really tweak out the core AI system and ultimately produced a VERY easy way to move the camera around. BTW, in other sequences to get the fighter to run across the arena, I simply commanded him to move to the other side of the arena, then he decided on his own that it was a long distance so decided to run to the position rather than walk. So he simply entered in the same input commands you would to start running.
I’m not going to discuss the AI system any more, there’s some more cool stuff, but it’ll get a little too technical and I don’t feel like getting into that (sorry).





