Skip to content

HolonProduction/godot_standalone_plugin

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

5 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

πŸ“¦ Standalone Plugin

Godot: 4.0.beta5

This package makes it possible to develop a godot plugin and a corresponding standalone app using the same codebase.


🌱 Setup

  1. Add your plugin to the res://addons folder or create a new plugin.
  2. Copy res://standalone_plugin/editor.gd into your plugins directory. (And rename it if you want.)
  3. Modify the main script of your plugin to inherit the copied file from step 2.
  4. You are ready to go. πŸŽ‰

Step 2 and 3 can also be done automatically by calling Project>Tools>Make Plugin Standalone

If you use any of the helper options inside of the tools menu it is highly recommended to restart the edior afterwards. The build in script editor may not update the changed scripts otherwise. (No way to do it by code :/)


πŸš€ Features

Not every method of EditorPlugin can be reproduced without Godot internals like the import or export systems. Therefore not all methods of EditorPlugin will have an effect when running standalone. This won't throw an error though, in case your plugin has more functionality in Godot but should still run standalone.

Calling unsuported methods won't throw an error but when it comes to return values there can be problems. You should add null checks for all return values (e.g. get_script_create_dialog will return null on runtime). Same goes for everything returned from EditorInterface

Check if running standalone

If your plugin relies on godot internal systems adapting to standalone may require to disable some features. You can easily test whether you are running in the editor by calling Engine.is_editor_hint. This allows you to enable certain features only when running standalone or as plugin. For example the standalone app may require additional steps to select a file to edit.

Supported methods of EditorPlugin

Method Standalone Editor May Return null
_apply_changes virtual ❌ βœ”οΈ
_build virtual ❌ βœ”οΈ
_clear virtual ❌ βœ”οΈ
_disable_plugin virtual βœ”οΈ βœ”οΈ
_edit virtual ❌ βœ”οΈ
_enable_plugin virtual βœ”οΈ βœ”οΈ
_forward_3d_draw_over_viewport virtual ❌ βœ”οΈ
_forward_3d_force_draw_over_viewport virtual ❌ βœ”οΈ
_forward_3d_gui_input virtual ❌ βœ”οΈ
_forward_canvas_draw_over_viewport virtual ❌ βœ”οΈ
_forward_canvas_force_draw_over_viewport virtual ❌ βœ”οΈ
_forward_canvas_gui_input virtual ❌ βœ”οΈ
_get_breakpoints virtual ❌ βœ”οΈ
_get_plugin_icon virtual βœ”οΈ βœ”οΈ
_get_plugin_name virtual βœ”οΈ βœ”οΈ
_get_state virtual ❌ βœ”οΈ
_get_window_layout virtual βœ”οΈ βœ”οΈ
_handles virtual ❌ βœ”οΈ
_has_main_screen virtual βœ”οΈ βœ”οΈ
_make_visible virtual βœ”οΈ βœ”οΈ
_save_external_data virtual βœ”οΈ only when exiting βœ”οΈ
_set_state virtual ❌ βœ”οΈ
_set_window_layout virtual βœ”οΈ βœ”οΈ
add_autoload_singelton πŸ”Ά not at runtime but when registered in editor plugin it is still in the export βœ”οΈ
add_control_to_bottom_panel βœ”οΈ βœ”οΈ
add_control_to_container πŸ”Ά Only CONTAINER_TOOLBAR. Also adds new containers that are not supported in editor: CONTAINER_LAUNCH_PAD βœ”οΈ
add_control_to_dock βœ”οΈ βœ”οΈ
add_custom_type ❌ βœ”οΈ
add_debugger_plugin ❌ βœ”οΈ
add_export_plugin ❌ βœ”οΈ
add_import_plugin ❌ βœ”οΈ
add_inspector_plugin ❌ βœ”οΈ
add_scene_format_importer_plugin ❌ βœ”οΈ
add_scene_post_import_plugin ❌ βœ”οΈ
add_spacial_gizmo_plugin ❌ βœ”οΈ
add_tool_menu_item πŸ”Ά use the standalone exclusive menu api βœ”οΈ
add_tool_submenu_item πŸ”Ά use the standalone exclusive menu api βœ”οΈ
add_translation_parser_plugin ❌ βœ”οΈ
add_undo_redo_inspector_hook_callback ❌ βœ”οΈ
get_editor_interface πŸ”Ά returns an standalone interface βœ”οΈ No
get_export_as_menu ❌ βœ”οΈ Yes
get_script_create_dialog ❌ βœ”οΈ Yes
get_undo_redo βœ”οΈ βœ”οΈ No
hide_bottom_panel βœ”οΈ βœ”οΈ
make_bottom_panel_item_visible βœ”οΈ βœ”οΈ
queue_save_layout βœ”οΈ βœ”οΈ
remove_autoload_singelton ❌ βœ”οΈ
remove_control_from_bottom_panel βœ”οΈ βœ”οΈ
remove_control_from_container πŸ”Ά βœ”οΈ
remove_control_from_docks βœ”οΈ βœ”οΈ
remove_custom_type ❌ βœ”οΈ
remove_debugger_plugin ❌ βœ”οΈ
remove_export_plugin ❌ βœ”οΈ
remove_import_plugin ❌ βœ”οΈ
remove_inspector_plugin ❌ βœ”οΈ
remove_scene_format_importer_plugin ❌ βœ”οΈ
remove_scene_post_import_plugin ❌ βœ”οΈ
remove_spatial_gizmo_plugin ❌ βœ”οΈ
remove_tool_menu_item ❌ βœ”οΈ
remove_translation_parser_plugin ❌ βœ”οΈ
remove_undo_redo_inspector_hook_callback ❌ βœ”οΈ
set_force_draw_over_forwarding_enabled ❌ βœ”οΈ
update_overlays ❌ βœ”οΈ
add_menu_popup βœ”οΈπŸš§ ❌
remove_menu_popup βœ”οΈπŸš§ ❌

