godotengine / godot

Godot Engine – Multi-platform 2D and 3D game engine
https://godotengine.org
MIT License
91.55k stars 21.26k forks source link

Allow us to export folders outside the PCK when exporting a project. #22950

Closed exts closed 4 years ago

exts commented 6 years ago

Essentially this stemmed from a discussion I had here https://github.com/godotengine/godot/issues/22825#issuecomment-427816708 which turned into a complete new issue which lead into confusion near the end.

Description of the suggestion

I want to be able to exclude a folder from within a PCK file and export the folder directly alongside the executable to allow for a traditional way of distributing game data (such as lua scripts, json files, sqlite loot tables and translation tables, etc...) that can be modified by the user directly for reading.

This would open up a cleaner way of modding in the classic civ or fallout way (such as separating save files, keybindings and settings in the user:// from game data that can be modified by the user)

Since you can already use current filesystem apis by omitting res:// from say file.Open('path/to/file') it'll look inside the folder that's located where the exe is located.

You can see an example of this here win64-bin.zip - all this would mean is making it easy to dump the appropriate folders when exporting a project to the same folder we save it to. Saving time of manually copying/pasting it ourselves.

What About Mobile

I think there's ways to detect which platform you're using with OS, so you should be able to determine which path to use at runtime (res://CustomFolder or CustomFolder) using a simple switch/if statement and when you export your project you can decide to keep the folder inside or outside of the PCK file from the export project dialog. Mobile/HTML5 aren't really meant to be modded anyways based on how things are packaged.

Straight to the point, clean, simple. Nothing more, nothing less.

LikeLakers2 commented 6 years ago

Okay. This I can understand, and this I'm in support of. 👍

P.S. I sincerely apologize for the confusion on the previous issue.

Zireael07 commented 6 years ago

Adding that it could be useful for some language bindings (e.g. Python bindings work by placing the Python interpreter in res://, which gets of course exported and packed away in pck/zip, therefore rendering Python interpreter inoperable in exports. Excluding the Python interpreter folder would solve the problem in one fell swoop :)

Faless commented 6 years ago

I honestly don't see much value in this. You can already exclude folders and files when exporting, using the resource export filter export

Can't you then just copy the excluded folders yourself?

exts commented 6 years ago

@Faless

all this would mean is making it easy to dump the appropriate folders when exporting a project to the same folder we save it too. Saving time of manually copying/pasting it ourselves.

from the main post.

Faless commented 6 years ago

@exts oh, sorry, I didn't see that. Well, I don't think this makes much sense, It's not like you export every 2 minutes, and if you do, you usually make a script for that. But that's just my take.

exts commented 6 years ago

@Faless I wouldn't mind making a script if there was a way to execute said script on the completion of a project export, but that's currently not possible making it less convenient for a normal workflow.

Faless commented 6 years ago

@exts yes you can, well, not the end, but the beginning, which in this case is the same I guess.

tool
extends EditorPlugin

class Exporter extends EditorExportPlugin:
    func _export_begin(features, is_debug, path, flags):
        # Move files or exec script here. path is the path of the exported binary
        print(path)

var _exporter = Exporter.new()

func _enter_tree():
    add_export_plugin(_exporter)

func _exit_tree():
    remove_export_plugin(_exporter)

Checkout the EditorPlugin docs for setting it up.

exts commented 6 years ago

@Faless i wasn't specifically talking about gd based scripts, I meant third party executable's - with that said, I still see this as a convenient feature for godot and I don't really see a reason not to add it.

neikeq commented 6 years ago

The following script should do what you want. I haven't tested if the code works or even compiles, but it should be something like this:

extends EditorExportPlugin

 # You could make these into project settings
var include_dirs = []
var include_files = []

var output_root_dir

func _export_begin(features, is_debug, path, flags):
    output_root_dir = path.get_base_dir()

func _export_file(path, type, features):
    for file in include_files:
        if path == file:
            _export_file_our_way(path)
            return
    for dir in include_dirs:
        dir = dir.rstrip("/")
        if path.begins_with(dir) and (len(path) == len(dir) || path[len(dir)] == "/"):
            _export_file_our_way(path)
            return

func _export_file_our_way(path):
    # EditorExportPlugin function that tells it not to export the file
    skip()

    # Copy to the output directory

    var rfile = File.new()
    rfile.open(path, File.READ)
    var buffer = rfile.get_buffer(rfile.get_len())
    rfile.close()

    output_path = output_root_dir.plus_file(path.trim_prefix("res://"))
    output_dir = output_path.get_base_dir()

    var dir = DirAccess.new()
    if not dir.dir_exists(output_dir):
        dir.make_recursive(output_dir)

    var wfile = File.new()
    wfile.open(output_path, File.WRITE)
    wfile.store_buffer(buffer)
    wfile.close()

You have to register the export plugin as shown in @Faless's comment.

Faless commented 6 years ago

@exts you can use OS.execute to run OS scripts from there: http://docs.godotengine.org/en/latest/classes/class_os.html#class-os-execute

On Fri, Oct 12, 2018, 17:34 Lamonte notifications@github.com wrote:

@Faless https://github.com/Faless i wasn't specifically talking about gd based scripts, I meant third party executable's

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/godotengine/godot/issues/22950#issuecomment-429366756, or mute the thread https://github.com/notifications/unsubscribe-auth/ABnBbsMo1WCfO7U6fdy_FAmkw0f0STvwks5ukLaAgaJpZM4XYb4y .

ARPasescu commented 5 years ago

This needs to happen. Right now you can create and write to files and folders in the root directory by using paths without "res://" (in the editor testing). You can also create files like that on export builds, however they won't let you create new folders. If someone can figure out why it doesn't allow this, and hopefully add this functionality, it's already pretty damn amazing. Next step would be, as this issue suggests, to add an option in the export menus to export files & folders outside of the .pck.

EIREXE commented 5 years ago

I think the problem will be that godot only supports one filesystem type at the same time #16798

aaronfranke commented 5 years ago

@exts: I wouldn't mind making a script if there was a way to execute said script on the completion of a project export

https://github.com/unknown-horizons/godot-port/blob/develop/build.sh

#!/bin/bash
$GODOT --path . --export linux "Builds/Desktop/$PROJECTNAME.x86_64"
$GODOT --path . --export windows "Builds/Desktop/$PROJECTNAME.exe"
# Do whatever else you need to do after you export...
dalexeev commented 4 years ago

What do you think about the following proposal?

  1. Add the OS.change_dir(path: String) method;
  2. Add support for the cwd:// pseudo-protocol. Relative paths should use the current working directory, as in other programming languages.

Then it will be possible to specify the location of cwd:// change current working directory at the start of a game as required. For example, like this:

# global.gd
extends Node

func _init():
    if OS.has_feature('editor') || OS.has_feature('mobile'):
        OS.change_dir('user://')
    else:
        OS.change_dir(OS.get_executable_path().get_base_dir())

Alternatively, you can give the opportunity to change the location of user:// in runtime.

(For me, data:// from #22825 and user:// are identical by purpose.)

clayjohn commented 4 years ago

Feature and improvement proposals for the Godot Engine are now being discussed and reviewed in a dedicated Godot Improvement Proposals (GIP) (godotengine/godot-proposals) issue tracker. The GIP tracker has a detailed issue template designed so that proposals include all the relevant information to start a productive discussion and help the community assess the validity of the proposal for the engine.

The main (godotengine/godot) tracker is now solely dedicated to bug reports and Pull Requests, enabling contributors to have a better focus on bug fixing work. Therefore, we are now closing all older feature proposals on the main issue tracker.

If you are interested in this feature proposal, please open a new proposal on the GIP tracker following the given issue template (after checking that it doesn't exist already). Be sure to reference this closed issue if it includes any relevant discussion (which you are also encouraged to summarize in the new proposal). Thanks in advance!