Animations don't Play in Multiplayer Game
by Caleb · in Torque 3D Professional · 08/24/2011 (11:44 am) · 7 replies
I've just about finished the player code for the game I am working on, so it's time to test the multiplayer aspect. When doing this I noticed an interesting problem. While animations that are played continuously (such as root, run, and fall animations) play correctly on both machines, animations that are played a single time (like jump, and land animations) are not. These single-serving animations (as I like to call them) only appear on the machine that is preforming that action. . Also, calling "setActionThread" from script correctly plays an animation on all machines, which makes me think maybe setMaskBits isn't be used somewhere it that it should be? I haven't had a chance to look into it though. .
The machine I press jump on jumps correctly. . .

The client machine does not. . .

So one animation not playing wouldn't be so bad, except I have several single-serving animations that need to work correctly.


Another odd thing is that it seems this problem has been around since TGE. A little searching will bring up a number of similar posts, yet none I found with solutions. It's like a dirty little secret that everyone knows but nobody wants to talk about. :p
Anywho. . I'd just love to tackle this myself, but classes started back a few days ago and I'm barely able to find the time to type this. Any advice, suggestions, or comments would be super duper, so thanks for anything!
Some Additional Notes-
I have tried this with stock game files to ensure it isn't just something I've changed. The Animations seem to attempt to play on occasion, but it's like they're always cut short (I might need to check out "pickActionAnimation"). And lastly, I'm still using 1.0.1. I don't know if this problem exists in 1.1 but if it doesn't then it might be a good time to switch. ;)
The machine I press jump on jumps correctly. . .

The client machine does not. . .

So one animation not playing wouldn't be so bad, except I have several single-serving animations that need to work correctly.


