Ejemplo n.º 1
0
		public Manifest(string mod)
		{
			var path = new[] { "mods", mod, "mod.yaml" }.Aggregate(Path.Combine);
			var yaml = new MiniYaml(null, MiniYaml.FromFile(path)).ToDictionary();

			Mod = FieldLoader.Load<ModMetadata>(yaml["Metadata"]);
			Mod.Id = mod;

			// TODO: Use fieldloader
			Folders = YamlList(yaml, "Folders");
			MapFolders = YamlDictionary(yaml, "MapFolders");
			Packages = YamlDictionary(yaml, "Packages");
			Rules = YamlList(yaml, "Rules");
			ServerTraits = YamlList(yaml, "ServerTraits");
			Sequences = YamlList(yaml, "Sequences");
			VoxelSequences = YamlList(yaml, "VoxelSequences");
			Cursors = YamlList(yaml, "Cursors");
			Chrome = YamlList(yaml, "Chrome");
			Assemblies = YamlList(yaml, "Assemblies");
			ChromeLayout = YamlList(yaml, "ChromeLayout");
			Weapons = YamlList(yaml, "Weapons");
			Voices = YamlList(yaml, "Voices");
			Notifications = YamlList(yaml, "Notifications");
			Music = YamlList(yaml, "Music");
			Movies = YamlList(yaml, "Movies");
			Translations = YamlList(yaml, "Translations");
			TileSets = YamlList(yaml, "TileSets");
			ChromeMetrics = YamlList(yaml, "ChromeMetrics");
			PackageContents = YamlList(yaml, "PackageContents");
			LuaScripts = YamlList(yaml, "LuaScripts");
			Missions = YamlList(yaml, "Missions");

			LoadScreen = yaml["LoadScreen"];
			LobbyDefaults = yaml["LobbyDefaults"];

			if (yaml.ContainsKey("ContentInstaller"))
				ContentInstaller = FieldLoader.Load<InstallData>(yaml["ContentInstaller"]);

			Fonts = yaml["Fonts"].ToDictionary(my =>
				{
					var nd = my.ToDictionary();
					return Pair.New(nd["Font"].Value, Exts.ParseIntegerInvariant(nd["Size"].Value));
				});

			if (yaml.ContainsKey("TileSize"))
				TileSize = FieldLoader.GetValue<Size>("TileSize", yaml["TileSize"].Value);

			if (yaml.ContainsKey("TileShape"))
				TileShape = FieldLoader.GetValue<TileShape>("TileShape", yaml["TileShape"].Value);

			// Allow inherited mods to import parent maps.
			var compat = new List<string>();
			compat.Add(mod);

			if (yaml.ContainsKey("SupportsMapsFrom"))
				foreach (var c in yaml["SupportsMapsFrom"].Value.Split(','))
					compat.Add(c.Trim());

			MapCompatibility = compat.ToArray();
		}
