瀏覽代碼

Merge branch '4.5' into stable

Rémi Verschelde 13 小時之前
父節點
當前提交
63aa9360a7

文件差異過大導致無法顯示
+ 1069 - 103
_extensions/gdscript.py


+ 110 - 23
_static/css/custom.css

@@ -80,7 +80,7 @@
 
     --tabs-background-color: #e1e4e5;
     --tabs-selected-color: #a2a9ae;
-    --code-tabs-background-color: #e3ecd1;
+    --code-tabs-background-color: #e6e6e6;
     --code-tabs-selected-color: #8a9378;
 
     --classref-primary-color: #252525;
@@ -100,20 +100,30 @@
     --search-highlighted-color: rgb(255 205 0 / 25%);
     --search-context-color: #6c6e72;
 
-    --highlight-background-color: #f5ffe1;
+    --highlight-background-color: #ffffff;
     --highlight-background-emph-color: #dbe6c3;
     --highlight-default-color: #404040;
-    --highlight-comment-color: #408090;
-    --highlight-keyword-color: #007020;
-    --highlight-keyword2-color: #902000;
-    --highlight-control-flow-keyword-color: #902060;
-    --highlight-number-color: #208050;
-    --highlight-decorator-color: #4070a0;
-    --highlight-type-color: #007020;
-    --highlight-type2-color: #0e84b5;
-    --highlight-function-color: #06287e;
-    --highlight-operator-color: #666666;
-    --highlight-string-color: #4070a0;
+    --highlight-comment-color: rgba(20, 20, 20, 0.5);
+    --highlight-doc-comment-color: rgba(38, 38, 102, 0.7);
+    --highlight-region-comment-color: rgba(173, 117, 196, 20);
+    --highlight-keyword-color: #e62282;
+    --highlight-literal-color: var(--highlight-keyword-color);
+    --highlight-keyword2-color: #009933;
+    --highlight-control-flow-keyword-color: #bd1fcc;
+    --highlight-number-color: #008c47;
+    --highlight-decorator-color: #cc5e00;
+    --highlight-base-type-color: #009933;
+    --highlight-engine-type-color: #1c8c66;
+    --highlight-user-type-color: #2e7366;
+    --highlight-member-variable-color: #0066ad;
+    --highlight-function-color: #0039e6;
+    --highlight-function-declaration-color: #009999;
+    --highlight-global-function-color: #5c2eb8;
+    --highlight-operator-color: #00009c;
+    --highlight-string-color: #996b00;
+    --highlight-get-node-shorthand-color: #2e8c00;
+    --highlight-node-path-color: #008000;
+    --highlight-string-name-color: #ffc2a6;
 
     --copybtn-background-color: #f6f8fa;
     --copybtn-background-color-hover: #f3f4f6;
@@ -236,16 +246,26 @@
         --highlight-background-emph-color: #2d3444;
         --highlight-default-color: rgba(255, 255, 255, 0.85);
         --highlight-comment-color: rgba(204, 206, 211, 0.5);
+        --highlight-doc-comment-color: rgba(153, 179, 204, 0.8);
+        --highlight-region-comment-color: rgba(173, 117, 196, 20);
         --highlight-keyword-color: #ff7085;
+        --highlight-literal-color: var(--highlight-keyword-color);
         --highlight-keyword2-color: #42ffc2;
         --highlight-control-flow-keyword-color: #ff8ccc;
         --highlight-number-color: #a1ffe0;
         --highlight-decorator-color: #ffb373;
-        --highlight-type-color: #8effda;
-        --highlight-type2-color: #c6ffed;
+        --highlight-base-type-color: #42ffc2;
+        --highlight-engine-type-color: #8fffdb;
+        --highlight-user-type-color: #c7ffed;
+        --highlight-member-variable-color: #bce0ff;
         --highlight-function-color: #57b3ff;
+        --highlight-function-declaration-color: #66e6ff;
+        --highlight-global-function-color: #a3a3f5;
         --highlight-operator-color: #abc8ff;
         --highlight-string-color: #ffeca1;
+        --highlight-get-node-shorthand-color: #63c259;
+        --highlight-node-path-color: #b8c47d;
+        --highlight-string-name-color: #ffc2a6;
 
         --copybtn-background-color: #2a303c;
         --copybtn-background-color-hover: #3e4450;
@@ -281,7 +301,7 @@
         --kbd-outline-color: #3d4144;
         --kbd-shadow-color: #1e2023;
         --kbd-text-color: #e2f2ff;
-        
+
         --role-button-background-color: #22252d;
 
         --code-example-good-color: #3fb950;
