// Prepare an environment definition from legacy planet definitions.
        public static MyWorldEnvironmentDefinition FromLegacyPlanet(MyObjectBuilder_PlanetGeneratorDefinition pgdef, MyModContext context)
        {
            var envOb = MyObjectBuilderSerializer.CreateNewObject <MyObjectBuilder_ProceduralWorldEnvironment>(pgdef.Id.SubtypeId);;

            envOb.Id = new SerializableDefinitionId(envOb.TypeId, envOb.SubtypeName);

            // storage
            var staticModule = new SerializableDefinitionId(typeof(MyObjectBuilder_ProceduralEnvironmentModuleDefinition), "Static");

            var memoryModule = new SerializableDefinitionId(typeof(MyObjectBuilder_ProceduralEnvironmentModuleDefinition), "Memory");

            // proxies
            var breakable = new SerializableDefinitionId(typeof(MyObjectBuilder_EnvironmentModuleProxyDefinition), "Breakable");

            var voxelmap = new SerializableDefinitionId(typeof(MyObjectBuilder_EnvironmentModuleProxyDefinition), "VoxelMap");

            var botSpawner = new SerializableDefinitionId(typeof(MyObjectBuilder_EnvironmentModuleProxyDefinition), "BotSpawner");

            // TODO: Implement environmental particles.
            var environmentalParticleMarker = new SerializableDefinitionId(typeof(MyObjectBuilder_EnvironmentModuleProxyDefinition), "EnvironmentalParticles");

            envOb.ItemTypes = new[]
            {
                new MyEnvironmentItemTypeDefinition()
                {
                    LodFrom  = -1,
                    Name     = "Tree",
                    Provider = staticModule,
                    Proxies  = new [] { breakable }
                },
                new MyEnvironmentItemTypeDefinition()
                {
                    LodFrom  = 0,
                    Name     = "Bush",
                    Provider = staticModule,
                    Proxies  = new [] { breakable }
                },
                new MyEnvironmentItemTypeDefinition()
                {
                    LodFrom  = 0,
                    Name     = "VoxelMap",
                    Provider = memoryModule,
                    Proxies  = new [] { voxelmap }
                },
                new MyEnvironmentItemTypeDefinition()
                {
                    LodFrom  = 0,
                    Name     = "Bot",
                    Provider = null,
                    Proxies  = new [] { botSpawner }
                },
            };

            envOb.ScanningMethod  = MyProceduralScanningMethod.Random;
            envOb.ItemsPerSqMeter = 0.0017;

            envOb.MaxSyncLod = 0;
            envOb.SectorSize = 384;

            List <MyProceduralEnvironmentMapping> mappings = new List <MyProceduralEnvironmentMapping>();

            List <MyEnvironmentItemInfo> items = new List <MyEnvironmentItemInfo>();

            var defaultRule = new MyPlanetSurfaceRule();

            if (pgdef.EnvironmentItems != null)
            {
                foreach (var matmap in pgdef.EnvironmentItems)
                {
                    var map = new MyProceduralEnvironmentMapping();
                    map.Biomes    = matmap.Biomes;
                    map.Materials = matmap.Materials;

                    var rule = matmap.Rule ?? defaultRule;

                    map.Height    = rule.Height;
                    map.Latitude  = rule.Latitude;
                    map.Longitude = rule.Longitude;
                    map.Slope     = rule.Slope;

                    items.Clear();
                    foreach (var item in matmap.Items)
                    {
                        var it = new MyEnvironmentItemInfo
                        {
                            Density = item.Density,
                            Subtype = MyStringHash.GetOrCompute(item.SubtypeId)
                        };

                        switch (item.TypeId)
                        {
                        case "MyObjectBuilder_DestroyableItems":
                            it.Type = "Bush";
                            break;

                        case "MyObjectBuilder_Trees":
                            it.Type = "Tree";
                            break;

                        case "MyObjectBuilder_VoxelMapStorageDefinition":
                            it.Type = "VoxelMap";

                            if (item.SubtypeId == null)
                            {
                                var subtype = MyStringHash.GetOrCompute(string.Format("G({0})M({1})", item.GroupId, item.ModifierId));

                                var vcolDef = MyDefinitionManager.Static.GetDefinition <MyVoxelMapCollectionDefinition>(subtype);

                                if (vcolDef == null)
                                {
                                    var vdefOb = MyObjectBuilderSerializer.CreateNewObject <MyObjectBuilder_VoxelMapCollectionDefinition>(subtype.ToString());

                                    vdefOb.Id = new SerializableDefinitionId(vdefOb.TypeId, vdefOb.SubtypeName);

                                    vdefOb.StorageDefs = new MyObjectBuilder_VoxelMapCollectionDefinition.VoxelMapStorage[1]
                                    {
                                        new MyObjectBuilder_VoxelMapCollectionDefinition.VoxelMapStorage()
                                        {
                                            Storage = item.GroupId
                                        }
                                    };

                                    vdefOb.Modifier = item.ModifierId;

                                    vcolDef = new MyVoxelMapCollectionDefinition();
                                    vcolDef.Init(vdefOb, context);

                                    MyDefinitionManager.Static.Definitions.AddDefinition(vcolDef);
                                }

                                it.Subtype = subtype;
                            }

                            break;

                        default:
                            MyLog.Default.Error("Planet Generator {0}: Invalid Item Type: {1}", pgdef.SubtypeName, item.SubtypeId);
                            continue;
                            break;
                        }

                        if (it.Subtype == null)
                        {
                            MyLog.Default.Error("Planet Generator {0}: Missing subtype for item of type {1}", pgdef.SubtypeName, it.Type);
                            continue;
                        }

                        items.Add(it);
                    }

                    map.Items = items.ToArray();

                    mappings.Add(map);
                }
            }

            mappings.Capacity = mappings.Count;

            envOb.EnvironmentMappings = mappings.GetInternalArray();

            var def = new MyProceduralEnvironmentDefinition();

            def.Context = context;
            def.Init(envOb);

            return(def);
        }