One more question: is the save game compression done by some standard method? In other words, could it be uncompressed (or even recompressed) outside of the game?
It uses GZip. Specifically we use Ionic.Zlib.GZipStream from Ionic.Zlib.Reduced.dll .
In theory you could even write to the planet's location fields in the save game record to perform the untangling
FYI, here's the first bit of the serialization code for the planet object:
Builder.Append( this.PlanetNumber ).Append( '|' );
Builder.Append( this.GalaxyLocationOriginalCenter.X ).Append( '|' );
Builder.Append( this.GalaxyLocationOriginalCenter.Y ).Append( '|' );
Builder.Append( (int)this.Type ).Append( '|' );
Builder.Append( 0 ).Append( '|' ); //was diffuse color
Builder.Append( this.ControllingPlayer ).Append( '|' );
Builder.Append( this.Name ).Append( '|' );
#region fow
isFirst = true;
for ( int i = 0; i < this.LastKnownControllingPlayers.Length; i++ )
{
if ( isFirst )
isFirst = false;
else
Builder.Append( ':' );
Builder.Append( this.LastKnownControllingPlayers[i] );
}
Builder.Append( '|' );
#endregion
#region linkedPlanets
isFirst = true;
foreach ( Planet p in this.LinkedPlanets )
{
if ( isFirst )
isFirst = false;
else
Builder.Append( ':' );
Builder.Append( p.PlanetNumber );
}
Builder.Append( '|' );
#endregion
and the corresponding deserialization:
string[] stateParts = StateString.Split( '|' );
this.PlanetNumber = Convert.ToInt32( stateParts[0] );
this.GalaxyLocationOriginalCenter.X = Convert.ToInt32( stateParts[1] );
this.GalaxyLocationOriginalCenter.Y = Convert.ToInt32( stateParts[2] );
this.Type = (PlanetType)Convert.ToInt32( stateParts[3] );
//stateParts[4]; //unused
this.ControllingPlayer = Convert.ToInt32( stateParts[5] );
this.Name = stateParts[6];
if ( stateParts.Length > 7 && stateParts[7].Length > 0 )
{
string[] fow = stateParts[7].Split( ':' );
for ( int i = 0; i < fow.Length; i++ )
this.LastKnownControllingPlayers[i] = Convert.ToInt32( fow[i] );
}
if ( stateParts.Length > 8 && stateParts[8].Length > 0 )
{
string[] linkedPlanets = stateParts[8].Split( ':' );
for ( int i = 0; i < linkedPlanets.Length; i++ )
this.LinkedPlanetIds.Add( Convert.ToInt32( linkedPlanets[i] ) );
}
Before anyone asks: yes, we are aware that there are
massively more efficient ways to do this, and in fact our later stuff is much more efficient, but this particular bit really doesn't need the optimization and the chance of breaking something outweighs the benefit