Ejemplo n.º 2
0
        public Manifest(string modId, IReadOnlyPackage package)
        {
            Id      = modId;
            Package = package;

            var nodes = MiniYaml.FromStream(package.GetStream("mod.yaml"), "mod.yaml");

            for (var i = nodes.Count - 1; i >= 0; i--)
            {
                if (nodes[i].Key != "Include")
                {
                    continue;
                }

                // Replace `Includes: filename.yaml` with the contents of filename.yaml
                var filename = nodes[i].Value.Value;
                var contents = package.GetStream(filename);
                if (contents == null)
                {
                    throw new YamlException("{0}: File `{1}` not found.".F(nodes[i].Location, filename));
                }

                nodes.RemoveAt(i);
                nodes.InsertRange(i, MiniYaml.FromStream(contents, filename));
            }

            // Merge inherited overrides
            yaml = new MiniYaml(null, MiniYaml.Merge(new[] { nodes })).ToDictionary();

            Metadata = FieldLoader.Load <ModMetadata>(yaml["Metadata"]);

            // TODO: Use fieldloader
            MapFolders = YamlDictionary(yaml, "MapFolders");

            if (yaml.TryGetValue("Packages", out var packages))
            {
                Packages = packages.ToDictionary(x => x.Value);
            }

            Rules          = YamlList(yaml, "Rules");
            Sequences      = YamlList(yaml, "Sequences");
            ModelSequences = YamlList(yaml, "ModelSequences");
            Cursors        = YamlList(yaml, "Cursors");
            Chrome         = YamlList(yaml, "Chrome");
            Assemblies     = YamlList(yaml, "Assemblies");
            ChromeLayout   = YamlList(yaml, "ChromeLayout");
            Weapons        = YamlList(yaml, "Weapons");
            Voices         = YamlList(yaml, "Voices");
            Notifications  = YamlList(yaml, "Notifications");
            Music          = YamlList(yaml, "Music");
            TileSets       = YamlList(yaml, "TileSets");
            ChromeMetrics  = YamlList(yaml, "ChromeMetrics");
            Missions       = YamlList(yaml, "Missions");
            Hotkeys        = YamlList(yaml, "Hotkeys");

            ServerTraits = YamlList(yaml, "ServerTraits");

            if (!yaml.TryGetValue("LoadScreen", out LoadScreen))
            {
                throw new InvalidDataException("`LoadScreen` section is not defined.");
            }

            // Allow inherited mods to import parent maps.
            var compat = new List <string> {
                Id
            };

            if (yaml.ContainsKey("SupportsMapsFrom"))
            {
                compat.AddRange(yaml["SupportsMapsFrom"].Value.Split(',').Select(c => c.Trim()));
            }

            MapCompatibility = compat.ToArray();

            if (yaml.ContainsKey("PackageFormats"))
            {
                PackageFormats = FieldLoader.GetValue <string[]>("PackageFormats", yaml["PackageFormats"].Value);
            }

            if (yaml.ContainsKey("SoundFormats"))
            {
                SoundFormats = FieldLoader.GetValue <string[]>("SoundFormats", yaml["SoundFormats"].Value);
            }

            if (yaml.ContainsKey("SpriteFormats"))
            {
                SpriteFormats = FieldLoader.GetValue <string[]>("SpriteFormats", yaml["SpriteFormats"].Value);
            }

            if (yaml.ContainsKey("VideoFormats"))
            {
                VideoFormats = FieldLoader.GetValue <string[]>("VideoFormats", yaml["VideoFormats"].Value);
            }
        }
Ejemplo n.º 3
0
        public Manifest(string mod)
        {
            var path = Platform.ResolvePath(".", "mods", mod, "mod.yaml");

            yaml = new MiniYaml(null, MiniYaml.FromFile(path)).ToDictionary();

            Mod    = FieldLoader.Load <ModMetadata>(yaml["Metadata"]);
            Mod.Id = mod;

            // TODO: Use fieldloader
            Folders        = YamlList(yaml, "Folders", true);
            MapFolders     = YamlDictionary(yaml, "MapFolders", true);
            Packages       = YamlDictionary(yaml, "Packages", true);
            Rules          = YamlList(yaml, "Rules", true);
            Sequences      = YamlList(yaml, "Sequences", true);
            VoxelSequences = YamlList(yaml, "VoxelSequences", true);
            Cursors        = YamlList(yaml, "Cursors", true);
            Chrome         = YamlList(yaml, "Chrome", true);
            Assemblies     = YamlList(yaml, "Assemblies", true);
            ChromeLayout   = YamlList(yaml, "ChromeLayout", true);
            Weapons        = YamlList(yaml, "Weapons", true);
            Voices         = YamlList(yaml, "Voices", true);
            Notifications  = YamlList(yaml, "Notifications", true);
            Music          = YamlList(yaml, "Music", true);
            Translations   = YamlList(yaml, "Translations", true);
            TileSets       = YamlList(yaml, "TileSets", true);
            ChromeMetrics  = YamlList(yaml, "ChromeMetrics", true);
            Missions       = YamlList(yaml, "Missions", true);

            ServerTraits = YamlList(yaml, "ServerTraits");

            if (!yaml.TryGetValue("LoadScreen", out LoadScreen))
            {
                throw new InvalidDataException("`LoadScreen` section is not defined.");
            }

            if (!yaml.TryGetValue("LobbyDefaults", out LobbyDefaults))
            {
                throw new InvalidDataException("`LobbyDefaults` section is not defined.");
            }

            Fonts = yaml["Fonts"].ToDictionary(my =>
            {
                var nd = my.ToDictionary();
                return(Pair.New(nd["Font"].Value, Exts.ParseIntegerInvariant(nd["Size"].Value)));
            });

            // Allow inherited mods to import parent maps.
            var compat = new List <string>();

            compat.Add(mod);

            if (yaml.ContainsKey("SupportsMapsFrom"))
            {
                foreach (var c in yaml["SupportsMapsFrom"].Value.Split(','))
                {
                    compat.Add(c.Trim());
                }
            }

            MapCompatibility = compat.ToArray();

            if (yaml.ContainsKey("SpriteFormats"))
            {
                SpriteFormats = FieldLoader.GetValue <string[]>("SpriteFormats", yaml["SpriteFormats"].Value);
            }
        }
Ejemplo n.º 4
0
        public Manifest(string modId, IReadOnlyPackage package)
        {
            Id      = modId;
            Package = package;
            yaml    = new MiniYaml(null, MiniYaml.FromStream(package.GetStream("mod.yaml"), "mod.yaml")).ToDictionary();

            Metadata = FieldLoader.Load <ModMetadata>(yaml["Metadata"]);

            // TODO: Use fieldloader
            MapFolders = YamlDictionary(yaml, "MapFolders");

            MiniYaml packages;

            if (yaml.TryGetValue("Packages", out packages))
            {
                Packages = packages.ToDictionary(x => x.Value).AsReadOnly();
            }

            Rules          = YamlList(yaml, "Rules");
            Sequences      = YamlList(yaml, "Sequences");
            ModelSequences = YamlList(yaml, "ModelSequences");
            Cursors        = YamlList(yaml, "Cursors");
            Chrome         = YamlList(yaml, "Chrome");
            Assemblies     = YamlList(yaml, "Assemblies");
            ChromeLayout   = YamlList(yaml, "ChromeLayout");
            Weapons        = YamlList(yaml, "Weapons");
            Voices         = YamlList(yaml, "Voices");
            Notifications  = YamlList(yaml, "Notifications");
            Music          = YamlList(yaml, "Music");
            Translations   = YamlList(yaml, "Translations");
            TileSets       = YamlList(yaml, "TileSets");
            ChromeMetrics  = YamlList(yaml, "ChromeMetrics");
            Missions       = YamlList(yaml, "Missions");
            Hotkeys        = YamlList(yaml, "Hotkeys");

            ServerTraits = YamlList(yaml, "ServerTraits");

            if (!yaml.TryGetValue("LoadScreen", out LoadScreen))
            {
                throw new InvalidDataException("`LoadScreen` section is not defined.");
            }

            // Allow inherited mods to import parent maps.
            var compat = new List <string> {
                Id
            };

            if (yaml.ContainsKey("SupportsMapsFrom"))
            {
                compat.AddRange(yaml["SupportsMapsFrom"].Value.Split(',').Select(c => c.Trim()));
            }

            MapCompatibility = compat.ToArray();

            if (yaml.ContainsKey("PackageFormats"))
            {
                PackageFormats = FieldLoader.GetValue <string[]>("PackageFormats", yaml["PackageFormats"].Value);
            }

            if (yaml.ContainsKey("SoundFormats"))
            {
                SoundFormats = FieldLoader.GetValue <string[]>("SoundFormats", yaml["SoundFormats"].Value);
            }

            if (yaml.ContainsKey("SpriteFormats"))
            {
                SpriteFormats = FieldLoader.GetValue <string[]>("SpriteFormats", yaml["SpriteFormats"].Value);
            }
        }
