Problems with explosions in TGE 1.4
by Jeff Faust · in Torque Game Engine · 03/06/2006 (9:34 pm) · 12 replies
There are problems with explosions in TGE 1.4 that prevent the Explosion's emitters, and possibly other details from running. I hesitate to call them bugs, because I think changes to Explosion in 1.4 were trying to improve its behavior as a client/server object, however, the changes break some of the way explosions are used in other parts of TGE. (If you run the standard starter.fps demo, you should notice that the crossbow impacts no longer produce smoke and are possibly missing some other details.)
Here's the situation. Explosions are a bit odd because they are often created and used as client-only objects. This is done inside TGE by Projectile, Splash, Debris, and Explosion itself to create sub-explosions. However, when this is done, the Explosion thinks it is a server object (based on what isServerObject() returns) even though it's running on the client. However, to make matters more complicated, parts of Explosion depend on the advanceTime() method being called, which is normally only called on client objects. In TGE 1.3, the advanceTime() method does get called because Explosion explicitly adds itself to gClientProcessList.
So with Explosion, when used by Projectiles and other objects, we have a client-only object that thinks its a server-object, but expects to get advanceTime() calls like other client objects.
Now in TGE 1.4 it looks like a number of isServerObject() and isClientObject() tests have been added. Some of these seem ok, but in one case, the test prevents Explosion from being added to gClientProcessList. This prevents Explosion from getting advanceTime() calls and in turn prevents certain explosion details from running, namely the emitters. for smoke etc. There is another test that may be preventing camera shake effects.
It appears that removing the one isServerObject() test that prevented Explosion from being added to the gClientProcessList restores the proper emitter behavior. Hopefully this doesn't break something else out there.
Here's the situation. Explosions are a bit odd because they are often created and used as client-only objects. This is done inside TGE by Projectile, Splash, Debris, and Explosion itself to create sub-explosions. However, when this is done, the Explosion thinks it is a server object (based on what isServerObject() returns) even though it's running on the client. However, to make matters more complicated, parts of Explosion depend on the advanceTime() method being called, which is normally only called on client objects. In TGE 1.3, the advanceTime() method does get called because Explosion explicitly adds itself to gClientProcessList.
So with Explosion, when used by Projectiles and other objects, we have a client-only object that thinks its a server-object, but expects to get advanceTime() calls like other client objects.
Now in TGE 1.4 it looks like a number of isServerObject() and isClientObject() tests have been added. Some of these seem ok, but in one case, the test prevents Explosion from being added to gClientProcessList. This prevents Explosion from getting advanceTime() calls and in turn prevents certain explosion details from running, namely the emitters. for smoke etc. There is another test that may be preventing camera shake effects.
It appears that removing the one isServerObject() test that prevented Explosion from being added to the gClientProcessList restores the proper emitter behavior. Hopefully this doesn't break something else out there.
About the author
Recent Threads
#2
I've got a version that's up and working that supports both server-spawned explosions (via standard script calls using "new Explosion()") and the typical client-side only collisions generated by projectiles -- all without bugs -- and the IFL-based animations (exported from Maya no less) work fine.
I'd post the code for it but I haven't got time to verify it works on a vanilla version of TGE 1.4 anymore. From memory it should do -- except for a call to makeGhost (which doesn't exist in 1.4). If you want the code, try emailing me -- just don't expect any support. I don't have time.
03/07/2006 (6:04 am)
I went through the explosion code just last week. It's hideously broken in places in an attempt to make it client-side only (which it doesn't need to be).I've got a version that's up and working that supports both server-spawned explosions (via standard script calls using "new Explosion()") and the typical client-side only collisions generated by projectiles -- all without bugs -- and the IFL-based animations (exported from Maya no less) work fine.
I'd post the code for it but I haven't got time to verify it works on a vanilla version of TGE 1.4 anymore. From memory it should do -- except for a call to makeGhost (which doesn't exist in 1.4). If you want the code, try emailing me -- just don't expect any support. I don't have time.
#3
The only place I can find it is in projectile.cc and it's there in 2 places.
I used the search function in msvc2005 to search the whole project.
05/13/2006 (11:20 am)
I don't find "isServerObject() " in explosion.cc The only place I can find it is in projectile.cc and it's there in 2 places.
I used the search function in msvc2005 to search the whole project.
#4
05/13/2006 (11:27 am)
There's one on line 732, 959, 990, 1048, 1073... are you sure you're using your search tool correctly? Unless you downloaded from cvs and they were removed?
#5
I did find it tho. Do I just remove all the ifs??
05/13/2006 (12:03 pm)
I hve a stock download. I've never been able to use cvs.I did find it tho. Do I just remove all the ifs??
if(!isServerObject())It seems vs5s search feature thinks that's one word. :D
#6
05/13/2006 (12:24 pm)
In explosion.cc, there are 4 instances. The first one is the following if statement:// Try to explode!
if( mDelayMS == 0 && !explode() )
return false;
mRandomVal = sgRandom.randF();
if(!isServerObject())
{
gClientContainer.addObject(this);
gClientSceneGraph->addObjectToScene(this);
removeFromProcessList();
gClientProcessList.addObject(this);
NetConnection* pNC = NetConnection::getConnectionToServer();
AssertFatal(pNC != NULL, "Error, must have a connection to the server!");
pNC->addObject(this);
}Do I remove the whole if? Removing the other 3 makes things work better, but I'm curious about this one.
#7
Also, don't try to make sense of the logic. The problems arise because isServerObject() and isClientObject() don't return valid answers in some of the contexts in which Explosion is used.
05/13/2006 (1:22 pm)
The isServerObject() test that prevents adding of the Explosion instance to various client-oriented lists is the key one. Don't remove the contents of the if statement. Just remove the test.Also, don't try to make sense of the logic. The problems arise because isServerObject() and isClientObject() don't return valid answers in some of the contexts in which Explosion is used.
#8
05/13/2006 (1:23 pm)
Ok, thankyou.
#9
Have anyone of you tried it trough multiplayer? Because what I found was that the clients which were connected to the server got occasional freezes, and sometimes explosions were skipped.
So I'm quite sure there's sideeffects to these changes.
05/14/2006 (12:23 pm)
I adopted this fix and ran it trough alot of tests in our multiplayer enviorment.Have anyone of you tried it trough multiplayer? Because what I found was that the clients which were connected to the server got occasional freezes, and sometimes explosions were skipped.
So I'm quite sure there's sideeffects to these changes.
#10
05/14/2006 (2:31 pm)
I have tried it thru a multiplayer and it worked fine. I was getting lag and missed explosions before the fix.
#11
05/14/2006 (11:21 pm)
Quote:Same here.
I have tried it thru a multiplayer and it worked fine. I was getting lag and missed explosions before the fix.
#12
Is there a solution yet that fixes the explosion code?
11/01/2006 (10:40 am)
Sorry for bringing this thread back to the light, but I just found this via the search tool and I've got the same problems. If I am deleting the isServerObject test from onAdd to make the code block that adds the explosion to the client list active, it'll also remove the explosion from the tick processing list. Explosion objects won't be ever deleted then (deletion logic is in processTick() ). Is there a solution yet that fixes the explosion code?
Torque Owner Tim Heldna
Above worked for me. I was using a projectile for a vehicle explosion. The projectile being set to bounce before exploding and the explosionData containing a shape with an ifl animation. In 1.4 the explosion wasn't appearing, remove the isServerObject() test from explosion.cc and it works.
P.S. To save on double posting, in my thread I'll refer people to this thread.