From 9109f763c3457a2c655703de094884990f9dd013 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Verschelde?= Date: Mon, 3 Mar 2025 16:30:01 +0100 Subject: [PATCH 01/12] Branch docs version for Godot 4.4 --- .github/workflows/sync_class_ref.yml | 8 +------- conf.py | 6 +++--- index.rst | 4 ++-- 3 files changed, 6 insertions(+), 12 deletions(-) diff --git a/.github/workflows/sync_class_ref.yml b/.github/workflows/sync_class_ref.yml index a210f6f2bd0..fb786c547b9 100644 --- a/.github/workflows/sync_class_ref.yml +++ b/.github/workflows/sync_class_ref.yml @@ -2,12 +2,6 @@ name: Sync Class Reference on: workflow_dispatch: - # Scheduled updates only run on the default/master branch. - # Other branches need to be run manually (usually after a new release for that branch). - schedule: - # Run it at (European) night time every Saturday. - # The offset is there to try and avoid high load times. - - cron: '15 3 * * 6' # Make sure jobs cannot overlap. concurrency: @@ -23,7 +17,7 @@ jobs: runs-on: ubuntu-24.04 timeout-minutes: 10 env: - engine_rev: 'master' + engine_rev: '4.4' permissions: contents: write pull-requests: write diff --git a/conf.py b/conf.py index 939ac5d75af..688f342b723 100644 --- a/conf.py +++ b/conf.py @@ -91,7 +91,7 @@ # Version info for the project, acts as replacement for |version| and |release| # The short X.Y version -version = os.getenv("READTHEDOCS_VERSION", "latest") +version = os.getenv("READTHEDOCS_VERSION", "4.4") # The full version, including alpha/beta/rc tags release = version @@ -184,7 +184,7 @@ "display_github": not is_i18n, # Integrate GitHub "github_user": "godotengine", # Username "github_repo": "godot-docs", # Repo name - "github_version": "master", # Version + "github_version": "4.4", # Version "conf_py_path": "/", # Path in the checkout to the docs root "godot_docs_title": supported_languages[language], "godot_docs_basepath": "https://docs.godotengine.org/", @@ -194,7 +194,7 @@ "godot_title_prefix": "" if on_rtd else "(DEV) ", # Set this to `True` when in the `latest` branch to clearly indicate to the reader # that they are not reading the `stable` documentation. - "godot_is_latest": True, + "godot_is_latest": False, "godot_version": "4.4", # Enables a banner that displays the up-to-date status of each article. "godot_show_article_status": True, diff --git a/index.rst b/index.rst index 1615a93af51..b0ae2c09815 100644 --- a/index.rst +++ b/index.rst @@ -1,7 +1,7 @@ :allow_comments: False -Godot Docs – *master* branch -============================ +Godot Docs – *4.4* branch +========================= .. only:: not i18n From 6fd5aa26e3cd55db382630c591148730f85115c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Verschelde?= Date: Mon, 3 Mar 2025 17:34:13 +0100 Subject: [PATCH 02/12] Fix version for Edit on GitHub, should link to master --- conf.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conf.py b/conf.py index 688f342b723..da7ef6b6164 100644 --- a/conf.py +++ b/conf.py @@ -184,7 +184,7 @@ "display_github": not is_i18n, # Integrate GitHub "github_user": "godotengine", # Username "github_repo": "godot-docs", # Repo name - "github_version": "4.4", # Version + "github_version": "master", # Version for Edit on GitHub - keep `master` for 4.x branches "conf_py_path": "/", # Path in the checkout to the docs root "godot_docs_title": supported_languages[language], "godot_docs_basepath": "https://docs.godotengine.org/", From df7d8ddf64816560904fc4b3d80a735e0c7bcaff Mon Sep 17 00:00:00 2001 From: Max Hilbrunner Date: Sat, 13 Sep 2025 04:25:03 +0200 Subject: [PATCH 03/12] Create 4.5 branch --- .github/workflows/cherrypick.yml | 2 +- .github/workflows/sync_class_ref.yml | 2 +- conf.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/cherrypick.yml b/.github/workflows/cherrypick.yml index cb3b0fca665..50d7e270e01 100644 --- a/.github/workflows/cherrypick.yml +++ b/.github/workflows/cherrypick.yml @@ -10,7 +10,7 @@ on: env: # TODO: Add a way to handle multiple potential cherrypick targets. - TARGET_BRANCH: '4.3' + TARGET_BRANCH: '4.5' USERNAME: 'Godot Organization' EMAIL: 'noreply@godotengine.org' diff --git a/.github/workflows/sync_class_ref.yml b/.github/workflows/sync_class_ref.yml index e864e74e2e6..c8fe7b4ccea 100644 --- a/.github/workflows/sync_class_ref.yml +++ b/.github/workflows/sync_class_ref.yml @@ -23,7 +23,7 @@ jobs: runs-on: ubuntu-24.04 timeout-minutes: 10 env: - engine_rev: 'master' + engine_rev: '4.5' permissions: contents: write pull-requests: write diff --git a/conf.py b/conf.py index f42ecace1c8..c97d31997b5 100644 --- a/conf.py +++ b/conf.py @@ -171,7 +171,7 @@ "godot_title_prefix": "" if on_rtd else "(DEV) ", # Set this to `True` when in the `latest` branch to clearly indicate to the reader # that they are not reading the `stable` documentation. - "godot_is_latest": True, + "godot_is_latest": False, "godot_version": "4.5", # Enables a banner that displays the up-to-date status of each article. "godot_show_article_status": True, From 54621ec4354690e5a336f8081d75bf7929622ddb Mon Sep 17 00:00:00 2001 From: Max Hilbrunner Date: Sat, 13 Sep 2025 06:46:21 +0200 Subject: [PATCH 04/12] Update RTD version --- conf.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conf.py b/conf.py index 771aa73d55d..bd4671c4cb8 100644 --- a/conf.py +++ b/conf.py @@ -68,7 +68,7 @@ # Version info for the project, acts as replacement for |version| and |release| # The short X.Y version -version = os.getenv("READTHEDOCS_VERSION", "4.4") +version = os.getenv("READTHEDOCS_VERSION", "4.5") # The full version, including alpha/beta/rc tags release = version From 9874cad4d07464722276366d369d20034c6db1a4 Mon Sep 17 00:00:00 2001 From: Max Hilbrunner Date: Sat, 13 Sep 2025 08:25:04 +0200 Subject: [PATCH 05/12] Update 4.4 to 4.5 --- engine_details/development/compiling/getting_source.rst | 8 ++++---- index.rst | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/engine_details/development/compiling/getting_source.rst b/engine_details/development/compiling/getting_source.rst index ea49d29fa9e..55312234cb3 100644 --- a/engine_details/development/compiling/getting_source.rst +++ b/engine_details/development/compiling/getting_source.rst @@ -44,11 +44,11 @@ after the ``--branch`` (or just ``-b``) argument: :: - # Clone the continuously maintained stable branch (`4.4` as of writing). - git clone https://github.com/godotengine/godot.git -b 4.4 + # Clone the continuously maintained stable branch (`4.5` as of writing). + git clone https://github.com/godotengine/godot.git -b 4.5 - # Clone the `4.4-stable` tag. This is a fixed revision that will never change. - git clone https://github.com/godotengine/godot.git -b 4.4-stable + # Clone the `4.5-stable` tag. This is a fixed revision that will never change. + git clone https://github.com/godotengine/godot.git -b 4.5-stable # After cloning, optionally go to a specific commit. # This can be used to access the source code at a specific point in time, diff --git a/index.rst b/index.rst index 614af39b1b3..ed2436f1876 100644 --- a/index.rst +++ b/index.rst @@ -1,6 +1,6 @@ :allow_comments: False -Godot Docs – *4.4* branch +Godot Docs – *4.5* branch ========================= .. only:: not i18n From afb929b74fb13e0bbbe9f81dce484515c78ba019 Mon Sep 17 00:00:00 2001 From: Ste Date: Tue, 19 Aug 2025 14:24:45 +0200 Subject: [PATCH 06/12] expands the pygments lexer to cover GDScript 2 better (cherry picked from commit 5ebeb22bd08bf3b5ea58d4751b94e5ca90efb08c) --- _extensions/gdscript.py | 1344 +++++++++++++++++++++++++++++++++++---- _static/css/custom.css | 133 +++- 2 files changed, 1328 insertions(+), 149 deletions(-) diff --git a/_extensions/gdscript.py b/_extensions/gdscript.py index f7c1e214c45..1dac79fd0e7 100644 --- a/_extensions/gdscript.py +++ b/_extensions/gdscript.py @@ -9,46 +9,39 @@ :license: MIT. modified by Daniel J. Ramirez based on the original python.py pygment + further expanded and consolidated with the godot-docs lexer by Zackery R. Smith and Ste. """ -import re - -from pygments.lexer import ( - RegexLexer, - include, - bygroups, - default, - words, - combined, -) +from pygments.lexer import RegexLexer, include, bygroups, words, combined from pygments.token import ( - Text, - Comment, - Operator, Keyword, + Literal, Name, + Comment, String, Number, - Punctuation, + Operator, Whitespace, + Punctuation, ) __all__ = ["GDScriptLexer"] -line_re = re.compile(".*?\n") - class GDScriptLexer(RegexLexer): """ - For `GDScript source code `_. + For GDScript source code. """ name = "GDScript" + url = "https://www.godotengine.org" aliases = ["gdscript", "gd"] filenames = ["*.gd"] mimetypes = ["text/x-gdscript", "application/x-gdscript"] - def innerstring_rules(ttype): + # taken from pygments/gdscript.py + @staticmethod + def inner_string_rules(ttype): return [ # the old style '%s' % (...) string formatting ( @@ -56,7 +49,7 @@ def innerstring_rules(ttype): "[hlL]?[E-GXc-giorsux%]", String.Interpol, ), - # backslashes, quotes and formatting signs must be parsed one at a time + # backslashes, quotes, and formatting signs must be parsed one at a time (r'[^\\\'"%\n]+', ttype), (r'[\'"\\]', ttype), # unhandled string formatting sign @@ -65,78 +58,19 @@ def innerstring_rules(ttype): ] tokens = { - "root": [ - (r"\n", Whitespace), - ( - r'^(\s*)([rRuUbB]{,2})("""(?:.|\n)*?""")', - bygroups(Whitespace, String.Affix, String.Doc), - ), - ( - r"^(\s*)([rRuUbB]{,2})('''(?:.|\n)*?''')", - bygroups(Whitespace, String.Affix, String.Doc), - ), - (r"[^\S\n]+", Whitespace), + "whitespace": [(r"\s+", Whitespace)], + "comment": [ + (r"##.*$", Comment.Doc), + (r"#(?:end)?region.*$", Comment.Region), (r"#.*$", Comment.Single), - (r"[]{}:(),;[]", Punctuation), - (r"(\\)(\n)", Whitespace), - (r"\\", Text), - # modules/gdscript/gdscript.cpp - GDScriptLanguage::get_reserved_words() - # Operators. - (r"(and|as|in|is|not|or)\b", Operator.Word), - ( - r"!=|==|<<|>>|&&|\+=|-=|\*=|/=|%=|&=|\|=|\|\||[-~+/*%=<>&^.!|$]", - Operator, - ), - include("keywords"), - include("control_flow_keywords"), - (r"(func)((?:\s|\\\s)+)", bygroups(Keyword, Whitespace), "funcname"), - (r"(class)((?:\s|\\\s)+)", bygroups(Keyword, Whitespace), "classname"), - include("builtins"), - include("decorators"), - ( - '([rR]|[uUbB][rR]|[rR][uUbB])(""")', - bygroups(String.Affix, String.Double), - "tdqs", - ), - ( - "([rR]|[uUbB][rR]|[rR][uUbB])(''')", - bygroups(String.Affix, String.Single), - "tsqs", - ), - ( - '([rR]|[uUbB][rR]|[rR][uUbB])(")', - bygroups(String.Affix, String.Double), - "dqs", - ), - ( - "([rR]|[uUbB][rR]|[rR][uUbB])(')", - bygroups(String.Affix, String.Single), - "sqs", - ), - ( - '([uUbB]?)(""")', - bygroups(String.Affix, String.Double), - combined("stringescape", "tdqs"), - ), - ( - "([uUbB]?)(''')", - bygroups(String.Affix, String.Single), - combined("stringescape", "tsqs"), - ), - ( - '([uUbB]?)(")', - bygroups(String.Affix, String.Double), - combined("stringescape", "dqs"), - ), - ( - "([uUbB]?)(')", - bygroups(String.Affix, String.Single), - combined("stringescape", "sqs"), - ), - include("name"), - include("numbers"), ], - "keywords": [ + "punctuation": [ + (r"[]{}(),:;[]", Punctuation), + (r":\n", Punctuation), + (r"\\", Punctuation), + ], + # NOTE: from github.com/godotengine/godot-docs + "keyword": [ ( words( ( @@ -148,27 +82,26 @@ def innerstring_rules(ttype): "enum", "extends", "func", - "namespace", # Reserved for potential future use. + "namespace", # Reserved for potential future use. "signal", "static", - "trait", # Reserved for potential future use. + "trait", # Reserved for potential future use. "var", # Other keywords. "await", "breakpoint", "self", "super", - "yield", # Reserved for potential future use. + "yield", # Reserved for potential future use. # Not really keywords, but used in property syntax. - "set", - "get", + # also colored like functions, not keywords + #"set", + #"get", ), suffix=r"\b", ), Keyword, ), - ], - "control_flow_keywords": [ ( words( ( @@ -185,6 +118,7 @@ def innerstring_rules(ttype): "return", "when", "while", + "yield", ), suffix=r"\b", ), @@ -193,7 +127,16 @@ def innerstring_rules(ttype): Keyword.ControlFlow, ), ], - "builtins": [ + "builtin": [ + ( + words( + ("true", "false", "PI", "TAU", "NAN", "INF", "null"), + prefix=r"(?>|&&|\+=|-=|\*=|/=|%=|&=|\|=|\|\||[-~+/*%=<>&^.!|$]", + Operator, ), - (r"(-)?(\d|(?<=\d)_)+[eE][+-]?(\d|(?<=\d)_)+j?", Number.Float), - (r"(-)?0[xX]([a-fA-F0-9]|(?<=[a-fA-F0-9])_)+", Number.Hex), + (r"(in|is|and|as|or|not)\b", Operator.Word), + ], + "number": [ + (r"([\d_]+\.[\d_]*|[\d_]*\.[\d_]+)([eE][+-]?[\d_]+)?", Number.Float), + (r"[\d_]+[eE][+-]?[\d_]+", Number.Float), + (r"0[xX][a-fA-F\d_]+", Number.Hex), (r"(-)?0[bB]([01]|(?<=[01])_)+", Number.Bin), - (r"(-)?(\d|(?<=\d)_)+j?", Number.Integer), + (r"[\d_]+", Number.Integer), + ], + "name": [(r"[a-zA-Z_]\w*", Name)], + "typehint": [ + (r"[a-zA-Z_]\w*", Name.Class, "#pop"), ], - "name": [(r"@?[a-zA-Z_]\w*", Name)], - "funcname": [(r"[a-zA-Z_]\w*", Name.Function, "#pop"), default("#pop")], - "classname": [(r"[a-zA-Z_]\w*", Name.Class, "#pop")], - "stringescape": [ + "string_escape": [ ( r'\\([\\abfnrtv"\']|\n|N\{.*?\}|u[a-fA-F0-9]{4}|' - r"U[a-fA-F0-9]{8}|x[a-fA-F0-9]{2}|[0-7]{1,3})", + r"U[a-fA-F0-9]{6}|x[a-fA-F0-9]{2}|[0-7]{1,3})", String.Escape, ) ], - "strings-single": innerstring_rules(String.Single), - "strings-double": innerstring_rules(String.Double), - "dqs": [ + "string_single": inner_string_rules(String.Single), + "string_double": inner_string_rules(String.Double), + "string_other": inner_string_rules(String.Other), + "string_stringname": inner_string_rules(String.StringName), + "string_nodepath": inner_string_rules(String.NodePath), + "double_quotes": [ (r'"', String.Double, "#pop"), (r'\\\\|\\"|\\\n', String.Escape), # included here for raw strings - include("strings-double"), + include("string_double"), ], - "sqs": [ + "single_quotes": [ (r"'", String.Single, "#pop"), (r"\\\\|\\'|\\\n", String.Escape), # included here for raw strings - include("strings-single"), + include("string_single"), ], - "tdqs": [ + "triple_double_quotes": [ (r'"""', String.Double, "#pop"), - include("strings-double"), - (r"\n", Whitespace), + include("string_double"), + include("whitespace"), ], - "tsqs": [ + "triple_single_quotes": [ (r"'''", String.Single, "#pop"), - include("strings-single"), - (r"\n", Whitespace), + include("string_single"), + include("whitespace"), + ], + "node_reference": [ + (r'[\$%]"', String.Other, include("node_reference_double")), + (r"[\$%]'", String.Other, include("node_reference_single")), + (r"[\$%][A-Za-z_][\w/]*/?", String.Other), + ], + "node_reference_double": [ + (r'"', String.Other, "#pop"), + include("string_other"), + ], + "node_reference_single": [ + (r"'", String.Other, "#pop"), + include("string_other"), + ], + "stringname": [ + (r'[&]"', String.StringName, include("stringname_double")), + (r"[&]'", String.StringName, include("stringname_single")), + ], + "stringname_double": [ + (r'"', String.StringName, "#pop"), + include("string_stringname"), + ], + "stringname_single": [ + (r"'", String.StringName, "#pop"), + include("string_stringname"), + ], + "nodepath": [ + (r'[\^]"', String.NodePath, include("nodepath_double")), + (r"[\^]'", String.NodePath, include("nodepath_single")), + ], + "nodepath_double": [ + (r'"', String.NodePath, "#pop"), + include("string_nodepath"), + ], + "nodepath_single": [ + (r"'", String.NodePath, "#pop"), + include("string_nodepath"), + ], + "function_name": [(r"[a-zA-Z_]\w*", Name.Function.Declaration, "#pop")], + "enum_name": [(r"[a-zA-Z_]\w*", Name, "#pop")], + "function": [ + (r"\b([a-zA-Z_]\w*)\s*(?=\()", Name.Function), + ( + # colored like functions, even without braces + words(("set", "get",), suffix=r"\b", ), + Name.Function, + ), + ], + + ####################################################################### + # LEXER ENTRY POINT + ####################################################################### + "root": [ + include("whitespace"), + include("comment"), + include("punctuation"), + include("builtin"), + # strings + include("stringname"), + include("nodepath"), + include("node_reference"), + ( + '(r)(""")', + bygroups(String.Affix, String.Double), + "triple_double_quotes", + ), + ( + "(r)(''')", + bygroups(String.Affix, String.Single), + "triple_single_quotes", + ), + ( + '(r)(")', + bygroups(String.Affix, String.Double), + "double_quotes", + ), + ( + "(r)(')", + bygroups(String.Affix, String.Single), + "single_quotes", + ), + ( + '(r?)(""")', + bygroups(String.Affix, String.Double), + combined("string_escape", "triple_double_quotes"), + ), + ( + "(r?)(''')", + bygroups(String.Affix, String.Single), + combined("string_escape", "triple_single_quotes"), + ), + ( + '(r?)(")', + bygroups(String.Affix, String.Double), + combined("string_escape", "double_quotes"), + ), + ( + "(r?)(')", + bygroups(String.Affix, String.Single), + combined("string_escape", "single_quotes"), + ), + # consider Name after a . as instance/members variables + (r"(? Date: Mon, 1 Sep 2025 18:16:18 +0200 Subject: [PATCH 07/12] Document applying updates on MSVC in Compiling for Windows This is sometimes required to fix compilation errors. (cherry picked from commit fe23e577a5ecaf6da5d354f0f4846234ab1c9084) --- .../development/compiling/compiling_for_windows.rst | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/engine_details/development/compiling/compiling_for_windows.rst b/engine_details/development/compiling/compiling_for_windows.rst index 5f84cfcfd4a..cd1745e9621 100644 --- a/engine_details/development/compiling/compiling_for_windows.rst +++ b/engine_details/development/compiling/compiling_for_windows.rst @@ -354,6 +354,14 @@ and able to build Godot using Visual Studio's **Build** button. .. seealso:: See :ref:`doc_configuring_an_ide_vs` for further details. +Troubleshooting +~~~~~~~~~~~~~~~ + +If you get a compilation failure when using MSVC, make sure to apply the +latest updates. You can do so by starting the Visual Studio IDE and using +:button:`Continue without code`, then :menu:`Help > Check for Updates` in the +menu bar at the top. Install all updates, then try compiling again. + Cross-compiling for Windows from other operating systems -------------------------------------------------------- From b458814995fb887e19a606a4ace9c7ae60680cc0 Mon Sep 17 00:00:00 2001 From: Hugo Locurcio Date: Fri, 5 Sep 2025 19:43:13 +0200 Subject: [PATCH 08/12] Add logging documentation This also covers how to create custom loggers. - Remove notice on Windows 10 requirement for `print_rich()` in Output panel, since Godot requires Windows 10 as of 4.5. (cherry picked from commit 7b98025f2e421c97041cb5d4426a7db2c6a038cd) --- tutorials/io/data_paths.rst | 39 +-- tutorials/scripting/debug/debugger_panel.rst | 2 + tutorials/scripting/debug/output_panel.rst | 40 ++- tutorials/scripting/index.rst | 1 + tutorials/scripting/logging.rst | 270 +++++++++++++++++++ 5 files changed, 309 insertions(+), 43 deletions(-) create mode 100644 tutorials/scripting/logging.rst diff --git a/tutorials/io/data_paths.rst b/tutorials/io/data_paths.rst index 3e69484d188..7f0de3db569 100644 --- a/tutorials/io/data_paths.rst +++ b/tutorials/io/data_paths.rst @@ -114,44 +114,9 @@ through the :ref:`JavaScriptBridge ` singleton.) File logging ------------ -By default, Godot writes log files in ``user://logs/godot.log`` on desktop -platforms. You can change this location by modifying the -``debug/file_logging/log_path`` project setting. Logs are rotated to keep older -files available for inspection. Each session creates a new log file, with the -old file renamed to contain the date at which it was rotated. Up to 5 log files -are kept by default, which can be adjusted using the -``debug/file_logging/max_log_files`` project setting. - -File logging can also be disabled completely using the -``debug/file_logging/enable_file_logging`` project setting. - -When the project crashes, crash logs are written to the same file as the log -file. The crash log will only contain a usable backtrace if the binary that was -run contains debugging symbols, or if it can find a debug symbols file that -matches the binary. Official binaries don't provide debugging symbols, so this -requires a custom build to work. See -:ref:`Debugging symbols `. -for guidance on compiling binaries with debugging symbols enabled. +.. seealso:: -.. note:: - - Log files for :ref:`print` - statements are updated when standard output is *flushed* by the engine. - Standard output is flushed on every print in debug builds only. In projects that - are exported in release mode, standard output is only flushed when the project exits - or crashes to improve performance, especially if the project is often printing - text to standard output. - - On the other hand, the standard error stream - (used by :ref:`printerr`, - :ref:`push_error` and - :ref:`push_warning`) is always - flushed on every print, even in projects exported in release mode. - - For some use cases like dedicated servers, it can be preferred to have release - builds always flush stdout on print, so that logging services like journald can - collect logs while the process is running. This can be done by enabling - ``application/run/flush_stdout_on_print`` in the Project Settings. + Documentation on file logging has been moved to :ref:`doc_logging`. Converting paths to absolute paths or "local" paths --------------------------------------------------- diff --git a/tutorials/scripting/debug/debugger_panel.rst b/tutorials/scripting/debug/debugger_panel.rst index b8754848814..c20a04e606b 100644 --- a/tutorials/scripting/debug/debugger_panel.rst +++ b/tutorials/scripting/debug/debugger_panel.rst @@ -120,6 +120,8 @@ and how that effects performance. A detailed explanation of how to use the profiler can be found in the dedicated :ref:`doc_the_profiler` page. +.. _doc_debugger_panel_visual_profiler: + Visual Profiler --------------- diff --git a/tutorials/scripting/debug/output_panel.rst b/tutorials/scripting/debug/output_panel.rst index 1c00e389e3b..80c38c9e3e1 100644 --- a/tutorials/scripting/debug/output_panel.rst +++ b/tutorials/scripting/debug/output_panel.rst @@ -47,6 +47,8 @@ is controlled by the **Run > Output > Always Clear Output on Play** editor setti Additionally, you can manually clear messages by clicking the "cleaning brush" icon in the top-right corner of the Output panel. +.. _doc_output_panel_printing_messages: + Printing messages ----------------- @@ -54,6 +56,8 @@ Several methods are available to print messages: - :ref:`print() `: Prints a message. This method accepts multiple arguments which are concatenated together upon printing. + This method has variants that separate arguments with tabs and spaces respectively: + :ref:`printt() ` and :ref:`prints() `. - :ref:`print_rich() `: Same as ``print()``, but BBCode can be used to format the text that is printed (see below). - :ref:`push_error() `: Prints an error message. @@ -63,9 +67,37 @@ Several methods are available to print messages: When a warning is printed in a running project, it's displayed in the **Debugger > Errors** tab instead. +For more complex use cases, these can be used: + +- :ref:`print_verbose() `: Same as ``print()``, + but only prints when verbose mode is enabled in the Project Settings + or the project is run with the ``--verbose`` command line argument. +- :ref:`printerr() `: Same as ``print()``, + but prints to the standard error stream instead of the standard output string. + ``push_error()`` should be preferred in most cases. +- :ref:`printraw() `: Same as ``print()``, + but prints without a blank line at the end. This is the only method + that does **not** print to the editor Output panel. + It prints to the standard output stream *only*, which means it's still included + in file logging. +- :ref:`print_stack() `: Print a stack trace + from the current location. Only supported when running from the editor, + or when the project is exported in debug mode. +- :ref:`print_tree() `: Prints the scene tree + relative to the current node. Useful for debugging node structures created at runtime. +- :ref:`print_tree_pretty() `: Same as + ``print_tree()``, but with Unicode characters for a more tree-like appearance. This relies on + `box-drawing characters `__, + so it may not render correctly with all fonts. + To get more advanced formatting capabilities, consider using :ref:`doc_gdscript_printf` along with the above printing functions. +.. seealso:: + + The engine's logging facilities are covered in the :ref:`logging ` + documentation. + .. _doc_output_panel_printing_rich_text: Printing rich text @@ -85,9 +117,5 @@ same colors as they would in the project. .. note:: - ANSI escape code support varies across terminal emulators. On Windows, only - Windows 10 and later can display ANSI escape codes in its default terminal - application. - - The exact colors displayed in terminal output also depend on the terminal - theme chosen by the user. + ANSI escape code support varies across terminal emulators. The exact colors + displayed in terminal output also depend on the terminal theme chosen by the user. diff --git a/tutorials/scripting/index.rst b/tutorials/scripting/index.rst index dfaf28cc7af..46c2ff946c1 100644 --- a/tutorials/scripting/index.rst +++ b/tutorials/scripting/index.rst @@ -57,3 +57,4 @@ below will help you make the most of Godot. singletons_autoload scene_tree scene_unique_nodes + logging diff --git a/tutorials/scripting/logging.rst b/tutorials/scripting/logging.rst new file mode 100644 index 00000000000..4bc763afe49 --- /dev/null +++ b/tutorials/scripting/logging.rst @@ -0,0 +1,270 @@ +.. _doc_logging: + +Logging +======= + +Godot comes with several ways to organize and collect log messages. + +Printing messages +----------------- + +.. seealso:: + + See :ref:`doc_output_panel_printing_messages` for instructions on printing + messages. The printed output is generally identical to the logged output. + + When running a project from the editor, the editor will display logged text + in the :ref:`doc_output_panel`. + +Project settings +---------------- + +There are several project settings to control logging behavior in Godot: + +- **Application > Run > Disable stdout:** Disables logging to standard output entirely. + This also affects what custom loggers receive. This can be controlled at runtime + by setting :ref:`Engine.print_to_stdout `. +- **Application > Run > Disable stderr:** Disables logging to standard error entirely. + This also affects what custom loggers receive. This can be controlled at runtime + by setting :ref:`Engine.print_error_messages `. +- **Debug > Settings > stdout > Verbose stdout:** Enables verbose logging to standard output. + Prints from :ref:`print_verbose() ` are only + visible if verbose mode is enabled. +- **Debug > Settings > stdout > Print FPS:** Prints the frames per second every second, + as well as the V-Sync status on startup (as it can effectively cap the maximum framerate). +- **Debug > Settings > stdout > Print GPU Profile:** Prints a report of GPU utilization + every second, using the same data source as the :ref:`doc_debugger_panel_visual_profiler`. + +Some of these project settings can also be overridden using +:ref:`command line arguments ` such as ``--quiet``, +``--verbose``, and ``--print-fps``. + +The engine's own file logging is also configurable, as described in the section below. + +Built-in file logging +--------------------- + +By default, Godot writes log files in ``user://logs/godot.log`` on desktop +platforms. You can change this location by modifying the +``debug/file_logging/log_path`` project setting. Logs are rotated to keep older +files available for inspection. Each session creates a new log file, with the +old file renamed to contain the date at which it was rotated. Up to 5 log files +are kept by default, which can be adjusted using the +``debug/file_logging/max_log_files`` project setting. + +File logging can also be disabled completely using the +``debug/file_logging/enable_file_logging`` project setting. + +When the project crashes, crash logs are written to the same file as the log +file. The crash log will only contain a usable backtrace if the binary that was +run contains debugging symbols, or if it can find a debug symbols file that +matches the binary. Official binaries don't provide debugging symbols, so this +requires a custom build to work. See +:ref:`Debugging symbols ` +for guidance on compiling binaries with debugging symbols enabled. + +.. note:: + + Log files for :ref:`print() ` + statements are updated when standard output is *flushed* by the engine. + Standard output is flushed on every print in debug builds only. In projects that + are exported in release mode, standard output is only flushed when the project exits + or crashes to improve performance, especially if the project is often printing + text to standard output. + + On the other hand, the standard error stream + (used by :ref:`printerr() `, + :ref:`push_error() `, and + :ref:`push_warning() `) is always + flushed on every print, even in projects exported in release mode. + + For some use cases like dedicated servers, it can be preferred to have release + builds always flush stdout on print, so that logging services like journald can + collect logs while the process is running. This can be done by enabling + ``application/run/flush_stdout_on_print`` in the Project Settings. + +Script backtraces +----------------- + +Since Godot 4.5, when GDScript code encounters an error, it will log a backtrace that points +to the origin of the error, while also containing the call stack leading to it. This behavior +is always enabled when running in the editor, or when the project is exported in debug mode. + +In projects exported in release mode, backtraces are disabled by default for performance reasons. +You can enable them by checking **Debug > Settings > GDScript > Always Track Call Stacks** in +the Project Settings. If you use a custom logging system that reports exceptions to a remote +service, it's recommended to enable this to make reported errors more actionable. + +Crash backtraces +---------------- + +.. warning:: + + Crash backtraces are only useful if they were recorded in a build that + contains :ref:`debugging symbols `. + Official Godot binaries do not contain debugging symbols, so you must compile a + custom editor or export template binary to get useful crash backtraces. + +When the project crashes, a crash backtrace is printed to the standard error stream. This is what +it can look like in a build with debug symbols: + +:: + + ================================================================ + handle_crash: Program crashed with signal 4 + Engine version: Godot Engine v4.5.beta.custom_build (6c9aa4c7d3b9b91cd50714c40eeb234874df7075) + Dumping the backtrace. Please include this when reporting the bug to the project developer. + [1] /lib64/libc.so.6(+0x1a070) [0x7f6e5e277070] (??:0) + [2] godot() [0x4da3358] (/path/to/godot/core/core_bind.cpp:336 (discriminator 2)) + [3] godot() [0xdf5f2f] (/path/to/godot/modules/gdscript/gdscript.h:591) + [4] godot() [0xbffd46] (/path/to/godot/modules/gdscript/gdscript.cpp:2065 (discriminator 1)) + [5] godot() [0x30f2ea4] (/path/to/godot/core/variant/variant.h:870) + [6] godot() [0x550d4e1] (/path/to/godot/core/object/object.cpp:933) + [7] godot() [0x30d996a] (/path/to/godot/scene/main/node.cpp:318 (discriminator 1)) + [8] godot() [0x3131a7f] (/path/to/godot/core/templates/hash_map.h:465) + [9] godot() [0x424589] (/path/to/godot/platform/linuxbsd/os_linuxbsd.cpp:970) + [10] /lib64/libc.so.6(+0x3575) [0x7f6e5e260575] (??:0) + [11] /lib64/libc.so.6(__libc_start_main+0x88) [0x7f6e5e260628] (??:0) + [12] godot() [0x464df5] (??:?) + -- END OF C++ BACKTRACE -- + ================================================================ + GDScript backtrace (most recent call first): + [0] _ready (res://test.gd:5) + -- END OF GDSCRIPT BACKTRACE -- + ================================================================ + +On the other hand, without debug symbols, it will look like this instead: + +:: + + ================================================================ + handle_crash: Program crashed with signal 4 + Engine version: Godot Engine v4.5.beta.custom_build (6c9aa4c7d3b9b91cd50714c40eeb234874df7075) + Dumping the backtrace. Please include this when reporting the bug to the project developer. + [1] /lib64/libc.so.6(+0x1a070) [0x7fdfaf666070] (??:0) + [2] godot() [0x4da3358] (??:0) + [3] godot() [0xdf5f2f] (??:0) + [4] godot() [0xbffd46] (??:0) + [5] godot() [0x30f2ea4] (??:0) + [6] godot() [0x550d4e1] (??:0) + [7] godot() [0x30d996a] (??:0) + [8] godot() [0x3131a7f] (??:0) + [9] godot() [0x424589] (??:0) + [10] /lib64/libc.so.6(+0x3575) [0x7fdfaf64f575] (??:0) + [11] /lib64/libc.so.6(__libc_start_main+0x88) [0x7fdfaf64f628] (??:0) + [12] godot() [0x464df5] (??:0) + -- END OF C++ BACKTRACE -- + ================================================================ + GDScript backtrace (most recent call first): + [0] _ready (res://test.gd:5) + -- END OF GDSCRIPT BACKTRACE -- + ================================================================ + +This backtrace is also logged to the file for the current session, but it is **not** +visible in the editor Output panel. Since the engine's scripting system is not running +anymore when the engine is crashing, it is not possible to access it from scripting in +the same session. However, you can still read the crash backtrace on the next session +by loading log files and searching for the crash backtrace string +(``Program crashed with signal``) using :ref:`class_FileAccess`. This allows you to access +the backtrace information even after a crash, as long as the user restarts the project +and file logging is enabled: + +.. code-block:: gdscript + + # This script can be made an autoload, so that it runs when the project starts. + extends Node + + func _ready() -> void: + var log_dir: String = String(ProjectSettings.get_setting("debug/file_logging/log_path")).get_base_dir() + # Get the last log file by alphabetical order. + # Since the timestamp is featured in the file name, it should always be the most recent + # log file that was rotated. The non-timestamped log file is for the current session, + # so we don't want to read that one. + var last_log_file: String = log_dir.path_join(DirAccess.get_files_at(log_dir)[-1]) + var last_long_contents: String = FileAccess.get_file_as_string(last_log_file) + + var crash_begin_idx: int = last_long_contents.find("Program crashed with signal") + if crash_begin_idx != -1: + print("The previous session has crashed with the following backtrace:\n") + print(last_long_contents.substr(crash_begin_idx)) + +You can customize the message that appears at the top of the backtrace using the +**Debug > Settings > Crash Handler > Message** project setting. This can be used +to point to a URL or email address that users can report issues to. + +Creating custom loggers +----------------------- + +Since Godot 4.5, it is possible to create custom loggers. This custom logging can +be used for many purposes: + +- Show an in-game console with the same messages as printed by the engine, + without requiring other scripts to be modified. +- Report printed errors from the player's machine to a remote server. + This can make it easier for developers to fix bugs when the game is already released, + or during playtesting. +- Integrate a dedicated server export with monitoring platforms. + +A custom logger can be registered by creating a class that inherits from :ref:`class_logger`, +then passing an instance of this class to :ref:`OS.add_logger `, +in a script's :ref:`_init() ` method. A good place to do this +is an :ref:`autoload `. + +The class must define two methods: :ref:`_log_message() ` +and :ref:`_log_error() `. + +Here is a minimal working example of a custom logger, with the script added as an autoload: + +.. code-block:: gdscript + + extends Node + + class CustomLogger extends Logger: + # Note that this method is not called for messages that use + # `push_error()` and `push_warning()`, even though these are printed to stderr. + func _log_message(message: String, error: bool) -> void: + # Do something with `message`. + # `error` is `true` for messages printed to the standard error stream (stderr) with `print_error()`. + pass + + func _log_error( + function: String, + file: String, + line: int, + code: String, + rationale: String, + editor_notify: bool, + error_type: int, + script_backtraces: Array[ScriptBacktrace] + ) -> void: + # Do something with the error. The error text is in `rationale`. + # See the Logger class reference for details on other parameters. + pass + + # Use `_init()` to initialize the logger as early as possible, which ensures that messages + # printed early are taken into account. However, even when using `_init()`, the engine's own + # initialization messages are not accessible. + func _init() -> void: + OS.add_logger(CustomLogger.new()) + +Note that to avoid infinite recursion, you cannot effectively use +:ref:`print() ` and its related methods in +``_log_message()``. You also can't effectively use +:ref:`push_error() ` +or :ref:`push_warning() ` in +``_log_error()``. Attempting to do so will print a message to the same stream +as the original message. This message is not available in the custom logger, +which is what prevents infinite recursion from occurring: + +:: + + While attempting to print a message, another message was printed: + ... + + While attempting to print an error, another error was printed: + ... + +.. seealso:: + + You can find an example of an in-game console built with a custom logger in the + `Custom Logging demo project `__. From 841102005406da2d985737b0664c577c99817fa9 Mon Sep 17 00:00:00 2001 From: Hugo Locurcio Date: Sun, 14 Sep 2025 22:46:50 +0200 Subject: [PATCH 09/12] Fix code block highlighting in Logging Some blocks were using syntax highlighting when they shouldn't. (cherry picked from commit 3b11c2f5abbd959f62aaea939fe83f7ddf250006) --- tutorials/scripting/logging.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tutorials/scripting/logging.rst b/tutorials/scripting/logging.rst index 4bc763afe49..ee6a1ecd3e6 100644 --- a/tutorials/scripting/logging.rst +++ b/tutorials/scripting/logging.rst @@ -108,7 +108,7 @@ Crash backtraces When the project crashes, a crash backtrace is printed to the standard error stream. This is what it can look like in a build with debug symbols: -:: +.. code-block:: none ================================================================ handle_crash: Program crashed with signal 4 @@ -135,7 +135,7 @@ it can look like in a build with debug symbols: On the other hand, without debug symbols, it will look like this instead: -:: +.. code-block:: none ================================================================ handle_crash: Program crashed with signal 4 @@ -256,7 +256,7 @@ or :ref:`push_warning() ` in as the original message. This message is not available in the custom logger, which is what prevents infinite recursion from occurring: -:: +.. code-block:: none While attempting to print a message, another message was printed: ... From e2b54fffeea3604480f00eeda155c3d2e77aa93f Mon Sep 17 00:00:00 2001 From: Hugo Locurcio Date: Mon, 8 Sep 2025 16:27:17 +0200 Subject: [PATCH 10/12] Remove outdated/broken shared library section in Custom modules in C++ - Replace Mono example with GridMap in the introduction, as Mono/.NET is not enabled by default in non-C# builds. - Recommend GDExtension in the beginning, as it's more suited for most use cases that involve C++ as of September 2025. (cherry picked from commit 160aa371c6cc041fd56775358cba78e518d7ae56) --- .../architecture/custom_modules_in_cpp.rst | 125 ++---------------- 1 file changed, 11 insertions(+), 114 deletions(-) diff --git a/engine_details/architecture/custom_modules_in_cpp.rst b/engine_details/architecture/custom_modules_in_cpp.rst index 6b7b625bdd6..1bc01f9c582 100644 --- a/engine_details/architecture/custom_modules_in_cpp.rst +++ b/engine_details/architecture/custom_modules_in_cpp.rst @@ -13,7 +13,7 @@ split for use and reuse in different modules. Modules are located in the ``modules/`` subdirectory of the build system. By default, dozens of modules are enabled, such as GDScript (which, yes, -is not part of the base engine), the Mono runtime, a regular expressions +is not part of the base engine), GridMap support, a regular expressions module, and others. As many new modules as desired can be created and combined. The SCons build system will take care of it transparently. @@ -31,6 +31,16 @@ instead. Adding C++ modules can be useful in the following scenarios: - Porting an existing game to Godot. - Write a whole, new game in C++ because you can't live without C++. + +.. note:: + + While it is possible to use modules for custom game logic, + :ref:`GDExtension ` is generally more suited as it doesn't + require recompiling the engine after every code change. + + C++ modules are mainly needed when GDExtension doesn't suffice and deeper engine + integration is required. + Creating a new module --------------------- @@ -378,119 +388,6 @@ We now need to add this method to ``register_types`` header and source files: // Nothing to do here in this example. } -Improving the build system for development ------------------------------------------- - -.. warning:: - - This shared library support is not designed to support distributing a module - to other users without recompiling the engine. For that purpose, use - a GDExtension instead. - -So far, we defined a clean SCsub that allows us to add the sources -of our new module as part of the Godot binary. - -This static approach is fine when we want to build a release version of our -game, given we want all the modules in a single binary. - -However, the trade-off is that every single change requires a full recompilation of the -game. Even though SCons is able to detect and recompile only the file that was -changed, finding such files and eventually linking the final binary takes a long time. - -The solution to avoid such a cost is to build our own module as a shared -library that will be dynamically loaded when starting our game's binary. - -.. code-block:: python - :caption: godot/modules/summator/SCsub - - Import('env') - - sources = [ - "register_types.cpp", - "summator.cpp" - ] - - # First, create a custom env for the shared library. - module_env = env.Clone() - - # Position-independent code is required for a shared library. - module_env.Append(CCFLAGS=['-fPIC']) - - # Don't inject Godot's dependencies into our shared library. - module_env['LIBS'] = [] - - # Define the shared library. By default, it would be built in the module's - # folder, however it's better to output it into `bin` next to the - # Godot binary. - shared_lib = module_env.SharedLibrary(target='#bin/summator', source=sources) - - # Finally, notify the main build environment it now has our shared library - # as a new dependency. - - # LIBPATH and LIBS need to be set on the real "env" (not the clone) - # to link the specified libraries to the Godot executable. - - env.Append(LIBPATH=['#bin']) - - # SCons wants the name of the library with it custom suffixes - # (e.g. ".linuxbsd.tools.64") but without the final ".so". - shared_lib_shim = shared_lib[0].name.rsplit('.', 1)[0] - env.Append(LIBS=[shared_lib_shim]) - -Once compiled, we should end up with a ``bin`` directory containing both the -``godot*`` binary and our ``libsummator*.so``. However given the .so is not in -a standard directory (like ``/usr/lib``), we have to help our binary find it -during runtime with the ``LD_LIBRARY_PATH`` environment variable: - -.. code-block:: shell - - export LD_LIBRARY_PATH="$PWD/bin/" - ./bin/godot* - -.. note:: - You have to ``export`` the environment variable. Otherwise, - you won't be able to run your project from the editor. - -On top of that, it would be nice to be able to select whether to compile our -module as shared library (for development) or as a part of the Godot binary -(for release). To do that we can define a custom flag to be passed to SCons -using the ``ARGUMENT`` command: - -.. code-block:: python - :caption: godot/modules/summator/SCsub - - Import('env') - - sources = [ - "register_types.cpp", - "summator.cpp" - ] - - module_env = env.Clone() - module_env.Append(CCFLAGS=['-O2']) - - if ARGUMENTS.get('summator_shared', 'no') == 'yes': - # Shared lib compilation - module_env.Append(CCFLAGS=['-fPIC']) - module_env['LIBS'] = [] - shared_lib = module_env.SharedLibrary(target='#bin/summator', source=sources) - shared_lib_shim = shared_lib[0].name.rsplit('.', 1)[0] - env.Append(LIBS=[shared_lib_shim]) - env.Append(LIBPATH=['#bin']) - else: - # Static compilation - module_env.add_source_files(env.modules_sources, sources) - -Now by default ``scons`` command will build our module as part of Godot's binary -and as a shared library when passing ``summator_shared=yes``. - -Finally, you can even speed up the build further by explicitly specifying your -shared module as target in the SCons command: - -.. code-block:: shell - - scons summator_shared=yes platform=linuxbsd bin/libsummator.linuxbsd.tools.64.so - Writing custom documentation ---------------------------- From 87e3c8f416011bbe0f726578e9a85ea5c01377c4 Mon Sep 17 00:00:00 2001 From: Aaron Franke Date: Fri, 12 Sep 2025 20:27:16 -0700 Subject: [PATCH 11/12] Add note about "Naming Version" in 3D model importers (cherry picked from commit 4688ffc1a616862aa7f0ebf283bedc0e0409c047) --- .../migrating/img/gltf_naming_version.webp | Bin 0 -> 13706 bytes tutorials/migrating/upgrading_to_godot_4.5.rst | 13 +++++++++++++ 2 files changed, 13 insertions(+) create mode 100644 tutorials/migrating/img/gltf_naming_version.webp diff --git a/tutorials/migrating/img/gltf_naming_version.webp b/tutorials/migrating/img/gltf_naming_version.webp new file mode 100644 index 0000000000000000000000000000000000000000..4c4216909efa38b18ece6334f921c1ae8ba8f39d GIT binary patch literal 13706 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 literal 0 HcmV?d00001 diff --git a/tutorials/migrating/upgrading_to_godot_4.5.rst b/tutorials/migrating/upgrading_to_godot_4.5.rst index 6cbbf8351d2..871d6e6467b 100644 --- a/tutorials/migrating/upgrading_to_godot_4.5.rst +++ b/tutorials/migrating/upgrading_to_godot_4.5.rst @@ -190,6 +190,17 @@ Behavior changes In 4.5 some behavior changes have been introduced, which might require you to adjust your project. +3D Model Import +~~~~~~~~~~~~~~~ + +A fix has been made to the 3D model importers to correctly handle non-joint nodes within a skeleton hierarchy (`GH-104184`_). +To preserve compatibility, the default behavior is to import existing files with the same behavior as before (`GH-107352`_). +New ``.gltf``, ``.glb``, ``.blend``, and ``.fbx`` files (without a corresponding ``.import`` file) +will be imported with the new behavior. However, for existing files, if you want to use the +new behavior, you must change the "Naming Version" option at the bottom of the Import dock: + +.. image:: img/gltf_naming_version.webp + Core ~~~~ @@ -240,6 +251,7 @@ Text .. _GH-103869: https://github.com/godotengine/godot/pull/103869 .. _GH-103941: https://github.com/godotengine/godot/pull/103941 .. _GH-104087: https://github.com/godotengine/godot/pull/104087 +.. _GH-104184: https://github.com/godotengine/godot/pull/104184 .. _GH-104269: https://github.com/godotengine/godot/pull/104269 .. _GH-104872: https://github.com/godotengine/godot/pull/104872 .. _GH-104890: https://github.com/godotengine/godot/pull/104890 @@ -251,6 +263,7 @@ Text .. _GH-106300: https://github.com/godotengine/godot/pull/106300 .. _GH-106848: https://github.com/godotengine/godot/pull/106848 .. _GH-107347: https://github.com/godotengine/godot/pull/107347 +.. _GH-107352: https://github.com/godotengine/godot/pull/107352 .. _GH-107618: https://github.com/godotengine/godot/pull/107618 .. _GH-108041: https://github.com/godotengine/godot/pull/108041 .. _GH-108825: https://github.com/godotengine/godot/pull/108825 From 417bf9eb48ff3a1ec7f6fb0b01a0dac94c913c96 Mon Sep 17 00:00:00 2001 From: Hugo Locurcio Date: Thu, 21 Aug 2025 03:28:21 +0200 Subject: [PATCH 12/12] Add documentation on using the Engine compilation configuration editor (cherry picked from commit 697eabd14d24e8f3fd7d1b25578d63e0112f4c16) --- about/list_of_features.rst | 10 +- .../compiling/optimizing_for_size.rst | 23 ++++ ...mpilation_configuration_editor_detect.webp | Bin 0 -> 14532 bytes ...ilation_configuration_editor_detected.webp | Bin 0 -> 14244 bytes tutorials/editor/index.rst | 1 + ...ngine_compilation_configuration_editor.rst | 107 ++++++++++++++++++ 6 files changed, 140 insertions(+), 1 deletion(-) create mode 100644 tutorials/editor/img/engine_compilation_configuration_editor_detect.webp create mode 100644 tutorials/editor/img/engine_compilation_configuration_editor_detected.webp create mode 100644 tutorials/editor/using_engine_compilation_configuration_editor.rst diff --git a/about/list_of_features.rst b/about/list_of_features.rst index b3fcee1572c..f0f69792e0b 100644 --- a/about/list_of_features.rst +++ b/about/list_of_features.rst @@ -669,7 +669,7 @@ XR support (AR and VR) - Currently only exporting an application for use on a flat plane within the headset is supported. Immersive experiences are not supported. - + - Other devices supported through an XR plugin structure. - Various advanced toolkits are available that implement common features required by XR applications. @@ -776,8 +776,16 @@ Miscellaneous - Print colored text to standard output on all platforms using :ref:`print_rich `. +- The editor can + :ref:`detect features used in a project and create a compilation profile `, + which can be used to create smaller export template binaries + with unneeded features disabled. - Support for :ref:`C++ modules ` statically linked into the engine binary. + + - Most built-in modules can be disabled at compile-time to reduce binary size + in custom builds. See :ref:`doc_optimizing_for_size` for details. + - Engine and editor written in C++17. - Can be :ref:`compiled ` using GCC, diff --git a/engine_details/development/compiling/optimizing_for_size.rst b/engine_details/development/compiling/optimizing_for_size.rst index bb0ac935c77..768ebc370ef 100644 --- a/engine_details/development/compiling/optimizing_for_size.rst +++ b/engine_details/development/compiling/optimizing_for_size.rst @@ -93,6 +93,29 @@ Godot 4.5 introduced the ``size_extra`` option, which can further reduce size. scons target=template_release optimize=size_extra +Detecting used features from the current project and disabling unused features +------------------------------------------------------------------------------ + +- **Space savings:** Moderate to high depending on project +- **Difficulty:** Easy to medium depending on project +- **Performed in official builds:** No + +Godot features an :ref:`doc_engine_compilation_configuration_editor` tool that can detect +the features used in the current project and create a build profile. Once saved, +this build profile can then be passed to SCons when compiling custom export templates: + +:: + + scons target=template_release build_profile=/path/to/profile.gdbuild + +Note that for certain projects, the feature detection may be too aggressive and disable +features that are actually needed at runtime. This can occur if certain features are used +in a way that their usage cannot be detected statically (such as a script being procedurally +created and run at runtime). + +More specific features can be disabled by following the sections below, but remember +that many of them are automatically detected by the engine compilation configuration detector. + Disabling advanced text server ------------------------------ diff --git a/tutorials/editor/img/engine_compilation_configuration_editor_detect.webp b/tutorials/editor/img/engine_compilation_configuration_editor_detect.webp new file mode 100644 index 0000000000000000000000000000000000000000..6ced779da87c919efacefb525a2107e404a86bb2 GIT binary patch literal 14532 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 literal 0 HcmV?d00001 diff --git a/tutorials/editor/img/engine_compilation_configuration_editor_detected.webp b/tutorials/editor/img/engine_compilation_configuration_editor_detected.webp new file mode 100644 index 0000000000000000000000000000000000000000..72427bf16807861dbcf8d858108b8e083872f14c GIT binary patch literal 14244 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 bCZ7yeoj0c{yMYISADqsIu!hVlIWGSnYk>Bm literal 0 HcmV?d00001 diff --git a/tutorials/editor/index.rst b/tutorials/editor/index.rst index 572eb6aa80d..66b364173bc 100644 --- a/tutorials/editor/index.rst +++ b/tutorials/editor/index.rst @@ -81,6 +81,7 @@ like Visual Studio Code or Emacs. command_line_tutorial external_editor + using_engine_compilation_configuration_editor Managing editor features ------------------------ diff --git a/tutorials/editor/using_engine_compilation_configuration_editor.rst b/tutorials/editor/using_engine_compilation_configuration_editor.rst new file mode 100644 index 00000000000..aea286140e9 --- /dev/null +++ b/tutorials/editor/using_engine_compilation_configuration_editor.rst @@ -0,0 +1,107 @@ +.. _doc_engine_compilation_configuration_editor: + +Using the engine compilation configuration editor +================================================= + +Godot comes with a large set of built-in features. While this is convenient, +this also means its binary size is larger than it could be, especially +for projects that only use a small portion of its feature set. + +To help reduce binary size, it is possible to compile custom export templates +with certain features disabled. This is described in detail in :ref:`doc_optimizing_for_size`. +However, determining which features need to be disabled can be a tedious task. +The engine compilation configuration editor aims to address this +by providing an interface to view and manage these features easily, +while also being able to detect the features currently being used in the project. + +The :menu:`Project > Tools > Engine Compilation Configuration Editor` +allows you to create and manage build profiles for your Godot project. + +From now on, you have two possibilities: + +- View the list and manually uncheck features that you don't need. +- Use the :button:`Detect from Project` button to automatically detect features + currently used in the project and disable unused features. Note that this will + override the existing list of features, so if you have manually unchecked some + items, their state will be reset based on whether the project actually + uses the feature. + +.. figure:: img/engine_compilation_configuration_editor_detect.webp + :align: center + :alt: Opening the Engine Compilation Configuration Editor + + Opening the Engine Compilation Configuration Editor + +Once you click :button:`Detect from Project`, the project detection step will run. +This can take from a few seconds up to several minutes depending on the project size. +Once detection is complete, you'll see an updated list of features with some features disabled: + +.. figure:: img/engine_compilation_configuration_editor_detected.webp + :align: center + :alt: Updated features list after using feature detection (example from the 3D platformer demo) + + Updated features list after using feature detection (example from the 3D platformer demo) + +.. warning:: + + Unchecking features in this dialog will not reduce binary size directly on export. + Since it is only possible to actually remove features from the binary at compile-time, + you still need to compile custom export templates with the build profile specified + to actually benefit from the engine compilation configuration editor. + +You can now save the build profile by clicking **Save As** at the top. +The build profile can be saved in any location, but it's a good idea to +save it somewhere in your project folder and add it to version control to be able +to go back to it later when needed. This also allows using version control +to track changes to the build profile. + +The build profile is a JSON file (and ``.gdbuild`` extension) that looks like this +after detection in the above example: + +:: + + { + "disabled_build_options": { + "disable_navigation_3d": true, + "disable_xr": true, + "module_godot_physics_3d_enabled": false, + "module_msdfgen_enabled": false, + "module_openxr_enabled": false + }, + "disabled_classes": [ + "AESContext", + ... + "ZIPReader" + ], + "type": "build_profile" + } + +This file can be passed as a SCons option when :ref:`compiling ` +export templates: + +:: + + scons target=template_release build_profile=/path/to/profile.gdbuild + +The buildsystem will use this to disable unused classes and reduce binary size as a result. + +Limitations +----------- + +The :button:`Detect from Project` functionality relies on reading the project's scenes and scripts. +It will not be able to detect used features in the following scenarios: + +- Features that are used in GDScripts that are procedurally created then run at runtime. +- Features that are used in :ref:`expressions `. +- Features that are used in :ref:`GDExtensions `, unless the language binding + allows for defining used classes and the extension makes use of the functionality. + See `GH-104129 `__ for details. +- Features that are used in :ref:`external PCKs loaded at runtime `. +- Certain edge cases may exist. If unsure, please + `open an issue on GitHub `__ + with a minimal reproduction project attached. + +.. seealso:: + + You can achieve further size reductions by passing other options that reduce binary size. + See :ref:`doc_optimizing_for_size` for more information.