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

Add "dedicated server" export mode which can strip unneeded visual resources #70377

Merged
merged 1 commit into from
Jan 23, 2023

Conversation

dsnopek
Copy link
Contributor

@dsnopek dsnopek commented Dec 20, 2022

This PR implements godotengine/godot-proposals#5970 and supersedes #69546

Based on feedback from @Faless on the old PR, this PR is mostly contained within the export system.

It also includes two suggestions that @jordo gave on the old PR:

  • The name of the headless video driver and dummy audio driver were moved into constants in main.cpp
  • A virtual method create_placeholder() was added to Resource so that it's up to each resource to convert itself into a placeholder if it can. This will make it a little easier to add more placeholder classes going forward. Per @reduz's request this isn't a virtual method on Resource, it's bound individually on each resource that can make a placeholder.

Here's a current screenshot of the UI:

Selection_486

Otherwise, see the proposal for information about how this feature is meant to work!

Bugsquad edit: This closes godotengine/godot-proposals#5970.


🍀 This work has been financed and kindly donated to the Godot Engine project by W4 Games. 🍀

Copy link
Collaborator

@Faless Faless left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Really amazing work 🚀 🏆 !
The code overall looks good, I tested it out a bit but it seems to have issues with instantiate scenes which have Editable Children set.
See this project.

It seems that the SubScene/MeshInstance -> Surface Material Override still reference the old texture:

ERROR: Resource file not found: res://.godot/imported/icon.png-487276ed1e3a0c39cad0279d744ee560.s3tc.ctex.
   at: _load (core/io/resource_loader.cpp:219)
ERROR: Failed loading resource: res://icon.png. Make sure resources have been imported by opening the project in the editor at least once.
   at: _load (core/io/resource_loader.cpp:214)
ERROR: Can't load dependency: res://icon.png.
   at: load (core/io/resource_format_binary.cpp:699)
ERROR: Failed loading resource: res://.godot/exported/133200997/export-14584830dbc22d3f76a596eed5f4948e-node_3d.scn. Make sure resources have been imported by opening the project in the editor at least once.
   at: _load (core/io/resource_loader.cpp:214)
ERROR: Failed loading scene: res://node_3d.tscn
   at: start (main/main.cpp:3009)

@dsnopek dsnopek force-pushed the server-export-mk2 branch 2 times, most recently from 8cb9390 to 3ec4554 Compare January 12, 2023 19:01
@dsnopek
Copy link
Contributor Author

dsnopek commented Jan 12, 2023

@Faless The changes I just pushed fix the issue you found with "Editable Children"! If you re-test with the same project, you'll probably need to delete .godot/exported for the changes to take effect (otherwise it'll re-use the cached exported resources from the last time).

Another note: the surface_material_override/0 property that you're overriding in your test project will actually become null rather than PlaceholderMaterial. I originally thought this meant it wasn't working, but after spending too much time trying to figure out why, I realized that this is expected! It's also replacing the mesh with PlaceholderMesh, which is reporting a surface count of 0, emptying out all the surface material overrides. :-)

I did a more targeted test as well, overriding mesh on the child of the instanced scene instead, and it correctly gets replaced with PlaceholderMesh too.

Unrelated to the "Editable Children" bug, I also added a UI change, where it'll set "res://" as Strip by default when you first switch to doing a dedicated server export (but it won't mess with existing customizations, if there are any). This fits in with the original proposal that wanted to make Strip be the default. And it will prevent users from wondering why their export is still so big after just selecting the mode, but failing to mark any paths as Strip.

@dsnopek dsnopek requested a review from Faless January 12, 2023 19:12
@dsnopek
Copy link
Contributor Author

dsnopek commented Jan 12, 2023

One more thing: I hadn't realized that @reduz added the export plugin system (in #65135) specifically thinking about the dedicated server export!

When I first started working on this PR, I couldn't figure out how to make the cascading path-based configuration work as an export plugin. However, I think I'm going to re-explore how this could be done as an export plugin, even if it means making changes to how export plugins work to accommodate it.

If this looks better as an export plugin, I'll either push those changes here or make a new PR. In any case, I'll share what comes up in that exploration!

