1818
1919namespace PolyMod ;
2020
21+ /// <summary>
22+ /// Handles loading of mods and their assets.
23+ /// </summary>
2124public static class Loader
2225{
26+ /// <summary>
27+ /// Mappings from JSON data types to their corresponding C# types.
28+ /// </summary>
2329 internal static Dictionary < string , Type > typeMappings = new ( )
2430 {
2531 { "tribeData" , typeof ( TribeData . Type ) } ,
@@ -35,7 +41,15 @@ public static class Loader
3541 { "playerAbility" , typeof ( PlayerAbility . Type ) } ,
3642 { "weaponData" , typeof ( UnitData . WeaponEnum ) }
3743 } ;
44+
45+ /// <summary>
46+ /// List of custom game modes to be added.
47+ /// </summary>
3848 internal static List < GameModeButtonsInformation > gamemodes = new ( ) ;
49+
50+ /// <summary>
51+ /// Handlers for processing specific data types during mod loading.
52+ /// </summary>
3953 private static readonly Dictionary < Type , Action < JObject , bool > > typeHandlers = new ( )
4054 {
4155 [ typeof ( TribeData . Type ) ] = new ( ( token , duringEnumCacheCreation ) =>
@@ -131,8 +145,21 @@ public static class Loader
131145 } )
132146 } ;
133147
148+ /// <summary>
149+ /// Represents information for a custom game mode button.
150+ /// </summary>
151+ /// <param name="gameModeIndex">The index of the game mode.</param>
152+ /// <param name="action">The action to perform when the button is clicked.</param>
153+ /// <param name="buttonIndex">The index of the button in the UI.</param>
154+ /// <param name="sprite">The sprite for the button.</param>
134155 public record GameModeButtonsInformation ( int gameModeIndex , UIButtonBase . ButtonAction action , int ? buttonIndex , Sprite ? sprite ) ;
135156
157+ /// <summary>
158+ /// Adds a new game mode button.
159+ /// </summary>
160+ /// <param name="id">The unique identifier for the game mode.</param>
161+ /// <param name="action">The action to perform when the button is clicked.</param>
162+ /// <param name="sprite">The sprite for the button.</param>
136163 public static void AddGameModeButton ( string id , UIButtonBase . ButtonAction action , Sprite ? sprite )
137164 {
138165 EnumCache < GameMode > . AddMapping ( id , ( GameMode ) Registry . gameModesAutoidx ) ;
@@ -141,12 +168,21 @@ public static void AddGameModeButton(string id, UIButtonBase.ButtonAction action
141168 Registry . gameModesAutoidx ++ ;
142169 }
143170
171+ /// <summary>
172+ /// Adds a new data type for patching.
173+ /// </summary>
174+ /// <param name="typeId">The identifier for the data type in JSON.</param>
175+ /// <param name="type">The C# type corresponding to the identifier.</param>
144176 public static void AddPatchDataType ( string typeId , Type type )
145177 {
146178 if ( ! typeMappings . ContainsKey ( typeId ) )
147179 typeMappings . Add ( typeId , type ) ;
148180 }
149181
182+ /// <summary>
183+ /// Loads all mods from the mods directory.
184+ /// </summary>
185+ /// <param name="mods">A dictionary to populate with the loaded mods.</param>
150186 internal static void LoadMods ( Dictionary < string , Mod > mods )
151187 {
152188 Directory . CreateDirectory ( Plugin . MODS_PATH ) ;
@@ -159,6 +195,7 @@ internal static void LoadMods(Dictionary<string, Mod> mods)
159195 Mod . Manifest ? manifest = null ;
160196 List < Mod . File > files = new ( ) ;
161197
198+ // Load mod from directory or zip archive
162199 if ( Directory . Exists ( modContainer ) )
163200 {
164201 foreach ( var file in Directory . GetFiles ( modContainer ) )
@@ -196,6 +233,7 @@ internal static void LoadMods(Dictionary<string, Mod> mods)
196233 }
197234 }
198235
236+ // Validate manifest
199237 if ( manifest == null )
200238 {
201239 Plugin . logger . LogError ( $ "Mod manifest not found in { modContainer } ") ;
@@ -234,6 +272,7 @@ internal static void LoadMods(Dictionary<string, Mod> mods)
234272 Plugin . logger . LogInfo ( $ "Registered mod { manifest . id } ") ;
235273 }
236274
275+ // Check dependencies
237276 foreach ( var ( id , mod ) in mods )
238277 {
239278 foreach ( var dependency in mod . dependencies ?? Array . Empty < Mod . Dependency > ( ) )
@@ -271,6 +310,11 @@ internal static void LoadMods(Dictionary<string, Mod> mods)
271310 }
272311 }
273312
313+ /// <summary>
314+ /// Sorts mods based on their dependencies using a topological sort.
315+ /// </summary>
316+ /// <param name="mods">The dictionary of mods to sort.</param>
317+ /// <returns>True if the mods could be sorted (no circular dependencies), false otherwise.</returns>
274318 internal static bool SortMods ( Dictionary < string , Mod > mods )
275319 {
276320 Stopwatch s = new ( ) ;
@@ -330,6 +374,11 @@ internal static bool SortMods(Dictionary<string, Mod> mods)
330374 return true ;
331375 }
332376
377+ /// <summary>
378+ /// Loads an assembly file from a mod.
379+ /// </summary>
380+ /// <param name="mod">The mod the assembly belongs to.</param>
381+ /// <param name="file">The assembly file to load.</param>
333382 public static void LoadAssemblyFile ( Mod mod , Mod . File file )
334383 {
335384 try
@@ -364,6 +413,11 @@ public static void LoadAssemblyFile(Mod mod, Mod.File file)
364413 }
365414 }
366415
416+ /// <summary>
417+ /// Loads a localization file from a mod.
418+ /// </summary>
419+ /// <param name="mod">The mod the localization file belongs to.</param>
420+ /// <param name="file">The localization file to load.</param>
367421 public static void LoadLocalizationFile ( Mod mod , Mod . File file )
368422 {
369423 try
@@ -378,6 +432,11 @@ public static void LoadLocalizationFile(Mod mod, Mod.File file)
378432 }
379433 }
380434
435+ /// <summary>
436+ /// Loads a sprite file from a mod.
437+ /// </summary>
438+ /// <param name="mod">The mod the sprite file belongs to.</param>
439+ /// <param name="file">The sprite file to load.</param>
381440 public static void LoadSpriteFile ( Mod mod , Mod . File file )
382441 {
383442 string name = Path . GetFileNameWithoutExtension ( file . name ) ;
@@ -400,6 +459,10 @@ public static void LoadSpriteFile(Mod mod, Mod.File file)
400459 Registry . sprites . Add ( name , sprite ) ;
401460 }
402461
462+ /// <summary>
463+ /// Updates a sprite with new information.
464+ /// </summary>
465+ /// <param name="name">The name of the sprite to update.</param>
403466 public static void UpdateSprite ( string name )
404467 {
405468 if ( Registry . spriteInfos . ContainsKey ( name ) && Registry . sprites . ContainsKey ( name ) )
@@ -415,6 +478,12 @@ public static void UpdateSprite(string name)
415478 }
416479 }
417480
481+ /// <summary>
482+ /// Loads a sprite info file from a mod.
483+ /// </summary>
484+ /// <param name="mod">The mod the sprite info file belongs to.</param>
485+ /// <param name="file">The sprite info file to load.</param>
486+ /// <returns>A dictionary of sprite information, or null if an error occurred.</returns>
418487 public static Dictionary < string , Visual . SpriteInfo > ? LoadSpriteInfoFile ( Mod mod , Mod . File file )
419488 {
420489 try
@@ -445,6 +514,11 @@ public static void UpdateSprite(string name)
445514 }
446515 }
447516
517+ /// <summary>
518+ /// Loads an audio file from a mod.
519+ /// </summary>
520+ /// <param name="mod">The mod the audio file belongs to.</param>
521+ /// <param name="file">The audio file to load.</param>
448522 public static void LoadAudioFile ( Mod mod , Mod . File file )
449523 {
450524 // AudioSource audioSource = new GameObject().AddComponent<AudioSource>();
@@ -454,6 +528,11 @@ public static void LoadAudioFile(Mod mod, Mod.File file)
454528 // TODO: issue #71
455529 }
456530
531+ /// <summary>
532+ /// Loads a prefab info file from a mod and creates a new unit prefab.
533+ /// </summary>
534+ /// <param name="mod">The mod the prefab info file belongs to.</param>
535+ /// <param name="file">The prefab info file to load.</param>
457536 public static void LoadPrefabInfoFile ( Mod mod , Mod . File file )
458537 {
459538 try
@@ -493,6 +572,11 @@ public static void LoadPrefabInfoFile(Mod mod, Mod.File file)
493572 }
494573 }
495574
575+ /// <summary>
576+ /// Clears existing visual parts from a prefab and extracts the material.
577+ /// </summary>
578+ /// <param name="spriteContainer">The transform containing the sprite parts.</param>
579+ /// <returns>The material of the original sprite parts.</returns>
496580 private static Material ? ClearExistingPartsAndExtractMaterial ( Transform spriteContainer )
497581 {
498582 Material ? material = null ;
@@ -510,6 +594,13 @@ public static void LoadPrefabInfoFile(Mod mod, Mod.File file)
510594 return material ;
511595 }
512596
597+ /// <summary>
598+ /// Applies new visual parts to a prefab.
599+ /// </summary>
600+ /// <param name="partInfos">A list of visual part information.</param>
601+ /// <param name="spriteContainer">The transform to add the parts to.</param>
602+ /// <param name="material">The material to use for the parts.</param>
603+ /// <returns>A list of the created visual parts.</returns>
513604 private static List < SkinVisualsReference . VisualPart > ApplyVisualParts (
514605 List < Visual . VisualPartInfo > partInfos ,
515606 Transform spriteContainer ,
@@ -525,6 +616,13 @@ public static void LoadPrefabInfoFile(Mod mod, Mod.File file)
525616 return parts ;
526617 }
527618
619+ /// <summary>
620+ /// Creates a single visual part for a prefab.
621+ /// </summary>
622+ /// <param name="info">The information for the visual part.</param>
623+ /// <param name="parent">The parent transform for the part.</param>
624+ /// <param name="material">The material to use for the part.</param>
625+ /// <returns>The created visual part.</returns>
528626 private static SkinVisualsReference . VisualPart CreateVisualPart (
529627 Visual . VisualPartInfo info ,
530628 Transform parent ,
@@ -567,11 +665,18 @@ private static SkinVisualsReference.VisualPart CreateVisualPart(
567665 return visualPart ;
568666 }
569667
668+ /// <summary>
669+ /// Loads and applies a game logic data patch from a mod.
670+ /// </summary>
671+ /// <param name="mod">The mod the patch belongs to.</param>
672+ /// <param name="gld">The original game logic data.</param>
673+ /// <param name="patch">The patch to apply.</param>
570674 public static void LoadGameLogicDataPatch ( Mod mod , JObject gld , JObject patch )
571675 {
572676 try
573677 {
574678 HandleSkins ( gld , patch ) ;
679+ // First pass: add new enum values and create mappings
575680 foreach ( JToken jtoken in patch . SelectTokens ( "$.*.*" ) . ToArray ( ) )
576681 {
577682 JObject ? token = jtoken . TryCast < JObject > ( ) ;
@@ -601,6 +706,7 @@ public static void LoadGameLogicDataPatch(Mod mod, JObject gld, JObject patch)
601706 }
602707 }
603708 }
709+ // Second pass: apply special handling
604710 foreach ( JToken jtoken in patch . SelectTokens ( "$.*.*" ) . ToArray ( ) )
605711 {
606712 JObject ? token = jtoken . TryCast < JObject > ( ) ;
@@ -616,6 +722,7 @@ public static void LoadGameLogicDataPatch(Mod mod, JObject gld, JObject patch)
616722 }
617723 }
618724 }
725+ // Final pass: merge the patch into the game logic data
619726 gld . Merge ( patch , new ( ) { MergeArrayHandling = MergeArrayHandling . Replace , MergeNullValueHandling = MergeNullValueHandling . Merge } ) ;
620727 Plugin . logger . LogInfo ( $ "Registered patch from { mod . id } mod") ;
621728 }
@@ -626,6 +733,11 @@ public static void LoadGameLogicDataPatch(Mod mod, JObject gld, JObject patch)
626733 }
627734 }
628735
736+ /// <summary>
737+ /// Loads an asset bundle from a mod.
738+ /// </summary>
739+ /// <param name="mod">The mod the asset bundle belongs to.</param>
740+ /// <param name="file">The asset bundle file to load.</param>
629741 public static void LoadAssetBundle ( Mod mod , Mod . File file )
630742 {
631743 Registry . assetBundles . Add (
@@ -634,6 +746,11 @@ public static void LoadAssetBundle(Mod mod, Mod.File file)
634746 ) ;
635747 }
636748
749+ /// <summary>
750+ /// Handles skin data from a patch.
751+ /// </summary>
752+ /// <param name="gld">The original game logic data.</param>
753+ /// <param name="patch">The patch to apply.</param>
637754 public static void HandleSkins ( JObject gld , JObject patch )
638755 {
639756 foreach ( JToken jtoken in patch . SelectTokens ( "$.tribeData.*" ) . ToArray ( ) )
0 commit comments