MaskBits out of bits
by Danner Jones · in Torque Game Engine · 03/08/2004 (7:09 am) · 11 replies
I've added two values to the Player class's MaskBits enum and I noticed that these have "overflowed" the bits in there. Meaning, the values have been shifted so far to the left that they've rolled back to 0. Uh oh. Any ideas? :)
-nerseus
-nerseus
#2
My original thought was why even use those masks - why not just use a bool variable and use that flag in the pack/unpackUpdate functions?
But when I looked more at the flags I saw them being used by setMaskBits, which is defined in NetObject and modifies some "dirty" lists. Not fully understanding all of that yet, I decided to ask first and see what others might suggest.
I wonder - would there be any problem with using my own "dirty" flag (bool variable) and just using that flag to write data in packUpdate/unpackUpdate? Would I be "breaking" things by not use setMaskBits?
-Nerseus
03/08/2004 (12:11 pm)
@Paul: I like both of your ideas. I was going to just piggy back on one of the existing flags at first, but decided to try and expand things. Then I decided I'd update every tick, but that seemed overkill for my updates.My original thought was why even use those masks - why not just use a bool variable and use that flag in the pack/unpackUpdate functions?
But when I looked more at the flags I saw them being used by setMaskBits, which is defined in NetObject and modifies some "dirty" lists. Not fully understanding all of that yet, I decided to ask first and see what others might suggest.
I wonder - would there be any problem with using my own "dirty" flag (bool variable) and just using that flag to write data in packUpdate/unpackUpdate? Would I be "breaking" things by not use setMaskBits?
-Nerseus
#3
I believe PackUpdate only gets called once to ship all the info to the ghosts for each update, so I see no reason why you couldn't create your own string of masks. you might want to trigger all of your masks with a "real" masks so that torque knows that it actually needs to send some data over to the ghosts.
-Pascal
03/08/2004 (5:20 pm)
I got rid of TeamMask, ShieldMask, and InvincibleMask and the corresponding code in shapebase.h/.cc and that freed up some masks for other uses.I believe PackUpdate only gets called once to ship all the info to the ghosts for each update, so I see no reason why you couldn't create your own string of masks. you might want to trigger all of your masks with a "real" masks so that torque knows that it actually needs to send some data over to the ghosts.
-Pascal
#4
When you set a mask (any mask) using the setMaskBits function, the dirtyBit is then considered 'dirty'. All the setMaskBits function is ever used for (AFAIK) is to notify the server when it has updates to give to clients. When the dirtyBit is 'dirty', server sends an update, otherwise, it doesn't.
The dirtyBit is then used again in the packUpdate fuction (U32 mask) to determine what information is to be included in the update (moves, cloaking, invincibility, etc.).
Hopes this help your understanding of the masking system...
By the way, no one needs 8 mountable images... you could easily cut that one down :)
07/27/2004 (9:22 pm)
Hey All,When you set a mask (any mask) using the setMaskBits function, the dirtyBit is then considered 'dirty'. All the setMaskBits function is ever used for (AFAIK) is to notify the server when it has updates to give to clients. When the dirtyBit is 'dirty', server sends an update, otherwise, it doesn't.
The dirtyBit is then used again in the packUpdate fuction (U32 mask) to determine what information is to be included in the update (moves, cloaking, invincibility, etc.).
Hopes this help your understanding of the masking system...
By the way, no one needs 8 mountable images... you could easily cut that one down :)
#5
.... or you can do like I did: use an internal mask for each class.
What this means: create a mask that is locally defined, just a class member variable, and its bit fields, then there is an extendedInfoMask in the code that isn't used, so you set this mask with the setMaskBits function and then your local mask, just remember to reset to 0 your internal mask after you have used it, example:
In the player class
In the packUpdate function
In the unpackUpdate
When you need to set the mask you have to do something like
07/30/2004 (12:10 am)
Hi,.... or you can do like I did: use an internal mask for each class.
What this means: create a mask that is locally defined, just a class member variable, and its bit fields, then there is an extendedInfoMask in the code that isn't used, so you set this mask with the setMaskBits function and then your local mask, just remember to reset to 0 your internal mask after you have used it, example:
In the player class
enum PlayerExtMask {
DestroyHeadMask = 0x00000001,
DestroyLeftArmMask = 0x00000002,
DestroyRightArmMask = 0x00000004
};
protected:
U32 PlayerExtMaskBits; ///< Extra mask bits used internally by the player classIn the packUpdate function
if (stream->writeFlag(mask & ExtendedInfoMask)) //Extended mask
{
if (stream->writeFlag(PlayerExtMaskBits & DestroyHeadMask))
{
}
if (stream->writeFlag(PlayerExtMaskBits & DestroyRightArmMask))
{
}
if (stream->writeFlag(PlayerExtMaskBits & DestroyLeftArmMask))
{
}
}
else
{
PlayerExtMaskBits = 0; //Reset the mask
}In the unpackUpdate
if (stream->readFlag()) //ExtendInfoMask flag
{
if (stream->readFlag()) //Destroy head flag
{
DestroyLimb(ICArmorData::Loc_Head);
}
if (stream->readFlag()) //Destroy right arm flag
{
DestroyLimb(ICArmorData::Loc_RightArm);
}
if (stream->readFlag()) //Destroy left arm flag
{
DestroyLimb(ICArmorData::Loc_LeftArm);
}
}When you need to set the mask you have to do something like
setMaskBits(ExtendedInfoMask); PlayerExtMaskBits |= DestroyHeadMask;Obviously you can't do all the beautiful things you can do with a basic mask, but for simple things like the above is enough
#6
07/30/2004 (1:32 pm)
That doesn't work well in the case where you have more than one person playing. If you're going to modify stuff, you might want to try making the mask bits 64 bits wide.
#7
I thought to use a 64 bits or a bitSet class, but this means to change all the packUpdate and unpackUpdate functions, but thanks for the info, until now I've tried it only with one host and a client, in a LAN, it works well, but if I'll see a problem with multiple users I'll try using 64 bits.
07/30/2004 (10:55 pm)
Hi Ben,I thought to use a 64 bits or a bitSet class, but this means to change all the packUpdate and unpackUpdate functions, but thanks for the info, until now I've tried it only with one host and a client, in a LAN, it works well, but if I'll see a problem with multiple users I'll try using 64 bits.
#8
10/14/2004 (7:08 pm)
We're running into this same issue and I was wondering if anybody has had any success with moving to a 64 bit mask. Problems with moving to 64 bits would be helpful to know about too!
#9
10/27/2004 (5:44 am)
I don't understand why that code won't work with multiple players?
#10
10/27/2004 (6:59 am)
The reason it won't work with multiple players is that there is one copy of the update mask for each client that has that object in scope-- and there's a bunch of under-the-covers work to make sure that when a packet gets dropped that mask bit states are reset to 1. See the documentation of the network layer for a more detailed explanation.
#11
10/27/2004 (7:08 am)
@Michael, I have had the proof that my code doesn't work with multiple players, also, on certain conditions, it doesn't work with just a host and a client, the set-up I usually use to test my game, so now, just for fun (!!! about 14 hours of fun!) I have changed the network code to use a BitVector class instead of a U32 as the mask, and it seems to work right, at least this has passed the test where the above method failed.
Associate Paul Dana
or...you can just NOT add a new flag but ride your changes in on another flag with roughly the same frequency of usage. For example the Position mask for vehicles fires every single tick. Other flags happen less often. Re-use a flag that does not see much work.