Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
exts opened this issue Oct 11, 2018 · 15 comments
Closed

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

exts opened this issue Oct 11, 2018 · 15 comments

Comments

@exts
Copy link
Contributor

exts commented Oct 11, 2018

Essentially this stemmed from a discussion I had here #22825 (comment) 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.

  • /AFolderExportedAlongsideTheExe
  • /AndAnotherCustomFolder
  • PROJECTNAME.exe
  • PROJECTNAME.pck

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
Copy link
Contributor

LikeLakers2 commented Oct 11, 2018

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
Copy link
Contributor

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
Copy link
Collaborator

Faless commented Oct 12, 2018

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
Copy link
Contributor Author

exts commented Oct 12, 2018

@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
Copy link
Collaborator

Faless commented Oct 12, 2018

@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
Copy link
Contributor Author

exts commented Oct 12, 2018

@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
Copy link
Collaborator

Faless commented Oct 12, 2018

@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
Copy link
Contributor Author

exts commented Oct 12, 2018

@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
Copy link
Contributor

neikeq commented Oct 12, 2018

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
Copy link
Collaborator

Faless commented Oct 12, 2018 via email

@ARPasescu
Copy link

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
Copy link
Contributor

EIREXE commented Mar 22, 2019

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

@aaronfranke
Copy link
Member

@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
Copy link
Member

dalexeev commented Jan 5, 2020

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
Copy link
Member

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!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests