Index: code/branches/network/src/network/GamestateManager.cc
===================================================================
--- code/branches/network/src/network/GamestateManager.cc	(revision 1799)
+++ code/branches/network/src/network/GamestateManager.cc	(revision 1800)
@@ -61,5 +61,5 @@
 
   bool GamestateManager::update(){
-    cleanup();
+//     cleanup();
     return getSnapshot();
   }
@@ -92,7 +92,7 @@
     reference = new packet::Gamestate();
     reference->collectData(++id_);
-    COUT(4) << "inserting gamestate: " << reference << std::endl;
-    gamestateMap.insert(std::pair<int, packet::Gamestate*>(id_, reference));
-    gamestateUsed[id_]=0;
+    //COUT(4) << "inserting gamestate: " << reference << std::endl;
+    //gamestateMap_.insert(std::pair<int, packet::Gamestate*>(id_, reference));
+//     gamestateUsed[id_]=0;
     return true;
   }
@@ -104,5 +104,5 @@
    * 
    */
-  void GamestateManager::cleanup(){
+/*  void GamestateManager::cleanup(){
     std::map<int,int>::iterator it = gamestateUsed.begin();
     while(it!=gamestateUsed.end()){
@@ -124,5 +124,5 @@
       it++;
     }
-  }
+  }*/
 
   packet::Gamestate *GamestateManager::popGameState(int clientID) {
@@ -131,18 +131,25 @@
     packet::Gamestate *gs;
     int gID = ClientInformation::findClient(clientID)->getGamestateID();
-    //COUT(4) << "G.St.Man: popgamestate: sending gstate_id: " << id_ << " diffed from: " << gID << std::endl;
+    gs = reference->doSelection(clientID);
+//     gs = new packet::Gamestate(*reference);
+    // save the (undiffed) gamestate in the clients gamestate map
+    gamestateMap_[clientID].insert(std::pair<int, packet::Gamestate*>(gs->getID(), gs));
     //chose wheather the next gamestate is the first or not
+    packet::Gamestate *client=NULL;
     if(gID != GAMESTATEID_INITIAL){
-      packet::Gamestate *client=NULL;
-      std::map<int, packet::Gamestate*>::iterator it = gamestateMap.find(gID);
-      if(it!=gamestateMap.end())
-        client = it->second;
-      if(client)
-        gs = reference->diff(client);
-      else
-        gs = new packet::Gamestate(*reference);
-    } else {
-      COUT(4) << "we got a GAMESTATEID_INITIAL for clientID: " << clientID << std::endl;
-      gs = new packet::Gamestate(*reference);
+      std::map<unsigned int, std::map<int, packet::Gamestate*> >::iterator clientMap = gamestateMap_.find(clientID);
+      if(clientMap!=gamestateMap_.end()){
+        std::map<int, packet::Gamestate*>::iterator it = clientMap->second.find(gID);
+        if(it!=clientMap->second.end())
+          client = it->second;
+      }
+    }
+    if(client){
+//       COUT(3) << "diffing" << std::endl;
+      gs = gs->diff(client);
+    }
+    else{
+//       COUT(3) << "not diffing" << std::endl;
+      gs = new packet::Gamestate(*gs);
     }
     assert(gs->compressData());
@@ -153,42 +160,33 @@
   bool GamestateManager::ack(int gamestateID, int clientID) {
     ClientInformation *temp = ClientInformation::findClient(clientID);
-    if(temp==0)
-      return false;
+    assert(temp);
     int curid = temp->getGamestateID();
     
     if(gamestateID == 0){
       temp->setGamestateID(GAMESTATEID_INITIAL);
-      if(curid!=GAMESTATEID_INITIAL){
-        assert(gamestateUsed.find(curid)!=gamestateUsed.end());
-        --(gamestateUsed.find(curid)->second);
-      }
       return true;
     }
-    //if(curid > gamestateID)
+    
     assert(curid<gamestateID);
-      // the network packets got messed up 
-      //return true;
     COUT(4) << "acking gamestate " << gamestateID << " for clientid: " << clientID << " curid: " << curid << std::endl;
-    // decrease usage of gamestate and save it
-//     deleteUnusedGameState(curid);
-    //increase gamestateused
-    std::map<int, int>::iterator it = gamestateUsed.find(curid);
-    if(curid!=GAMESTATEID_INITIAL){
-      if(it!=gamestateUsed.end())
-        --(it->second);
-    }
-    it = gamestateUsed.find(gamestateID);
-    if(it!=gamestateUsed.end()){
-      ++(it->second);
-      temp->setGamestateID(gamestateID);
-    }
+    std::map<int, packet::Gamestate*>::iterator it, tempit;
+    for(it = gamestateMap_[clientID].begin(); it!=gamestateMap_[clientID].end() && it->first<gamestateID; it++){
+      delete it->second;
+      tempit=it++;
+      gamestateMap_[clientID].erase(tempit);
+    }
+    temp->setGamestateID(gamestateID);
     return true;
   }
 
   void GamestateManager::removeClient(ClientInformation* client){
-    if(!client)
-      return;
-    if(client->getGamestateID()>=0)
-      gamestateUsed[client->getGamestateID()]--;
+    assert(client);
+    std::map<unsigned int, std::map<int, packet::Gamestate*> >::iterator clientMap = gamestateMap_.find(client->getID());
+    // first delete all remained gamestates
+    std::map<int, packet::Gamestate*>::iterator it;
+    for(it=clientMap->second.begin(); it!=clientMap->second.end(); it++)
+      delete it->second;
+    // now delete the clients gamestatemap
+    gamestateMap_.erase(clientMap);
   }
   
Index: code/branches/network/src/network/GamestateManager.h
===================================================================
--- code/branches/network/src/network/GamestateManager.h	(revision 1799)
+++ code/branches/network/src/network/GamestateManager.h	(revision 1800)
@@ -81,9 +81,10 @@
     void removeClient(ClientInformation *client);
     private:
-    void cleanup(); // "garbage handler"
+//     void cleanup(); // "garbage handler"
     bool processGamestate(packet::Gamestate *gs);
 
-    std::map<int, packet::Gamestate*> gamestateMap; //map gsID to gamestate*
-    std::map<int, int> gamestateUsed; // save the number of clients, that use the specific gamestate
+    std::map<unsigned int, std::map<int, packet::Gamestate*> > gamestateMap_;
+    //std::map<int, packet::Gamestate*> gamestateMap; //map gsID to gamestate*
+    //std::map<int, int> gamestateUsed; // save the number of clients, that use the specific gamestate
     std::map<int, packet::Gamestate*> gamestateQueue;
     packet::Gamestate *reference;
Index: code/branches/network/src/network/Synchronisable.cc
===================================================================
--- code/branches/network/src/network/Synchronisable.cc	(revision 1799)
+++ code/branches/network/src/network/Synchronisable.cc	(revision 1800)
@@ -364,10 +364,13 @@
 
   /**
-   * This function determines, wheter the object should be saved to the bytestream (according to its syncfrequency)
+   * This function determines, wheter the object should be saved to the bytestream (according to its syncmode/direction)
    * @param id gamestate id
    * @return true/false
    */
   bool Synchronisable::isMyTick(unsigned int id){
-//     return true;
+    return ( (objectMode_&state_)!=0 );
+  }
+  
+  bool Synchronisable::doSelection(unsigned int id){
     return ( id==0 || id%objectFrequency_==objectID%objectFrequency_ ) && ((objectMode_&state_)!=0);
   }
Index: code/branches/network/src/network/Synchronisable.h
===================================================================
--- code/branches/network/src/network/Synchronisable.h	(revision 1799)
+++ code/branches/network/src/network/Synchronisable.h	(revision 1800)
@@ -91,4 +91,5 @@
     bool updateData(unsigned char*& mem, int mode=0x0);
     bool isMyData(unsigned char* mem);
+    bool doSelection(unsigned int id);
     void setObjectMode(int mode);
     void setObjectFrequency(unsigned int freq){ objectFrequency_ = freq; }
Index: code/branches/network/src/network/packet/Chat.cc
===================================================================
--- code/branches/network/src/network/packet/Chat.cc	(revision 1799)
+++ code/branches/network/src/network/packet/Chat.cc	(revision 1800)
@@ -55,5 +55,5 @@
   : Packet(data, clientID)
 {
-  messageLength_ = *(unsigned int *)&data[ _MESSAGELENGTH ];
+  messageLength_ = *(unsigned int *)(data + _MESSAGELENGTH );
 }
 
Index: code/branches/network/src/network/packet/Gamestate.cc
===================================================================
--- code/branches/network/src/network/packet/Gamestate.cc	(revision 1799)
+++ code/branches/network/src/network/packet/Gamestate.cc	(revision 1800)
@@ -54,4 +54,9 @@
     Packet(data, clientID)
 {
+}
+
+Gamestate::Gamestate(unsigned char *data)
+{
+  data_=data;
 }
 
@@ -96,4 +101,6 @@
     }// stop allocate additional memory
 
+    if(it->doSelection(id))
+      dataMap_[*it]=mem;  // save the mem location of the synchronisable data
     if(!it->getData(mem, id, mode))
       return false; // mem pointer gets automatically increased because of call by reference
@@ -312,4 +319,31 @@
 }
 