@dsnopek dsnopek force-pushed the server-export-mk2 branch 2 times, most recently from c51cce7 to 0798f59 Compare January 12, 2023 22:07
@dsnopek
Copy link
Contributor Author

dsnopek commented Jan 12, 2023

Alright! I just pushed a version that converts as much as I could into an export plugin. I still have a backup of the non-plugin version, in case folks end up wanting to go that way. But the code changes are much smaller in the plugin version (which is always good :-)) so just went ahead and pushed it here right away, rather than making a new PR.

There's still things that aren't in the plugin, for example:

  • The changes to EditorExportPreset to store the additional configuration data
  • The UI changes in ProjectExportDialog
  • Putting together the list of files to include or omit in EditorExportPlatform

... but, overall, with the plugin, the changes to EditorExportPlatform are much more minor.

I also had to make some improvements to EditorExportPlugin to allow implementing this plugin from inside the engine (it was very geared to GDExtension) and allow plugins to add custom feature tags.

Please let me know what you think!

Copy link
Collaborator

@Faless Faless left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks much cleaner indeed! And it correctly exports scenes with editable children.

Though I am getting the following message spammed multiple times when exporting:

ERROR: Condition "!is_ancestor_of(p_node)" is true. Returning: false
   at: is_editable_instance (scene/main/node.cpp:2010)

Which is weird, because the only usage of is_editable_instance is in _export_customize_scene_resources/_is_editable_ancestor but at a glance it's supposed to work (the p_root received is not an ancestor of p_node? How can it be the root then?)

I'll make a MRP and post it below.

@Faless
Copy link
Collaborator

Faless commented Jan 13, 2023

Okay, it took me a while because I couldn't get the error reliably (until I realized that you need to change the scene when re-trying to avoid cache to kick in).

So, the error is now spammed for scenes without editable children (though the export works correctly). See the attached project. proj_srv_export_2.zip

@dsnopek
Copy link
Contributor Author

dsnopek commented Jan 13, 2023

@Faless Aha, thanks so much for working that out! I've added your suggested change to the PR :-)

Copy link
Collaborator

@Faless Faless left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking great now, amazing work! 💯 🎊

@jordo
Copy link
Contributor

jordo commented Jan 13, 2023

👍

@dsnopek
Copy link
Contributor Author

dsnopek commented Jan 20, 2023

Had a call with @reduz and he requested the following changes:

  • Rather than using a virtual method on Resource, register the create_placeholder() method on each of the resources that support becoming a placeholder
  • Show a message about which resources support being stripped in the UI (by looking up which have a create_placeholder() method in the ClassDB)

My latest push implements both things!

Here's a screenshot of the UI (the new message appears below the tree of files):

Selection_482

@reduz Does this match what you were thinking?

@dsnopek
Copy link
Contributor Author

dsnopek commented Jan 23, 2023

On RocketChat, @reduz requested that the "Strip" text in the dropdown be changed to "Strip visuals". My latest push makes this change! I've updated the screenshot in the PR description to reflect the new text.

doc/classes/Cubemap.xml Outdated Show resolved Hide resolved
doc/classes/Material.xml Outdated Show resolved Hide resolved
doc/classes/Mesh.xml Outdated Show resolved Hide resolved
doc/classes/Texture2D.xml Outdated Show resolved Hide resolved
doc/classes/Texture3D.xml Outdated Show resolved Hide resolved
@dsnopek dsnopek force-pushed the server-export-mk2 branch 2 times, most recently from 904dba7 to 8c70e0f Compare January 23, 2023 18:35
@dsnopek
Copy link
Contributor Author

dsnopek commented Jan 23, 2023

@Calinou Thanks for all the review and suggestions! I think I've got them all merged into my latest push

@akien-mga akien-mga modified the milestones: 4.x, 4.0 Jan 23, 2023
@akien-mga akien-mga merged commit 1dfd236 into godotengine:master Jan 23, 2023
@akien-mga
Copy link
Member

Thanks!

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

Successfully merging this pull request may close these issues.

Implement dedicated server export mode that strips unneeded visual resources and forces --headless
6 participants