public GameWorld(GameWorldConfiguration configuration, FileSystemPath worldFilePath, TrippingCubesGame game) { DateTime startTime = DateTime.Now; Game = game; Entities = new ReadOnlyCollection <IEntity>(entities); Physics = new PhysicsSystem(IsBlockSolid, IsBlockLiquid); Paths = new ReadOnlyDictionary <string, PathLinear>( configuration.Paths ?? new Dictionary <string, PathLinear>()); Log.Trace("Initializing world style..."); try { Game.Resources.LoadMesh(MeshData.Skybox).Subscribe( r => skyboxMesh = r); Game.Resources.LoadTexture(configuration.SkyboxPath, TextureFilter.Linear).Subscribe( r => skyboxTexture = r); if (!configuration.InnerSkyboxPath.IsEmpty) { Game.Resources.LoadTexture(configuration.InnerSkyboxPath, TextureFilter.Linear).Subscribe( r => innerSkyboxTexture = r); } } catch (Exception exc) { Log.Warning("The skybox couldn't be loaded and will not " + "be available.", exc); } try { DateTime localStartTime = DateTime.Now; BlockRegistryBuilder blockRegistryBuilder = BlockRegistryBuilder.FromXml( configuration.BlockRegistryPath, FileSystem, false); Blocks = blockRegistryBuilder.GenerateRegistry( FileSystem); Log.Trace("Block registry with " + Blocks.Count + " block definitions initialized in " + (DateTime.Now - localStartTime).TotalMilliseconds + "ms."); } catch (Exception exc) { throw new Exception("The block registry couldn't be " + "initialized.", exc); } Log.Trace("Initializing world chunk manager..."); try { FileSystemPath primaryWorldBackupPath = FileSystemPath.Combine(worldFilePath.GetParentDirectory(), $"{worldFilePath.GetFileName(false)}1"); FileSystemPath secondaryWorldBackupPath = FileSystemPath.Combine(worldFilePath.GetParentDirectory(), $"{worldFilePath.GetFileName(false)}2"); if (FileSystem.IsWritable) { try { if (FileSystem.ExistsFile(primaryWorldBackupPath)) { using Stream secondaryBackupStream = FileSystem.CreateFile(secondaryWorldBackupPath, true); using Stream primaryWorldBackup = FileSystem.OpenFile(primaryWorldBackupPath, false); primaryWorldBackup.CopyTo(secondaryBackupStream); } if (FileSystem.ExistsFile(worldFilePath)) { using Stream primaryWorldBackup = FileSystem.CreateFile(primaryWorldBackupPath, true); using Stream worldFile = FileSystem.OpenFile(worldFilePath, false); worldFile.CopyTo(primaryWorldBackup); } } catch (Exception exc) { throw new Exception("The world backups couldn't be " + "updated.", exc); } } if (FileSystem.ExistsFile(worldFilePath)) { zipFileSystem = new ZipFileSystem(FileSystem.OpenFile( worldFilePath, FileSystem.IsWritable)); } else if (FileSystem.IsWritable) { Log.Information("No world data file was found at the " + "specified path. A new world file is initialized."); zipFileSystem = ZipFileSystem.Initialize(FileSystem, worldFilePath, false); } else { throw new Exception("The world data file doesn't exist " + $"under the path {worldFilePath} and can't be created, " + "as the file system is read-only."); } RootChunk = new Chunk <BlockVoxel>( new BlockChunkManager(Blocks, Game.Resources, zipFileSystem, "/")); } catch (Exception exc) { throw new Exception("The world chunk manager couldn't be " + "initialized.", exc); } Log.Trace("Spawning entities..."); foreach (EntityInstantiation instantiation in configuration.Entities) { if (configuration.EntityConfigurations.TryGetValue( instantiation.ConfigurationIdentifier, out EntityConfiguration entityConfiguration)) { try { IEntity entity = entityConfiguration.Instantiate(this, instantiation.InstanceParameters); entities.Add(entity); } catch (Exception exc) { Log.Warning($"Entity #{entities.Count} couldn't " + "be spawned and will be skipped.", exc); } } } Log.Trace($"Spawned {entities.Count} entities."); Log.Trace("Game world initialized in " + (DateTime.Now - startTime).TotalMilliseconds + "ms."); }