-
Notifications
You must be signed in to change notification settings - Fork 31
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
Project binary injection [old version] #81
Project binary injection [old version] #81
Conversation
ProjectSettings.set_setting(settings.IS_LOADER_SETUP_APPLIED, true) | ||
ProjectSettings.save_custom(modloaderutils.get_override_path()) | ||
|
||
# run the game again to apply the changed project settings | ||
var _exit_code_game_start = OS.execute(exe_path + "Brotato.exe", ["--script", "addons/mod_loader/mod_loader_setup.gd", '--pck-name="Brotato.pck"', "--log-debug"], false) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Qubus0 is correct, we can't hardcode the EXE name.
Regarding the starting of the game only working on Windows, I think that's fine for the MVP if this only happens when using the --silent
CLI arg (see my other review comment here), because we can just say "silent installation is currently only supported on Windows" -- then we can expand that later. This would let us, for example, allow silent installations on Thunderstore by default, if we choose to do that.
As long as it's an opt-in to run platform-specific code, we won't be preventing users who aren't on that platform from installing/running ModLoader, and that's fine for the MVP. Just be sure to keep the docs updated, perhaps with a dedicated "Platform Specifics" page to maximise its visability ;)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I fixed the hard coded exe name ( not sure how I missed that one in the first place 👀 )
About the --silent
Currently I have it like this:
func restart_game() -> void:
# run the game again to apply the changed project settings
var _exit_code_game_start = OS.execute(path.exe, ["--script", path.mod_loader_dir + "mod_loader_setup.gd", "--log-debug"], false)
# quit the current execution
quit()
So the game is always executed before quitting the first instance.
What I read here is that the default should be OS.alert()
and leave the restart to the user - right?
In that case I will add --unattended
to show the UI and auto restart.
So we have:
- no arg -> user handles the restart after
OS.alert()
message --unattended
user gets notified by restart timer - setup handles "restart"--silent
no restart notification - setup immediately "restarts" the game
From the latest discord chat with Mythic:
--only-setup
no restart - setup just quits the current game instance
"restart" in quotes because it's not really a restart, we have to execute the second game instance before we quit the first one.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds good, as long as CLI args are documented I'm happy :)
@KANAjetzt We've been talking on Discord about offering a CLI arg that lets you only save the override.cfg file. Could you include support for this in this PR please? The current use case is Dome Keeper, which has an embedded PCK, so we can't patch it with the methods currently applied in this PR. Eg. the CLI arg could be NotesDome Keeper users could use GodotPCKExplorer to extract the PCK, but that'll need to be done after every game update, and can't be handled automatically, so this isn't really viable if the user is using Thunderstore. Granted, override.cfg has the major limitation of not being able to put ModLoader at the top of the autoloads list (and Dome Keeper does indeed have many autoloads of its own), but @Qubus0 has suggested that this is a reasonable trade-off considering how impractical the alternative would be (ie. repeatedly using GodotPCKExplorer), and that their knowledge of the current scope of Dome Keeper mods suggests that modifying DK's autoloads may not be necessary. I also think that this is a good thing to support anyway, and will keep the code that generates override.cfg in place for if/when Godot implements Ste's proposal to allow changing the autoloads order. Note: I also mentioned this approach briefly in this review comment |
Once this PR is finished and merged, we can look into extending the features here for #83 |
@ithinkandicode |
what's missing still @KANAjetzt? |
else: | ||
restart_timer.start(4) | ||
|
||
ProjectSettings.set_setting(settings.IS_LOADER_SETUP_APPLIED, true) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this set_setting (and the one in L75) has no effect if it isn't saved to anything.
modloaderutils.log_debug_json_print("file_name: ", file_name, LOG_NAME) | ||
|
||
|
||
func setup_ui() -> void: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
are we sure this will always be on top of everything?
if for example some autoload has stuff that visualizes a game loading bar or something along those lines
|
||
var icon := Image.new() | ||
var _error_load_icon := icon.load(ProjectSettings.get_setting("application/config/icon")) | ||
OS.set_icon(icon) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you add a brief comment to the code here please, stating why this is needed?
if not modloaderutils.dir_exists(path.game_base_dir + "mods"): | ||
var dir = Directory.new() | ||
dir.make_dir(path.game_base_dir + "mods") | ||
modloaderutils.log_debug("created mods folder" , LOG_NAME) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is great but would it not be better in its own PR, dedicated to closing #34?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've closed issue #34 -- TL;DR is that I don't think this is needed because some games might use Steam Workshop etc
# In that case we add a override.cfg file to the base game dir. | ||
else: | ||
modloaderutils.log_debug("using the override.cfg file", LOG_NAME) | ||
create_override_cfg() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This will trigger if either is_setup_create_override_cfg
is true, or the PCK file doesn't exist. Is this intentional? Or shouldn't it only trigger if is_setup_create_override_cfg
is true?
It's a nice idea to have things happen automatically, but I think it's generally better for things to happen predictably -- eg. if a CLI arg exists to perform an action, that action should only be performed if you use that CLI arg.
This would also let you perform both actions, if (for whatever reason) you might want to. Atm this code only lets you create the override.cfg if the PCK file doesn't exist, but I don't think we need to add this extra level of conditional complexity. Best to just let users interact with the API without such hidden conditions.
I might be wrong here so I'm open to discussion
modloaderutils.log_debug_json_print("file_name: ", file_name, LOG_NAME) | ||
|
||
|
||
func setup_ui() -> void: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe make the GUI stuff optional via a CLI arg?
Tbh though I think this GUI feature would be better in a separate subsequent PR, as this PR is focused on patching the binary. Best to keep things small and contained IMO, makes it easier to review, keeps discussions focused, and gets stuff merged faster
@KANAjetzt Don't forget to fix the merge conflict! ;) |
poor @KANAjetzt hahaha, we believe in you! |
This was closed because it's doing several things, so KANA is going to split it up into smaller chunks, eg: |
Project binary injection
Because we cant set the order of autoloads via
override.cfg
we have to use external tooling ( GodotPckTool ) to inject the modified project settings in to the games .pck file.Relevant feature proposal:
godotengine/godot-proposals#6137
OS.execute() - GodotPckTool
This is the main part of this PR.
Executing the GodotPckTool, adding the before created
project.binary
to the main.pck
.New cli arguments
--silent
Executes the setup with no user interaction.
Restarts the game immediately after the setup, without showing the countdown
--setup-create-override-cfg
Forces the setup to create the
override.cfg
in the game base directory.Skips the
project.binary
injection.The setup checks if there is a
exe_name.pck
file in the game base directory and decides based on this if the injection can happen. So this argument is only required if this behavior is not wanted.--exe-name="name"
Override the
exe_name
.--pck-name="name"
Override the
pck_name
.Things this PR not covers
.pck
filescloses #34