Ejemplo n.º 5
0
        public Manifest(string mod)
        {
            var path = Platform.ResolvePath(".", "mods", mod, "mod.yaml");

            yaml = new MiniYaml(null, MiniYaml.FromFile(path)).ToDictionary();

            Mod    = FieldLoader.Load <ModMetadata>(yaml["Metadata"]);
            Mod.Id = mod;

            // TODO: Use fieldloader
            Folders        = YamlList(yaml, "Folders", true);
            MapFolders     = YamlDictionary(yaml, "MapFolders", true);
            Packages       = YamlDictionary(yaml, "Packages", true);
            Rules          = YamlList(yaml, "Rules", true);
            Sequences      = YamlList(yaml, "Sequences", true);
            VoxelSequences = YamlList(yaml, "VoxelSequences", true);
            Cursors        = YamlList(yaml, "Cursors", true);
            Chrome         = YamlList(yaml, "Chrome", true);
            Assemblies     = YamlList(yaml, "Assemblies", true);
            ChromeLayout   = YamlList(yaml, "ChromeLayout", true);
            Weapons        = YamlList(yaml, "Weapons", true);
            Voices         = YamlList(yaml, "Voices", true);
            Notifications  = YamlList(yaml, "Notifications", true);
            Music          = YamlList(yaml, "Music", true);
            Translations   = YamlList(yaml, "Translations", true);
            TileSets       = YamlList(yaml, "TileSets", true);
            ChromeMetrics  = YamlList(yaml, "ChromeMetrics", true);
            Missions       = YamlList(yaml, "Missions", true);

            ServerTraits = YamlList(yaml, "ServerTraits");

            if (!yaml.TryGetValue("LoadScreen", out LoadScreen))
            {
                throw new InvalidDataException("`LoadScreen` section is not defined.");
            }

            if (!yaml.TryGetValue("LobbyDefaults", out LobbyDefaults))
            {
                throw new InvalidDataException("`LobbyDefaults` section is not defined.");
            }

            Fonts = yaml["Fonts"].ToDictionary(my =>
            {
                var nd = my.ToDictionary();
                return(Pair.New(nd["Font"].Value, Exts.ParseIntegerInvariant(nd["Size"].Value)));
            });

            if (yaml.ContainsKey("TileSize"))
            {
                TileSize = FieldLoader.GetValue <Size>("TileSize", yaml["TileSize"].Value);
            }

            if (yaml.ContainsKey("TileShape"))
            {
                TileShape = FieldLoader.GetValue <TileShape>("TileShape", yaml["TileShape"].Value);
            }

            if (yaml.ContainsKey("MaximumTerrainHeight"))
            {
                MaximumTerrainHeight = FieldLoader.GetValue <byte>("MaximumTerrainHeight", yaml["MaximumTerrainHeight"].Value);
            }

            if (yaml.ContainsKey("SubCells"))
            {
                var subcells = yaml["SubCells"].ToDictionary();

                // Read (x,y,z) offset (relative to cell center) pairs for positioning subcells
                if (subcells.ContainsKey("Offsets"))
                {
                    SubCellOffsets = FieldLoader.GetValue <WVec[]>("Offsets", subcells["Offsets"].Value);
                }

                if (subcells.ContainsKey("DefaultIndex"))
                {
                    SubCellDefaultIndex = FieldLoader.GetValue <int>("DefaultIndex", subcells["DefaultIndex"].Value);
                }
                else                    // Otherwise set the default subcell index to the middle subcell entry
                {
                    SubCellDefaultIndex = SubCellOffsets.Length / 2;
                }
            }

            // Validate default index - 0 for no subcells, otherwise > 1 & <= subcell count (offset triples count - 1)
            if (SubCellDefaultIndex < (SubCellOffsets.Length > 1 ? 1 : 0) || SubCellDefaultIndex >= SubCellOffsets.Length)
            {
                throw new InvalidDataException("Subcell default index must be a valid index into the offset triples and must be greater than 0 for mods with subcells");
            }

            // Allow inherited mods to import parent maps.
            var compat = new List <string>();

            compat.Add(mod);

            if (yaml.ContainsKey("SupportsMapsFrom"))
            {
                foreach (var c in yaml["SupportsMapsFrom"].Value.Split(','))
                {
                    compat.Add(c.Trim());
                }
            }

            MapCompatibility = compat.ToArray();

            if (yaml.ContainsKey("SpriteFormats"))
            {
                SpriteFormats = FieldLoader.GetValue <string[]>("SpriteFormats", yaml["SpriteFormats"].Value);
            }
        }
Ejemplo n.º 6
0
        public Manifest(string modId)
        {
            var package = ModMetadata.AllMods[modId].Package;

            yaml = new MiniYaml(null, MiniYaml.FromStream(package.GetStream("mod.yaml"))).ToDictionary();

            Mod    = FieldLoader.Load <ModMetadata>(yaml["Metadata"]);
            Mod.Id = modId;

            // TODO: Use fieldloader
            MapFolders = YamlDictionary(yaml, "MapFolders");

            MiniYaml packages;

            if (yaml.TryGetValue("Packages", out packages))
            {
                Packages = packages.ToDictionary(x => x.Value).AsReadOnly();
            }

            Rules          = YamlList(yaml, "Rules");
            Sequences      = YamlList(yaml, "Sequences");
            VoxelSequences = YamlList(yaml, "VoxelSequences");
            Cursors        = YamlList(yaml, "Cursors");
            Chrome         = YamlList(yaml, "Chrome");
            Assemblies     = YamlList(yaml, "Assemblies");
            ChromeLayout   = YamlList(yaml, "ChromeLayout");
            Weapons        = YamlList(yaml, "Weapons");
            Voices         = YamlList(yaml, "Voices");
            Notifications  = YamlList(yaml, "Notifications");
            Music          = YamlList(yaml, "Music");
            Translations   = YamlList(yaml, "Translations");
            TileSets       = YamlList(yaml, "TileSets");
            ChromeMetrics  = YamlList(yaml, "ChromeMetrics");
            Missions       = YamlList(yaml, "Missions");

            ServerTraits = YamlList(yaml, "ServerTraits");

            if (!yaml.TryGetValue("LoadScreen", out LoadScreen))
            {
                throw new InvalidDataException("`LoadScreen` section is not defined.");
            }

            Fonts = yaml["Fonts"].ToDictionary(my =>
            {
                var nd = my.ToDictionary();
                return(Pair.New(nd["Font"].Value, Exts.ParseIntegerInvariant(nd["Size"].Value)));
            });

            RequiresMods = yaml["RequiresMods"].ToDictionary(my => my.Value);

            // Allow inherited mods to import parent maps.
            var compat = new List <string> {
                Mod.Id
            };

            if (yaml.ContainsKey("SupportsMapsFrom"))
            {
                compat.AddRange(yaml["SupportsMapsFrom"].Value.Split(',').Select(c => c.Trim()));
            }

            MapCompatibility = compat.ToArray();

            if (yaml.ContainsKey("SoundFormats"))
            {
                SoundFormats = FieldLoader.GetValue <string[]>("SoundFormats", yaml["SoundFormats"].Value);
            }

            if (yaml.ContainsKey("SpriteFormats"))
            {
                SpriteFormats = FieldLoader.GetValue <string[]>("SpriteFormats", yaml["SpriteFormats"].Value);
            }
        }
Ejemplo n.º 7
0
        public Manifest(string mod)
        {
            var path = new[] { "mods", mod, "mod.yaml" }.Aggregate(Path.Combine);
            var yaml = new MiniYaml(null, MiniYaml.FromFile(path)).ToDictionary();

            Mod    = FieldLoader.Load <ModMetadata>(yaml["Metadata"]);
            Mod.Id = mod;

            // TODO: Use fieldloader
            Folders         = YamlList(yaml, "Folders");
            MapFolders      = YamlDictionary(yaml, "MapFolders");
            Packages        = YamlDictionary(yaml, "Packages");
            Rules           = YamlList(yaml, "Rules");
            ServerTraits    = YamlList(yaml, "ServerTraits");
            Sequences       = YamlList(yaml, "Sequences");
            VoxelSequences  = YamlList(yaml, "VoxelSequences");
            Cursors         = YamlList(yaml, "Cursors");
            Chrome          = YamlList(yaml, "Chrome");
            Assemblies      = YamlList(yaml, "Assemblies");
            ChromeLayout    = YamlList(yaml, "ChromeLayout");
            Weapons         = YamlList(yaml, "Weapons");
            Voices          = YamlList(yaml, "Voices");
            Notifications   = YamlList(yaml, "Notifications");
            Music           = YamlList(yaml, "Music");
            Movies          = YamlList(yaml, "Movies");
            Translations    = YamlList(yaml, "Translations");
            TileSets        = YamlList(yaml, "TileSets");
            ChromeMetrics   = YamlList(yaml, "ChromeMetrics");
            PackageContents = YamlList(yaml, "PackageContents");
            LuaScripts      = YamlList(yaml, "LuaScripts");
            Missions        = YamlList(yaml, "Missions");

            LoadScreen    = yaml["LoadScreen"];
            LobbyDefaults = yaml["LobbyDefaults"];

            if (yaml.ContainsKey("ContentInstaller"))
            {
                ContentInstaller = FieldLoader.Load <InstallData>(yaml["ContentInstaller"]);
            }

            Fonts = yaml["Fonts"].ToDictionary(my =>
            {
                var nd = my.ToDictionary();
                return(Pair.New(nd["Font"].Value, Exts.ParseIntegerInvariant(nd["Size"].Value)));
            });

            if (yaml.ContainsKey("TileSize"))
            {
                TileSize = FieldLoader.GetValue <Size>("TileSize", yaml["TileSize"].Value);
            }

            if (yaml.ContainsKey("TileShape"))
            {
                TileShape = FieldLoader.GetValue <TileShape>("TileShape", yaml["TileShape"].Value);
            }

            // Allow inherited mods to import parent maps.
            var compat = new List <string>();

            compat.Add(mod);

            if (yaml.ContainsKey("SupportsMapsFrom"))
            {
                foreach (var c in yaml["SupportsMapsFrom"].Value.Split(','))
                {
                    compat.Add(c.Trim());
                }
            }

            MapCompatibility = compat.ToArray();
        }
Ejemplo n.º 8
0
        public Manifest(string mod)
        {
            var path = Platform.ResolvePath(".", "mods", mod, "mod.yaml");
            var yaml = new MiniYaml(null, MiniYaml.FromFile(path)).ToDictionary();

            Mod = FieldLoader.Load<ModMetadata>(yaml["Metadata"]);
            Mod.Id = mod;

            // TODO: Use fieldloader
            Folders = YamlList(yaml, "Folders", true);
            MapFolders = YamlDictionary(yaml, "MapFolders", true);
            Packages = YamlDictionary(yaml, "Packages", true);
            Rules = YamlList(yaml, "Rules", true);
            Sequences = YamlList(yaml, "Sequences", true);
            VoxelSequences = YamlList(yaml, "VoxelSequences", true);
            Cursors = YamlList(yaml, "Cursors", true);
            Chrome = YamlList(yaml, "Chrome", true);
            Assemblies = YamlList(yaml, "Assemblies", true);
            ChromeLayout = YamlList(yaml, "ChromeLayout", true);
            Weapons = YamlList(yaml, "Weapons", true);
            Voices = YamlList(yaml, "Voices", true);
            Notifications = YamlList(yaml, "Notifications", true);
            Music = YamlList(yaml, "Music", true);
            Movies = YamlList(yaml, "Movies", true);
            Translations = YamlList(yaml, "Translations", true);
            TileSets = YamlList(yaml, "TileSets", true);
            ChromeMetrics = YamlList(yaml, "ChromeMetrics", true);
            Missions = YamlList(yaml, "Missions", true);

            ServerTraits = YamlList(yaml, "ServerTraits");
            LoadScreen = yaml["LoadScreen"];
            LobbyDefaults = yaml["LobbyDefaults"];

            if (yaml.ContainsKey("ContentInstaller"))
                ContentInstaller = FieldLoader.Load<InstallData>(yaml["ContentInstaller"]);

            Fonts = yaml["Fonts"].ToDictionary(my =>
                {
                    var nd = my.ToDictionary();
                    return Pair.New(nd["Font"].Value, Exts.ParseIntegerInvariant(nd["Size"].Value));
                });

            if (yaml.ContainsKey("TileSize"))
                TileSize = FieldLoader.GetValue<Size>("TileSize", yaml["TileSize"].Value);

            if (yaml.ContainsKey("TileShape"))
                TileShape = FieldLoader.GetValue<TileShape>("TileShape", yaml["TileShape"].Value);

            if (yaml.ContainsKey("SubCells"))
            {
                var subcells = yaml["SubCells"].ToDictionary();

                // Read (x,y,z) offset (relative to cell center) pairs for positioning subcells
                if (subcells.ContainsKey("Offsets"))
                    SubCellOffsets = FieldLoader.GetValue<WVec[]>("Offsets", subcells["Offsets"].Value);

                if (subcells.ContainsKey("DefaultIndex"))
                    SubCellDefaultIndex = FieldLoader.GetValue<int>("DefaultIndex", subcells["DefaultIndex"].Value);
                else	// Otherwise set the default subcell index to the middle subcell entry
                    SubCellDefaultIndex = SubCellOffsets.Length / 2;
            }

            // Validate default index - 0 for no subcells, otherwise > 1 & <= subcell count (offset triples count - 1)
            if (SubCellDefaultIndex < (SubCellOffsets.Length > 1 ? 1 : 0) || SubCellDefaultIndex >= SubCellOffsets.Length)
                throw new InvalidDataException("Subcell default index must be a valid index into the offset triples and must be greater than 0 for mods with subcells");

            // Allow inherited mods to import parent maps.
            var compat = new List<string>();
            compat.Add(mod);

            if (yaml.ContainsKey("SupportsMapsFrom"))
                foreach (var c in yaml["SupportsMapsFrom"].Value.Split(','))
                    compat.Add(c.Trim());

            MapCompatibility = compat.ToArray();

            if (yaml.ContainsKey("SpriteFormats"))
                SpriteFormats = FieldLoader.GetValue<string[]>("SpriteFormats", yaml["SpriteFormats"].Value);
        }