@@ -544,7 +564,7 @@ html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(
     padding: 6px 8px;
 }
 html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) .sig-prename.descclassname {
-    color: var(--highlight-type2-color);
+    color: var(--highlight-engine-type-color);
     font-weight: normal;
 }
 html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) .sig-name.descname {
@@ -917,14 +937,36 @@ code,
 
 /* Syntax highlighting */
 
+.highlight {
+    background-color: var(--highlight-background-color);
+    tab-size: 4;
+}
+
 /* Remove default red boxes around Pygments errors */
 .highlight .err {
     border: none;
 }
 
-.highlight {
-    background-color: var(--highlight-background-color);
-    tab-size: 4;
+/* Default Pygments styles make all of these bold */
+.highlight .k /* Keyword */,
+.highlight .ges /* Generic.EmphStrong */,
+.highlight .gh /* Generic.Heading */,
+.highlight .gp /* Generic.Prompt */,
+.highlight .gs /* Generic.Strong */,
+.highlight .gu /* Generic.Subheading */,
+.highlight .kc /* Keyword.Constant */,
+.highlight .kd /* Keyword.Declaration */,
+.highlight .kn /* Keyword.Namespace */,
+.highlight .kr /* Keyword.Reserved */,
+.highlight .nc /* Name.Class */,
+.highlight .nd /* Name.Decorator */,
+.highlight .ni /* Name.Entity */,
+.highlight .nl /* Name.Label */,
+.highlight .nn /* Name.Namespace */,
+.highlight .nt /* Name.Tag */,
+.highlight .ow /* Operator.Word */,
+.highlight .se /* Literal.String.Escape */ {
+    font-weight: revert;
 }
 
 /* Emphasized lines */
@@ -932,6 +974,10 @@ code,
     background-color: var(--highlight-background-emph-color);
 }
 
+.highlight .n /* Name */ {
+    color: var(--body-color);
+}
+
 .highlight .gh /* Generic.Heading */,
 .highlight .gu /* Generic.Subheading */,
 .highlight .go /* Generic.Output */,
@@ -967,6 +1013,10 @@ code,
     color: var(--highlight-keyword2-color);
 }
 
+.highlight .l  /* Literal */ {
+    color: var(--highlight-literal-color)
+}
+
 .highlight .m  /* Literal.Number */,
 .highlight .mf /* Literal.Number.Float */,
 .highlight .mi /* Literal.Number.Integer */,
@@ -986,7 +1036,7 @@ code,
 
 .highlight .nb /* Name.Builtin */,
 .highlight .ne /* Name.Exception */ {
-    color: var(--highlight-type-color);
+    color: var(--highlight-engine-type-color);
 }
 
 .highlight .nc /* Name.Class */,
@@ -995,9 +1045,12 @@ code,
 .highlight .nv /* Name.Variable */,
 .highlight .vc /* Name.Variable.Class */,
 .highlight .vg /* Name.Variable.Global */,
-.highlight .vi /* Name.Variable.Instance */,
 .highlight .vm /* Name.Variable.Magic */ {
-    color: var(--highlight-type2-color);
+    color: var(--highlight-user-type-color);
+}
+
+.highlight .vi /* Name.Variable.Instance */ {
+    color: var(--highlight-member-variable-color);
 }
 
 .highlight .nf /* Name.Function */,
@@ -1007,6 +1060,7 @@ code,
 }
 
 .highlight .o  /* Operator */,
+.highlight .p  /* Punctuation */,
 .highlight .si /* Literal.String.Interpol */,
 .highlight .sx /* Literal.String.Other */,
 .highlight .sr /* Literal.String.Regex */,
@@ -1028,6 +1082,39 @@ code,
     color: var(--highlight-string-color);
 }
 
+.highlight .nf.nf-Declaration /* Name.Function.Declaration */ {
+	color: var(--highlight-function-declaration-color);
+}
+
+.highlight .nb.nb-Type /* Name.Builtin.Type */ {
+	color: var(--highlight-base-type-color);
+}
+
+.highlight .c.c-Doc /* Comment.Doc */ {
+	color: var(--highlight-doc-comment-color);
+}
+
+.highlight .c.c-Region /* Comment.Region */ {
+	color: var(--highlight-region-comment-color);
+}
+
+.highlight .nb.nb-Function /* Name.Builtin.Function */ {
+	color: var(--highlight-global-function-color);
+}
+
+.highlight .sx /* String.Other */ {
+	color: var(--highlight-get-node-shorthand-color);
+}
+
+.highlight .s.s-NodePath /* String.NodePath */ {
+	color: var(--highlight-node-path-color);
+}
+
+.highlight .s.s-StringName /* String.StringName */ {
+	color: var(--highlight-string-name-color);
+}
+
+
 /* Call to action for missing documentation */
 .rst-content .contribute {
     background-color: var(--contribute-background-color);

+ 9 - 1
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 <class_@GlobalScope_method_print_rich>`.
 
+- The editor can
+  :ref:`detect features used in a project and create a compilation profile <doc_engine_compilation_configuration_editor>`,
+  which can be used to create smaller export template binaries
+  with unneeded features disabled.
 - Support for :ref:`C++ modules <doc_custom_modules_in_cpp>` 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 <doc_introduction_to_the_buildsystem>` using GCC,

+ 11 - 114
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 <doc_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
 ----------------------------
 

+ 8 - 0
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
 --------------------------------------------------------
 

+ 23 - 0
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
 ------------------------------
 

二進制
tutorials/editor/img/engine_compilation_configuration_editor_detect.webp


二進制
tutorials/editor/img/engine_compilation_configuration_editor_detected.webp


+ 1 - 0
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
 ------------------------

+ 107 - 0
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 <doc_compiling_index>`
+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 <doc_evaluating_expressions>`.
+- Features that are used in :ref:`GDExtensions <doc_gdextension>`, unless the language binding
+  allows for defining used classes and the extension makes use of the functionality.
+  See `GH-104129 <https://github.com/godotengine/godot/pull/104129>`__ for details.
+- Features that are used in :ref:`external PCKs loaded at runtime <doc_exporting_pcks>`.
+- Certain edge cases may exist. If unsure, please
+  `open an issue on GitHub <https://github.com/godotengine/godot/issues>`__
+  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.

+ 2 - 37
tutorials/io/data_paths.rst

@@ -114,44 +114,9 @@ through the :ref:`JavaScriptBridge <class_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 <doc_introduction_to_the_buildsystem_debugging_symbols>`.
-for guidance on compiling binaries with debugging symbols enabled.
+.. seealso::
 
-.. note::
-
-    Log files for :ref:`print<class_@GlobalScope_method_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<class_@GlobalScope_method_printerr>`,
-    :ref:`push_error<class_@GlobalScope_method_push_error>` and
-    :ref:`push_warning<class_@GlobalScope_method_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
 ---------------------------------------------------

二進制
tutorials/migrating/img/gltf_naming_version.webp


+ 13 - 0
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

+ 2 - 0
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
 ---------------
 

+ 34 - 6
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() <class_@GlobalScope_method_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() <class_@GlobalScope_method_printt>` and :ref:`prints() <class_@GlobalScope_method_prints>`.
 - :ref:`print_rich() <class_@GlobalScope_method_print_rich>`: Same as ``print()``,
   but BBCode can be used to format the text that is printed (see below).
 - :ref:`push_error() <class_@GlobalScope_method_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() <class_@GlobalScope_method_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() <class_@GlobalScope_method_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() <class_@GlobalScope_method_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() <class_@GDScript_method_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() <class_Node_method_print_tree>`: Prints the scene tree
+  relative to the current node. Useful for debugging node structures created at runtime.
+- :ref:`print_tree_pretty() <class_Node_method_print_tree_pretty>`: Same as
+  ``print_tree()``, but with Unicode characters for a more tree-like appearance. This relies on
+  `box-drawing characters <https://en.wikipedia.org/wiki/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 <doc_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.

+ 1 - 0
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

+ 270 - 0
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 <class_Engine_property_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 <class_Engine_property_print_error_messages>`.
+- **Debug > Settings > stdout > Verbose stdout:** Enables verbose logging to standard output.
+  Prints from :ref:`print_verbose() <class_@GlobalScope_method_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 <doc_command_line_tutorial>` 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 <doc_introduction_to_the_buildsystem_debugging_symbols>`
+for guidance on compiling binaries with debugging symbols enabled.
+
+.. note::
+
+    Log files for :ref:`print() <class_@GlobalScope_method_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() <class_@GlobalScope_method_printerr>`,
+    :ref:`push_error() <class_@GlobalScope_method_push_error>`, and
+    :ref:`push_warning() <class_@GlobalScope_method_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 <doc_introduction_to_the_buildsystem_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:
+
+.. code-block:: none
+
+    ================================================================
+    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:
+
+.. code-block:: none
+
+    ================================================================
+    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 <class_OS_method_add_logger>`,
+in a script's :ref:`_init() <class_Object_private_method__init>` method. A good place to do this
+is an :ref:`autoload <doc_singletons_autoload>`.
+
+The class must define two methods: :ref:`_log_message() <class_Logger_private_method__log_message>`
+and :ref:`_log_error() <class_Logger_private_method__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() <class_@GlobalScope_method_print>` and its related methods in
+``_log_message()``. You also can't effectively use
+:ref:`push_error() <class_@GlobalScope_method_push_error>`
+or :ref:`push_warning() <class_@GlobalScope_method_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:
+
+.. code-block:: none
+
+    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 <https://github.com/godotengine/godot-demo-projects/tree/master/misc/custom_logging>`__.

部分文件因文件數量過多而無法顯示