Game Development Community

Ghosting code and questions

by Novack · in Torque Game Engine · 01/02/2008 (8:19 am) · 3 replies

I've been reading all I could about Torque ghosting functionality. I think I got the concepts, and all in all Im going well. However, Im having a hard time, trying to follow the code logic, specifically the unpackUpdate() precedure. If I understood well, you can have sets of fields, grouped under a mask. When the mask is dirty the packUpdate() procedure pack the data into the stream, in base of the proper mask.

My problem comes when I try to follow unpackUpdate(), and found a bunch of exactly the same IF statements.
Taking the simple example from TDN:

///        void  unpackUpdate(NetConnection  *,  BitStream  *stream)
///        {
///              //  the  unpackUpdate  function  must  be  symmetrical  to  packUpdate
///             [b] if(stream->readFlag())[/b]
///              {
///                    stream->readString(message1);
///                    Con::printf("Got  message1:  %s",  message1);
///              }
///             [b] if(stream->readFlag())[/b]
///              {
///                    stream->readString(message2);
///                    Con::printf("Got  message2:  %s",  message2);
///              }
///        }
///

Now, what it means with "unpackUpdate function must be symmetrical to packUpdate"?
How this procedure actually works with many equal IF statatments?

In conclusion: can anybody help understand the logic of this function? Or maybe I didnt understood the whole ghosting functionality?


And! here you have another one: can a field be in more than one set? I mean: under more than one mask.

Thank you to anyone who can take me out of my misery.

#1
01/02/2008 (8:46 am)
Regarding the "unpackUpdate function must be symmetrical to packUpdate," what this means is the order in which data is written out in packUpdate determines the order in which it must be read in unpackUpdate. As an example, consider the following bit of code:

void packUpdate(NetConnection *conn, U32 mask, BitStream *stream)
{
     stream->writeFlag(myFlag);
     stream->writeInt(myInteger, 8);
     stream->writeFloat(myFloat, 8);
}

void unpackUpdate(NetConnection *conn, BitStream *stream)
{
     myFlag      =  stream->readFlag();
     myInteger = stream->readInt(8);
     myFloat     = stream->readFloat(8);
}

Now, using the above bit of code, you can see that that the order you write data out via packUpdate() determines the order you must read it in unpackUpdate(). If you tried to, for example, read myInteger before myFlag bad things would happen. :)

As for the if(stream->readFlag()) part, that's simply a way of determining how much data can be read at one time based on a 1-bit flag. It's essentially like telling unpackUpdate(), "Hey, there's a specific group of data coming down the pipe, get ready to read it."

And for your last question, assuming I'm understanding it correctly, yes, you can send a field under multiple masks.
#2
01/02/2008 (8:55 am)
Chris, I feel like Im leaving the zombie status!! Thank you!
#3
01/02/2008 (9:19 am)
Glad I could help. :)