Another odd thing is that it seems this problem has been around since TGE. A little searching will bring up a number of similar posts, yet none I found with solutions. It's like a dirty little secret that everyone knows but nobody wants to talk about. :p
Anywho. . I'd just love to tackle this myself, but classes started back a few days ago and I'm barely able to find the time to type this. Any advice, suggestions, or comments would be super duper, so thanks for anything!
Some Additional Notes-
I have tried this with stock game files to ensure it isn't just something I've changed. The Animations seem to attempt to play on occasion, but it's like they're always cut short (I might need to check out "pickActionAnimation"). And lastly, I'm still using 1.0.1. I don't know if this problem exists in 1.1 but if it doesn't then it might be a good time to switch. ;)
#2
i have same problem, and fixed now.
open player.cpp.
go to 'void Player::writePacketData()' function.
add this code
go to 'void Player::readPacketData()' function.
add this code
go to 'U32 Player::packUpdate()' function.
add this code
into
go to 'void Player::unpackUpdate()' function.
add this code
into
and recompile your project.
08/28/2011 (7:42 am)
torque's jump animation and poses need work network.i have same problem, and fixed now.
open player.cpp.
go to 'void Player::writePacketData()' function.
add this code
stream->writeInt(mPose, NumPoseBits);
go to 'void Player::readPacketData()' function.
add this code
mPose = (Pose)stream->readInt(NumPoseBits);
go to 'U32 Player::packUpdate()' function.
add this code
stream->writeInt(mPose, NumPoseBits);
into
if (stream->writeFlag(mask & MoveMask))
{
...
}go to 'void Player::unpackUpdate()' function.
add this code
Pose pose = (Pose)stream->readInt(NumPoseBits); setPose(pose);
into
if (stream->readFlag()) {
mPredictionCount = sMaxPredictionTicks;
mFalling = stream->readFlag();
...
}and recompile your project.
#3
open player.h.
add this code
after
open player.cpp.
add this code
after
add this code into 'void Player::updateMove()' function.
before
comment out
after
go to 'void Player::pickActionAnimation()' function.
add this code
after
go to 'U32 Player::packUpdate()' function.
add this code
into
go to 'void Player::unpackUpdate()' function.
add this code
into
ok, recompile your project.
08/28/2011 (8:05 am)
this source for jump animation on multiplay.open player.h.
add this code
bool mJumping;
after
bool mFalling; S32 mJumpDelay;
open player.cpp.
add this code
mJumping = false;
after
mJetting = false; mFalling = false; mSwimming = false;
add this code into 'void Player::updateMove()' function.
mJumping = true;
before
F32 zSpeedScale = mVelocity.z;
if (zSpeedScale <= mDataBlock->maxJumpSpeed)
{
...comment out
// If we don't have a StandJumpAnim, just play the JumpAnim... S32 seq = (mVelocity.len() < 0.5) ? PlayerData::StandJumpAnim: PlayerData::JumpAnim; if ( mDataBlock->actionList[seq].sequence == -1 ) seq = PlayerData::JumpAnim; setActionThread( seq, true, false, true ); [/cdoe] add this code [code] if (mJumpSurfaceLastContact) mJumping = false;
after
else
{
if (jumpSurface)
{
if (mJumpDelay > 0)
mJumpDelay--;go to 'void Player::pickActionAnimation()' function.
add this code
else if (mJumping) {
action = PlayerData::JumpAnim;
fsp = true;
}after
else if (mFalling) {
// Not in contact with any surface and falling
action = PlayerData::FallAnim;
fsp = true;
}go to 'U32 Player::packUpdate()' function.
add this code
stream->writeFlag(mJumping);
into
if (stream->writeFlag(mask & MoveMask))
{
...
}go to 'void Player::unpackUpdate()' function.
add this code
mJumping = stream->readFlag();
into
if (stream->readFlag()) {
...
}ok, recompile your project.
#4
@Mquaker: Thank you very much for taking the time to post all that! It seems odd that this was never taken care of as I can find posts relating to this problem dating back 4 or 5 years. I managed to get my jump animations to play correctly after doing something very similar (almost identical) to everything you posted. Thank you very much!
I'm currently working on a way to make all "single-serving" animations work without having to pack a new variable into the stream for each individual animation. Perhaps I'll post it here if I finish.
08/28/2011 (10:05 am)
@Richard: The problem seems to only show up when using setActionThread from inside the engine. Using the proper commandToServer calls from scripts lets the animation play fine.@Mquaker: Thank you very much for taking the time to post all that! It seems odd that this was never taken care of as I can find posts relating to this problem dating back 4 or 5 years. I managed to get my jump animations to play correctly after doing something very similar (almost identical) to everything you posted. Thank you very much!
I'm currently working on a way to make all "single-serving" animations work without having to pack a new variable into the stream for each individual animation. Perhaps I'll post it here if I finish.
#5
In player.h somewhere near "mFalling" add:
Thanks again!
08/28/2011 (11:02 am)
Okay here's what I've got thus far for anyone interested.In player.h somewhere near "mFalling" add:
//Used to update action threads (such as the jump animation) across a network. U32 mNetworkedAnim; S32 mNetworkedAnimTick;Then in player.cpp, anywhere in the "Player::Player()" constructor, add:
mNetworkedAnim = 0; mNetworkedAnimTick = 0;Next, find your "pickActionAnimation" function. Right after your. .
else if (mFalling)
{
. . .
}Add:else if (mNetworkedAnim)
{
//Give the client time to catch up before setting a new animation.
if (mNetworkedAnimTick > 2)
{
mNetworkedAnim = 0;
mNetworkedAnimTick = 0;
}
else
{
mNetworkedAnimTick++;
setActionThread(mNetworkedAnim, forward, false, false, fsp);
}
return;
}Now find the "packUpdate" function. Add the following inside of it after "stream->writeFlag(mFalling);"://Send the action thread to the client
stream->write(mNetworkedAnim);
stream->write(mNetworkedAnimTick);And finally, find your "unpackUpdate". After "mFalling = stream->readFlag();", add://Client needs thread stream->read(&mNetworkedAnim); stream->read(&mNetworkedAnimTick);And that should just about do it! Now when I want to play a "single-serving" animation, I set "mNetworkedAnim" equal to the animation I want to play. For example, for playing the jump animation correctly I've augmented the last part of the jump code to look something like this:
// If we don't have a StandJumpAnim, just play the JumpAnim...
S32 seq = (mVelocity.len() < 0.5) ? PlayerData::StandJumpAnim: PlayerData::JumpAnim;
if ( mDataBlock->actionList[seq].sequence == -1 )
seq = PlayerData::JumpAnim;
setActionThread( seq, true, false, true );
//ALL THAT'S ADDED!
mNetworkedAnim = seq;
mJumpSurfaceLastContact = JumpSkipContactsMax;
}
}All this has not been extensively tested, but so far so good. It's working for me for now.Thanks again!
#6
i using torque game engine since 2005.
but, do not still fixed current version.
08/29/2011 (2:25 am)
i think this problems(?) must be fix future update..i using torque game engine since 2005.
but, do not still fixed current version.
#7
08/29/2011 (6:34 am)
Sweet work, Caleb! Thanks for sharing!
Torque Owner Richard Ranft
Roostertail Games
I'm not certain that you have to do this, but it seems like the right direction.