Supported methods of EditorInterface

Method Standalone Editor May Return null
edit_node ❌ βœ”οΈ
edit_resource ❌ βœ”οΈ
edit_script ❌ βœ”οΈ
get_base_control βœ”οΈ βœ”οΈ No
get_command_palette ❌ βœ”οΈ Yes
get_current_path πŸ”Ά will always return user:// βœ”οΈ No
get_edited_scene_root ❌ βœ”οΈ Yes
get_editor_main_screen βœ”οΈ βœ”οΈ No
get_editor_paths βœ”οΈ the paths are diffrent βœ”οΈ No
get_editor_scale βœ”οΈ will always return 1.0 βœ”οΈ No
get_editor_settings ❌ βœ”οΈ Yes
get_file_system_dock ❌ βœ”οΈ Yes
get_inspector ❌ βœ”οΈ Yes
get_open_scenes πŸ”Ά will always be empty βœ”οΈ No
get_playing_scene πŸ”Ά will always be empty βœ”οΈ No
get_resource_filesystem ❌ βœ”οΈ Yes
get_resource_previewer ❌ βœ”οΈ Yes
get_script_editor ❌ βœ”οΈ Yes
get_selected_path πŸ”Ά will always return user:// βœ”οΈ No
get_selection ❌ βœ”οΈ Yes
inspect_object ❌ βœ”οΈ
is_playing_scene πŸ”Ά will always be false βœ”οΈ No
is_plugin_enabled βœ”οΈ βœ”οΈ No
make_mesh_previews ❌ will return PlaceholderTexture2D βœ”οΈ No
open_scene_from_path ❌ βœ”οΈ
play_current_scene ❌ βœ”οΈ
play_custom_scene ❌ βœ”οΈ
play_main_scene ❌ βœ”οΈ
reload_scene_from_path ❌ βœ”οΈ
restart_editor ❌ βœ”οΈ
save_scene ❌ will always return OK βœ”οΈ No
save_scene_as ❌ βœ”οΈ
select_file ❌ βœ”οΈ
set_main_screen_editor βœ”οΈ βœ”οΈ
set_plugin_enabled βœ”οΈ βœ”οΈ
stop_playing_scene ❌ βœ”οΈ

πŸ”§ For the curious minded (and for me in one month)

🀷 How on earth does this piece of witchcraft work?

The script you copied before starts with the following line of code.

#@standalone

Before building your project the package will loop over all activated plugins. It will check for each whether the main script inherits a script which starts with this very line. In this way a list of plugins that should run standalone is obtained. This list is then stored in your ProjectSettings (the key is editor_plugins/standalone). When running your app the runtime compontents will read the list from the settings and there you have it.

πŸ™‹ But wait. The script does still inherit EditorPlugin or does it?

The script in your plugins directory does. This is the reason why your plugin can still be used in the godot editor. But this package does another usefull thing on build time. With the list of standalone plugins it also has a list of all scripts, that inherit EditorPlugin. Luckily Godot has the powerfull feature to load resource packs on runtime (read more on it here). This resource packs can override files at certain paths.
While building a resource pack is created, that overrides all the scripts inheriting EditorPlugin. They get replaced with a version that hooks the methods into the standalone UI.

πŸ™† I see, it is that simple!

Of course one still needs an ExportPlugin that ensures that the resource pack and all the plugins are included in the export. But you must have thought of that yourself, haven't you?

πŸ™‡ Sure...

About

Package to develope a godot plugin and a corresponding standalone app using the same codebase.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Sponsor this project

Packages

 
 
 

Contributors