NetStringTable out-of-sync in demo playback
by Stephane Conde · in Torque Game Engine · 11/08/2006 (4:53 am) · 3 replies
Hello,
I was noticing that in our demo playbacks most of the clientCmd... function calls were not being called. Upon further investigation, it seems like the NetStringTable's are out-of-sync between the original run-through (when the demo was recorded) and the demo playback run-through. The tables being out-of-sync causes the wrong clientCmd... function to be called in the demo.
Here is an example of the NetStringTable using the dumpToConsole command:
Original run-through:
Demo run-through:
So, for example, if a RemoteCommandEvent packet for the clientCmdClearCenterPrint function was received on the client, the ID 30 would be recorded in the demo because that is the ID associated with clientCmdClearCenterPrint in the original run-through. But when the demo sees the RemoteCommandEvent packet and reads the ID 30, it will call clientCmdMissionStartPhase1 instead of clientCmdClearCenterPrint because that is what is stored at ID 30 in the demo run-through.
There are a couple of reasons the tables get out-of-sync. One is because in the original run-through, all of the commandToServer calls make entries in the NetStringTable, but in the demo run-through they obviously don't ever get called since the demo is just a client snapshot... In the above example StartGame, MissionStartPhase1Ack, MissionStartPhase2Ack and MissionStartPhase3Ack are all entries from commandToServer calls.
The other issue seems to be that for some strange reason certain strings get added later or earlier in the demo run-through than in the original run-through. In the above example you'll notice that GameStart is added to the list much later in the demo run-through than in the original run-through. This could be due to the fact that I don't start recording the demo until a little bit after the mission has started, so perhaps the server had already added the GameStart string to the table before the demo recording began...
Either way, am I looking in the correct place to figure out why my clientCmd... functions are not being called in the demo playback? Has anyone else experienced this problem? Does this make any sense? If so, does anyone have any ideas on how to remedy the problem?
Thank you very much in advance for any help you might be able to provide.
Cheers,
Stephane
I was noticing that in our demo playbacks most of the clientCmd... function calls were not being called. Upon further investigation, it seems like the NetStringTable's are out-of-sync between the original run-through (when the demo was recorded) and the demo playback run-through. The tables being out-of-sync causes the wrong clientCmd... function to be called in the demo.
Here is an example of the NetStringTable using the dumpToConsole command:
Original run-through:
26: "ServerMessage" REF: 12 27: "GameOver" REF: 6 28: "StartGame" REF: 3 29: "PopActionMap" REF: 3 30: "ClearCenterPrint" REF: 3 31: "MissionStartPhase1" REF: 3 32: "GameStart" REF: 3 33: "MissionStartPhase1Ack" REF: 3 34: "MissionStartPhase2" REF: 3 35: "MissionStartPhase2Ack" REF: 3 36: "MissionStartPhase3" REF: 3 37: "MissionStartPhase3Ack" REF: 3 38: "MissionStart" REF: 3
Demo run-through:
26: "ServerMessage" REF: 1 27: "GameOver" REF: 2 28: "PopActionMap" REF: 1 29: "ClearCenterPrint" REF: 1 30: "MissionStartPhase1" REF: 1 31: "MissionStartPhase2" REF: 1 32: "MissionStartPhase3" REF: 1 33: "MissionStart" REF: 1 34: "GameStart" REF: 1
So, for example, if a RemoteCommandEvent packet for the clientCmdClearCenterPrint function was received on the client, the ID 30 would be recorded in the demo because that is the ID associated with clientCmdClearCenterPrint in the original run-through. But when the demo sees the RemoteCommandEvent packet and reads the ID 30, it will call clientCmdMissionStartPhase1 instead of clientCmdClearCenterPrint because that is what is stored at ID 30 in the demo run-through.
There are a couple of reasons the tables get out-of-sync. One is because in the original run-through, all of the commandToServer calls make entries in the NetStringTable, but in the demo run-through they obviously don't ever get called since the demo is just a client snapshot... In the above example StartGame, MissionStartPhase1Ack, MissionStartPhase2Ack and MissionStartPhase3Ack are all entries from commandToServer calls.
The other issue seems to be that for some strange reason certain strings get added later or earlier in the demo run-through than in the original run-through. In the above example you'll notice that GameStart is added to the list much later in the demo run-through than in the original run-through. This could be due to the fact that I don't start recording the demo until a little bit after the mission has started, so perhaps the server had already added the GameStart string to the table before the demo recording began...
Either way, am I looking in the correct place to figure out why my clientCmd... functions are not being called in the demo playback? Has anyone else experienced this problem? Does this make any sense? If so, does anyone have any ideas on how to remedy the problem?
Thank you very much in advance for any help you might be able to provide.
Cheers,
Stephane
About the author
Recent Threads
#2
This is really the only issue I've found with the demo playback... unfortunately its not a small one and I haven't been able to think of a solution.
Does anyone have any suggestions for how to get around this?
Thanks!
Stephane
11/08/2006 (11:49 am)
Thanks Stefan for the reply.This is really the only issue I've found with the demo playback... unfortunately its not a small one and I haven't been able to think of a solution.
Does anyone have any suggestions for how to get around this?
Thanks!
Stephane
#3
This fixed demo recording entirely for us and we ended up shipping Once Upon A Time with it:
The lines preceded by 'Added the following line' (one in each function) are what fixed the issue. Writing and reading the event's sequence counts synced up the NetStringTable between the original run through and the demo.
Happy demo recording!
Stephane
11/05/2008 (10:09 pm)
I had actually fixed this almost two years ago, but never got back to posting the fix.This fixed demo recording entirely for us and we ended up shipping Once Upon A Time with it:
void NetConnection::eventWriteStartBlock(ResizeBitStream* stream)
{
stream->write(mNextRecvEventSeq);
for(NetEventNote* walk = mWaitSeqEvents; walk; walk = walk->mNextEvent)
{
stream->writeFlag(true);
S32 classId = walk->mEvent->getClassId(getNetClassGroup());
stream->writeClassId(classId, NetClassTypeEvent, getNetClassGroup());
walk->mEvent->write(this, stream);
// Added the following line:
stream->write(walk->mSeqCount);
stream->validate();
}
stream->writeFlag(false);
}
void NetConnection::eventReadStartBlock(BitStream* stream)
{
stream->read(&mNextRecvEventSeq);
NetEventNote* lastEvent = NULL;
while(stream->readFlag())
{
S32 classTag = stream->readClassId(NetClassTypeEvent, getNetClassGroup());
NetEvent* evt = (NetEvent*)ConsoleObject::create(getNetClassGroup(), NetClassTypeEvent, classTag);
evt->unpack(this, stream);
NetEventNote* add = mEventNoteChunker.alloc();
add->mEvent = evt;
add->mEvent->incRef();
// Added the following line:
stream->read(&add->mSeqCount);
add->mNextEvent = NULL;
if (!lastEvent)
mWaitSeqEvents = add;
else
lastEvent->mNextEvent = add;
lastEvent = add;
}
}The lines preceded by 'Added the following line' (one in each function) are what fixed the issue. Writing and reading the event's sequence counts synced up the NetStringTable between the original run through and the demo.
Happy demo recording!
Stephane
Torque Owner Stefan Lundmark