Game Development Community

"BitStream::readClassId - unexpected class ID!"

by JeffH · in Torque 3D Professional · 11/18/2013 (4:39 pm) · 11 replies

"BitStream::readClassId - unexpected class ID!"

I keep getting this error on datablock transmission when a person is hosting a server for my game. We have tried removing datablocks that we have made ourselves, but now its doing it on the default ones themselves from the stock engine.

I'm using Torque3D MIT 3.0 with openGL and PhysX, but I have not touched the bitstream class at all. Any information on this topic would be greatly appreciated!!!

Thanks guys!

#1
11/18/2013 (5:39 pm)
Errors like that are usually the result of mismatched packData()/unpackData() functions. If you have edited any of these functions, that would be the first place to look. If that's the case, compiling with TORQUE_DEBUG_NET defined can help identify the class with the mismatched functions.
#2
11/18/2013 (6:03 pm)
Yes I did actually. I actually modified the NetObject namespace of those so that I could have a scriptable stream. Hmm I'll look into it further, thanks!

Heres what I did if anybody sees anything wrong with it (it does work for at least SP in transferring dynamic fields to the client)

U32 NetObject::packUpdate(NetConnection* conn, U32 mask, BitStream* stream)
{
   // Jeff: torquescript networking powerzzz!
   // 1. make a call to the scripting engine and write the amount of fields we will be sending
   // 2. let the scripting engine call obj.sentToClient() as much
   //    as the programmer wants
   // 3. send each piece of data
   // 4. clear the vector
   // and if we get packet loss, screw it! :D
   if (stream->writeFlag(mTorqueNetworking))
   {
      writePacket_callback();
   
      U32 count = mTorqueName.size();
      stream->write(count);

      for (U32 i = 0; i < count; i ++)
      {
         stream->write(mTorqueName[i]);
         stream->write(mTorqueValue[i]);
      }

      // Jeff: write the count as well
      mTorqueName.clear();
      mTorqueValue.clear();
   }
   
   return 0;
}

void NetObject::unpackUpdate(NetConnection* conn, BitStream* stream)
{
   // Jeff: unpack the scripting
   if (stream->readFlag())
   {
      U32 count;
      stream->read(&count);

      // Jeff: parse the data
      String name;
      String value;
      for (U32 i = 0; i < count; i ++)
      {
         stream->read(&name);
         stream->read(&value);

         // Jeff: inform torqueScript that we got a name and value
         // coming in
         readPacket_callback(name, value);
         name = "";
         value = "";
      }
   }
}

But then again the datablock is not a netobject, right? isn't it a simdatablock?

EDIT: I removed the above and its still doing the same thing D:
#3
11/18/2013 (6:54 pm)
Everything in your posted code snipet seems to be matched properly. Once the bitstream becomes corrupted, it's impossible to predict where the error will show up. Values that are not validated when read will not give any indication of an error, they will just store bogus values. Did running with TORQUE_DEBUG_NET defined provide any clues? It will be tough to track down without the debugging tools.
#4
11/18/2013 (6:55 pm)
Just checked and found this:

c:\users\jeff\desktop\my svn\marblegame\engine\source\t3d\gamebase\gameconnectionevents.cpp(213) : Fatal-ISV - unpack did not match pack for event of class PathMarkerData.

gonna go look now (custom class I made for markers, as I wanted my own class :P)

I'll post back results.

Thanks for the top of that define!

spoilers! I'm not making a FPS game o.o
#5
11/18/2013 (7:01 pm)
Reply to above:

yep, it was that class, but I don't see what is possibly wrong with it, here is the struct for this datablock:
struct PathMarkerData : public ShapeBaseData
{
   typedef ShapeBaseData Parent;

public:
   DECLARE_CONOBJECT(PathMarkerData);
   PathMarkerData();

   bool onAdd();
   void onRemove();

   static void initPersistFields();
   virtual void packData(BitStream* stream);
   virtual void unpackData(BitStream* stream);
};
#6
11/18/2013 (7:22 pm)
How do the packData/unpackData functions in that class match up in terms of bits written/bits read? There doesn't appear to be any data to network with PathMarkerData...Is it's uniqueness entirely within the onAdd/onRemove functionality? Since there's no data, my only guess would be that you're failing to call the parent pack or unpack function.
#7
11/18/2013 (9:27 pm)
post full defination of

virtual void packData(BitStream* stream);
virtual void unpackData(BitStream* stream);
#8
11/19/2013 (1:19 pm)
Konrad posted an excellent resource that has saved my butt a couple of times - finding these issues...def worth checking it out.

http://www.garagegames.com/community/resources/view/21649
#9
11/21/2013 (12:56 pm)
Where is mTorqueName and mTorqueValue defined? My guess is that you're having something missing in terms of a value defined for one of your vars and stream->read(&value); cannot locate this.
#10
11/21/2013 (3:14 pm)
@Robert I found out that wasn't the problem. The issue was my custom PathMarker/PathMarkerData classes.

@Ahsan

I was just calling parent in them, didn't implement much in it at all. What I did however was did an override on the hide method. Everything else should be okay. I didn't call parent on my hide as I wanted it to be custom (wanted a rendered dts shape to appear in editor, but still wanted bounding box detection when it was hidden)
#11
11/23/2013 (4:52 pm)
Well as long as you got it working to your needs, that's what matters. :)