Index: trunk/src/lib/network/message_manager.h
===================================================================
--- trunk/src/lib/network/message_manager.h	(revision 8145)
+++ trunk/src/lib/network/message_manager.h	(revision 8147)
@@ -29,5 +29,6 @@
 {
   TESTMESSAGEID = 1,
-  MSGID_DELETESYNCHRONIZEABLE
+  MSGID_DELETESYNCHRONIZEABLE,
+  MSGID_PREFEREDTEAM
 };
 
Index: trunk/src/lib/network/network_game_manager.cc
===================================================================
--- trunk/src/lib/network/network_game_manager.cc	(revision 8145)
+++ trunk/src/lib/network/network_game_manager.cc	(revision 8147)
@@ -59,4 +59,5 @@
   
   MessageManager::getInstance()->registerMessageHandler( MSGID_DELETESYNCHRONIZEABLE, delSynchronizeableHandler, NULL );
+  MessageManager::getInstance()->registerMessageHandler( MSGID_PREFEREDTEAM, preferedTeamHandler, NULL );
   
   this->gameState = 0;
@@ -86,6 +87,6 @@
   
   int team = rules.getTeamForNewUser();
-  ClassID playableClassId = rules.getPlayableClassId( team );
-  std::string playableModel = rules.getPlayableModelFileName( team, playableClassId );
+  ClassID playableClassId = rules.getPlayableClassId( userId, team );
+  std::string playableModel = rules.getPlayableModelFileName( userId, team, playableClassId );
   
   BaseObject * bo = Factory::fabricate( playableClassId );
@@ -159,4 +160,10 @@
     if ( dynamic_cast<Synchronizeable*>(*it)->getUniqueID() == uniqueId )
     {
+      if ( (*it)->isA(CL_PLAYABLE) )
+      {
+        getInstance()->playablesToDelete.push_back( dynamic_cast<Playable*>(*it) );
+        return true;
+      }
+        
       delete dynamic_cast<Synchronizeable*>(*it);
       return true;
@@ -180,5 +187,81 @@
 
 
-
-
-
+/**
+ * handler for MSGID_PREFEREDTEAM message
+ * @param messageId 
+ * @param data 
+ * @param dataLength 
+ * @param someData 
+ * @param userId 
+ * @return 
+ */
+bool NetworkGameManager::preferedTeamHandler( MessageId messageId, byte * data, int dataLength, void * someData, int userId )
+{
+  assert( NetworkGameManager::getInstance()->isServer() );
+  
+  int teamId = 0;
+  int len = Converter::byteArrayToInt( data, &teamId );
+  
+  if ( len != dataLength )
+  {
+    PRINTF(2)("Recieved DeleteSynchronizeable message with incorrect size (%d) from client %d!\n", dataLength, userId);
+    return true;
+  }
+  
+  NetworkGameManager::getInstance()->setPreferedTeam( userId, teamId );
+}
+
+void NetworkGameManager::setPreferedTeam( int userId, int teamId )
+{
+  if ( !PlayerStats::getStats( userId ) )
+    return;
+  
+  PlayerStats & stats = *(PlayerStats::getStats( userId ));
+  
+  stats.setPreferedTeamId( teamId );
+  
+}
+
+/**
+ * set prefered team for this host
+ * @param teamId 
+ */
+void NetworkGameManager::prefereTeam( int teamId )
+{
+  if ( isServer() )
+    setPreferedTeam( getHostID(), teamId );
+  else
+  {
+    byte buf[INTSIZE];
+    
+    assert( Converter::intToByteArray( teamId, buf, INTSIZE) == INTSIZE );
+    
+    MessageManager::getInstance()->sendMessage( MSGID_PREFEREDTEAM, buf, INTSIZE, RT_USER, 0, MP_HIGHBANDWIDTH );
+  }
+}
+
+/**
+ * this function will be called periodically by networkManager
+ * @param ds time elapsed since last call of tick
+ */
+void NetworkGameManager::tick( float ds )
+{
+  //delete playables if they are not assigned to local player anymore
+  for ( std::list<Playable*>::iterator it = playablesToDelete.begin(); it != playablesToDelete.end();  )
+  {
+    if ( State::getPlayer()->getPlayable() != *it )
+    {
+      PRINTF(0)("Delete unused playable: %s owner: %d\n", (*it)->getClassName(), (*it)->getOwner() );
+      std::list<Playable*>::iterator delit = it;
+      it++;
+      delete *delit;
+      playablesToDelete.erase( delit );
+      continue;
+    }
+    it++;
+  }
+}
+
+
+
+
Index: trunk/src/lib/network/network_game_manager.h
===================================================================
--- trunk/src/lib/network/network_game_manager.h	(revision 8145)
+++ trunk/src/lib/network/network_game_manager.h	(revision 8147)
@@ -12,4 +12,5 @@
 /* include base_object.h since all classes are derived from this one */
 #include "synchronizeable.h"
+#include "playable.h"
 #include "message_manager.h"
 
@@ -56,7 +57,11 @@
     
     void removeSynchronizeable( int uniqueId );
+    
+    void prefereTeam( int teamId );
 
     inline void setGameState( int gameState ){ this->gameState = gameState; }
     inline int getGameState(){ return this->gameState; }
+    
+    void tick( float ds );
 
   private:
@@ -64,8 +69,13 @@
     
     static bool delSynchronizeableHandler( MessageId messageId, byte * data, int dataLength, void * someData, int userId );
+    static bool preferedTeamHandler( MessageId messageId, byte * data, int dataLength, void * someData, int userId );
+    
+    void setPreferedTeam( int userId, int teamId );
 
     static NetworkGameManager*    singletonRef;
     
     int                           gameState;
+    
+    std::list<Playable*>          playablesToDelete;
 };
 
