Game Development Community

Making certain objects not exist for certain clients?

by Aloshi · in Torque 3D Professional · 01/21/2011 (5:33 pm) · 5 replies

So, I'd like to make objects that certain clients can't see or collide with, but behave normally for others. As far as I can tell, Torque doesn't have out-of-the-box support for something like this - I hope I'm wrong, though. Could anyone point me in the right direction?

#1
01/21/2011 (10:28 pm)
Hmm. Intriguing. Sounds potentially spooky.

I don't [u]think[/u] so. My desktop's off but I just dug through my references on TGE. I can't see a way in the cursory search I made to simply script that. I do see a few tantalizing ways to maybe mod it in.

The places I started thinking about it are with those classes closer to being able to handle and manage collision and rendering. ShapeBase and GameBase if I've read correctly. You could add a script/datablock visible bitflag member for storage that'd be used to control rendering and collision. Of course this gets silly after a bit, potentially. Some clients will have a lot of objects that are neither rendered nor colliding but are being sent to them.

So I backed up a bit and realized that the server ought to be communicating or not to these clients what they're getting. One set of methods of NetObjects that intrigues me with this question is scopeToClient, scopeAlways and clearScopeToClient. I hesitate at mucking the network code up, this could have side-effects, but looking at adding a scopeNever (?) and a scopeNotToThisClient and also a clearNotToThisClient (or however you phrase it). That doesn't sound like you'd have to work too hard at the mod (if you're up to that). It might be limitable to one class (helpful, easier). And it might give you the power to control the remainder of what you wish to do in script with the craziest scenarios you might want (powerful).

Or it might be buggy and crash like hell. I'm improvising off the cuff with a book.

Anyhow, hope that's somehow helpful. Mostly I'm intrigued to see where you go with your question.
#2
01/21/2011 (11:57 pm)
If you are also using different datablocks for each of the players you could have a statement that does not show certain items based on the players datablock.
#3
01/23/2011 (4:49 pm)
Well, if anyone wonders what I ended up doing - I modified the source so that it wouldn't send updates of objects of a certain class (this class can be defined separately for each client) to clients. It was actually pretty easy, but it took me a while since I'm terrible at C++ and this was my first time going through the source code.

However, I've still got to do collision. I think that's a job for tomorrow, though.
#4
01/27/2011 (1:14 pm)
How'd collision go? Or is it not that tomorrow yet? :-)
#5
01/27/2011 (1:40 pm)
I actually got it working pretty well. I probably didn't do this in the most efficient manner, but here's basically what I did:

1. In player.cpp - Player::updateWorkingCollisionSet. I added an extra argument to mConvex.updateWorkingList, which contains the class (defined in TorqueScript, you get it with object->getClassNamespace()) that client wants to ignore collision for.
2. In convex.cpp - Convex::updateWorkingList. I added an extra, optional argument to this method for the ignore collision class. In the findObjects method, I pass this class yet again to that function.
3. In sceneObject.cpp - Container::findObjects. I added an extra if surrounding the (*callback)(chain->object,key); line, to check if the ignore class is equal to that object's class.

Not super clean, but it works good. To fix client collision prediction, I did some class-specific stuff. I've only done it with TSStatic, but it should be easy enough to copy to other classes.

1. tsStatic.cpp - TSStatic::packUpdate. I placed an if/else above the I actually got it working pretty well. I probably didn't do this in the most efficient manner, but here's basically what I did:

1. In player.cpp - Player::updateWorkingCollisionSet. I added an extra argument to mConvex.updateWorkingList to pass the class (defined in TorqueScript, you get it with object->getClassNamespace()) that client wants to ignore collision for.
2. In convex.cpp - Convex::updateWorkingList. I added an extra, optional argument to this method for the ignore collision class. In the findObjects method, I pass this class yet again to that function.
3. In sceneObject.cpp - Container::findObjects. I added an extra if surrounding the (*callback)(chain->object,key); line, to check if the ignore class is equal to that object's class.

Not super clean, but it works good. To fix client collision prediction, I did some class-specific stuff. I've only done it with TSStatic, but it should be easy enough to copy to other types.

1. tsStatic.cpp - TSStatic::packUpdate. I placed an if/else statement above
if ( stream->writeFlag( mask & UpdateCollisionMask ) )
		  stream->write( (U32)mCollisionType );
that is basically a copy of that, but if the client's ignore class is the same as that object's, then it does stream->writeFlag( 0 );, which tells the client that the object is of the "None" collision type.

EDIT: Oh yeah, since the client prediction stuff is in packUpdate, you have to somehow make the client update objects that you want it to ignore (or stop ignoring). I loop through the RootGroup and find affected objects and call inspectPostApply() on them (which is also inefficient! Hooray!).