public override void AssetsLoaded(ICoreAPI coreApi) { if (!(coreApi is ICoreServerAPI api)) { return; } this.api = api; api.Logger.VerboseDebug("Starting to gather blocktypes, itemtypes and entities"); LoadWorldProperties(); int threads = Math.Max(1, Environment.ProcessorCount / 2 - 2); itemTypes = new Dictionary <AssetLocation, RegistryObjectType>(); blockTypes = new Dictionary <AssetLocation, RegistryObjectType>(); entityTypes = new Dictionary <AssetLocation, RegistryObjectType>(); foreach (KeyValuePair <AssetLocation, JObject> entry in api.Assets.GetMany <JObject>(api.Server.Logger, "itemtypes/")) { try { ItemType et = new ItemType(); et.CreateBasetype(entry.Key.Domain, entry.Value); itemTypes.Add(entry.Key, et); } catch (Exception e) { api.World.Logger.Error("Item type {0} could not be loaded. Will ignore. Exception thrown: {1}", entry.Key, e); continue; } } itemVariants = new List <RegistryObjectType> [itemTypes.Count]; api.Logger.VerboseDebug("Starting parsing ItemTypes in " + threads + " threads"); PrepareForLoading(threads); foreach (KeyValuePair <AssetLocation, JObject> entry in api.Assets.GetMany <JObject>(api.Server.Logger, "entities/")) { try { EntityType et = new EntityType(); et.CreateBasetype(entry.Key.Domain, entry.Value); entityTypes.Add(entry.Key, et); } catch (Exception e) { api.World.Logger.Error("Entity type {0} could not be loaded. Will ignore. Exception thrown: {1}", entry.Key, e); continue; } } entityVariants = new List <RegistryObjectType> [entityTypes.Count]; foreach (KeyValuePair <AssetLocation, JObject> entry in api.Assets.GetMany <JObject>(api.Server.Logger, "blocktypes/")) { try { BlockType et = new BlockType(); et.CreateBasetype(entry.Key.Domain, entry.Value); blockTypes.Add(entry.Key, et); } catch (Exception e) { api.World.Logger.Error("Block type {0} could not be loaded. Will ignore. Exception thrown: {1}", entry.Key, e); continue; } } blockVariants = new List <RegistryObjectType> [blockTypes.Count]; TyronThreadPool.QueueTask(GatherAllTypes_Async); // Now we've loaded everything, let's add one more gathering thread :) api.Logger.StoryEvent(Lang.Get("It remembers...")); api.Logger.VerboseDebug("Gathered all types, starting to load items"); LoadItems(itemVariants); api.Logger.VerboseDebug("Parsed and loaded items"); api.Logger.StoryEvent(Lang.Get("...all that came before")); LoadBlocks(blockVariants); api.Logger.VerboseDebug("Parsed and loaded blocks"); LoadEntities(entityVariants); api.Logger.VerboseDebug("Parsed and loaded entities"); api.Server.LogNotification("BlockLoader: Entities, Blocks and Items loaded"); FreeRam(); api.TriggerOnAssetsFirstLoaded(); }