Index: trunk/src/lib/network/network_manager.cc
===================================================================
--- trunk/src/lib/network/network_manager.cc	(revision 8145)
+++ trunk/src/lib/network/network_manager.cc	(revision 8147)
@@ -30,4 +30,5 @@
 #include "preferences.h"
 #include "network_log.h"
+#include "network_game_manager.h"
 
 
@@ -149,4 +150,6 @@
         static_cast<NetworkStream*>(*stream)->processData();
   }
+  
+  NetworkGameManager::getInstance()->tick( this->elapsedTime );
 }
 
Index: trunk/src/lib/network/player_stats.cc
===================================================================
--- trunk/src/lib/network/player_stats.cc	(revision 8145)
+++ trunk/src/lib/network/player_stats.cc	(revision 8147)
@@ -86,7 +86,4 @@
     
     PRINTF(0)("uniqueID changed %d %d\n", userId, getHostID());
-    
-    if ( userId == getHostID() )
-      State::getPlayer()->setPlayable( getPlayable() );
   }
 }
@@ -100,4 +97,7 @@
 {
   const std::list<BaseObject*> * list = ClassList::getList( CL_PLAYER_STATS );
+  
+  if ( !list )
+    return NULL;
   
   for ( std::list<BaseObject*>::const_iterator it = list->begin(); it != list->end(); it++ )
@@ -121,4 +121,10 @@
   const std::list<BaseObject*> * list = ClassList::getList( CL_PLAYABLE );
   
+  if ( !list )
+  {
+    this->playableUniqueId = uniqueId;
+    return;
+  }
+  
   this->playable = NULL;
   for ( std::list<BaseObject*>::const_iterator it = list->begin(); it != list->end(); it++ )
@@ -130,4 +136,7 @@
     }
   }
+  
+  if ( this->playable && userId == getHostID() )
+    State::getPlayer()->setPlayable( this->playable );
   
   this->playableUniqueId = uniqueId;
Index: trunk/src/lib/network/synchronizeable.cc
===================================================================
--- trunk/src/lib/network/synchronizeable.cc	(revision 8145)
+++ trunk/src/lib/network/synchronizeable.cc	(revision 8147)
@@ -108,5 +108,8 @@
 
   for ( SyncVarList::iterator it = syncVarList.begin(); it != syncVarList.end(); it++ )
+  {
+    //PRINTF(0)("SIZE = %d %s\n", (*it)->getSize(), (*it)->getName().c_str());
     neededSize += (*it)->getSize();
+  }
 
   if ( !( neededSize <= maxLength ) )
@@ -183,5 +186,5 @@
                     );
     
-    if ( ( hasPermission && (*it)->getPriority() >= priorityTH ) || sizeIter == stateFrom->sizeList.end() )
+    if ( ( sizeIter != stateFrom->sizeList.end() && *sizeIter != (*it)->getSize() ) || ( hasPermission && (*it)->getPriority() >= priorityTH ) || sizeIter == stateFrom->sizeList.end() )
     {
       n = (*it)->writeToBuf( stateTo->data+i, stateTo->dataLength - i );
@@ -209,5 +212,9 @@
   sentStates[userId].push_back( stateTo );
   
-  assert( i == neededSize );
+  if ( i != neededSize )
+  {
+    PRINTF(0)("strange error: (%s) %d != %d\n", this->getClassName(), i, neededSize);
+    assert(false);
+  }
 
   //write diff to data
Index: trunk/src/lib/network/synchronizeable_var/synchronizeable_string.cc
===================================================================
--- trunk/src/lib/network/synchronizeable_var/synchronizeable_string.cc	(revision 8145)
+++ trunk/src/lib/network/synchronizeable_var/synchronizeable_string.cc	(revision 8147)
@@ -48,4 +48,5 @@
   
   assert( res > 0 );
+  assert( res == vPtrIn->length()+INTSIZE );
   
   return res;
