Game Development Community

NetObject class ID issues

by Anthony Lovell · in Torque Game Engine · 08/17/2006 (8:53 am) · 3 replies

I have 4 applications in my simulation:

PlayerClient, AuthServer, WorldServer, ShipServer

which interconnect in 5 Client/Server varieties:

Player/Auth
Player/World
Player/Ship
World/Auth
Ship/World

I therefore have 5 subclasses of GhostConnection to help me isolate RPCs, NetEvents, etc to the smallest number required across each type of connection, so that (for instance) the PlayerAuthConnection never needs to assign a number to an event that will only ever pass across the ShipWorldConnection. My hope is that I can use the NetClassGroup enums to create 5 distinct number spaces for my NetEvents, NetObjects, etc.

However!

Unlike TNL_IMPLEMENT_NETEVENT(), TNL_IMPLEMENT_NETOBJECT() offers no groupMask parameter by which you indicate which NetClassGroups the NetObject must be included in. Worse, there is nothing to force the NetClassRep for each NetObject class to be included in the class map, as there is nothing which forces the NetObject to be linked into each application whose connections might have to convey this object (I had to work around this by using a "delete new MyNetObject()" on the clientside, as otherwise the client was being linked without code for a class it never instantiated explicitly.

For instance, my AuthServer's NetClassRep has 3 NetObjects declared for the PlayerAuthNet group. But the PlayerClient has 5... and the majority of these will never pass across the PlayerAuthConnection.

Should I be thinking about reworking this by using a richer version of the TNL_IMPLEMENT_NETOBJECT macro which allows you to specify which NetClassGroups the object should belong to? I'd love to see this global class map reduced to one which simply enumerates NetConnection classes, and have each NetConnection class, in turn, maintain a classmap (without groups, as the groups seem to correspond to the netconnection class) of objects it enumerates?

tone

#1
08/17/2006 (11:43 am)
While I do not yet have an elegant solution to the linking issue, I hit upon the simplest workaround for limiting NetObjects to only those groups they'll actually traverse, which was also Ben Garney's suggestion.

Alter TNL_IMPLEMENT_NETOBJECT (or create a new variant, as shown below) which permit you to specify a mask of those NetClassGroups that should allocate a slot for this NetObject.

#define TNL_IMPLEMENT_NETOBJECT2(className, groupMask) \
            TNL::NetClassRep* className::getClassRep() const { return &className::dynClassRep; } \
            TNL::NetClassRepInstance<className> className::dynClassRep(#className, groupMask, TNL::NetClassTypeObject, 0)

I did this, and the needless duplication of each NetObject across all my groups ceased.

tone
#2
08/18/2006 (4:08 pm)
Cool... in general I think you were heading in the right direction as far as a refactor though. It would be cool to have some static initialization method in the connection where you could add classes to that connection's list -- the only trick would be if you had an RPC on a NetObject that was only valid for one of the connections that NetObject travelled over. Probably not a highly frequent event, but who knows :)
#3
09/06/2006 (4:32 pm)
I'm not as good at making these macro things as you masters are, clearly. But I did see a good sense in basically "declaring" items on the class of the NetConnection subclass(es) they will actually be traversing in practice.

I did find, for instance, that when constructing a server application, it was necessary to provoke the linker to see the actual NetConnection subclasses it would be having to construct at runtime, e.g.:

// fancyServerOnlyApp.cc

int main(args) {

// make sure it has this code linked in, as the client will be trying to make it new them up dynamically
delete new MyConnectionClass();

...
}

That said, I'm going to hazard a few suggestions for improvements in another thread.

tone