Ghosting issues with TerrainManager
by J. Donavan Stanley · in Torque Game Engine · 03/04/2003 (3:38 am) · 16 replies
Last night I completed my merge of TerrainManager into the head source. Unfortunatly it doesn't work. I've tracked the problem down to what appears to be a ghosting issue. For some reason it looks as if the client TerrainManager is never getting created. The TerrainManager.cc that I'm using in this buld is the same one I was using before (and that worked) so I'm assuming something has changed in the simulation code?
Since this is diving into uncharted water for me I thought maybe someone who has more background with the network layer could enlighten me as to what might cause an object that's marked (Ghostable | ScopeAlways) to not get ghosted.
Another possibility is that the TerrainManager is getting ghosted, it's just getting ghosted after the client terrain blocks which is way too late.
Since this is diving into uncharted water for me I thought maybe someone who has more background with the network layer could enlighten me as to what might cause an object that's marked (Ghostable | ScopeAlways) to not get ghosted.
Another possibility is that the TerrainManager is getting ghosted, it's just getting ghosted after the client terrain blocks which is way too late.
#2
03/04/2003 (9:10 am)
You'll want to make sure that the Terrain Manager is marked as a scope always object (mNetFlags.set(Ghostable | ScopeAlways). All ghost always objects are constructed on the client in the order of construction on the server.
#3
@Mark: I'm fairly certain I verified those flags. Again, this all worked before and the only actual TM change I had to make was relatingo the new way to handle texture callbacks.
03/04/2003 (10:14 am)
@BT: Actualy the global pointer thing was one of the fixes I put into TM. TM has a static getTerrainManager function which takes a bool to indicate if you want the client or the server copy of the TerrainManager. When the TerrainManager gets added to the simulation it adds itself into a group reserved just for it. getTerrainManager then iterates over the group looking for the appropriate instance. In the GORPE tree this works like a charm. In the new HEAD tree the group containing the TerrainManagers has one entry instead of the two that it should have.@Mark: I'm fairly certain I verified those flags. Again, this all worked before and the only actual TM change I had to make was relatingo the new way to handle texture callbacks.
#4
03/04/2003 (4:48 pm)
The TerrainManager patch complete with ghostng bug is up on gorpe.com now. If someone wants to take a crack at it please feel free. It'll be a bit before I have time to devote to it. This patch is based on the HEAD as of 2/28.
#5
CGI Error
The specified CGI application misbehaved by not returning a complete set of HTTP headers. The headers it did return are:
03/05/2003 (6:32 am)
Hey J. Donavan Stanley. Great work!! I've been waiting to get the new version. When I try to get to your website I getCGI Error
The specified CGI application misbehaved by not returning a complete set of HTTP headers. The headers it did return are:
#6
03/05/2003 (8:16 am)
Yeah I'm not sure what's going on. I shot an email off this AM to my webmaster but I've not heard back from here. I'll call her in just a few.
#7
03/09/2003 (6:46 am)
I just found out that I somehow managed to send the OLD TerrainManager.rar to my webmaster. This has been corrected...
#8
Anyone have an idea? I had expected problems merging up to HEAD but not in this area. I would think that if there a ghost being created (and there is) it's OnAdd function would be called (it's not).
03/13/2003 (7:36 am)
I had a bit of time to dig a little deeper into the problem this morning. It appears that's happening is that the TerrainManager obejct get's ghosted over but never has OnAdd called. This means that when the client terrainBlocks interate over the "TerrainManagerSet" to try and find the client TerrainManager they end up with nothing.Anyone have an idea? I had expected problems merging up to HEAD but not in this area. I would think that if there a ghost being created (and there is) it's OnAdd function would be called (it's not).
#9
I'm sorry I'm not more help, terrain manager is important to me, I wish I better understood both it and torque.
If it helps any I've been having some pretty bad loading time/race issues with terrain and water in general, at one point I had a pause/check in waterblock because it was trying to start before the terrain existed.
-brad
03/13/2003 (9:23 am)
the only thing I can think of is diffing what works (your gorpe tree) with what doesn't (HEAD) and reading through it until something goes ah ha!I'm sorry I'm not more help, terrain manager is important to me, I wish I better understood both it and torque.
If it helps any I've been having some pretty bad loading time/race issues with terrain and water in general, at one point I had a pause/check in waterblock because it was trying to start before the terrain existed.
-brad
#10
03/13/2003 (2:14 pm)
When i run the debugger it stops in the function GetSquareSize(), which returns 0. But i cant see where the function is called, where the code is initialized. The function is called without that the object is created, which is strange.
#11
At this point, it fails with:
*** Phase 3: Mission Lighting
Failed to calculate validation info for object. Skipped.
Failed to calculate validation info for object. Skipped.
Mission lighting done
Not sure if this is any more help. I'll keep looking, but no promises.
- Brett
03/13/2003 (4:54 pm)
Taking a hint from Bryan above, I switched to location of the objects in the .mis file (not even sure if this would do anything). Well, it did... Very interesting. Upon inspecting the console.log file, I see that the second phase of downloading finished (which didn't before) and it goes on to lighting the scene.At this point, it fails with:
*** Phase 3: Mission Lighting
Failed to calculate validation info for object. Skipped.
Failed to calculate validation info for object. Skipped.
Mission lighting done
Not sure if this is any more help. I'll keep looking, but no promises.
- Brett
#12
What i understand, the mainproblem is that the server and the client are loading the terrainfiles in diffrent orders.
Server loads the terrainfile1 and the client loads terrainfile0 and so on.
Do the server only sends the last block to the client?
03/16/2003 (12:57 pm)
I guess that you havent solved this yet.What i understand, the mainproblem is that the server and the client are loading the terrainfiles in diffrent orders.
Server loads the terrainfile1 and the client loads terrainfile0 and so on.
Do the server only sends the last block to the client?
#13
1) server creates a terrainManager
2) server creates terrain files
3) Client creates terrain files
What *should* be step three is "client creates terrainManager". For some reason either th ghost of the terrain manager isn't create or it's way out of order.
03/16/2003 (2:56 pm)
What I've seen under the debugger looks like this:1) server creates a terrainManager
2) server creates terrain files
3) Client creates terrain files
What *should* be step three is "client creates terrainManager". For some reason either th ghost of the terrain manager isn't create or it's way out of order.
#14
1. The system pre-registers the Terrain Manager. In the function TerrainManager::getTerrainManager the boolean bClient is set to false, indicating a server side action.
2. The system pre-registers terrain0. Again in the function TerrainManager::getTerrainManager the boolean bClient is set to false indicating a server side action.
3. The system pre-registers terrain1. Again in the function TerrainManager::getTerrainManager the boolean bClient is set to false indicating a server side action.
Initialization continues.
The system arrives at actual allocation after loading objects. At this point I see...
The system experiences a fallthru - an attempt to register an object falls thru with a NULL value as bClient is set but the
function call to isClientObject() returns a different result leading to a mismatch of neither server nor client.
This repeats again in the next pass.
In the third pass the value comes up as a bClient is true and the system branches to TerrainBlock::setFile where the operation fails when pTerrainManager has a NULL value.
My suspicion is that the first two passes that fall-thru are the Terrain Manager failing to iniitalize and the terrain0 failing to initialize properly.
Anybody seeing anything different?
03/17/2003 (8:17 am)
I believe that you two of you are saying the same thing. When I drop on the debugger what I see is the following:1. The system pre-registers the Terrain Manager. In the function TerrainManager::getTerrainManager the boolean bClient is set to false, indicating a server side action.
2. The system pre-registers terrain0. Again in the function TerrainManager::getTerrainManager the boolean bClient is set to false indicating a server side action.
3. The system pre-registers terrain1. Again in the function TerrainManager::getTerrainManager the boolean bClient is set to false indicating a server side action.
Initialization continues.
The system arrives at actual allocation after loading objects. At this point I see...
The system experiences a fallthru - an attempt to register an object falls thru with a NULL value as bClient is set but the
function call to isClientObject() returns a different result leading to a mismatch of neither server nor client.
This repeats again in the next pass.
In the third pass the value comes up as a bClient is true and the system branches to TerrainBlock::setFile where the operation fails when pTerrainManager has a NULL value.
My suspicion is that the first two passes that fall-thru are the Terrain Manager failing to iniitalize and the terrain0 failing to initialize properly.
Anybody seeing anything different?
#15
The question is why? BT had made some chanes to netghost.cc that changed the order of some of the ghosting in his version. I had acciedntly left that out of the patch. However even having added that back in, I still get the same effect.
I'm going to take a bit of time soon and go back through my working codebase and see if I missed something else important during the upgrade to HEAD.
03/17/2003 (8:43 am)
That fallthrough you're observing is the root of the problem. If bClient is set to true there shouldn't ever be a fallthrough case. Again, the problem lies in that the client side TerrainManager never gets created, or at least gets created AFTER the client side TerrainBlocks. The question is why? BT had made some chanes to netghost.cc that changed the order of some of the ghosting in his version. I had acciedntly left that out of the patch. However even having added that back in, I still get the same effect.
I'm going to take a bit of time soon and go back through my working codebase and see if I missed something else important during the upgrade to HEAD.
#16
03/18/2003 (2:12 pm)
I just sent out an updated rar file to our webmaster. She should have it up sometime this evening. I've not completly tested it, only verified that the app would start and load a multi terrain mission.
Torque Owner Bryan Turner
Ghosting in wrong order:
The TerrainBlock ghosts were being sent over in reverse order, meaning a 2-terrain mission would receive: TerrainBlock, TerrainBlock, TerrainManager. This caused no end of grief. Finally I decided to re-write the ghosting loop to run through the objects in forward order. This would be my first suspicion as to the problem, since I know they've modified the net layer several times since my changes. If you need an exact file/line, I can dig that up.
TerrainManager on local server:
There was an interesting problem when running TerrainManager on the local server. Two instances of TerrainManager would be created, but the wrong one would be found when looking up the object. I made a quick-hack fix for this by setting up a global variable to hold the "right" TM class. I believe this fix has been adjusted by one of the developers after me, but I'm not familiar with the changes he made.
My debugging for these issues stayed well within the Terrain layer, so you won't have to venture far to check on them. Just put a breakpoint on the constructor for TerrainManager, TerrainBlocks, and the registering functions within TerrainManager. Then keep track of the addresses of each instance as they are called/registered.
There should be an initial volley of instances due to the pre-registration in Torque, but these instances will never be used. Once you select a mission for loading, then a set of instances will be created (server side), and ghosted to the client to be created there also.
Let me know if that gets you any closer..
--Bryan
bryan.turner@pobox.com