#PCK loading without dependencies?

1 messages · Page 1 of 1 (latest)

quick panther
#

So I have been experimenting with modding in Godot & as a consequence, the PCK system. So far it seems clear to me that this is not a fully functional system for modding. Let me explain why:

You cannot export parts of your game as a PCK without including all of it's dependencies. This is a huge problem because now you are required to have repeat resources in every one of your PCKs. This is obviously a huge waste of space if you have a lot of dependencies for your PCKs (e.g. scripts, plugins, reusable scenes) that you don't intend to include in the PCK as it will already be present in the main project files.

You can technically pack PCKs without their dependencies but they will not load correctly.

So I do have a solution to this, albeit very hacky. Basically what I'm doing is implementing my own system for loading external resources. It works by looking at a directory you give it (can be anywhere on the disk) then manually loads each resource it finds in the folder & calls take_over_path on it so it can be loaded with load, the only problem with this is you can't access them using DirAccess or FileAccess so I made my own methods that include these imported resources when looking through directories & files.

For the end user, my solution means you can just drag your DLC files into an external folder and load them at runtime, no packing, no dependency issues, it just works.

Now the reason I am making this post is so I can ask: is there an easier way? does something like this exist already?

full sparrow
#

You can do it if you make a custom editor export plugin that force-ignores certain directories. It also gives you additional flexibility like not tying it to a specific export template. I've done this before, you basically have to define a custom export platform then you can do whatever you want inside of it:

func _export_project(preset: EditorExportPreset, debug: bool, path: String, flags: int) -> Error:
    var zip := ZIPPacker.new()
    var open_err := zip.open(path)
    if open_err:
        return open_err
    export_project_files(preset, debug,
        func(file_path: String, file_data: PackedByteArray, file_index: int, file_count: int, encryption_include_filters: PackedStringArray, encryption_exclude_filters: PackedStringArray, encryption_key: PackedByteArray):
            if file_path.begins_with("res://icons") or file_path == "res://project.binary":
                return
            zip.start_file(file_path.trim_prefix("res://"))
            zip.write_file(file_data)
            zip.close_file()
    )
    zip.close()
    return OK

https://github.com/sockeye-d/sunfish/blob/main/addons/plugin_exporter/plugin_export_platform.gd

#

In my case I strip out some files I don't want