@tool extends Object class_name AssetLoader #region Declaration --- # === CONST === const DEFAULT_ASSETS_PATH = "res://mods" ## If you want to change the mod extension. Keep in mind that it's still a json under the hood const MOD_INFOS_EXTENSION = "modinfo" ## Path to the mods folder : [param res://mods] by default ## [br] ## (is not a const but should be treated as such, so the uppercase) var ASSETS_PATH # === VAR === var dir:DirAccess var mod_folders:PackedStringArray var critical_error := false var mod_paths : PackedStringArray var mod_manifests : Dictionary[String,ModManifest] # === SIGNALS === signal loading_finished #endregion --- func _init() -> void: print_verbose("------ MOD LOADING STARTED ------") ASSETS_PATH = ProjectSettings.get_setting("game/mods/mod_path", DEFAULT_ASSETS_PATH) dir = DirAccess.open(ASSETS_PATH) if not dir: push_error("AssetLoader: Mods folder not found at '%s'" % ASSETS_PATH) push_error("AssetLoader:",DirAccess.get_open_error()) _show_error_popup("Mods folder not found at '%s'" % ASSETS_PATH) critical_error = true return mod_folders = dir.get_directories() if mod_folders.is_empty(): push_error("AssetLoader: Mods folder '%s' is empty — no mods to load." % ASSETS_PATH) _show_error_popup("Mods folder '%s' is empty — no mods to load." % ASSETS_PATH) critical_error = true return # === PRIVATE === ## This will show a native MessageBox on Windows, ## a native dialog on macOS, and GTK/QT dialog on Linux. func _show_error_popup(message: String) -> void: OS.alert("AssetLoader:"+message, "AssetLoader:Error") # === PUBLIC === func load_all(): load_mods() load_mods_content() ## Load and unpack all .pck before serialization func load_mods(): for mod in mod_folders: var mod_name = mod var mod_path = ASSETS_PATH + "/" + mod_name var manifest_path = mod_path + "/" + mod_name + "." + MOD_INFOS_EXTENSION if FileAccess.file_exists(manifest_path): var manifest_file := FileAccess.open(manifest_path, FileAccess.READ) var manifest: ModManifest = ModManifest.new_from_file(manifest_file) if !manifest:continue if !mod_manifests.has(manifest.id): mod_manifests[manifest.id] = manifest print_verbose("Mod manifest is loaded: %s" % manifest.name) var modpacks:Array = manifest.get_mod_packs() if manifest.packs.size() > 0: for pack in manifest.packs: if dir.file_exists(ASSETS_PATH + "/" + mod_name + pack + ".pck"): # variable re-usage here pass modpacks.append(pack) else: push_warning("Another mod as the same id:\n %s will not be loaded" % manifest_path) else: push_warning("No manifest found in %s" % manifest_path) for mod in mod_manifests: print("Mod loaded: %s" % mod) func load_mods_content(): pass