+Gamestate* Gamestate::doSelection(unsigned int clientID){
+  assert(data_);
+  std::map<Synchronisable *, unsigned char *>::iterator it;
+  unsigned char *ndata, *tdata;
+  unsigned int nsize=0;
+  // calculate the size of the new gamestate
+  for(it=dataMap_.begin(); it!=dataMap_.end(); it++){
+    if(it->first->doSelection(HEADER->id))
+      nsize+=*(unsigned int*)it->second;
+  }
+  ndata = new unsigned char[nsize+sizeof(GamestateHeader)];
+  tdata = ndata;
+  tdata += sizeof(GamestateHeader);
+  for(it=dataMap_.begin(); it!=dataMap_.end(); it++){
+    if(it->first->doSelection(HEADER->id)){
+      memcpy(tdata, it->second, *(unsigned int*)it->second); // copy over the saved data of the synchronisable
+      tdata += *(unsigned int*)it->second;
+    }
+  }
+  COUT(3) << "oldsize: " << HEADER->datasize << " newsize: " << nsize << std::endl;
+  *(GamestateHeader *)ndata = *HEADER; //copy over the header
+  GAMESTATE_HEADER(ndata)->datasize = nsize;
+  Gamestate *gs = new Gamestate(ndata);
+  assert(HEADER->datasize>=nsize);
+  return gs;
+}
+
 Gamestate *Gamestate::undiff(Gamestate *base)
 {
Index: code/branches/network/src/network/packet/Gamestate.h
===================================================================
--- code/branches/network/src/network/packet/Gamestate.h	(revision 1799)
+++ code/branches/network/src/network/packet/Gamestate.h	(revision 1800)
@@ -29,4 +29,5 @@
 #include "Packet.h"
 #include "network/Synchronisable.h"
+#include <map>
 #ifndef NDEBUG
 #include "util/CRC32.h"
@@ -62,4 +63,5 @@
     Gamestate();
     Gamestate(unsigned char *data, int clientID);
+    Gamestate(unsigned char *data);
 
     ~Gamestate();
@@ -72,4 +74,5 @@
     int getBaseID();
     Gamestate *diff(Gamestate *base);
+    Gamestate* doSelection(unsigned int clientID);
     Gamestate *undiff(Gamestate *base);
     bool compressData();
@@ -77,4 +80,5 @@
 
     // Packet functions
+  private:
     virtual unsigned int getSize() const;
     virtual bool process();
@@ -84,6 +88,5 @@
     unsigned int calcGamestateSize(unsigned int id, int mode=0x0);
     void removeObject(orxonox::ObjectListIterator<Synchronisable> &it);
-
-  private:
+    std::map<Synchronisable *, unsigned char *> dataMap_;
 };
 
