Parcourir la source

Merge branch 'master' into 4.0

Max Hilbrunner il y a 2 ans
Parent
commit
ae7ded2191
100 fichiers modifiés avec 1651 ajouts et 704 suppressions
  1. 5 0
      .github/workflows/ci.yml
  2. 1 1
      about/list_of_features.rst
  3. 16 0
      about/troubleshooting.rst
  4. 5 0
      community/asset_library/submitting_to_assetlib.rst
  5. BIN
      contributing/development/core_and_modules/img/rendering_architecture_diagram.webp
  6. 1 0
      contributing/development/core_and_modules/index.rst
  7. 791 0
      contributing/development/core_and_modules/internal_rendering_architecture.rst
  8. 2 0
      getting_started/first_2d_game/01.project_setup.rst
  9. 1 1
      getting_started/first_2d_game/03.coding_the_player.rst
  10. 4 4
      getting_started/first_2d_game/04.creating_the_enemy.rst
  11. 12 10
      getting_started/first_2d_game/05.the_main_game_scene.rst
  12. 1 1
      getting_started/first_2d_game/06.heads_up_display.rst
  13. 14 4
      getting_started/first_2d_game/07.finishing-up.rst
  14. 1 1
      getting_started/first_3d_game/01.game_setup.rst
  15. 1 1
      getting_started/first_3d_game/02.player_input.rst
  16. 2 2
      getting_started/first_3d_game/03.player_movement_code.rst
  17. 2 2
      getting_started/first_3d_game/04.mob_scene.rst
  18. 5 5
      getting_started/first_3d_game/05.spawning_mobs.rst
  19. 24 24
      getting_started/first_3d_game/06.jump_and_squash.rst
  20. 3 3
      getting_started/first_3d_game/07.killing_player.rst
  21. 12 18
      getting_started/first_3d_game/08.score_and_replay.rst
  22. 5 5
      getting_started/first_3d_game/09.adding_animations.rst
  23. 2 1
      getting_started/introduction/key_concepts_overview.rst
  24. 6 6
      getting_started/step_by_step/instancing.rst
  25. 1 1
      getting_started/step_by_step/nodes_and_scenes.rst
  26. 13 13
      getting_started/step_by_step/scripting_first_script.rst
  27. 7 7
      getting_started/step_by_step/scripting_player_input.rst
  28. 5 5
      getting_started/step_by_step/signals.rst
  29. 2 2
      tutorials/2d/2d_movement.rst
  30. 1 1
      tutorials/2d/2d_transforms.rst
  31. 9 0
      tutorials/3d/csg_tools.rst
  32. 36 0
      tutorials/3d/global_illumination/using_lightmap_gi.rst
  33. BIN
      tutorials/3d/img/export_as_gltf.webp
  34. BIN
      tutorials/3d/img/volumetric_fog_quad_mesh_texture.webp
  35. 4 0
      tutorials/3d/introduction_to_3d.rst
  36. 1 1
      tutorials/3d/lights_and_shadows.rst
  37. 24 2
      tutorials/3d/standard_material_3d.rst
  38. 1 1
      tutorials/3d/using_gridmaps.rst
  39. 43 0
      tutorials/3d/volumetric_fog.rst
  40. 2 2
      tutorials/animation/animation_tree.rst
  41. 2 0
      tutorials/assets_pipeline/importing_images.rst
  42. 6 6
      tutorials/audio/recording_with_microphone.rst
  43. 9 10
      tutorials/best_practices/godot_interfaces.rst
  44. 11 11
      tutorials/best_practices/godot_notifications.rst
  45. 4 4
      tutorials/best_practices/scene_organization.rst
  46. 5 5
      tutorials/best_practices/scenes_versus_scripts.rst
  47. 2 2
      tutorials/best_practices/what_are_godot_classes.rst
  48. 4 4
      tutorials/editor/command_line_tutorial.rst
  49. 1 1
      tutorials/editor/project_settings.rst
  50. 27 4
      tutorials/export/exporting_for_android.rst
  51. 19 0
      tutorials/export/exporting_for_ios.rst
  52. 15 0
      tutorials/export/exporting_for_linux.rst
  53. 31 0
      tutorials/export/exporting_for_macos.rst
  54. 19 0
      tutorials/export/exporting_for_uwp.rst
  55. 15 0
      tutorials/export/exporting_for_web.rst
  56. 21 0
      tutorials/export/exporting_for_windows.rst
  57. 19 1
      tutorials/export/exporting_projects.rst
  58. 1 1
      tutorials/inputs/controllers_gamepads_joysticks.rst
  59. BIN
      tutorials/inputs/img/inputs_inputmap.png
  60. BIN
      tutorials/inputs/img/inputs_inputmap.webp
  61. 19 11
      tutorials/inputs/input_examples.rst
  62. 41 281
      tutorials/io/background_loading.rst
  63. 5 5
      tutorials/math/matrices_and_transforms.rst
  64. 1 1
      tutorials/migrating/upgrading_to_godot_4.rst
  65. 1 1
      tutorials/navigation/navigation_introduction_3d.rst
  66. 1 2
      tutorials/performance/cpu_optimization.rst
  67. 24 18
      tutorials/physics/kinematic_character_2d.rst
  68. 19 14
      tutorials/physics/physics_introduction.rst
  69. 3 4
      tutorials/physics/using_area_2d.rst
  70. 19 22
      tutorials/physics/using_character_body_2d.rst
  71. 12 12
      tutorials/platform/android/android_in_app_purchases.rst
  72. 7 7
      tutorials/plugins/editor/3d_gizmos.rst
  73. BIN
      tutorials/plugins/editor/img/installing_plugins_assetlib_tab.png
  74. BIN
      tutorials/plugins/editor/img/installing_plugins_assetlib_tab.webp
  75. BIN
      tutorials/plugins/editor/img/installing_plugins_project_settings.png
  76. BIN
      tutorials/plugins/editor/img/installing_plugins_project_settings.webp
  77. BIN
      tutorials/plugins/editor/img/making_plugins-create_plugin_dialog.png
  78. BIN
      tutorials/plugins/editor/img/making_plugins-create_plugin_dialog.webp
  79. BIN
      tutorials/plugins/editor/img/making_plugins-custom_dock.png
  80. BIN
      tutorials/plugins/editor/img/making_plugins-custom_dock.webp
  81. BIN
      tutorials/plugins/editor/img/making_plugins-custom_node_console.png
  82. BIN
      tutorials/plugins/editor/img/making_plugins-custom_node_console.webp
  83. BIN
      tutorials/plugins/editor/img/making_plugins-custom_node_create.png
  84. BIN
      tutorials/plugins/editor/img/making_plugins-custom_node_create.webp
  85. BIN
      tutorials/plugins/editor/img/making_plugins-my_custom_dock_scene.png
  86. BIN
      tutorials/plugins/editor/img/making_plugins-my_custom_dock_scene.webp
  87. BIN
      tutorials/plugins/editor/img/making_plugins-my_custom_mode_folder.png
  88. BIN
      tutorials/plugins/editor/img/making_plugins-my_custom_mode_folder.webp
  89. BIN
      tutorials/plugins/editor/img/making_plugins-project_settings.png
  90. BIN
      tutorials/plugins/editor/img/making_plugins-project_settings.webp
  91. 13 15
      tutorials/plugins/editor/import_plugins.rst
  92. 7 7
      tutorials/plugins/editor/inspector_plugins.rst
  93. 4 5
      tutorials/plugins/editor/installing_plugins.rst
  94. 2 2
      tutorials/plugins/editor/making_main_screen_plugins.rst
  95. 13 13
      tutorials/plugins/editor/making_plugins.rst
  96. 1 1
      tutorials/plugins/editor/visual_shader_plugins.rst
  97. 2 0
      tutorials/rendering/viewports.rst
  98. 17 4
      tutorials/scripting/gdextension/gdextension_cpp_example.rst
  99. 158 100
      tutorials/scripting/gdscript/gdscript_basics.rst
  100. 6 6
      tutorials/scripting/gdscript/static_typing.rst

+ 5 - 0
.github/workflows/ci.yml

@@ -1,8 +1,13 @@
 name: Continuous integration
+
 on:
   push:
   pull_request:
 
+concurrency:
+  group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
+  cancel-in-progress: true
+
 jobs:
   build:
     runs-on: ubuntu-20.04

+ 1 - 1
about/list_of_features.rst

@@ -185,7 +185,7 @@ Rendering
 - Parallax/relief mapping with automatic level of detail based on distance.
 - Detail mapping for the albedo and normal maps.
 - Sub-surface scattering and transmittance.
-- Refraction with support for material roughness (resulting in blurry refraction).
+- Screen-space refraction with support for material roughness (resulting in blurry refraction).
 - Proximity fade (soft particles) and distance fade.
 - Distance fade can use alpha blending or dithering to avoid going through
   the transparent pipeline.

+ 16 - 0
about/troubleshooting.rst

@@ -143,6 +143,22 @@ If you still wish to force sharpening or FXAA on other applications, it's
 recommended to do so on a per-application basis using the application profiles
 system provided by graphics drivers' control panels.
 
+The editor/project freezes or displays glitched visuals after resuming the PC from suspend
+------------------------------------------------------------------------------------------
+
+This is a known issue on Linux with NVIDIA graphics when using the proprietary
+driver. There is no definitive fix yet, as suspend on Linux + NVIDIA is often
+buggy when OpenGL or Vulkan is involved. The Compatibility rendering method
+(which uses OpenGL) is generally less prone to suspend-related issues compared
+to the Forward+ and Forward Mobile rendering methods (which use Vulkan).
+
+The NVIDIA driver offers an *experimental*
+`option to preserve video memory after suspend <https://wiki.archlinux.org/title/NVIDIA/Tips_and_tricks#Preserve_video_memory_after_suspend>`__
+which may resolve this issue. This option has been reported to work better with
+more recent NVIDIA driver versions.
+
+To avoid losing work, save scenes in the editor before putting the PC to sleep.
+
 The project works when run from the editor, but fails to load some files when running from an exported copy
 -----------------------------------------------------------------------------------------------------------
 

+ 5 - 0
community/asset_library/submitting_to_assetlib.rst

@@ -59,6 +59,11 @@ These things are not required for your asset to be approved, but
 if you follow these recommendations, you can help make the asset
 library a better place for all users.
 
+* When creating non-project assets, it is common practice to place your files
+  inside of an **addons/asset_name/** folder. Do this to avoid having your files 
+  clash with other assets, or with the files of users installing your asset. 
+  This folder will **not** be automatically generated when a user installs your asset.
+
 * Fix or suppress all script **warnings**. The warning system is there to
   help identify issues with your code, but people using your asset
   don't need to see them.

BIN
contributing/development/core_and_modules/img/rendering_architecture_diagram.webp


+ 1 - 0
contributing/development/core_and_modules/index.rst

@@ -19,6 +19,7 @@ This section covers the basics that you will encounter in (almost) every source
    variant_class
    object_class
    inheritance_class_tree
+   internal_rendering_architecture
 
 Extending Godot by modifying its source code
 --------------------------------------------

+ 791 - 0
contributing/development/core_and_modules/internal_rendering_architecture.rst

@@ -0,0 +1,791 @@
+.. _doc_internal_rendering_architecture:
+
+Internal rendering architecture
+===============================
+
+This page is a high-level overview of Godot 4's internal renderer design.
+It does not apply to previous Godot versions.
+
+The goal of this page is to document design decisions taken to best suit
+:ref:`Godot's design philosophy <doc_best_practices_for_engine_contributors>`,
+while providing a starting point for new rendering contributors.
+
+If you have questions about rendering internals not answered here, feel free to
+ask in the ``#rendering`` channel of the
+`Godot Contributors Chat <https://chat.godotengine.org/channel/rendering>`__.
+
+.. note::
+
+    If you have difficulty understanding concepts on this page, it is
+    recommended to go through an OpenGL tutorial such as
+    `LearnOpenGL <https://learnopengl.com/>`__.
+
+    Modern low-level APIs (Vulkan/Direct3D 12) require intermediate
+    knowledge of higher-level APIs (OpenGL/Direct3D 11) to be used
+    effectively. Thankfully, contributors rarely need to work directly with
+    low-level APIs. Godot's renderers are built entirely on OpenGL and
+    RenderingDevice, which is our abstraction over Vulkan/Direct3D 12.
+
+.. _doc_internal_rendering_architecture_methods:
+
+Rendering methods
+-----------------
+
+Forward+
+^^^^^^^^
+
+This is a forward renderer that uses a *clustered* approach to lighting.
+
+Clustered lighting uses a compute shader to group lights into a 3D frustum
+aligned grid. Then, at render time, pixels can lookup what lights affect the
+grid cell they are in and only run light calculations for lights that might
+affect that pixel.
+
+This approach can greatly speed up rendering performance on desktop hardware,
+but is substantially less efficient on mobile.
+
+Forward Mobile
+^^^^^^^^^^^^^^
+
+This is a forward renderer that uses a traditional single-pass approach to lighting.
+
+Intended for mobile platforms, but can also run on desktop platforms. This
+rendering method is optimized to perform well on mobile GPUs. Mobile GPUs have a
+very different architecture compared to desktop GPUs due to their unique
+constraints around battery usage, heat, and overall bandwidth limitations of
+reading and writing data. Compute shaders also have very limited support or
+aren't supported at all. As a result, the mobile renderer purely uses
+raster-based shaders (fragment/vertex).
+
+Unlike desktop GPUs, mobile GPUs perform *tile-based rendering*. Instead of
+rendering the whole image as a single unit, the image is divided in smaller
+tiles that fit within the faster internal memory of the mobile GPU. Each tile is
+rendered and then written out to the destination texture. This all happens
+automatically on the graphics driver.
+
+The problem is that this introduces bottlenecks in our traditional approach. For
+desktop rendering, we render all opaque geometry, then handle the background,
+then transparent geometry, then post-processing. Each pass will need to read the
+current result into tile memory, perform its operations and then write it out
+again. We then wait for all tiles to be completed before moving on to the next
+pass.
+
+The first important change in the mobile renderer is that the mobile renderer
+does not use the RGBA16F texture formats that the desktop renderer does.
+Instead, it is using a R10G10B10A2 UNORM texture format. This halves the bandwidth
+required and has further improvements as mobile hardware often further optimizes
+for 32-bit formats. The tradeoff is that the mobile renderer has limited HDR
+capabilities due to the reduced precision and maximum values in the color data.
+
+The second important change is the use of sub-passes whenever possible.
+Sub-passes allows us to perform the rendering steps end-to-end per tile saving
+on the overhead introduced by reading from and writing to the tiles between each
+rendering pass. The ability to use sub-passes is limited by the inability to
+read neighboring pixels, as we're constrained to working within a single tile.
+
+This limitation of subpasses results in not being able to implement features
+such as glow and depth of field efficiently. Similarly, if there is a
+requirement to read from the screen texture or depth texture, we must fully
+write out the rendering result limiting our ability to use sub-passes. When such
+features are enabled, a mix of sub-passes and normal passes are used, and these
+features result in a notable performance penalty.
+
+On desktop platforms, the use of sub-passes won't have any impact on
+performance. However, this rendering method can still perform better than
+Clustered Forward in simple scenes thanks to its lower complexity and lower
+bandwidth usage. This is especially noticeable on low-end GPUs, integrated
+graphics or in VR applications.
+
+Given its low-end focus, this rendering method does not provide high-end
+rendering features such as SDFGI and :ref:`doc_volumetric_fog`. Several
+post-processing effects are also not available.
+
+.. _doc_internal_rendering_architecture_compatibility:
+
+Compatibility
+^^^^^^^^^^^^^
+
+.. note::
+
+    This is the only rendering method available when using the OpenGL driver.
+    This rendering method is not available when using Vulkan or Direct3D 12.
+
+This is a traditional (non-clustered) forward renderer. It's intended for old
+GPUs that don't have Vulkan support, but still works very efficiently on newer
+hardware. Specifically, it is optimized for older and lower-end mobile devices
+However, many optimizations carry over making it a good choice for older and
+lower-end desktop as well.
+
+Like the Mobile renderer, the Compatibility renderer uses an R10G10B10A2 UNORM
+texture for 3D rendering. Unlike the mobile renderer, colors are tonemapped and
+stored in sRGB format so there is no HDR support. This avoids the need for a
+tonemapping pass and allows us to use the lower bit texture without substantial
+banding.
+
+The Compatibility renderer uses a traditional forward single-pass approach to
+drawing objects with lights, but it uses a multi-pass approach to draw lights
+with shadows. Specifically, in the first pass, it can draw multiple lights
+without shadows and up to one DirectionalLight3D with shadows. In each
+subsequent pass, it can draw up to one OmniLight3D, one SpotLight3D and one
+DirectionalLight3D with shadows. Lights with shadows will affect the scene
+differently than lights without shadows, as the lighting is blended in sRGB space
+instead of linear space. This difference in lighting will impact how the scene
+looks and needs to be kept in mind when designing scenes for the Compatibility
+renderer.
+
+Given its low-end focus, this rendering method does not provide high-end
+rendering features (even less so compared to Forward Mobile). Most
+post-processing effects are not available.
+
+Why not deferred rendering?
+^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Forward rendering generally provides a better tradeoff for performance versus
+flexibility, especially when a clustered approach to lighting is used. While
+deferred rendering can be faster in some cases, it's also less flexible and
+requires using hacks to be able to use MSAA. Since games with a less realistic
+art style can benefit a lot from MSAA, we chose to go with forward rendering for
+Godot 4 (like Godot 3).
+
+That said, parts of the forward renderer *are* performed with a deferred approach
+to allow for some optimizations when possible. This applies to VoxelGI and SDFGI
+in particular.
+
+A clustered deferred renderer may be developed in the future. This renderer
+could be used in situations where performance is favored over flexibility.
+
+Rendering drivers
+-----------------
+
+Godot 4 supports the following graphics APIs:
+
+Vulkan
+^^^^^^
+
+This is the main driver in Godot 4, with most of the development focus going
+towards this driver.
+
+Vulkan 1.0 is required as a baseline, with optional Vulkan 1.1 and 1.2 features
+used when available. `volk <https://github.com/zeux/volk>`__ is used as a Vulkan
+loader, and
+`Vulkan Memory Allocator <https://github.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator>`__
+is used for memory management.
+
+Both the Forward+ and Mobile
+:ref:`doc_internal_rendering_architecture_methods` are supported when using the
+Vulkan driver.
+
+**Vulkan context creation:**
+
+- `drivers/vulkan/vulkan_context.cpp <https://github.com/godotengine/godot/blob/4.0/drivers/vulkan/vulkan_context.cpp>`__
+
+Direct3D 12
+^^^^^^^^^^^
+
+Like Vulkan, the Direct3D 12 driver targets modern platforms only. It is
+designed to target both Windows and Xbox (whereas Vulkan can't be used directly on Xbox).
+
+Both the Forward+ and Mobile :ref:`doc_internal_rendering_architecture_methods` can be
+used with Direct3D 12.
+
+:ref:`doc_internal_rendering_architecture_core_shaders` are shared with the
+Vulkan renderer. Shaders are transpiled from GLSL to HLSL using
+Mesa NIR (`more information <https://godotengine.org/article/d3d12-adventures-in-shaderland/>`__).
+This means you don't need to know HLSL to work on the Direct3D 12 renderer,
+although knowing the language's basics is recommended to ease debugging.
+
+**As of May 2023, this driver is still in development and is not merged in
+Godot 4.0 or the master branch.** While Direct3D 12 allows supporting
+Direct3D-exclusive features on Windows 11 such as windowed optimizations and
+Auto HDR, Vulkan is still recommended for most projects. See the
+`pull request that introduced Direct3D 12 support <https://github.com/godotengine/godot/pull/70315>`__
+for more information.
+
+Metal
+^^^^^
+
+Godot supports Metal rendering via `MoltenVK <https://github.com/KhronosGroup/MoltenVK>`__,
+as macOS and iOS do not support Vulkan natively.
+This is done automatically when specifying the Vulkan driver in the Project Settings.
+
+MoltenVK makes driver maintenance easy at the cost of some performance overhead.
+Also, MoltenVK has several limitations that a native Metal driver implementation
+wouldn't have. Both the clustered and mobile
+:ref:`doc_internal_rendering_architecture_methods` can be used with a Metal
+backend via MoltenVK.
+
+A native Metal driver is planned in the future for better performance and
+compatibility.
+
+OpenGL
+^^^^^^
+
+This driver uses OpenGL ES 3.0 and targets legacy and low-end devices that don't
+support Vulkan. OpenGL 3.3 Core Profile is used on desktop platforms to run this
+driver, as most graphics drivers on desktop don't support OpenGL ES.
+WebGL 2.0 is used for web exports.
+
+Only the :ref:`doc_internal_rendering_architecture_compatibility` rendering
+method can be used with the OpenGL driver.
+
+:ref:`doc_internal_rendering_architecture_core_shaders` are entirely different
+from the Vulkan renderer.
+
+**As of May 2023, this driver is still in development.** Many features
+are still not implemented, especially in 3D.
+
+Summary of rendering drivers/methods
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The following rendering API + rendering method combinations are currently possible:
+
+- Vulkan + Forward+
+- Vulkan + Forward Mobile
+- Direct3D 12 + Forward+
+- Direct3D 12 + Forward Mobile
+- Metal + Forward+ (via MoltenVK)
+- Metal + Forward Mobile (via MoltenVK)
+- OpenGL + Compatibility
+
+Each combination has its own limitations and performance characteristics. Make
+sure to test your changes on all rendering methods if possible before opening a
+pull request.
+
+RenderingDevice abstraction
+---------------------------
+
+.. note::
+
+    The OpenGL driver does not use the RenderingDevice abstraction.
+
+To make the complexity of modern low-level graphics APIs more manageable,
+Godot uses its own abstraction called RenderingDevice.
+
+This means that when writing code for modern rendering methods, you don't
+actually use the Vulkan or Direct3D 12 APIs directly. While this is still
+lower-level than an API like OpenGL, this makes working on the renderer easier,
+as RenderingDevice will abstract many API-specific quirks for you. The
+RenderingDevice presents a similar level of abstraction as Metal or WebGPU.
+
+**Vulkan RenderingDevice implementation:**
+
+- `drivers/vulkan/rendering_device_vulkan.cpp <https://github.com/godotengine/godot/blob/4.0/drivers/vulkan/rendering_device_vulkan.cpp>`__
+
+Core rendering classes architecture
+-----------------------------------
+
+This diagram represents the structure of rendering classes in Godot, including the RenderingDevice abstraction:
+
+.. image:: img/rendering_architecture_diagram.webp
+
+`View at full size <https://raw.githubusercontent.com/godotengine/godot-docs/4.0/contributing/development/core_and_modules/img/rendering_architecture_diagram.webp>`__
+
+.. _doc_internal_rendering_architecture_core_shaders:
+
+Core shaders
+------------
+
+While shaders in Godot projects are written using a
+:ref:`custom language inspired by GLSL <doc_shading_language>`, core shaders are
+written directly in GLSL.
+
+These core shaders are embedded in the editor and export template binaries at
+compile-time. To see any changes you've made to those GLSL shaders, you need to
+recompile the editor or export template binary.
+
+Some material features such as height mapping, refraction and proximity fade are
+not part of core shaders, and are performed in the default BaseMaterial3D using
+the Godot shader language instead (not GLSL). This is done by procedurally
+generating the required shader code depending on the features enabled in the
+material.
+
+By convention, shader files with ``_inc`` in their name are included in other
+GLSL files for better code reuse. Standard GLSL preprocessing is used to achieve
+this.
+
+.. warning::
+
+    Core material shaders will be used by every material in the scene – both
+    with the default BaseMaterial3D and custom shaders. As a result, these
+    shaders must be kept as simple as possible to avoid performance issues and
+    ensure shader compilation doesn't become too slow.
+
+    If you use ``if`` branching in a shader, performance may decrease as
+    :abbr`VGPR (Vector General-Purpose Register)` usage will increase in the
+    shader. This happens even if all pixels evaluate to ``true`` or ``false`` in
+    a given frame.
+
+    If you use ``#if`` preprocessor branching, the number of required shader
+    versions will increase in the scene. In a worst-case scenario, adding a
+    single boolean ``#define`` can *double* the number of shader versions that
+    may need to be compiled in a given scene. In some cases, Vulkan
+    specialization constants can be used as a faster (but more limited)
+    alternative.
+
+    This means there is a high barrier to adding new built-in material features
+    in Godot, both in the core shaders and BaseMaterial3D. While BaseMaterial3D
+    can make use of dynamic code generation to only include the shader code if
+    the feature is enabled, it'll still require generating more shader versions
+    when these features are used in a project. This can make shader compilation
+    stutter more noticeable in complex 3D scenes.
+
+    See
+    `The Shader Permutation Problem <https://therealmjp.github.io/posts/shader-permutations-part1/>`__
+    and
+    `Branching on a GPU <https://medium.com/@jasonbooth_86226/branching-on-a-gpu-18bfc83694f2>`__
+    blog posts for more information.
+
+**Core GLSL material shaders:**
+
+- Forward+: `servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl <https://github.com/godotengine/godot/blob/4.0/servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl>`__
+- Forward Mobile: `servers/rendering/renderer_rd/shaders/scene_forward_mobile.glsl <https://github.com/godotengine/godot/blob/4.0/servers/rendering/renderer_rd/shaders/scene_forward_mobile.glsl>`__
+- Compatibility: `drivers/gles3/shaders/scene.glsl <https://github.com/godotengine/godot/blob/4.0/drivers/gles3/shaders/scene.glsl>`__
+
+**Material shader generation:**
+
+- `scene/resources/material.cpp <https://github.com/godotengine/godot/blob/4.0/scene/resources/material.cpp>`__
+
+**Other GLSL shaders for Forward+ and Forward Mobile rendering methods:**
+
+- `servers/rendering/renderer_rd/shaders/ <https://github.com/godotengine/godot/blob/4.0/servers/rendering/renderer_rd/shaders/>`__
+- `modules/lightmapper_rd/ <https://github.com/godotengine/godot/blob/4.0/modules/lightmapper_rd>`__
+
+**Other GLSL shaders for the Compatibility rendering method:**
+
+- `drivers/gles3/shaders/ <https://github.com/godotengine/godot/blob/4.0/drivers/gles3/shaders/>`__
+
+2D and 3D rendering separation
+------------------------------
+
+.. note::
+
+    The following is only applicable in the Forward+ and Forward Mobile
+    rendering methods, not in Compatibility. Multiple Viewports can be used to
+    emulate this when using the Compatibility backend, or to perform 2D
+    resolution scaling.
+
+2D and 3D are rendered to separate buffers, as 2D rendering in Godot is performed
+in :abbr:`LDR (Low Dynamic Range)` sRGB-space while 3D rendering uses
+:abbr:`HDR (High Dynamic Range)` linear space.
+
+3D resolution scaling is performed differently depending on whether bilinear or
+FSR 1.0 scaling is used. When bilinear scaling is used, no special upscaling
+shader is run. Instead, the viewport's texture is stretched and displayed with a
+linear sampler (which makes the filtering happen directly on the hardware). This
+allows maximizing the performance of bilinear 3D scaling.
+
+The ``configure()`` function in RenderSceneBuffersRD reallocates the 2D/3D
+buffers when the resolution or scaling changes.
+
+Dynamic resolution scaling isn't supported yet, but is planned in a future Godot
+release.
+
+**2D and 3D rendering buffer configuration C++ code:**
+
+- `servers/rendering/renderer_rd/storage_rd/render_scene_buffers_rd.cpp <https://github.com/godotengine/godot/blob/4.0/servers/rendering/renderer_rd/storage_rd/render_scene_buffers_rd.cpp>`__
+
+2D rendering techniques
+-----------------------
+
+2D light rendering is performed in a single pass to allow for better performance
+with large amounts of lights.
+
+The Forward+ and Mobile rendering methods don't feature 2D batching yet, but
+it's planned for a future release.
+
+The Compatibility backend features 2D batching to improve performance, which is
+especially noticeable with lots of text on screen.
+
+MSAA can be enabled in 2D to provide "automatic" line and polygon antialiasing,
+but FXAA does not affect 2D rendering as it's calculated before 2D rendering
+begins. Godot's 2D drawing methods such as the Line2D node or some CanvasItem
+``draw_*()`` methods provide their own way of antialiasing based on triangle
+strips and vertex colors, which don't require MSAA to work.
+
+A 2D signed distance field representing LightOccluder2D nodes in the viewport is
+automatically generated if an user shader requests it. This can be used for
+various effects in custom shaders, such as 2D global illumination. It is also
+used to calculate particle collisions in 2D.
+
+**2D SDF generation GLSL shader:**
+
+- `https://github.com/godotengine/godot/blob/4.0/servers/rendering/renderer_rd/shaders/canvas_sdf.glsl <servers/rendering/renderer_rd/shaders/canvas_sdf.glsl>`__
+
+3D rendering techniques
+-----------------------
+
+Batching and instancing
+^^^^^^^^^^^^^^^^^^^^^^^
+
+In the Forward+ backend, Vulkan instancing is used to group rendering
+of identical objects for performance. This is not as fast as static mesh
+merging, but it still allows instances to be culled individually.
+
+Light, decal and reflection probe rendering
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+.. note::
+
+  Reflection probe and decal rendering are currently not available in the
+  Compatibility backend.
+
+As its name implies, the Forward+ backend uses clustered lighting. This
+allows using as many lights as you want; performance largely depends on screen
+coverage. Shadow-less lights can be almost free if they don't occupy much space
+on screen.
+
+All rendering methods also support rendering up to 8 directional lights at the
+same time (albeit with lower shadow quality when more than one light has shadows
+enabled).
+
+The Forward Mobile backend uses a single-pass lighting approach, with a
+limitation of 8 OmniLights + 8 SpotLights affecting each Mesh *resource* (plus a
+limitation of 256 OmniLights + 256 SpotLights in the camera view). These limits
+are hardcoded and can't be adjusted in the project settings.
+
+The Compatibility backend uses a hybrid single-pass + multi-pass lighting
+approach. Lights without shadows are rendered in a single pass. Lights with
+shadows are rendered in multiple passes. This is required for performance
+reasons on mobile devices. As a result, performance does not scale well with
+many shadow-casting lights. It is recommended to only have a handful of lights
+with shadows in the camera frustum at a time and for those lights to be spread
+apart so that each object is only touched by 1 or 2 shadowed lights at a time.
+The maximum number of lights visible at once can be adjusted in the project
+settings.
+
+In all 3 methods, lights without shadows are much cheaper than lights with
+shadows. To improve performance, lights are only updated when the light is
+modified or when objects in its radius are modified. Godot currently doesn't
+separate static shadow rendering from dynamic shadow rendering, but this is
+planned in a future release.
+
+Clustering is also used for reflection probes and decal rendering in the
+Forward+ backend.
+
+Shadow mapping
+^^^^^^^^^^^^^^
+
+Both Forward+ and Forward Mobile methods use
+:abbr:`PCF (Percentage Closer Filtering)` to filter shadow maps and create a
+soft penumbra. Instead of using a fixed PCF pattern, these methods use a vogel
+disk pattern which allows for changing the number of samples and smoothly
+changing the quality.
+
+Godot also supports percentage-closer soft shadows (PCSS) for more realistic
+shadow penumbra rendering. PCSS shadows are limited to the Forward+
+backend as they're too demanding to be usable in the Forward Mobile backend.
+PCSS also uses a vogel-disk shaped kernel.
+
+Additionally, both shadow-mapping techniques rotate the kernel on a per-pixel
+basis to help soften under-sampling artifacts.
+
+The Compatibility backend doesn't support shadow mapping for any light types yet.
+
+Temporal antialiasing
+^^^^^^^^^^^^^^^^^^^^^
+
+.. note::
+
+    Only available in the Forward+ backend, not the Forward Mobile or
+    Compatibility methods.
+
+Godot uses a custom TAA implementation based on the old TAA implementation from
+`Spartan Engine <https://github.com/PanosK92/SpartanEngine>`__.
+
+Temporal antialiasing requires motion vectors to work. If motion vectors
+are not correctly generated, ghosting will occur when the camera or objects move.
+
+Motion vectors are generated on the GPU in the main material shader. This is
+done by running the vertex shader corresponding to the previous rendered frame
+(with the previous camera transform) in addition to the vertex shader for the
+current rendered frame, then storing the difference between them in a color buffer.
+
+Using `FSR 2.0 <https://github.com/GPUOpen-Effects/FidelityFX-FSR2>`__ instead
+of a custom TAA implementation is planned in a future release.
+
+**TAA resolve:**
+
+- `servers/rendering/renderer_rd/shaders/effects/taa_resolve.glsl <https://github.com/godotengine/godot/blob/4.0/servers/rendering/renderer_rd/shaders/effects/taa_resolve.glsl>`__
+
+Global illumination
+^^^^^^^^^^^^^^^^^^^
+
+.. note::
+
+    VoxelGI and SDFGI are only available in the Forward+ backend, not the
+    Forward Mobile or Compatibility methods.
+
+    LightmapGI *baking* is only available in the Forward+ and Forward Mobile
+    methods, and can only be performed within the editor (not in an exported
+    project). LightmapGI *rendering* will eventually be supported by the
+    Compatibility backend.
+
+Godot supports voxel-based GI (VoxelGI), signed distance field GI (SDFGI) and
+lightmap baking and rendering (LightmapGI). These techniques can be used
+simultaneously if desired.
+
+Lightmap baking happens on the GPU using Vulkan compute shaders. The GPU-based
+lightmapper is implemented in the LightmapperRD class, which inherits from the
+Lightmapper class. This allows for implementing additional lightmappers, paving
+the way for a future port of the CPU-based lightmapper present in Godot 3.x.
+This would allow baking lightmaps while using the Compatibility backend.
+
+**Core GI C++ code:**
+
+- `servers/rendering/renderer_rd/environment/gi.cpp <https://github.com/godotengine/godot/blob/4.0/servers/rendering/renderer_rd/environment/gi.cpp>`__
+- `scene/3d/voxel_gi.cpp <https://github.com/godotengine/godot/blob/4.0/scene/3d/voxel_gi.cpp>`__ - VoxelGI node
+- `editor/plugins/voxel_gi_editor_plugin.cpp <https://github.com/godotengine/godot/blob/4.0/editor/plugins/voxel_gi_editor_plugin.cpp>`__ - Editor UI for the VoxelGI node
+
+**Core GI GLSL shaders:**
+
+- `servers/rendering/renderer_rd/shaders/environment/voxel_gi.glsl <https://github.com/godotengine/godot/blob/4.0/servers/rendering/renderer_rd/shaders/environment/voxel_gi.glsl>`__
+- `servers/rendering/renderer_rd/shaders/environment/voxel_gi_debug.glsl <https://github.com/godotengine/godot/blob/4.0/servers/rendering/renderer_rd/shaders/environment/voxel_gi_debug.glsl>`__ - VoxelGI debug draw mode
+- `servers/rendering/renderer_rd/shaders/environment/sdfgi_debug.glsl <https://github.com/godotengine/godot/blob/4.0/servers/rendering/renderer_rd/shaders/environment/sdfgi_debug.glsl>`__ - SDFGI Cascades debug draw mode
+- `servers/rendering/renderer_rd/shaders/environment/sdfgi_debug_probes.glsl <https://github.com/godotengine/godot/blob/4.0/servers/rendering/renderer_rd/shaders/environment/sdfgi_debug_probes.glsl>`__ - SDFGI Probes debug draw mode
+- `servers/rendering/renderer_rd/shaders/environment/sdfgi_integrate.glsl <https://github.com/godotengine/godot/blob/4.0/servers/rendering/renderer_rd/shaders/environment/sdfgi_integrate.glsl>`__
+- `servers/rendering/renderer_rd/shaders/environment/sdfgi_preprocess.glsl <https://github.com/godotengine/godot/blob/4.0/servers/rendering/renderer_rd/shaders/environment/sdfgi_preprocess.glsl>`__
+- `servers/rendering/renderer_rd/shaders/environment/sdfgi_direct_light.glsl <https://github.com/godotengine/godot/blob/4.0/servers/rendering/renderer_rd/shaders/environment/sdfgi_direct_light.glsl>`__
+
+**Lightmapper C++ code:**
+
+- `scene/3d/lightmap_gi.cpp <https://github.com/godotengine/godot/blob/4.0/scene/3d/lightmap_gi.cpp>`__ - LightmapGI node
+- `editor/plugins/lightmap_gi_editor_plugin.cpp <https://github.com/godotengine/godot/blob/4.0/editor/plugins/lightmap_gi_editor_plugin.cpp>`__ - Editor UI for the LightmapGI node
+- `scene/3d/lightmapper.cpp <https://github.com/godotengine/godot/blob/4.0/scene/3d/lightmapper.cpp>`__ - Abstract class
+- `modules/lightmapper_rd/lightmapper_rd.cpp <https://github.com/godotengine/godot/blob/4.0/modules/lightmapper_rd/lightmapper_rd.cpp>`__ - GPU-based lightmapper implementation
+
+**Lightmapper GLSL shaders:**
+
+- `modules/lightmapper_rd/lm_raster.glsl <https://github.com/godotengine/godot/blob/4.0/modules/lightmapper_rd/lm_raster.glsl>`__
+- `modules/lightmapper_rd/lm_compute.glsl <https://github.com/godotengine/godot/blob/4.0/modules/lightmapper_rd/lm_compute.glsl>`__
+- `modules/lightmapper_rd/lm_blendseams.glsl <https://github.com/godotengine/godot/blob/4.0/modules/lightmapper_rd/lm_blendseams.glsl>`__
+
+Depth of field
+^^^^^^^^^^^^^^
+
+.. note::
+
+    Only available in the Forward+ and Forward Mobile methods, not the
+    Compatibility backend.
+
+The Forward+ and Forward Mobile methods use different approaches to
+DOF rendering, with different visual results. This is done to best
+match the performance characteristics of the target hardware. In Clustered
+Forward, DOF is performed using a compute shader. In Forward Mobile, DOF is
+performed using a fragment shader (raster).
+
+Box, hexagon and circle bokeh shapes are available (from fastest to slowest).
+Depth of field can optionally be jittered every frame to improve its appearance
+when temporal antialiasing is enabled.
+
+**Depth of field C++ code:**
+
+- `servers/rendering/renderer_rd/effects/bokeh_dof.cpp <https://github.com/godotengine/godot/blob/4.0/servers/rendering/renderer_rd/effects/bokeh_dof.cpp>`__
+
+**Depth of field GLSL shader (compute - used for Forward+):**
+
+- `servers/rendering/renderer_rd/shaders/effects/bokeh_dof.glsl <https://github.com/godotengine/godot/blob/4.0/servers/rendering/renderer_rd/shaders/effects/bokeh_dof.glsl>`__
+
+**Depth of field GLSL shader (raster - used for Forward Mobile):**
+
+- `servers/rendering/renderer_rd/shaders/effects/bokeh_dof_raster.glsl <https://github.com/godotengine/godot/blob/4.0/servers/rendering/renderer_rd/shaders/effects/bokeh_dof_raster.glsl>`__
+
+Screen-space effects (SSAO, SSIL, SSR, SSS)
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+.. note::
+
+    Only available in the Forward+ backend, not the Forward Mobile or
+    Compatibility methods.
+
+The Forward+ backend supports screen-space ambient occlusion,
+screen-space indirect lighting, screen-space reflections and subsurface scattering.
+
+SSAO uses an implementation derived from Intel's
+`ASSAO <https://www.intel.com/content/www/us/en/developer/articles/technical/adaptive-screen-space-ambient-occlusion.html>`__
+(converted to Vulkan). SSIL is derived from SSAO to provide high-performance
+indirect lighting.
+
+When both SSAO and SSIL are enabled, parts of SSAO and SSIL are shared to reduce
+the performance impact.
+
+SSAO and SSIL are performed at half resolution by default to improve performance.
+SSR is always performed at half resolution to improve performance.
+
+**Screen-space effects C++ code:**
+
+- `servers/rendering/renderer_rd/effects/ss_effects.cpp <https://github.com/godotengine/godot/blob/4.0/servers/rendering/renderer_rd/effects/ss_effects.cpp>`__
+
+**Screen-space ambient occlusion GLSL shader:**
+
+- `servers/rendering/renderer_rd/shaders/effects/ssao.glsl <https://github.com/godotengine/godot/blob/4.0/servers/rendering/renderer_rd/shaders/effects/ssao.glsl>`__
+- `servers/rendering/renderer_rd/shaders/effects/ssao_blur.glsl <https://github.com/godotengine/godot/blob/4.0/servers/rendering/renderer_rd/shaders/effects/ssao_blur.glsl>`__
+- `servers/rendering/renderer_rd/shaders/effects/ssao_interleave.glsl <https://github.com/godotengine/godot/blob/4.0/servers/rendering/renderer_rd/shaders/effects/ssao_interleave.glsl>`__
+- `servers/rendering/renderer_rd/shaders/effects/ssao_importance_map.glsl <https://github.com/godotengine/godot/blob/4.0/servers/rendering/renderer_rd/shaders/effects/ssao_importance_map.glsl>`__
+
+**Screen-space indirect lighting GLSL shader:**
+
+- `servers/rendering/renderer_rd/shaders/effects/ssil.glsl <https://github.com/godotengine/godot/blob/4.0/servers/rendering/renderer_rd/shaders/effects/ssil.glsl>`__
+- `servers/rendering/renderer_rd/shaders/effects/ssil_blur.glsl <https://github.com/godotengine/godot/blob/4.0/servers/rendering/renderer_rd/shaders/effects/ssil_blur.glsl>`__
+- `servers/rendering/renderer_rd/shaders/effects/ssil_interleave.glsl <https://github.com/godotengine/godot/blob/4.0/servers/rendering/renderer_rd/shaders/effects/ssil_interleave.glsl>`__
+- `servers/rendering/renderer_rd/shaders/effects/ssil_importance_map.glsl <https://github.com/godotengine/godot/blob/4.0/servers/rendering/renderer_rd/shaders/effects/ssil_importance_map.glsl>`__
+
+**Screen-space reflections GLSL shader:**
+
+- `servers/rendering/renderer_rd/shaders/effects/screen_space_reflection.glsl <https://github.com/godotengine/godot/blob/4.0/servers/rendering/renderer_rd/shaders/effects/screen_space_reflection.glsl>`__
+- `servers/rendering/renderer_rd/shaders/effects/screen_space_reflection_scale.glsl <https://github.com/godotengine/godot/blob/4.0/servers/rendering/renderer_rd/shaders/effects/screen_space_reflection_scale.glsl>`__
+- `servers/rendering/renderer_rd/shaders/effects/screen_space_reflection_filter.glsl <https://github.com/godotengine/godot/blob/4.0/servers/rendering/renderer_rd/shaders/effects/screen_space_reflection_filter.glsl>`__
+
+**Subsurface scattering GLSL:**
+
+- `servers/rendering/renderer_rd/shaders/effects/subsurface_scattering.glsl <https://github.com/godotengine/godot/blob/4.0/servers/rendering/renderer_rd/shaders/effects/subsurface_scattering.glsl>`__
+
+Sky rendering
+^^^^^^^^^^^^^
+
+.. seealso::
+
+    :ref:`doc_sky_shader`
+
+Godot supports using shaders to render the sky background. The radiance map
+(which is used to provide ambient light and reflections for PBR materials) is
+automatically updated based on the sky shader.
+
+The SkyMaterial resources such as ProceduralSkyMaterial, PhysicalSkyMaterial and
+PanoramaSkyMaterial generate a built-in shader for sky rendering. This is
+similar to what BaseMaterial3D provides for 3D scene materials.
+
+A detailed technical implementation can be found in the
+`Custom sky shaders in Godot 4.0 <https://godotengine.org/article/custom-sky-shaders-godot-4-0>`__
+article.
+
+**Sky rendering C++ code:**
+
+- `servers/rendering/renderer_rd/environment/sky.cpp <https://github.com/godotengine/godot/blob/4.0/servers/rendering/renderer_rd/environment/sky.cpp>`__ - Sky rendering
+- `scene/resources/sky.cpp <https://github.com/godotengine/godot/blob/4.0/scene/resources/sky.cpp>`__ - Sky resource (not to be confused with sky rendering)
+- `scene/resources/sky_material.cpp <https://github.com/godotengine/godot/blob/4.0/scene/resources/sky_material.cpp>`__ SkyMaterial resources (used in the Sky resource)
+
+**Sky rendering GLSL shader:**
+
+Volumetric fog
+^^^^^^^^^^^^^^
+
+.. note::
+
+    Only available in the Forward+ backend, not the Forward Mobile or
+    Compatibility methods.
+
+.. seealso::
+
+    :ref:`doc_fog_shader`
+
+Godot supports a frustum-aligned voxel (froxel) approach to volumetric fog
+rendering. As opposed to a post-processing filter, this approach is more
+general-purpose as it can work with any light type. Fog can also use shaders for
+custom behavior, which allows animating the fog or using a 3D texture to
+represent density.
+
+The FogMaterial resource generates a built-in shader for FogVolume nodes. This is
+similar to what BaseMaterial3D provides for 3D scene materials.
+
+A detailed technical explanation can be found in the
+`Fog Volumes arrive in Godot 4.0 <https://godotengine.org/article/fog-volumes-arrive-in-godot-4>`__
+article.
+
+**Volumetric fog C++ code:**
+
+- `servers/rendering/renderer_rd/environment/fog.cpp <https://github.com/godotengine/godot/blob/4.0/servers/rendering/renderer_rd/environment/fog.cpp>`__ - General volumetric fog
+- `scene/3d/fog_volume.cpp <https://github.com/godotengine/godot/blob/4.0/scene/3d/fog_volume.cpp>`__ - FogVolume node
+- `scene/resources/fog_material.cpp <https://github.com/godotengine/godot/blob/4.0/scene/resources/fog_material.cpp>`__ - FogMaterial resource (used by FogVolume)
+
+**Volumetric fog GLSL shaders:**
+
+- `servers/rendering/renderer_rd/shaders/environment/volumetric_fog.glsl <https://github.com/godotengine/godot/blob/4.0/servers/rendering/renderer_rd/shaders/environment/volumetric_fog.glsl>`__
+- `servers/rendering/renderer_rd/shaders/environment/volumetric_fog_process.glsl <https://github.com/godotengine/godot/blob/4.0/servers/rendering/renderer_rd/shaders/environment/volumetric_fog_process.glsl>`__
+
+Occlusion culling
+^^^^^^^^^^^^^^^^^
+
+While modern GPUs can handle drawing a lot of triangles, the number of draw
+calls in complex scenes can still be a bottleneck (even with Vulkan and Direct3D
+12).
+
+Godot 4 supports occlusion culling to reduce overdraw (when the depth prepass
+is disabled) and reduce vertex throughput.
+This is done by rasterizing a low-resolution buffer on the CPU using
+`Embree <https://github.com/embree/embree>`__. The buffer's resolution depends
+on the number of CPU threads on the system, as this is done in parallel.
+This buffer includes occluder shapes that were baked in the editor or created at
+run-time.
+
+As complex occluders can introduce a lot of strain on the CPU, baked occluders
+can be simplified automatically when generated in the editor.
+
+Godot's occlusion culling doesn't support dynamic occluders yet, but
+OccluderInstance3D nodes can still have their visibility toggled or be moved.
+However, this will be slow when updating complex occluders this way. Therefore,
+updating occluders at run-time is best done only on simple occluder shapes such
+as quads or cuboids.
+
+This CPU-based approach has a few advantages over other solutions, such as
+portals and rooms or a GPU-based culling solution:
+
+- No manual setup required (but can be tweaked manually for best performance).
+- No frame delay, which is problematic in cutscenes during camera cuts or when
+  the camera moves fast behind a wall.
+- Works the same on all rendering drivers and methods, with no unpredictable
+  behavior depending on the driver or GPU hardware.
+
+Occlusion culling is performed by registering occluder meshes, which is done
+using OccluderInstance3D *nodes* (which themselves use Occluder3D *resources*).
+RenderingServer then performs occlusion culling by calling Embree in
+RendererSceneOcclusionCull.
+
+**Occlusion culling C++ code:**
+
+- `scene/3d/occluder_instance_3d.cpp <https://github.com/godotengine/godot/blob/4.0/scene/3d/occluder_instance_3d.cpp>`__
+- `servers/rendering/renderer_scene_occlusion_cull.cpp <https://github.com/godotengine/godot/blob/4.0/servers/rendering/renderer_scene_occlusion_cull.cpp>`__
+
+Visibility range (LOD)
+^^^^^^^^^^^^^^^^^^^^^^^
+
+Godot supports manually authored hierarchical level of detail (HLOD), with
+distances specified by the user in the inspector.
+
+In RenderingSceneCull, the ``_scene_cull()`` and ``_render_scene()`` functions
+are where most of the LOD determination happens. Each viewport can render the
+same mesh with different LODs (to allow for split screen rendering to look correct).
+
+**Visibility range C++ code:**
+
+- `servers/rendering/renderer_scene_cull.cpp <https://github.com/godotengine/godot/blob/4.0/servers/rendering/renderer_scene_cull.cpp>`__
+
+Automatic mesh LOD
+^^^^^^^^^^^^^^^^^^
+
+The ImporterMesh class is used for the 3D mesh import workflow in the editor.
+Its ``generate_lods()`` function handles generating using the
+`meshoptimizer <https://meshoptimizer.org/>`__ library.
+
+LOD mesh generation also generates shadow meshes at the same time. These are
+meshes that have their vertices welded regardless of smoothing and materials.
+This is used to improve shadow rendering performance by lowering the vertex
+throughput required to render shadows.
+
+The RenderingSceneCull class's ``_render_scene()`` function determines which
+mesh LOD should be used when rendering. Each viewport can render the
+same mesh with different LODs (to allow for split screen rendering to look correct).
+
+The mesh LOD is automatically chosen based on a screen coverage metric. This
+takes resolution and camera FOV changes into account without requiring user
+intervention. The threshold multiplier can be adjusted in the project settings.
+
+To improve performance, shadow rendering and reflection probe rendering also choose
+their own mesh LOD thresholds (which can be different from the main scene rendering).
+
+**Mesh LOD generation on import C++ code:**
+
+- `scene/resources/importer_mesh.cpp <https://github.com/godotengine/godot/blob/4.0/scene/resources/importer_mesh.cpp>`__
+
+**Mesh LOD determination C++ code:**
+
+- `servers/rendering/renderer_scene_cull.cpp <https://github.com/godotengine/godot/blob/4.0/servers/rendering/renderer_scene_cull.cpp>`__

+ 2 - 0
getting_started/first_2d_game/01.project_setup.rst

@@ -9,6 +9,8 @@ Launch Godot and create a new project.
 
 .. image:: img/new-project-button.webp
 
+When creating the new project, you only need to choose a valid *Project Path*. You can leave the other default settings alone.
+
 .. tabs::
  .. tab:: GDScript
 

+ 1 - 1
getting_started/first_2d_game/03.coding_the_player.rst

@@ -40,7 +40,7 @@ Start by declaring the member variables this object will need:
     public partial class Player : Area2D
     {
         [Export]
-        public int Speed = 400; // How fast the player will move (pixels/sec).
+        public int Speed { get; set; } = 400; // How fast the player will move (pixels/sec).
 
         public Vector2 ScreenSize; // Size of the game window.
     }

+ 4 - 4
getting_started/first_2d_game/04.creating_the_enemy.rst

@@ -94,7 +94,7 @@ Add a script to the ``Mob`` like this:
     public:
         void _init() {}
         void _ready();
-        void _on_VisibleOnScreenNotifier2D_screen_exited();
+        void _on_visible_on_screen_notifier_2d_screen_exited();
 
         static void _register_methods();
     };
@@ -145,8 +145,8 @@ these names from the list (array indices start at ``0``). ``randi() % n``
 selects a random integer between ``0`` and ``n-1``.
 
 The last piece is to make the mobs delete themselves when they leave the screen.
-Connect the ``screen_exited()`` signal of the ``VisibleOnScreenNotifier2D`` node and
-add this code:
+Connect the ``screen_exited()`` signal of the ``VisibleOnScreenNotifier2D`` node
+to the ``Mob`` and add this code:
 
 .. tabs::
  .. code-tab:: gdscript GDScript
@@ -164,7 +164,7 @@ add this code:
  .. code-tab:: cpp
 
     // This code goes in `mob.cpp`.
-    void Mob::_on_VisibleOnScreenNotifier2D_screen_exited() {
+    void Mob::_on_visible_on_screen_notifier_2d_screen_exited() {
         queue_free();
     }
 

+ 12 - 10
getting_started/first_2d_game/05.the_main_game_scene.rst

@@ -10,7 +10,7 @@ Create a new scene and add a :ref:`Node <class_Node>` named ``Main``.
 be a container for handling game logic. It does not require 2D functionality itself.)
 
 Click the **Instance** button (represented by a chain link icon) and select your saved
-``Player.tscn``.
+``player.tscn``.
 
 .. image:: img/instance_scene.webp
 
@@ -178,21 +178,23 @@ under "Script Variables".
 
 You can assign this property's value in two ways:
 
-- Drag ``Mob.tscn`` from the "FileSystem" dock and drop it in the **Mob Scene**
+- Drag ``mob.tscn`` from the "FileSystem" dock and drop it in the **Mob Scene**
   property.
-- Click the down arrow next to "[empty]" and choose "Load". Select ``Mob.tscn``.
+- Click the down arrow next to "[empty]" and choose "Load". Select ``mob.tscn``.
 
-Next, select the ``Player`` node in the Scene dock, and access the Node dock on
-the sidebar. Make sure to have the Signals tab selected in the Node dock.
+Next, select the instance of the ``Player`` scene under ``Main`` node in the Scene dock,
+and access the Node dock on the sidebar. Make sure to have the Signals tab selected
+in the Node dock.
 
 You should see a list of the signals for the ``Player`` node. Find and
 double-click the ``hit`` signal in the list (or right-click it and select
 "Connect..."). This will open the signal connection dialog. We want to make a
 new function named ``game_over``, which will handle what needs to happen when a
 game ends. Type "game_over" in the "Receiver Method" box at the bottom of the
-signal connection dialog and click "Connect". Add the following code to the new
-function, as well as a ``new_game`` function that will set everything up for a
-new game:
+signal connection dialog and click "Connect". You are aiming to have the ``hit`` signal
+emitted from ``Player`` and handled in the ``Main`` script. Add the following code
+to the new function, as well as a ``new_game`` function that will set
+everything up for a new game:
 
 .. tabs::
  .. code-tab:: gdscript GDScript
@@ -422,11 +424,11 @@ call to ``_ready()``:
     }
 
 Let's also assign ``Main`` as our "Main Scene" - the one that runs automatically
-when the game launches. Press the "Play" button and select ``Main.tscn`` when
+when the game launches. Press the "Play" button and select ``main.tscn`` when
 prompted.
 
 .. tip:: If you had already set another scene as the "Main Scene", you can right
-         click ``Main.tscn`` in the FileSystem dock and select "Set As Main Scene".
+         click ``main.tscn`` in the FileSystem dock and select "Set As Main Scene".
 
 You should be able to move the player around, see mobs spawning, and see the
 player disappear when hit by a mob.

+ 1 - 1
getting_started/first_2d_game/06.heads_up_display.rst

@@ -411,7 +411,7 @@ with the changing score:
         _hud->update_score(score);
 
 Now you're ready to play! Click the "Play the Project" button. You will be asked
-to select a main scene, so choose ``Main.tscn``.
+to select a main scene, so choose ``main.tscn``.
 
 Removing old creeps
 ~~~~~~~~~~~~~~~~~~~

+ 14 - 4
getting_started/first_2d_game/07.finishing-up.rst

@@ -33,8 +33,12 @@ Add two :ref:`AudioStreamPlayer <class_AudioStreamPlayer>` nodes as children of
 click on the ``Stream`` property, select "Load", and choose the corresponding
 audio file.
 
-To play the music, add ``$Music.play()`` in the ``new_game()`` function and
-``$Music.stop()`` in the ``game_over()`` function.
+All audio is automatically imported with the ``Loop`` setting disabled.
+If you want the music to loop seamlessly, click on the Stream file arrow,
+select ``Make Unique``, then click on the Stream file and check the ``Loop`` box. 
+
+To play the music, add ``$Music.play()`` in the ``new_game()``
+function and ``$Music.stop()`` in the ``game_over()`` function.
 
 Finally, add ``$DeathSound.play()`` in the ``game_over()`` function.
 
@@ -53,9 +57,15 @@ tab. In the same way you created the movement input actions, create a new
 input action called ``start_game`` and add a key mapping for the :kbd:`Enter`
 key.
 
+Now would be a good time to add controller support if you have one available.
+Attach or pair your controller and then under each input action that you wish
+to add controller support for, click on the "+" button and press the corresponding
+button, d-pad, or stick direction that you want to map to the respective input action.
+
 In the ``HUD`` scene, select the ``StartButton`` and find its **Shortcut**
-property in the Inspector. Create a new :ref:`Shortcut <class_Shortcut>` resource,
-open the **Events** array and add a new array element to it.
+property in the Inspector. Create a new :ref:`Shortcut <class_Shortcut>` resource
+by clicking within the box, open the **Events** array and add a new array element
+to it by clicking on **Array[InputEvent] (size 0)**.
 
 .. image:: img/start_button_shortcut.webp
 

+ 1 - 1
getting_started/first_3d_game/01.game_setup.rst

@@ -47,7 +47,7 @@ a node to the scene, you can press :kbd:`Ctrl + a` (or :kbd:`Cmd + a` on macOS).
 
 .. image:: img/01.game_setup/05.main_node.png
 
-Save the scene as ``Main.tscn`` by pressing :kbd:`Ctrl + s` (:kbd:`Cmd + s` on macOS).
+Save the scene as ``main.tscn`` by pressing :kbd:`Ctrl + s` (:kbd:`Cmd + s` on macOS).
 
 We'll start by adding a floor that'll prevent the characters from falling. To
 create static colliders like the floor, walls, or ceilings, you can use :ref:`StaticBody3D <class_StaticBody3D>` nodes. They require :ref:`CollisionShape3D <class_CollisionShape3D>` child nodes to

+ 1 - 1
getting_started/first_3d_game/02.player_input.rst

@@ -81,7 +81,7 @@ You can toggle the model's visibility by clicking the eye icon next to the
 
 |image5|
 
-Save the scene as ``Player.tscn``
+Save the scene as ``player.tscn``
 
 With the nodes ready, we can almost get coding. But first, we need to define
 some input actions.

+ 2 - 2
getting_started/first_3d_game/03.player_movement_code.rst

@@ -359,14 +359,14 @@ tab at the top of the editor to do so.
 |image1|
 
 If you closed the scene before, head to the *FileSystem* dock and double-click
-``Main.tscn`` to re-open it.
+``main.tscn`` to re-open it.
 
 To instantiate the ``Player``, right-click on the ``Main`` node and select *Instance
 Child Scene*.
 
 |image2|
 
-In the popup, double-click ``Player.tscn``. The character should appear in the
+In the popup, double-click ``player.tscn``. The character should appear in the
 center of the viewport.
 
 Adding a camera

+ 2 - 2
getting_started/first_3d_game/04.mob_scene.rst

@@ -9,7 +9,7 @@ In this part, you're going to code the monsters, which we'll call mobs. In the
 next lesson, we'll spawn them randomly around the playable area.
 
 Let's design the monsters themselves in a new scene. The node structure is going
-to be similar to the ``Player.tscn`` scene.
+to be similar to the ``player.tscn`` scene.
 
 Create a scene with, once again, a :ref:`CharacterBody3D <class_CharacterBody3D>` node as its root. Name it
 ``Mob``. Add a child node :ref:`Node3D <class_Node3D>`, name it ``Pivot``. And drag and drop
@@ -93,7 +93,7 @@ Coding the mob's movement
 
 Let's implement the monster's motion. We're going to do this in two steps.
 First, we'll write a script on the ``Mob`` that defines a function to initialize
-the monster. We'll then code the randomized spawn mechanism in the ``Main.tscn`` scene
+the monster. We'll then code the randomized spawn mechanism in the ``main.tscn`` scene
 and call the function from there.
 
 Attach a script to the ``Mob``.

+ 5 - 5
getting_started/first_3d_game/05.spawning_mobs.rst

@@ -10,7 +10,7 @@ you will have monsters roaming the game board.
 
 |image0|
 
-Double-click on ``Main.tscn`` in the *FileSystem* dock to open the ``Main`` scene.
+Double-click on ``main.tscn`` in the *FileSystem* dock to open the ``Main`` scene.
 
 Before drawing the path, we're going to change the game resolution. Our game has
 a default window size of ``1152x648``. We're going to set it to ``720x540``, a
@@ -157,7 +157,7 @@ Spawning monsters randomly
 
 Right-click on the ``Main`` node and attach a new script to it.
 
-We first export a variable to the *Inspector* so that we can assign ``Mob.tscn``
+We first export a variable to the *Inspector* so that we can assign ``mob.tscn``
 or any other monster to it.
 
 .. tabs::
@@ -181,9 +181,9 @@ or any other monster to it.
 
 We want to spawn mobs at regular time intervals. To do this, we need to go back
 to the scene and add a timer. Before that, though, we need to assign the
-``Mob.tscn`` file to the ``mob_scene`` property above (otherwise it's null!)
+``mob.tscn`` file to the ``mob_scene`` property above (otherwise it's null!)
 
-Head back to the 3D screen and select the ``Main`` node. Drag ``Mob.tscn`` from
+Head back to the 3D screen and select the ``Main`` node. Drag ``mob.tscn`` from
 the *FileSystem* dock to the *Mob Scene* slot in the *Inspector*.
 
 |image20|
@@ -269,7 +269,7 @@ what the *PathFollow* node's ``progress_ratio`` expects:
 The path we have set is around the camera's viewport, so any random value between 0 and 1
 is a random position alongside the edges of the viewport!
 
-Here is the complete ``Main.gd`` script so far, for reference.
+Here is the complete ``main.gd`` script so far, for reference.
 
 .. tabs::
  .. code-tab:: gdscript GDScript

+ 24 - 24
getting_started/first_3d_game/06.jump_and_squash.rst

@@ -74,7 +74,7 @@ see a list of named checkboxes.
 
 |image4|
 
-Next up are the ``Player`` and the ``Mob``. Open ``Player.tscn`` by double-clicking
+Next up are the ``Player`` and the ``Mob``. Open ``player.tscn`` by double-clicking
 the file in the *FileSystem* dock.
 
 Select the *Player* node and set its *Collision -> Mask* to both "enemies" and
@@ -83,7 +83,7 @@ Select the *Player* node and set its *Collision -> Mask* to both "enemies" and
 
 |image5|
 
-Then, open the *Mob* scene by double-clicking on ``Mob.tscn`` and select the
+Then, open the *Mob* scene by double-clicking on ``mob.tscn`` and select the
 ``Mob`` node.
 
 Set its *Collision -> Layer* to "enemies" and unset its *Collision -> Mask*,
@@ -180,7 +180,7 @@ We need to detect collisions with a monster and to differentiate them from
 collisions with the floor. To do so, we can use Godot's :ref:`group
 <doc_groups>` tagging feature.
 
-Open the scene ``Mob.tscn`` again and select the *Mob* node. Go to the *Node*
+Open the scene ``mob.tscn`` again and select the *Mob* node. Go to the *Node*
 dock on the right to see a list of signals. The *Node* dock has two tabs:
 *Signals*, which you've already used, and *Groups*, which allows you to assign
 tags to nodes.
@@ -235,26 +235,26 @@ With this code, if no collisions occurred on a given frame, the loop won't run.
 .. tabs::
  .. code-tab:: gdscript GDScript
 
-   func _physics_process(delta):
-        #...
-
-        # Iterate through all collisions that occurred this frame
-        for index in range(get_slide_collision_count()):
-            # We get one of the collisions with the player
-            var collision = get_slide_collision(index)
-
-            # If the collision is with ground
-            if (collision.get_collider() == null):
-                continue
-
-            # If the collider is with a mob
-            if collision.get_collider().is_in_group("mob"):
-                var mob = collision.get_collider()
-                # we check that we are hitting it from above.
-                if Vector3.UP.dot(collision.get_normal()) > 0.1:
-                    # If so, we squash it and bounce.
-                    mob.squash()
-                    target_velocity.y = bounce_impulse
+    func _physics_process(delta):
+       #...
+
+       # Iterate through all collisions that occurred this frame
+       for index in range(get_slide_collision_count()):
+           # We get one of the collisions with the player
+           var collision = get_slide_collision(index)
+
+           # If the collision is with ground
+           if (collision.get_collider() == null):
+               continue
+
+           # If the collider is with a mob
+           if collision.get_collider().is_in_group("mob"):
+               var mob = collision.get_collider()
+               # we check that we are hitting it from above.
+               if Vector3.UP.dot(collision.get_normal()) > 0.1:
+                   # If so, we squash it and bounce.
+                   mob.squash()
+                   target_velocity.y = bounce_impulse
 
  .. code-tab:: csharp
 
@@ -347,7 +347,7 @@ destroy the mob.
 We will use the signal to add points to the score in the next lesson.
 
 With that, you should be able to kill monsters by jumping on them. You can press
-:kbd:`F5` to try the game and set ``Main.tscn`` as your project's main scene.
+:kbd:`F5` to try the game and set ``main.tscn`` as your project's main scene.
 
 However, the player won't die yet. We'll work on that in the next part.
 

+ 3 - 3
getting_started/first_3d_game/07.killing_player.rst

@@ -17,7 +17,7 @@ works well for hitboxes.
 Hitbox with the Area node
 -------------------------
 
-Head back to the ``Player.tscn`` scene and add a new child node :ref:`Area3D <class_Area3D>`. Name it
+Head back to the ``player.tscn`` scene and add a new child node :ref:`Area3D <class_Area3D>`. Name it
 ``MobDetector``
 Add a :ref:`CollisionShape3D <class_CollisionShape3D>` node as a child of it.
 
@@ -128,7 +128,7 @@ We can use the ``Player``\ 's ``hit`` signal to end the game. All we need
 to do is connect it to the ``Main`` node and stop the ``MobTimer`` in
 reaction.
 
-Open ``Main.tscn``, select the ``Player`` node, and in the *Node* dock,
+Open ``main.tscn``, select the ``Player`` node, and in the *Node* dock,
 connect its ``hit`` signal to the ``Main`` node.
 
 |image5|
@@ -165,7 +165,7 @@ Code checkpoint
 Here are the complete scripts for the ``Main``, ``Mob``, and ``Player`` nodes,
 for reference. You can use them to compare and check your code.
 
-Starting with ``Main.gd``.
+Starting with ``main.gd``.
 
 .. tabs::
  .. code-tab:: gdscript GDScript

+ 12 - 18
getting_started/first_3d_game/08.score_and_replay.rst

@@ -102,12 +102,12 @@ monsters from the code, we cannot connect the mob signal to the ``ScoreLabel`` v
 Instead, we have to make the connection from the code every time we spawn a
 monster.
 
-Open the script ``Main.gd``. If it's still open, you can click on its name in
+Open the script ``main.gd``. If it's still open, you can click on its name in
 the script editor's left column.
 
 |image8|
 
-Alternatively, you can double-click the ``Main.gd`` file in the *FileSystem*
+Alternatively, you can double-click the ``main.gd`` file in the *FileSystem*
 dock.
 
 At the bottom of the ``_on_mob_timer_timeout()`` function, add the following
@@ -119,7 +119,7 @@ line:
     func _on_mob_timer_timeout():
         #...
         # We connect the mob to the score label to update the score upon squashing one.
-        mob.squashed.connect($UserInterface/ScoreLabel._on_Mob_squashed.bind())
+        mob.squashed.connect($UserInterface/ScoreLabel._on_mob_squashed.bind())
 
   .. code-tab:: csharp
 
@@ -131,9 +131,9 @@ line:
     }
 
 This line means that when the mob emits the ``squashed`` signal, the
-``ScoreLabel`` node will receive it and call the function ``_on_Mob_squashed()``.
+``ScoreLabel`` node will receive it and call the function ``_on_mob_squashed()``.
 
-Head back to the ``ScoreLabel.gd`` script to define the ``_on_Mob_squashed()``
+Head back to the ``ScoreLabel.gd`` script to define the ``_on_mob_squashed()``
 callback function.
 
 There, we increment the score and update the displayed text.
@@ -141,7 +141,7 @@ There, we increment the score and update the displayed text.
 .. tabs::
   .. code-tab:: gdscript GDScript
 
-    func _on_Mob_squashed():
+    func _on_mob_squashed():
         score += 1
         text = "Score: %s" % score
 
@@ -155,20 +155,14 @@ There, we increment the score and update the displayed text.
 
 The second line uses the value of the ``score`` variable to replace the
 placeholder ``%s``. When using this feature, Godot automatically converts values
-to string text, which is convenient to output text in labels or using the ``print()``
-function.
+to string text, which is convenient when outputting text in labels or
+when using the ``print()`` function.
 
 .. seealso::
 
     You can learn more about string formatting here: :ref:`doc_gdscript_printf`.
     In C#, consider using `string interpolation with "$" <https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/tokens/interpolated>`_.
 
-
-.. note::
-
-    If you get an error when you squash a mob
-    check your capital letters in the signal "_on_Mob_squashed"
-
 You can now play the game and squash a few enemies to see the score
 increase.
 
@@ -188,7 +182,7 @@ Retrying the game
 We'll now add the ability to play again after dying. When the player dies, we'll
 display a message on the screen and wait for input.
 
-Head back to the ``Main.tscn`` scene, select the ``UserInterface`` node, add a
+Head back to the ``main.tscn`` scene, select the ``UserInterface`` node, add a
 child node :ref:`ColorRect <class_ColorRect>`, and name it ``Retry``. This node fills a
 rectangle with a uniform color and will serve as an overlay to darken the
 screen.
@@ -234,7 +228,7 @@ Coding the retry option
 We can now head to the code to show and hide the ``Retry`` node when the player
 dies and plays again.
 
-Open the script ``Main.gd``. First, we want to hide the overlay at the start of
+Open the script ``main.gd``. First, we want to hide the overlay at the start of
 the game. Add this line to the ``_ready()`` function.
 
 .. tabs::
@@ -361,7 +355,7 @@ game's viewport.
 And that does it for this lesson. In the next part, we'll add an animation to
 make the game both look and feel much nicer.
 
-Here is the complete ``Main.gd`` script for reference.
+Here is the complete ``main.gd`` script for reference.
 
 .. tabs::
   .. code-tab:: gdscript GDScript
@@ -391,7 +385,7 @@ Here is the complete ``Main.gd`` script for reference.
         add_child(mob)
 
         # We connect the mob to the score label to update the score upon squashing one.
-        mob.squashed.connect($UserInterface/ScoreLabel._on_Mob_squashed.bind())
+        mob.squashed.connect($UserInterface/ScoreLabel._on_mob_squashed.bind())
 
     func _on_player_hit():
         $MobTimer.stop()

+ 5 - 5
getting_started/first_3d_game/09.adding_animations.rst

@@ -259,11 +259,11 @@ node structure, you can copy them to different scenes.
 For example, both the ``Mob`` and the ``Player`` scenes have a ``Pivot`` and a
 ``Character`` node, so we can reuse animations between them.
 
-Open the *Player* scene, select the AnimationPlayer node and open the "float" 
-animation. Next, click on **Animation > Copy**. Then open ``Mob.tscn``, 
-create an AnimationPlayer child node and select it. Click **Animation > Paste** 
-and make sure that the button with an "A+" icon (Autoplay on Load) and the 
-looping arrows (Animation looping) are also turned on in the animation editor 
+Open the *Player* scene, select the AnimationPlayer node and open the "float"
+animation. Next, click on **Animation > Copy**. Then open ``mob.tscn``,
+create an AnimationPlayer child node and select it. Click **Animation > Paste**
+and make sure that the button with an "A+" icon (Autoplay on Load) and the
+looping arrows (Animation looping) are also turned on in the animation editor
 in the bottom panel. That's it; all monsters will now play the float animation.
 
 We can change the playback speed based on the creature's ``random_speed``. Open

+ 2 - 1
getting_started/introduction/key_concepts_overview.rst

@@ -46,7 +46,8 @@ It is made of a ``CharacterBody2D`` node named "Character", a ``Sprite2D``, a
 ``Camera2D``, and a ``CollisionShape2D``.
 
 .. note:: The node names end with "2D" because this is a 2D scene. Their 3D
-          counterparts have names that end with "3D".
+          counterparts have names that end with "3D". Be aware that "Spatial"
+          Nodes are now called "Node3D" starting with Godot 4.
 
 Notice how nodes and scenes look the same in the editor. When you save a tree of
 nodes as a scene, it then shows as a single node, with its internal structure

+ 6 - 6
getting_started/step_by_step/instancing.rst

@@ -11,7 +11,7 @@ into any number of scenes. This feature helps you break down and organize your
 game's different components.
 
 You can create as many scenes as you'd like and save them as files with the
-``.tscn`` extension, which stands for "text scene". The ``Label.tscn`` file from
+``.tscn`` extension, which stands for "text scene". The ``tabel.tscn`` file from
 the previous lesson was an example. We call those files "Packed Scenes" as they
 pack information about your scene's content.
 
@@ -33,7 +33,7 @@ editor hides their content by default. When you instance the Ball, you only see
 the Ball node. Notice also how each duplicate has a unique name.
 
 Every instance of the Ball scene starts with the same structure and properties
-as ``Ball.tscn``. However, you can modify each independently, such as changing
+as ``ball.tscn``. However, you can modify each independently, such as changing
 how they bounce, how heavy they are, or any property exposed by the source
 scene.
 
@@ -64,8 +64,8 @@ Finally, click the Import & Edit button.
 
 .. image:: img/instancing_import_and_edit_button.png
 
-The project contains two packed scenes: ``Main.tscn``, containing walls against
-which the ball collides, and ``Ball.tscn``. The Main scene should open
+The project contains two packed scenes: ``main.tscn``, containing walls against
+which the ball collides, and ``ball.tscn``. The Main scene should open
 automatically.
 
 .. image:: img/instancing_main_scene.png
@@ -111,14 +111,14 @@ There is more to instances. With this feature, you can:
 
 1. Change the properties of one ball without affecting the others using the
    Inspector.
-2. Change the default properties of every Ball by opening the ``Ball.tscn`` scene
+2. Change the default properties of every Ball by opening the ``ball.tscn`` scene
    and making a change to the Ball node there. Upon saving, all instances of the
    Ball in the project will see their values update.
 
 .. note:: Changing a property on an instance always overrides values from the
           corresponding packed scene.
 
-Let's try this. Open ``Ball.tscn`` and select the Ball node. In the Inspector on
+Let's try this. Open ``ball.tscn`` and select the Ball node. In the Inspector on
 the right, click on the PhysicsMaterial property to expand it.
 
 .. image:: img/instancing_physics_material_expand.png

+ 1 - 1
getting_started/step_by_step/nodes_and_scenes.rst

@@ -173,7 +173,7 @@ A popup window appears and invites you to select the main scene.
 .. image:: img/nodes_and_scenes_13_main_scene_popup.webp
 
 Click the Select button, and in the file dialog that appears, double click on
-label.tscn.
+``label.tscn``.
 
 .. image:: img/nodes_and_scenes_14_select_main_scene.webp
 

+ 13 - 13
getting_started/step_by_step/scripting_first_script.rst

@@ -89,7 +89,7 @@ other options by default and click the Create button to create the script.
 
 .. image:: img/scripting_first_script_attach_node_script.webp
 
-The Script workspace should appear with your new ``Sprite2D.gd`` file open and
+The Script workspace should appear with your new ``sprite_2d.gd`` file open and
 the following line of code:
 
 .. tabs::
@@ -101,7 +101,7 @@ the following line of code:
 
     using Godot;
 
-    public partial class Sprite : Sprite2D
+    public partial class MySprite2D : Sprite2D
     {
     }
 
@@ -143,7 +143,7 @@ Add the following code to your script:
 
  .. code-tab:: csharp C#
 
-    public Sprite()
+    public MySprite2D()
     {
         GD.Print("Hello, world!");
     }
@@ -183,8 +183,8 @@ angular speed in radians per second.  Add the following after the ``extends Spri
 
  .. code-tab:: csharp C#
 
-    private int Speed = 400;
-    private float AngularSpeed = Mathf.Pi;
+    private int _speed = 400;
+    private float _angularSpeed = Mathf.Pi;
 
 Member variables sit near the top of the script, after any "extends" lines,
 but before functions. Every node
@@ -226,7 +226,7 @@ At the bottom of the script, define the function:
 
     public override void _Process(double delta)
     {
-        Rotation += AngularSpeed * (float)delta;
+        Rotation += _angularSpeed * (float)delta;
     }
 
 The ``func`` keyword defines a new function. After it, we have to write the
@@ -272,7 +272,7 @@ them.
 
  .. code-tab:: csharp C#
 
-    var velocity = Vector2.Up.Rotated(Rotation) * Speed;
+    var velocity = Vector2.Up.Rotated(Rotation) * _speed;
 
     Position += velocity * (float)delta;
 
@@ -305,7 +305,7 @@ Our node currently moves by itself. In the next part
 Complete script
 ---------------
 
-Here is the complete ``Sprite2D.gd`` file for reference.
+Here is the complete ``sprite_2d.gd`` file for reference.
 
 .. tabs::
  .. code-tab:: gdscript GDScript
@@ -327,15 +327,15 @@ Here is the complete ``Sprite2D.gd`` file for reference.
 
     using Godot;
 
-    public partial class Sprite : Sprite2D
+    public partial class MySprite2D : Sprite2D
     {
-        private int Speed = 400;
-        private float AngularSpeed = Mathf.Pi;
+        private int _speed = 400;
+        private float _angularSpeed = Mathf.Pi;
 
         public override void _Process(double delta)
         {
-            Rotation += AngularSpeed * (float)delta;
-            var velocity = Vector2.Up.Rotated(Rotation) * Speed;
+            Rotation += _angularSpeed * (float)delta;
+            var velocity = Vector2.Up.Rotated(Rotation) * _speed;
 
             Position += velocity * (float)delta;
         }

+ 7 - 7
getting_started/step_by_step/scripting_player_input.rst

@@ -11,7 +11,7 @@ Listening to player input
 
 Building upon the previous lesson :ref:`doc_scripting_first_script`, let's look
 at another important feature of any game: giving control to the player.
-To add this, we need to modify our ``Sprite2D.gd`` code.
+To add this, we need to modify our ``sprite_2d.gd`` code.
 
 .. image:: img/scripting_first_script_moving_with_input.gif
 
@@ -56,7 +56,7 @@ code below.
         direction = 1;
     }
 
-    Rotation += AngularSpeed * direction * (float)delta;
+    Rotation += _angularSpeed * direction * (float)delta;
 
 Our ``direction`` local variable is a multiplier representing the direction in
 which the player wants to turn. A value of ``0`` means the player isn't pressing
@@ -114,7 +114,7 @@ causing the sprite to move forward.
 Complete script
 ---------------
 
-Here is the complete ``Sprite2D.gd`` file for reference.
+Here is the complete ``sprite_2d.gd`` file for reference.
 
 .. tabs::
  .. code-tab:: gdscript GDScript
@@ -146,8 +146,8 @@ Here is the complete ``Sprite2D.gd`` file for reference.
 
     public partial class Sprite : Sprite2D
     {
-        private float Speed = 400;
-        private float AngularSpeed = Mathf.Pi;
+        private float _speed = 400;
+        private float _angularSpeed = Mathf.Pi;
 
         public override void _Process(double delta)
         {
@@ -161,12 +161,12 @@ Here is the complete ``Sprite2D.gd`` file for reference.
                 direction = 1;
             }
 
-            Rotation += AngularSpeed * direction * (float)delta;
+            Rotation += _angularSpeed * direction * (float)delta;
 
             var velocity = Vector2.Zero;
             if (Input.IsActionPressed("ui_up"))
             {
-                velocity = Vector2.Up.Rotated(Rotation) * Speed;
+                velocity = Vector2.Up.Rotated(Rotation) * _speed;
             }
 
             Position += velocity * (float)delta;

+ 5 - 5
getting_started/step_by_step/signals.rst

@@ -184,7 +184,7 @@ following code, which we saw two lessons ago:
         Position += velocity * (float)delta;
     }
 
-Your complete ``Sprite2D.gd`` code should look like the following.
+Your complete ``sprite_2d.gd`` code should look like the following.
 
 .. tabs::
  .. code-tab:: gdscript GDScript
@@ -313,7 +313,7 @@ which the script is attached. When the Timer emits ``timeout``, we want to call
 the function ``_on_timer_timeout()``, that we need to define. Let's add it at the
 bottom of our script and use it to toggle our sprite's visibility.
 
-.. note:: By convention, we name these callback methods in GDScript as 
+.. note:: By convention, we name these callback methods in GDScript as
           "_on_node_name_signal_name" and in C# as "OnNodeNameSignalName".
           Here, it'll be "_on_timer_timeout" for GDScript and OnTimerTimeout() for C#.
 
@@ -341,7 +341,7 @@ Complete script
 ---------------
 
 That's it for our little moving and blinking Godot icon demo!
-Here is the complete ``Sprite2D.gd`` file for reference.
+Here is the complete ``sprite_2d.gd`` file for reference.
 
 .. tabs::
  .. code-tab:: gdscript GDScript
@@ -354,7 +354,7 @@ Here is the complete ``Sprite2D.gd`` file for reference.
 
     func _ready():
         var timer = get_node("Timer")
-        timer.timeout.connect(_on_Timer_timeout)
+        timer.timeout.connect(_on_timer_timeout)
 
 
     func _process(delta):
@@ -367,7 +367,7 @@ Here is the complete ``Sprite2D.gd`` file for reference.
         set_process(not is_processing())
 
 
-    func _on_Timer_timeout():
+    func _on_timer_timeout():
         visible = not visible
 
  .. code-tab:: csharp C#

+ 2 - 2
tutorials/2d/2d_movement.rst

@@ -136,7 +136,7 @@ while up/down moves it forward or backward in whatever direction it's facing.
         public void GetInput()
         {
             _rotationDirection = Input.GetAxis("left", "right");
-            Velocity = Transform.x * Input.GetAxis("down", "up") * Speed;
+            Velocity = Transform.X * Input.GetAxis("down", "up") * Speed;
         }
 
         public override void _PhysicsProcess(double delta)
@@ -189,7 +189,7 @@ is set by the mouse position instead of the keyboard. The character will always
         public void GetInput()
         {
             LookAt(GetGlobalMousePosition());
-            Velocity = Transform.x * Input.GetAxis("down", "up") * Speed;
+            Velocity = Transform.X * Input.GetAxis("down", "up") * Speed;
         }
 
         public override void _PhysicsProcess(double delta)

+ 1 - 1
tutorials/2d/2d_transforms.rst

@@ -80,7 +80,7 @@ coordinates, just multiply in the following order:
 
  .. code-tab:: csharp
 
-    var screenCord = (GetViewportTransform() * GetGlobalTransform()).Xform(localPos);
+    var screenCord = GetViewportTransform() * (GetGlobalTransform() * localPos);
 
 Keep in mind, however, that it is generally not desired to work with
 screen coordinates. The recommended approach is to simply work in Canvas

+ 9 - 0
tutorials/3d/csg_tools.rst

@@ -290,3 +290,12 @@ in the **Scale** property will cause the texture to repeat more often.
          and choose **Copy**. To paste it, select the node you'd like to apply
          the material onto, click the dropdown arrow next to its material
          property then choose **Paste**.
+
+Exporting as glTF
+------------------------
+
+It can be useful to block out a level using CSG, then export it as a 3d model, to
+import into 3D modelling software. You can do this by selecting **Scene > Export As... >
+glTF 2.0 Scene**.
+
+.. image:: img/export_as_gltf.webp

+ 36 - 0
tutorials/3d/global_illumination/using_lightmap_gi.rst

@@ -166,6 +166,32 @@ unwrappers in 3D modeling software are not quality-oriented, as they are meant
 to work quickly. You will mostly need to use seams or other techniques to create
 better unwrapping.
 
+Generating UV2 for primitive meshes
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+.. note::
+
+    This option is only available for primitive meshes such as :ref:`class_BoxMesh`,
+    :ref:`class_CylinderMesh`, :ref:`class_PlaneMesh`, etc.
+
+Enabling UV2 on primitive meshes allows you to make them receive and contribute
+to baked lighting. This can be used in certain lighting setups. For instance,
+you could hide a torus that has an emissive material after baking lightmaps to
+create an area light that follows the shape of a torus.
+
+By default, primitive meshes do not have UV2 generated to save resources (as
+these meshes may be created during gameplay). You can edit a primitive mesh in
+the inspector and enable **Add UV2** to make the engine procedurally generate
+UV2 for a primitive mesh. The default **UV2 Padding** value is tuned to avoid
+most lightmap bleeding, without wasting too much space on the edges. If you
+notice lightmap bleeding on a specific primitive mesh only, you may have to
+increase **UV2 Padding**.
+
+**Lightmap Size Hint** represents the size taken by a single mesh on the
+lightmap texture, which varies depending on the mesh's size properties and the
+**UV2 Padding** value. **Lightmap Size Hint** should not be manually changed, as
+any modifications will be lost when the scene is reloaded.
+
 Checking UV2
 ^^^^^^^^^^^^
 
@@ -273,6 +299,16 @@ To begin the bake process, click the **Bake Lightmaps** button at the top of the
 This can take from seconds to minutes (or hours) depending on scene size, bake
 method and quality selected.
 
+.. warning::
+
+    Baking lightmaps is a process that can require a lot of video memory,
+    especially if the resulting texture is large. Due to internal limitations,
+    the engine may also crash if the generated texture size is too large (even
+    on systems with a lot of video memory).
+
+    To avoid crashes, make sure the lightmap texel size in the Import dock is
+    set to a high enough value.
+
 Tweaks
 ^^^^^^
 

BIN
tutorials/3d/img/export_as_gltf.webp


BIN
tutorials/3d/img/volumetric_fog_quad_mesh_texture.webp


+ 4 - 0
tutorials/3d/introduction_to_3d.rst

@@ -24,6 +24,10 @@ Node3D node
 Following this reasoning, the 3D engine uses the :ref:`Node3D <class_Node3D>`
 node for everything 3D.
 
+.. note:: Be aware that "Spatial" Nodes are now called "Node3D"
+   starting with Godot 4. Any Godot 3.x references to "Spatial"
+   Nodes refer to "Node3D" in Godot 4.
+
 .. image:: img/tuto_3d1.png
 
 Node3Ds have a local transform, which is relative to the parent

+ 1 - 1
tutorials/3d/lights_and_shadows.rst

@@ -141,7 +141,7 @@ object. This is called *peter-panning*:
 
 In general, increasing **Shadow Normal Bias** is preferred over increasing
 **Shadow Bias**. Increasing **Shadow Normal Bias** does not cause as much
-peter-panning as increasing **Shadow Normal Bias**, but it can still resolve
+peter-panning as increasing **Shadow Bias**, but it can still resolve
 most shadow acne issues efficiently. The downside of increasing **Shadow Normal
 Bias** is that it can make shadows appear thinner for certain objects.
 

+ 24 - 2
tutorials/3d/standard_material_3d.rst

@@ -30,7 +30,7 @@ the mesh.
 The *Material Overlay* property will render a material **over** the current one being used by
 the mesh. As an example, this can be used to put a transparent shield effect on a mesh.
 
-BaseMaterial 3D Settings
+BaseMaterial 3D settings
 ------------------------
 
 StandardMaterial3D has many settings that determine the look of a material. All of these are
@@ -372,13 +372,35 @@ such as plant leaves, grass, human ears, etc.
 Refraction
 ----------
 
-
 When refraction is enabled, it supersedes alpha blending, and Godot attempts to
 fetch information from behind the object being rendered instead. This allows
 distorting the transparency in a way similar to refraction in real life.
 
+Remember to use a transparent albedo texture (or reduce the albedo color's alpha
+channel) to make refraction visible, as refraction relies on transparency to
+have a visible effect.
+
+A normal map can optionally be specified in the **Refraction Texture** property
+to allow distorting the refraction's direction on a per-pixel basis.
+
 .. image:: img/spatial_material23.png
 
+.. note::
+
+    Refraction is implemented as a screen-space effect and forces the material
+    to be transparent. This makes the effect relatively fast, but this results
+    in some limitations:
+
+    - :ref:`Transparency sorting <doc_3d_rendering_limitations_transparency_sorting>`
+      issues may occur.
+    - The refractive material cannot refract onto itself, or onto other
+      transparent materials. A refractive material behind another transparent
+      material will be invisible.
+    - Off-screen objects cannot appear in the refraction. This is most
+      noticeable with high refraction strength values.
+    - Opaque materials in front of the refractive material will appear to have
+      "refracted" edges, even though they shouldn't.
+
 Detail
 ------
 

+ 1 - 1
tutorials/3d/using_gridmaps.rst

@@ -28,7 +28,7 @@ Creating a MeshLibrary
 ----------------------
 
 To begin, you need a :ref:`class_MeshLibrary`, which is a collection
-of individual meshes that can be used in the gridmap. Open the "MeshLibrary_Source.tscn"
+of individual meshes that can be used in the gridmap. Open the "mesh_library_source.tscn"
 scene to see an example of how to set up the mesh library.
 
 .. image:: img/gridmap_meshlibrary1.png

+ 43 - 0
tutorials/3d/volumetric_fog.rst

@@ -223,3 +223,46 @@ Custom FogVolume shaders
 This page only covers the built-in settings offered by FogMaterial. If you need
 to customize fog behavior within a FogVolume node (such as creating animated fog),
 FogVolume nodes' appearance can be customized using :ref:`doc_fog_shader`.
+
+Faking volumetric fog using quads
+---------------------------------
+
+In some cases, it may be better to use specially configured QuadMeshes as an
+alternative to volumetric fog:
+
+- Quads work with any rendering method, including Forward Mobile and Compatibility.
+- Quads do not require temporal reprojection to look smooth, which makes
+  them suited to fast-moving dynamic effects such as lasers. They can also
+  represent small details which volumetric fog cannot do efficiently.
+- Quads generally have a lower performance cost than volumetric fog.
+
+This approach has a few downsides though:
+
+- The fog effect has less realistic falloff, especially if the camera enters the fog.
+- Transparency sorting issues may occur when sprites overlap.
+- Performance will not necessarily be better than volumetric fog if there are
+  lots of sprites close to the camera.
+
+To create a QuadMesh-based fog sprite:
+
+1. Create a MeshInstance3D node with a QuadMesh resource in the **Mesh**
+   property. Set the size as desired.
+2. Create a new StandardMaterial3D in the mesh's **Material** property.
+3. In the StandardMaterial3D, set **Shading > Shading Mode** to **Unshaded**,
+   **Billboard > Mode** to **Enabled**, enable **Proximity Fade** and set
+   **Distance Fade** to **Pixel Alpha**.
+4. Set the **Albedo > Texture** to the texture below (right-click and choose **Save as…**):
+
+   .. image:: img/volumetric_fog_quad_mesh_texture.webp
+
+5. *After* setting the albedo texture, go to the Import dock, select the texture
+   and change its compression mode to **Lossless** to improve quality.
+
+The fog's color is set using the **Albedo > Color** property; its density is set
+using the color's alpha channel. For best results, you will have to adjust
+**Proximity Fade > Distance** and **Distance Fade > Max Distance** depending on
+the size of your QuadMesh.
+
+Optionally, billboarding may be left disabled if you place the quad in a way
+where all of its corners are in solid geometry. This can be useful for fogging
+large planes that the camera cannot enter, such as bottomless pits.

+ 2 - 2
tutorials/animation/animation_tree.rst

@@ -93,7 +93,7 @@ This node will execute a sub-animation and return once it finishes. Blend times
 
 .. image:: img/animtree6b.gif
 
-After setting the request and changing the animation playback, the one-shot node automatically clears the request on the next process frame by setting its [code]request[/code] value to [constant ONE_SHOT_REQUEST_NONE].
+After setting the request and changing the animation playback, the one-shot node automatically clears the request on the next process frame by setting its ``request`` value to ``AnimationNodeOneShot.ONE_SHOT_REQUEST_NONE``.
 
 .. tabs::
  .. code-tab:: gdscript GDScript
@@ -161,7 +161,7 @@ Transition
 ^^^^^^^^^^
 
 Very simple state machine (when you don't want to cope with a ``StateMachine`` node). Animations can be connected to the outputs and transition times can be specified.
-After setting the request and changing the animation playback, the transition node automatically clears the request on the next process frame by setting its [code]transition_request[/code] value to empty.
+After setting the request and changing the animation playback, the transition node automatically clears the request on the next process frame by setting its ``transition_request`` value to an empty string (``""``).
 
 .. tabs::
  .. code-tab:: gdscript GDScript

+ 2 - 0
tutorials/assets_pipeline/importing_images.rst

@@ -25,6 +25,8 @@ Godot can import the following image formats:
 - SVG (``.svg``, ``.svgz``)
   - SVGs are rasterized using `ThorVG <https://www.thorvg.org/>`__
   when importing them. Support is limited; complex vectors may not render correctly.
+  You can check whether ThorVG can render a certain vector correctly using its
+  `web-based viewer <https://www.thorvg.org/viewer>`__.
   For complex vectors, rendering them to PNGs using `Inkscape <https://inkscape.org/>`__
   is often a better solution. This can be automated thanks to its
   `command-line interface <https://wiki.inkscape.org/wiki/index.php/Using_the_Command_Line#Export_files>`__.

+ 6 - 6
tutorials/audio/recording_with_microphone.rst

@@ -65,7 +65,7 @@ and :ref:`set_recording_active() <class_AudioEffectRecord_method_set_recording_a
 .. tabs::
   .. code-tab:: gdscript GDScript
 
-    func _on_RecordButton_pressed():
+    func _on_record_button_pressed():
         if effect.is_recording_active():
             recording = effect.get_recording()
             $PlayButton.disabled = false
@@ -82,7 +82,7 @@ and :ref:`set_recording_active() <class_AudioEffectRecord_method_set_recording_a
 
   .. code-tab:: csharp
 
-    public void OnRecordButtonPressed()
+    private void OnRecordButtonPressed()
     {
         if (_effect.IsRecordingActive())
         {
@@ -114,7 +114,7 @@ the recorded stream can be stored into the ``recording`` variable by calling
 .. tabs::
   .. code-tab:: gdscript GDScript
 
-    func _on_PlayButton_pressed():
+    func _on_play_button_pressed():
         print(recording)
         print(recording.format)
         print(recording.mix_rate)
@@ -126,7 +126,7 @@ the recorded stream can be stored into the ``recording`` variable by calling
 
   .. code-tab:: csharp
 
-    public void OnPlayButtonPressed()
+    private void OnPlayButtonPressed()
     {
         GD.Print(_recording);
         GD.Print(_recording.Format);
@@ -145,14 +145,14 @@ To playback the recording, you assign the recording as the stream of the
 .. tabs::
   .. code-tab:: gdscript GDScript
 
-    func _on_SaveButton_pressed():
+    func _on_save_button_pressed():
         var save_path = $SaveButton/Filename.text
         recording.save_to_wav(save_path)
         $Status.text = "Saved WAV file to: %s\n(%s)" % [save_path, ProjectSettings.globalize_path(save_path)]
 
   .. code-tab:: csharp
 
-    public void OnSavebuttonPressed()
+    private void OnSaveButtonPressed()
     {
         string savePath = GetNode<LineEdit>("SaveButton/Filename").Text;
         _recording.SaveToWav(savePath);

+ 9 - 10
tutorials/best_practices/godot_interfaces.rst

@@ -478,7 +478,7 @@ accesses:
 
     func my_method():
         if fn:
-            fn.call_func()
+            fn.call()
 
     # parent.gd
     extends Node
@@ -486,7 +486,7 @@ accesses:
     @onready var child = $Child
 
     func _ready():
-        child.fn = funcref(self, "print_me")
+        child.fn = print_me
         child.my_method()
 
     func print_me():
@@ -499,12 +499,11 @@ accesses:
 
     public partial class Child : Node
     {
-        public FuncRef FN = null;
+        public Callable? Callable { get; set; }
 
         public void MyMethod()
         {
-            Debug.Assert(FN != null);
-            FN.CallFunc();
+            Callable?.Call();
         }
     }
 
@@ -513,18 +512,18 @@ accesses:
 
     public partial class Parent : Node
     {
-        public Node Child;
+        private Child _child;
 
         public void _Ready()
         {
-            Child = GetNode("Child");
-            Child.Set("FN", GD.FuncRef(this, "PrintMe"));
-            Child.MyMethod();
+            _child = GetNode<Child>("Child");
+            _child.Callable = Callable.From(PrintMe);
+            _child.MyMethod();
         }
 
         public void PrintMe() {
         {
-            GD.Print(GetClass());
+            GD.Print(Name);
         }
     }
 

+ 11 - 11
tutorials/best_practices/godot_notifications.rst

@@ -128,9 +128,9 @@ deltatime methods as needed.
         }
 
         // Called during every input event. Equally true for _input().
-        public void _UnhandledInput(InputEvent event)
+        public void _UnhandledInput(InputEvent @event)
         {
-            switch (event)
+            switch (@event)
             {
                 case InputEventKey:
                     if (Input.IsActionJustPressed("ui_accept"))
@@ -242,7 +242,7 @@ nodes that one might create at runtime.
     var parent_cache
 
     func connection_check():
-        return parent.has_user_signal("interacted_with")
+        return parent_cache.has_user_signal("interacted_with")
 
     func _notification(what):
         match what:
@@ -263,34 +263,34 @@ nodes that one might create at runtime.
 
     public partial class MyNode : Node
     {
-        public Node ParentCache = null;
+        private Node _parentCache;
 
         public void ConnectionCheck()
         {
-            return ParentCache.HasUserSignal("InteractedWith");
+            return _parentCache.HasUserSignal("InteractedWith");
         }
 
         public void _Notification(int what)
         {
             switch (what)
             {
-                case NOTIFICATION_PARENTED:
-                    ParentCache = GetParent();
+                case NotificationParented:
+                    _parentCache = GetParent();
                     if (ConnectionCheck())
                     {
-                        ParentCache.Connect("InteractedWith", OnParentInteractedWith);
+                        _parentCache.Connect("InteractedWith", Callable.From(OnParentInteractedWith));
                     }
                     break;
-                case NOTIFICATION_UNPARENTED:
+                case NotificationUnparented:
                     if (ConnectionCheck())
                     {
-                        ParentCache.Disconnect("InteractedWith", OnParentInteractedWith);
+                        _parentCache.Disconnect("InteractedWith", Callable.From(OnParentInteractedWith));
                     }
                     break;
             }
         }
 
-        public void OnParentInteractedWith()
+        private void OnParentInteractedWith()
         {
             GD.Print("I'm reacting to my parent's interaction!");
         }

+ 4 - 4
tutorials/best_practices/scene_organization.rst

@@ -98,10 +98,10 @@ initialize it:
      .. code-tab:: gdscript GDScript
 
        # Parent
-       $Child.func_property = funcref(object_with_method, "method_on_the_object")
+       $Child.func_property = object_with_method.method_on_the_object
 
        # Child
-       func_property.call_func() # Call parent-defined method (can come from anywhere).
+       func_property.call() # Call parent-defined method (can come from anywhere).
 
      .. code-tab:: csharp
 
@@ -233,14 +233,14 @@ in another context without any extra changes to its API.
   satisfied? Other programmers, and especially designers and writers, will need
   clear instructions in the messages telling them what to do to configure it.
 
-So, why do all this complex switcharoo work? Well, because scenes operate
+So, why does all this complex switcharoo work? Well, because scenes operate
 best when they operate alone. If unable to work alone, then working with
 others anonymously (with minimal hard dependencies, i.e. loose coupling)
 is the next best thing. Inevitably, changes may need to be made to a class and
 if these changes cause it to interact with other scenes in unforeseen ways,
 then things will start to break down. The whole point of all this indirection
 is to avoid ending up in a situation where changing one class results in
-adversely effecting other classes.
+adversely effecting other classes dependent on it.
 
 Scripts and scenes, as extensions of engine classes, should abide
 by *all* OOP principles. Examples include...

+ 5 - 5
tutorials/best_practices/scenes_versus_scripts.rst

@@ -11,8 +11,8 @@ declarative code.
 
 Each system's capabilities are different as a result.
 Scenes can define how an extended class initializes, but not what its
-behavior actually is. Scenes are often used in conjunction with a script so
-that the scene acts as an extension of the scripts declarative code.
+behavior actually is. Scenes are often used in conjunction with a script,
+the scene declaring a composition of nodes, and the script adding behaviour with imperative code.
 
 Anonymous types
 ---------------
@@ -150,13 +150,13 @@ with it, and finally adds it as a child of the ``Main`` node:
 .. tabs::
   .. code-tab:: gdscript GDScript
 
-    # Main.gd
+    # main.gd
     extends Node
 
     func _init():
         var child = Node.new()
         child.name = "Child"
-        child.script = preload("Child.gd")
+        child.script = preload("child.gd")
         child.owner = self
         add_child(child)
 
@@ -226,7 +226,7 @@ In the end, the best approach is to consider the following:
       {
           public static PackedScene MyScene { get; } = GD.Load<PackedScene>("MyScene.tscn");
       }
-      
+
       // Main.cs
       public partial class Main : Node
       {

+ 2 - 2
tutorials/best_practices/what_are_godot_classes.rst

@@ -54,8 +54,8 @@ The behavior of scenes has many similarities to classes, so it can make sense to
 a class. Scenes are reusable, instantiable, and inheritable groups of nodes. Creating a scene is
 similar to having a script that creates nodes and adds them as children using ``add_child()``.
 
-We often pair a scene with a scripted root node that makes use of the scene's nodes. As such, the
-scene is often an extension of the script's declarative code.
+We often pair a scene with a scripted root node that makes use of the scene's nodes. As such, 
+the script extends the scene by adding behavior through imperative code.
 
 The content of a scene helps to define:
 

+ 4 - 4
tutorials/editor/command_line_tutorial.rst

@@ -237,7 +237,7 @@ For example, the full command for exporting your game (as explained below) might
 
 ::
 
-    godot --path path_to_your_project --export my_export_preset_name game.exe
+    godot --path path_to_your_project --export-release my_export_preset_name game.exe
 
 Creating a project
 ------------------
@@ -332,8 +332,8 @@ that is headless (server build, no video) is ideal for this.
     # `godot` must be a Godot editor binary, not an export template.
     # Also, export templates must be installed for the editor
     # (or a valid custom export template must be defined in the export preset).
-    godot --export "Linux/X11" /var/builds/project
-    godot --export Android /var/builds/project.apk
+    godot --export-release "Linux/X11" /var/builds/project
+    godot --export-release Android /var/builds/project.apk
 
 The preset name must match the name of an export preset defined in the
 project's ``export_presets.cfg`` file. If the preset name contains spaces or
@@ -348,7 +348,7 @@ The output path extension determines the package's format, either PCK or ZIP.
 
 .. warning::
 
-    When specifying a relative path as the path for `--export`, `--export-debug`
+    When specifying a relative path as the path for `--export-release`, `--export-debug`
     or `--export-pack`, the path will be relative to the directory containing
     the ``project.godot`` file, **not** relative to the current working directory.
 

+ 1 - 1
tutorials/editor/project_settings.rst

@@ -11,6 +11,6 @@ Godot stores the project settings in a project.godot file, a plain text file in
 
 To access that dialog, select Project -> Project Settings.
 
-Once the window opens, let's select a main scene. Locate the `Application/Run/Main Scene` property and click on it to select 'Hello.tscn'.
+Once the window opens, let's select a main scene. Locate the `Application/Run/Main Scene` property and click on it to select 'hello.tscn'.
 
 The project settings dialog provides a lot of options that can be saved to a project.godot file and shows their default values. If you change a value, a tick appears to the left of its name. This means that the property will be saved in the project.godot file and remembered.

+ 27 - 4
tutorials/export/exporting_for_android.rst

@@ -148,10 +148,6 @@ Now fill in the following forms in your Android Export Presets:
 - **Release User:** Replace with the key alias.
 - **Release Password:** Key password. Note that the keystore password and the key password currently have to be the same.
 
-**Your export_presets.cfg file now contains sensitive information.** If you use
-a version control system, you should remove it from public repositories and add
-it to your ``.gitignore`` file or equivalent.
-
 Don't forget to uncheck the **Export With Debug** checkbox while exporting.
 
 .. image:: img/export-with-debug-button.png
@@ -176,3 +172,30 @@ and ARMv8 is usually sufficient to cover most devices in use today.
 You can optimize the size further by compiling an Android export template with
 only the features you need. See :ref:`doc_optimizing_for_size` for more
 information.
+
+Environment variables
+---------------------
+
+You can use the following environment variables to set export options outside of
+the editor. During the export process, these override the values that you set in
+the export menu.
+
+.. list-table:: Android export environment variables
+   :header-rows: 1
+
+   * - Export option
+     - Environment variable
+   * - Encryption / Encryption Key
+     - GODOT_SCRIPT_ENCRYPTION_KEY
+   * - Options / Keystore / Debug
+     - GODOT_ANDROID_KEYSTORE_DEBUG_PATH
+   * - Options / Keystore / Debug User
+     - GODOT_ANDROID_KEYSTORE_DEBUG_USER
+   * - Options / Keystore / Debug Password
+     - GODOT_ANDROID_KEYSTORE_DEBUG_PASSWORD
+   * - Options / Keystore / Release
+     - GODOT_ANDROID_KEYSTORE_RELEASE_PATH
+   * - Options / Keystore / Release User
+     - GODOT_ANDROID_KEYSTORE_RELEASE_USER
+   * - Options / Keystore / Release Password
+     - GODOT_ANDROID_KEYSTORE_RELEASE_PASSWORD

+ 19 - 0
tutorials/export/exporting_for_ios.rst

@@ -104,3 +104,22 @@ Plugins for iOS
 
 Special iOS plugins can be used in Godot. Check out the
 :ref:`doc_plugins_for_ios` page.
+
+Environment variables
+---------------------
+
+You can use the following environment variables to set export options outside of
+the editor. During the export process, these override the values that you set in
+the export menu.
+
+.. list-table:: iOS export environment variables
+   :header-rows: 1
+
+   * - Export option
+     - Environment variable
+   * - Encryption / Encryption Key
+     - GODOT_SCRIPT_ENCRYPTION_KEY
+   * - Options / Application / Provisioning Profile UUID Debug
+     - GODOT_IOS_PROVISIONING_PROFILE_UUID_DEBUG
+   * - Options / Application / Provisioning Profile UUID Release
+     - GODOT_IOS_PROVISIONING_PROFILE_UUID_RELEASE

+ 15 - 0
tutorials/export/exporting_for_linux.rst

@@ -17,3 +17,18 @@ Godot offers a more elegant approach for PC distribution when using the export
 system. When exporting for Linux, the exporter takes all the project files and
 creates a ``data.pck`` file. This file is bundled with a specially optimized
 binary that is smaller, faster and does not contain the editor and debugger.
+
+Environment variables
+---------------------
+
+You can use the following environment variables to set export options outside of
+the editor. During the export process, these override the values that you set in
+the export menu.
+
+.. list-table:: Linux export environment variables
+   :header-rows: 1
+
+   * - Export option
+     - Environment variable
+   * - Encryption / Encryption Key
+     - GODOT_SCRIPT_ENCRYPTION_KEY

+ 31 - 0
tutorials/export/exporting_for_macos.rst

@@ -213,3 +213,34 @@ See `App Sandbox <https://developer.apple.com/documentation/security/app_sandbox
 .. note::
 
     You can override default entitlements by selecting custom entitlements file, in this case all other entitlement are ignored.
+
+Environment variables
+---------------------
+
+You can use the following environment variables to set export options outside of
+the editor. During the export process, these override the values that you set in
+the export menu.
+
+.. list-table:: macOS export environment variables
+   :header-rows: 1
+
+   * - Export option
+     - Environment variable
+   * - Encryption / Encryption Key
+     - GODOT_SCRIPT_ENCRYPTION_KEY
+   * - Options / Codesign / Certificate File
+     - GODOT_MACOS_CODESIGN_CERTIFICATE_FILE
+   * - Options / Codesign / Certificate Password
+     - GODOT_MACOS_CODESIGN_CERTIFICATE_PASSWORD
+   * - Options / Codesign / Provisioning Profile
+     - GODOT_MACOS_CODESIGN_PROVISIONING_PROFILE
+   * - Options / Notarization / API UUID
+     - GODOT_MACOS_NOTARIZATION_API_UUID
+   * - Options / Notarization / API Key
+     - GODOT_MACOS_NOTARIZATION_API_KEY
+   * - Options / Notarization / API Key ID
+     - GODOT_MACOS_NOTARIZATION_API_KEY_ID
+   * - Options / Notarization / Apple ID Name
+     - GODOT_MACOS_NOTARIZATION_APPLE_ID_NAME
+   * - Options / Notarization / Apple ID Password
+     - GODOT_MACOS_NOTARIZATION_APPLE_ID_PASSWORD

+ 19 - 0
tutorials/export/exporting_for_uwp.rst

@@ -102,3 +102,22 @@ It's also possible to install by using the ``Add-AppxPackage`` PowerShell cmdlet
 .. note:: If you want to update your already installed app, you must
           update the version number on the new package or first uninstall
           the previous package.
+
+Environment variables
+---------------------
+
+You can use the following environment variables to set export options outside of
+the editor. During the export process, these override the values that you set in
+the export menu.
+
+.. list-table:: UWP export environment variables
+   :header-rows: 1
+
+   * - Export option
+     - Environment variable
+   * - Encryption / Encryption Key
+     - GODOT_SCRIPT_ENCRYPTION_KEY
+   * - Options / Signing / Certificate
+     - GODOT_UWP_SIGNING_CERTIFICATE
+   * - Options / Signing / Password
+     - GODOT_UWP_SIGNING_PASSWORD

+ 15 - 0
tutorials/export/exporting_for_web.rst

@@ -368,3 +368,18 @@ defaulting to ``false`` to prevent polluting the global namespace:
         // thus adding a new JavaScript global variable `SomeGlobal`
         JavaScriptBridge.Eval("var SomeGlobal = {};", true);
     }
+
+Environment variables
+---------------------
+
+You can use the following environment variables to set export options outside of
+the editor. During the export process, these override the values that you set in
+the export menu.
+
+.. list-table:: HTML5 export environment variables
+   :header-rows: 1
+
+   * - Export option
+     - Environment variable
+   * - Encryption / Encryption Key
+     - GODOT_SCRIPT_ENCRYPTION_KEY

+ 21 - 0
tutorials/export/exporting_for_windows.rst

@@ -55,3 +55,24 @@ Under options there is a code signing category.
 ``Enabled`` must be set to true, and ``Identity`` must be set to the signing
 certificate. The other settings can be adjusted as needed. Once this is Done
 Godot will sign your project on export.
+
+Environment variables
+---------------------
+
+You can use the following environment variables to set export options outside of
+the editor. During the export process, these override the values that you set in
+the export menu.
+
+.. list-table:: Windows export environment variables
+   :header-rows: 1
+
+   * - Export option
+     - Environment variable
+   * - Encryption / Encryption Key
+     - GODOT_SCRIPT_ENCRYPTION_KEY
+   * - Options / Codesign / Identity Type
+     - GODOT_WINDOWS_CODESIGN_IDENTITY_TYPE
+   * - Options / Codesign / Identity
+     - GODOT_WINDOWS_CODESIGN_IDENTITY
+   * - Options / Codesign / Password
+     - GODOT_WINDOWS_CODESIGN_PASSWORD

+ 19 - 1
tutorials/export/exporting_projects.rst

@@ -130,10 +130,28 @@ select every scene or resource you want to export.
     ``.git`` from being included in the exported PCK file.
 
 Below the list of resources are two filters that can be setup. The first allows
-non resource files such as ``.txt``,``.json`` and ``.csv`` to be exported with
+non resource files such as ``.txt``, ``.json`` and ``.csv`` to be exported with
 the project. The second filter can be used to exclude every file of a certain
 type without manually deselecting every one. For example, ``.png`` files.
 
+Configuration files
+-------------------
+
+The export configuration is stored in two files that can both be found in the project
+directory:
+
+- ``export_presets.cfg``: This file contains the vast majority of the export
+  configuration and can be safely committed to version control. There is nothing
+  in here that you would normally have to keep secret.
+- ``.godot/export_credentials.cfg``: This file contains export options that are
+  considered confidential, like passwords and encryption keys. It should generally
+  **not** be committed to version control or shared with others unless you know
+  exactly what you are doing.
+
+Since the credentials file is usually kept out of version control systems, some
+export options will be missing if you clone the project to a new machine. The easiest
+way to deal with this is to copy the file manually from the old location to the new one.
+
 Exporting from the command line
 -------------------------------
 

+ 1 - 1
tutorials/inputs/controllers_gamepads_joysticks.rst

@@ -259,7 +259,7 @@ Then, instead of using ``Input.is_action_pressed(action)``, use
 ``Focus.input_is_action_pressed(action)`` where ``action`` is the name of
 the input action. Also, instead of using ``event.is_action_pressed(action)``,
 use ``Focus.event_is_action_pressed(event, action)`` where ``event`` is an
-InputEvent reference ``action`` is the name of the input action.
+InputEvent reference and ``action`` is the name of the input action.
 
 Power saving prevention
 ^^^^^^^^^^^^^^^^^^^^^^^

BIN
tutorials/inputs/img/inputs_inputmap.png


BIN
tutorials/inputs/img/inputs_inputmap.webp


+ 19 - 11
tutorials/inputs/input_examples.rst

@@ -101,13 +101,18 @@ event scroll by in the output window. Here's an example of the output:
 ::
 
     A
-    InputEventMouseMotion : button_mask=0, position=(108, 108), relative=(26, 1), speed=(164.152496, 159.119843), pressure=(0), tilt=(0, 0)
-    InputEventMouseButton : button_index=MOUSE_BUTTON_LEFT, pressed=true, position=(108, 107), button_mask=1, doubleclick=false
-    InputEventMouseButton : button_index=MOUSE_BUTTON_LEFT, pressed=false, position=(108, 107), button_mask=0, doubleclick=false
-    S
-    F
+    Mouse motion at position ((971, 5)) with velocity ((0, 0))
+    Right Mouse Button
+    Mouse motion at position ((870, 243)) with velocity ((0.454937, -0.454937))
+    Left Mouse Button
+    Mouse Wheel Up
+    A
+    B
+    Shift
+    Alt+Shift
     Alt
-    InputEventMouseMotion : button_mask=0, position=(108, 107), relative=(0, -1), speed=(164.152496, 159.119843), pressure=(0), tilt=(0, 0)
+    Shift+T
+    Mouse motion at position ((868, 242)) with velocity ((-2.134768, 2.134768))
 
 As you can see, the results are very different for the different types of
 input. Key events are even printed as their key symbols. For example, let's
@@ -150,11 +155,14 @@ InputMap
 The :ref:`InputMap <class_InputMap>` is the most flexible way to handle a
 variety of inputs. You use this by creating named input *actions*, to which
 you can assign any number of input events, such as keypresses or mouse clicks.
-A new Godot project includes a number of default actions already defined. To
-see them, and to add your own, open Project -> Project Settings and select
+To see them, and to add your own, open Project -> Project Settings and select
 the InputMap tab:
 
-.. image:: img/inputs_inputmap.png
+.. image:: img/inputs_inputmap.webp
+
+.. tip::
+    A new Godot project includes a number of default actions already defined.
+    To see them, turn on ``Show Built-in Actions`` in the InputMap dialog.
 
 Capturing actions
 ~~~~~~~~~~~~~~~~~
@@ -240,7 +248,7 @@ different when it's :kbd:`Shift + T`:
     func _input(event):
         if event is InputEventKey and event.pressed:
             if event.keycode == KEY_T:
-                if event.shift:
+                if event.shift_pressed:
                     print("Shift+T was pressed")
                 else:
                     print("T was pressed")
@@ -254,7 +262,7 @@ different when it's :kbd:`Shift + T`:
             switch (keyEvent.Keycode)
             {
                 case Key.T:
-                    GD.Print(keyEvent.Shift ? "Shift+T was pressed" : "T was pressed");
+                    GD.Print(keyEvent.ShiftPressed ? "Shift+T was pressed" : "T was pressed");
                     break;
             }
         }

+ 41 - 281
tutorials/io/background_loading.rst

@@ -1,309 +1,69 @@
-:article_outdated: True
-
 .. _doc_background_loading:
 
 Background loading
 ==================
 
+Commonly, games need to load resources asynchronously.
 When switching the main scene of your game (e.g. going to a new
 level), you might want to show a loading screen with some indication
-that progress is being made. The main load method
-(``ResourceLoader::load`` or just ``load`` from GDScript) blocks your
-thread, making your game appear frozen and unresponsive while the resource is being loaded. This
-document discusses the alternative of using the ``ResourceInteractiveLoader`` class for smoother
-load screens.
-
-ResourceInteractiveLoader
--------------------------
-
-The ``ResourceInteractiveLoader`` class allows you to load a resource in
-stages. Every time the method ``poll`` is called, a new stage is loaded,
-and control is returned to the caller. Each stage is generally a
-sub-resource that is loaded by the main resource. For example, if you're
-loading a scene that loads 10 images, each image will be one stage.
-
-Usage
------
-
-Usage is generally as follows
-
-Obtaining a ResourceInteractiveLoader
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-.. code-block:: cpp
-
-    Ref<ResourceInteractiveLoader> ResourceLoader::load_interactive(String p_path);
-
-This method will give you a ResourceInteractiveLoader that you will use
-to manage the load operation.
-
-Polling
-~~~~~~~
-
-.. code-block:: cpp
+that progress is being made, or you may want to load additional resources
+during gameplay.
 
-    Error ResourceInteractiveLoader::poll();
+The standard load method
+(:ref:`ResourceLoader.load <class_ResourceLoader_method_load>` or GDScript's simpler
+:ref:`load <class_@GDScript_method_load>`) blocks your
+thread, making your game appear unresponsive while the resource is being loaded.
 
-Use this method to advance the progress of the load. Each call to
-``poll`` will load the next stage of your resource. Keep in mind that
-each stage is one entire "atomic" resource, such as an image, or a mesh,
-so it will take several frames to load.
+One way around this is using ``ResourceLoader`` to load resources asynchronously
+in background threads.
 
-Returns ``OK`` on no errors, ``ERR_FILE_EOF`` when loading is finished.
-Any other return value means there was an error and loading has stopped.
+Using ResourceLoader
+--------------------
 
-Load progress (optional)
-~~~~~~~~~~~~~~~~~~~~~~~~
+Generally, you queue requests to load resources for a path using
+:ref:`ResourceLoader.load_threaded_request <class_ResourceLoader_method_load_threaded_request>`,
+which will then be loaded in threads in the background.
 
-To query the progress of the load, use the following methods:
+You can check the status with
+:ref:`ResourceLoader.load_threaded_get_status <class_ResourceLoader_method_load_threaded_get_status>`.
+Progress can be obtained by passing an array variable via progress which will return
+a one element array containing the percentage.
 
-.. code-block:: cpp
+Finally, you retrieved loaded resources by calling
+:ref:`ResourceLoader.load_threaded_get <class_ResourceLoader_method_load_threaded_get>`.
 
-    int ResourceInteractiveLoader::get_stage_count() const;
-    int ResourceInteractiveLoader::get_stage() const;
-
-``get_stage_count`` returns the total number of stages to load.
-``get_stage`` returns the current stage being loaded.
-
-Forcing completion (optional)
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-.. code-block:: cpp
-
-    Error ResourceInteractiveLoader::wait();
-
-Use this method if you need to load the entire resource in the current
-frame, without any more steps.
-
-Obtaining the resource
-~~~~~~~~~~~~~~~~~~~~~~
-
-.. code-block:: cpp
-
-    Ref<Resource> ResourceInteractiveLoader::get_resource();
-
-If everything goes well, use this method to retrieve your loaded
-resource.
+Once you call ``load_threaded_get()``, either the resource finished loading in
+the background and will be returned instantly or the load will block at this point like
+``load()`` would. If you want to guarantee this does not block,
+you either need to ensure there is enough time between requesting the load and
+retrieving the resource or you need to check the status manually.
 
 Example
 -------
 
-This example demonstrates how to load a new scene. Consider it in the
-context of the :ref:`doc_singletons_autoload` example.
+This example demonstrates how to load a scene in the background.
+We will have a button spawn a enemy when pressed.
+The enemy will be ``Enemy.tscn`` which we will load on ``_ready`` and instantiate when pressed.
+The path will be ``"Enemy.tscn"`` which is located at ``res://Enemy.tscn``.
 
-First, we set up some variables and initialize the ``current_scene``
-with the main scene of the game:
+First, we will start a request to load the resource and connect the button:
 
 ::
 
-    var loader
-    var wait_frames
-    var time_max = 100 # msec
-    var current_scene
-
+    const ENEMY_SCENE_PATH : String = "Enemy.tscn"
 
     func _ready():
-        var root = get_tree().get_root()
-        current_scene = root.get_child(root.get_child_count() -1)
-
-The function ``goto_scene`` is called from the game when the scene
-needs to be switched. It requests an interactive loader, and calls
-``set_process(true)`` to start polling the loader in the ``_process``
-callback. It also starts a "loading" animation, which could show a
-progress bar or loading screen.
-
-::
-
-    func goto_scene(path): # Game requests to switch to this scene.
-        loader = ResourceLoader.load_interactive(path)
-        if loader == null: # Check for errors.
-            show_error()
-            return
-        set_process(true)
-
-        current_scene.queue_free() # Get rid of the old scene.
-
-        # Start your "loading..." animation.
-        get_node("animation").play("loading")
-
-        wait_frames = 1
-
-``_process`` is where the loader is polled. ``poll`` is called, and then
-we deal with the return value from that call. ``OK`` means keep polling,
-``ERR_FILE_EOF`` means loading is done, anything else means there was an
-error. Also note we skip one frame (via ``wait_frames``, set on the
-``goto_scene`` function) to allow the loading screen to show up.
-
-Note how we use ``OS.get_ticks_msec`` to control how long we block the
-thread. Some stages might load fast, which means we might be able
-to cram more than one call to ``poll`` in one frame; some might take way
-more than your value for ``time_max``, so keep in mind we won't have
-precise control over the timings.
-
-::
-
-    func _process(time):
-        if loader == null:
-            # no need to process anymore
-            set_process(false)
-            return
-
-        # Wait for frames to let the "loading" animation show up.
-        if wait_frames > 0:
-            wait_frames -= 1
-            return
-
-        var t = OS.get_ticks_msec()
-        # Use "time_max" to control for how long we block this thread.
-        while OS.get_ticks_msec() < t + time_max:
-            # Poll your loader.
-            var err = loader.poll()
-
-            if err == ERR_FILE_EOF: # Finished loading.
-                var resource = loader.get_resource()
-                loader = null
-                set_new_scene(resource)
-                break
-            elif err == OK:
-                update_progress()
-            else: # Error during loading.
-                show_error()
-                loader = null
-                break
-
-Some extra helper functions. ``update_progress`` updates a progress bar,
-or can also update a paused animation (the animation represents the
-entire load process from beginning to end). ``set_new_scene`` puts the
-newly loaded scene on the tree. Because it's a scene being loaded,
-``instance()`` needs to be called on the resource obtained from the
-loader.
-
-::
-
-    func update_progress():
-        var progress = float(loader.get_stage()) / loader.get_stage_count()
-        # Update your progress bar?
-        get_node("progress").set_progress(progress)
-
-        # ...or update a progress animation?
-        var length = get_node("animation").get_current_animation_length()
+        ResourceLoader.load_threaded_request(ENEMY_SCENE_PATH)
+        self.pressed.connect(_on_button_pressed)
 
-        # Call this on a paused animation. Use "true" as the second argument to
-        # force the animation to update.
-        get_node("animation").seek(progress * length, true)
-
-
-    func set_new_scene(scene_resource):
-        current_scene = scene_resource.instantiate()
-        get_node("/root").add_child(current_scene)
-
-Using multiple threads
-----------------------
-
-ResourceInteractiveLoader can be used from multiple threads. A couple of
-things to keep in mind if you attempt it:
-
-Use a semaphore
-~~~~~~~~~~~~~~~
-
-While your thread waits for the main thread to request a new resource,
-use a ``Semaphore`` to sleep (instead of a busy loop or anything similar).
-
-Not blocking main thread during the polling
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-If you have a mutex to allow calls from the main thread to your loader
-class, don't lock the main thread while you call ``poll`` on your loader class. When a
-resource is done loading, it might require some resources from the
-low-level APIs (RenderingServer, etc), which might need to lock the main
-thread to acquire them. This might cause a deadlock if the main thread
-is waiting for your mutex while your thread is waiting to load a
-resource.
-
-Example class
--------------
-
-You can find an example class for loading resources in threads here:
-:download:`resource_queue.gd <files/resource_queue.gd>`. Usage is as follows:
+Now ``_on_button_pressed`` will be called when the button is pressed.
+This method will be used to spawn an enemy.
 
 ::
 
-    func start()
-
-Call after you instance the class to start the thread.
-
-::
-
-    func queue_resource(path, p_in_front = false)
-
-Queue a resource. Use optional argument "p_in_front" to put it in
-front of the queue.
-
-::
-
-    func cancel_resource(path)
-
-Remove a resource from the queue, discarding any loading done.
-
-::
-
-    func is_ready(path)
-
-Returns ``true`` if a resource is fully loaded and ready to be retrieved.
-
-::
-
-    func get_progress(path)
-
-Get the progress of a resource. Returns -1 if there was an error (for example if the
-resource is not in the queue), or a number between 0.0 and 1.0 with the
-progress of the load. Use mostly for cosmetic purposes (updating
-progress bars, etc), use ``is_ready`` to find out if a resource is
-actually ready.
-
-::
-
-    func get_resource(path)
-
-Returns the fully loaded resource, or ``null`` on error. If the resource is
-not fully loaded (``is_ready`` returns ``false``), it will block your thread
-and finish the load. If the resource is not on the queue, it will call
-``ResourceLoader::load`` to load it normally and return it.
-
-Example:
-~~~~~~~~
-
-::
-
-    # Initialize.
-    queue = preload("res://resource_queue.gd").new()
-    queue.start()
-
-    # Suppose your game starts with a 10 second cutscene, during which the user
-    # can't interact with the game.
-    # For that time, we know they won't use the pause menu, so we can queue it
-    # to load during the cutscene:
-    queue.queue_resource("res://pause_menu.tres")
-    start_cutscene()
-
-    # Later, when the user presses the pause button for the first time:
-    pause_menu = queue.get_resource("res://pause_menu.tres").instantiate()
-    pause_menu.show()
-
-    # When you need a new scene:
-    queue.queue_resource("res://level_1.tscn", true)
-    # Use "true" as the second argument to put it at the front of the queue,
-    # pausing the load of any other resource.
-
-    # To check progress.
-    if queue.is_ready("res://level_1.tscn"):
-        show_new_level(queue.get_resource("res://level_1.tscn"))
-    else:
-        update_progress(queue.get_progress("res://level_1.tscn"))
-
-    # When the user walks away from the trigger zone in your Metroidvania game:
-    queue.cancel_resource("res://zone_2.tscn")
-
-**Note**: this code, in its current form, is not tested in real world
-scenarios. If you run into any issues, ask for help in one of
-`Godot's community channels <https://godotengine.org/community>`__.
+    func _on_button_pressed(): # Button was pressed
+        # Obtain the resource now that we need it
+        var enemy_scene = ResourceLoader.load_threaded_get(ENEMY_SCENE_PATH)
+        # Instantiate the enemy scene and add it to the current scene
+        var enemy = enemy_scene.instantiate()
+        add_child(enemy)

+ 5 - 5
tutorials/math/matrices_and_transforms.rst

@@ -563,21 +563,21 @@ transformations:
     // The transform is the identity transform.
 
 Transforming a position by a transform and its inverse results in the
-same position (same for "xform_inv"):
+same position:
 
 .. tabs::
  .. code-tab:: gdscript GDScript
 
     var ti = transform.affine_inverse()
-    position = transform.xform(position)
-    position = ti.xform(position)
+    position = transform * position
+    position = ti * position
     # The position is the same as before.
 
  .. code-tab:: csharp
 
     Transform2D ti = Transform.AffineInverse();
-    Position = Transform.Xform(Position);
-    Position = ti.Xform(Position);
+    Position = Transform * Position;
+    Position = ti * Position;
     // The position is the same as before.
 
 How does it all work in 3D?

+ 1 - 1
tutorials/migrating/upgrading_to_godot_4.rst

@@ -430,7 +430,7 @@ table to find its new name.
 - MultiPlayerAPI's ``get_network_unique_id()`` is now ``get_unique_id()``.
 - MultiPlayerAPI's ``has_network_peer()`` is now ``has_multiplayer_peer()``.
 - PacketPeerUDP's ``is_listening()`` is now ``is_bound()``.
-- PacketPeerUDP's ``listen()`` is now ``bound()``.
+- PacketPeerUDP's ``listen()`` is now ``bind()``.
 - ParticleProcessMaterial's ``set_flag()`` is now ``set_particle_flag()``.
 - ResourceFormatLoader's ``get_dependencies()`` is now ``_get_dependencies()``
   (note the leading underscore, which denotes a virtual method).

+ 1 - 1
tutorials/navigation/navigation_introduction_3d.rst

@@ -157,7 +157,7 @@ a NavigationAgent3D for path movement.
         new_velocity = new_velocity.normalized()
         new_velocity = new_velocity * movement_speed
 
-        velocity = safe_velocity
+        velocity = new_velocity
         move_and_slide()
 
  .. code-tab:: csharp C#

+ 1 - 2
tutorials/performance/cpu_optimization.rst

@@ -191,8 +191,7 @@ Other languages
 ~~~~~~~~~~~~~~~
 
 Third parties provide support for several other languages, including `Rust
-<https://github.com/godot-rust/godot-rust>`_ and `Javascript
-<https://github.com/GodotExplorer/ECMAScript>`_.
+<https://github.com/godot-rust/gdext>`_.
 
 C++
 ~~~

+ 24 - 18
tutorials/physics/kinematic_character_2d.rst

@@ -65,9 +65,9 @@ or lose precision if the frame rate is too high or too low.
 
     using Godot;
 
-    public partial class PhysicsScript : CharacterBody2D
+    public partial class MyCharacterBody2D : CharacterBody2D
     {
-        public override void _PhysicsProcess(float delta)
+        public override void _PhysicsProcess(double delta)
         {
         }
     }
@@ -129,9 +129,9 @@ So, let's move our sprite downwards until it hits the floor:
 
     using Godot;
 
-    public partial class PhysicsScript : CharacterBody2D
+    public partial class MyCharacterBody2D : CharacterBody2D
     {
-        public override void _PhysicsProcess(float delta)
+        public override void _PhysicsProcess(double delta)
         {
             // Move down 1 pixel per physics frame
             MoveAndCollide(new Vector2(0, 1));
@@ -161,15 +161,17 @@ little more like a regular game character:
 
     using Godot;
 
-    public partial class PhysicsScript : CharacterBody2D
+    public partial class MyCharacterBody2D : CharacterBody2D
     {
-        const float gravity = 200.0f;
+        private const float Gravity = 200.0f;
 
-        public override void _PhysicsProcess(float delta)
+        public override void _PhysicsProcess(double delta)
         {
-            velocity.y += delta * gravity;
+            var velocity = Velocity;
+            velocity.Y += (float)delta * Gravity;
+            Velocity = velocity;
 
-            var motion = velocity * delta;
+            var motion = velocity * (float)delta;
             MoveAndCollide(motion);
         }
     }
@@ -205,30 +207,34 @@ This adds basic support for walking when pressing left and right:
 
     using Godot;
 
-    public partial class PhysicsScript : CharacterBody2D
+    public partial class MyCharacterBody2D : CharacterBody2D
     {
-        const float gravity = 200.0f;
-        const int walkSpeed = 200;
+        private const float Gravity = 200.0f;
+        private const int WalkSpeed = 200;
 
-        public override void _PhysicsProcess(float delta)
+        public override void _PhysicsProcess(double delta)
         {
-            velocity.y += delta * gravity;
+            var velocity = Velocity;
+
+            velocity.Y += (float)delta * Gravity;
 
             if (Input.IsActionPressed("ui_left"))
             {
-                velocity.x = -walkSpeed;
+                velocity.X = -WalkSpeed;
             }
             else if (Input.IsActionPressed("ui_right"))
             {
-                velocity.x = walkSpeed;
+                velocity.X = WalkSpeed;
             }
             else
             {
-                velocity.x = 0;
+                velocity.X = 0;
             }
 
+            Velocity = velocity;
+
             // "MoveAndSlide" already takes delta time into account.
-            MoveAndSlide(velocity, new Vector2(0, -1));
+            MoveAndSlide();
         }
     }
 

+ 19 - 14
tutorials/physics/physics_introduction.rst

@@ -286,19 +286,19 @@ For example, here is the code for an "Asteroids" style spaceship:
         private Vector2 _thrust = new Vector2(0, -250);
         private float _torque = 20000;
 
-        public override void _IntegrateForces(Physics2DDirectBodyState state)
+        public override void _IntegrateForces(PhysicsDirectBodyState2D state)
         {
             if (Input.IsActionPressed("ui_up"))
-                AppliedForce = _thrust.Rotated(Rotation);
+                state.ApplyForce(_thrust.Rotated(Rotation));
             else
-                AppliedForce = new Vector2();
+                state.ApplyForce(new Vector2());
 
             var rotationDir = 0;
             if (Input.IsActionPressed("ui_right"))
                 rotationDir += 1;
             if (Input.IsActionPressed("ui_left"))
                 rotationDir -= 1;
-            AppliedTorque = rotationDir * _torque;
+            state.ApplyTorque(rotationDir * _torque);
         }
     }
 
@@ -378,9 +378,9 @@ occurred:
     {
         private Vector2 _velocity = new Vector2(250, 250);
 
-        public override void _PhysicsProcess(float delta)
+        public override void _PhysicsProcess(double delta)
         {
-            var collisionInfo = MoveAndCollide(_velocity * delta);
+            var collisionInfo = MoveAndCollide(_velocity * (float)delta);
             if (collisionInfo != null)
             {
                 var collisionPoint = collisionInfo.GetPosition();
@@ -410,9 +410,9 @@ Or to bounce off of the colliding object:
     {
         private Vector2 _velocity = new Vector2(250, 250);
 
-        public override void _PhysicsProcess(float delta)
+        public override void _PhysicsProcess(double delta)
         {
-            var collisionInfo = MoveAndCollide(_velocity * delta);
+            var collisionInfo = MoveAndCollide(_velocity * (float)delta);
             if (collisionInfo != null)
                 _velocity = _velocity.Bounce(collisionInfo.Normal);
         }
@@ -473,23 +473,28 @@ the ground (including slopes) and jump when standing on the ground:
 
         private void GetInput()
         {
-            _velocity.x = 0;
+            var velocity = Velocity;
+            velocity.X = 0;
 
             var right = Input.IsActionPressed("ui_right");
             var left = Input.IsActionPressed("ui_left");
             var jump = Input.IsActionPressed("ui_select");
 
             if (IsOnFloor() && jump)
-                _velocity.y = _jumpSpeed;
+                velocity.Y = _jumpSpeed;
             if (right)
-                _velocity.x += _runSpeed;
+                velocity.X += _runSpeed;
             if (left)
-                _velocity.x -= _runSpeed;
+                velocity.X -= _runSpeed;
+
+            Velocity = velocity;
         }
 
-        public override void _PhysicsProcess(float delta)
+        public override void _PhysicsProcess(double delta)
         {
-            _velocity.y += _gravity * delta;
+            var velocity = Velocity;
+            velocity.Y += _gravity * (float)delta;
+            Velocity = velocity;
             GetInput();
             MoveAndSlide();
         }

+ 3 - 4
tutorials/physics/using_area_2d.rst

@@ -59,7 +59,7 @@ Here's the node setup for the coin:
 
 .. image:: img/area2d_coin_nodes.png
 
-To detect the overlap, we'll connect the appropriate signal on the Area2d. Which
+To detect the overlap, we'll connect the appropriate signal on the Area2D. Which
 signal to use depends on the player's node type. If the player is another area,
 use ``area_entered``. However, let's assume our player is a ``CharacterBody2D``
 (and therefore a ``CollisionObject2D`` type), so we'll connect the
@@ -73,7 +73,7 @@ use ``area_entered``. However, let's assume our player is a ``CharacterBody2D``
 
     extends Area2D
 
-    func _on_Coin_body_entered(body):
+    func _on_coin_body_entered(body):
         queue_free()
 
  .. code-tab:: csharp
@@ -82,8 +82,7 @@ use ``area_entered``. However, let's assume our player is a ``CharacterBody2D``
 
     public partial class Coin : Area2D
     {
-
-        public void OnCoinBodyEntered(PhysicsBody2D body)
+        private void OnCoinBodyEntered(PhysicsBody2D body)
         {
             QueueFree();
         }

+ 19 - 22
tutorials/physics/using_character_body_2d.rst

@@ -70,10 +70,6 @@ The ``move_and_slide()`` method is intended to simplify the collision
 response in the common case where you want one body to slide along the other.
 It is especially useful in platformers or top-down games, for example.
 
-.. tip:: ``move_and_slide()`` automatically calculates frame-based movement
-         using ``delta``. Do *not* multiply your velocity vector by ``delta``
-         before passing it to ``move_and_slide()``.
-
 When calling ``move_and_slide()``, the function uses a number of node properties
 to calculate its slide behavior. These properties can be found in the Inspector,
 or set in code.
@@ -191,8 +187,9 @@ the same collision response:
     var collision = MoveAndCollide(Velocity * (float)delta);
     if (collision != null)
     {
-        velocity = velocity.Slide(collision.GetNormal());
+        Velocity = Velocity.Slide(collision.GetNormal());
     }
+
     // using MoveAndSlide
     MoveAndSlide();
 
@@ -223,7 +220,7 @@ To see these examples in action, download the sample project:
 Movement and walls
 ~~~~~~~~~~~~~~~~~~
 
-If you've downloaded the sample project, this example is in "BasicMovement.tscn".
+If you've downloaded the sample project, this example is in "basic_movement.tscn".
 
 For this example, add a ``CharacterBody2D`` with two children: a ``Sprite2D`` and a
 ``CollisionShape2D``. Use the Godot "icon.png" as the Sprite2D's texture (drag it
@@ -254,14 +251,14 @@ Attach a script to the CharacterBody2D and add the following code:
 
     using Godot;
 
-    public partial class CBExample : CharacterBody2D
+    public partial class MyCharacterBody2D : CharacterBody2D
     {
-        public int Speed = 300;
+        private int _speed = 300;
 
         public void GetInput()
         {
             Vector2 inputDir = Input.GetVector("ui_left", "ui_right", "ui_up", "ui_down");
-            Velocity = inputDir * Speed;
+            Velocity = inputDir * _speed;
         }
 
         public override void _PhysicsProcess(double delta)
@@ -295,7 +292,7 @@ to get the behavior you want.
 Bouncing/reflecting
 ~~~~~~~~~~~~~~~~~~~
 
-What if you don't want a sliding collision response? For this example ("BounceandCollide.tscn"
+What if you don't want a sliding collision response? For this example ("bounce_and_collide.tscn"
 in the sample project), we have a character shooting bullets and we want the bullets to
 bounce off the walls.
 
@@ -310,7 +307,7 @@ uses the mouse pointer. Here is the code for the Player, using ``move_and_slide(
 
     extends CharacterBody2D
 
-    var Bullet = preload("res://Bullet.tscn")
+    var Bullet = preload("res://bullet.tscn")
     var speed = 200
 
     func get_input():
@@ -338,16 +335,16 @@ uses the mouse pointer. Here is the code for the Player, using ``move_and_slide(
 
     using Godot;
 
-    public partial class CBExample : CharacterBody2D
+    public partial class MyCharacterBody2D : CharacterBody2D
     {
-        private PackedScene _bullet = (PackedScene)GD.Load("res://Bullet.tscn");
-        public int Speed = 200;
+        private PackedScene _bullet = (PackedScene)GD.Load("res://bullet.tscn");
+        private int _speed = 200;
 
         public void GetInput()
         {
             // Add these actions in Project Settings -> Input Map.
             float inputDir = Input.GetAxis("backward", "forward");
-            Velocity = Transform.x * inputDir * Speed;
+            Velocity = Transform.X * inputDir * _speed;
             if (Input.IsActionPressed("shoot"))
             {
                 Shoot();
@@ -407,7 +404,7 @@ And the code for the Bullet:
 
     public partial class Bullet : CharacterBody2D
     {
-        public int Speed = 750;
+        public int _speed = 750;
 
         public void Start(Vector2 position, float direction)
         {
@@ -429,7 +426,7 @@ And the code for the Bullet:
             }
         }
 
-        public void OnVisibilityNotifier2DScreenExited()
+        private void OnVisibilityNotifier2DScreenExited()
         {
             // Deletes the bullet when it exits the screen.
             QueueFree();
@@ -494,10 +491,10 @@ Here's the code for the player body:
 
     using Godot;
 
-    public partial class CBExample : CharacterBody2D
+    public partial class MyCharacterBody2D : CharacterBody2D
     {
-        public float Speed = 100.0f;
-        public float JumpSpeed = -400.0f;
+        private float _speed = 100.0f;
+        private float _jumpSpeed = -400.0f;
 
         // Get the gravity from the project settings so you can sync with rigid body nodes.
         public float Gravity = ProjectSettings.GetSetting("physics/2d/default_gravity").AsSingle();
@@ -511,11 +508,11 @@ Here's the code for the player body:
 
             // Handle jump.
             if (Input.IsActionJustPressed("jump") && IsOnFloor())
-                velocity.Y = JumpSpeed;
+                velocity.Y = _jumpSpeed;
 
             // Get the input direction.
             Vector2 direction = Input.GetAxis("ui_left", "ui_right");
-            velocity.X = direction * Speed;
+            velocity.X = direction * _speed;
 
             Velocity = velocity;
             MoveAndSlide();

+ 12 - 12
tutorials/platform/android/android_in_app_purchases.rst

@@ -60,8 +60,8 @@ Initialization example:
             payment.price_change_acknowledged.connect(_on_price_acknowledged) # Response ID (int)
             payment.purchases_updated.connect(_on_purchases_updated) # Purchases (Dictionary[])
             payment.purchase_error.connect(_on_purchase_error) # Response ID (int), Debug message (string)
-            payment.sku_details_query_completed.connect(_on_sku_details_query_completed) # SKUs (Dictionary[])
-            payment.sku_details_query_error.connect(_on_sku_details_query_error) # Response ID (int), Debug message (string), Queried SKUs (string[])
+            payment.product_details_query_completed.connect(_on_product_details_query_completed) # Products (Dictionary[])
+            payment.product_details_query_error.connect(_on_product_details_query_error) # Response ID (int), Debug message (string), Queried SKUs (string[])
             payment.purchase_acknowledged.connect(_on_purchase_acknowledged) # Purchase token (string)
             payment.purchase_acknowledgement_error.connect(_on_purchase_acknowledgement_error) # Response ID (int), Debug message (string), Purchase token (string)
             payment.purchase_consumed.connect(_on_purchase_consumed) # Purchase token (string)
@@ -108,13 +108,13 @@ Example use of ``querySkuDetails()``:
     func _on_connected():
       payment.querySkuDetails(["my_iap_item"], "inapp") # "subs" for subscriptions
 
-    func _on_sku_details_query_completed(sku_details):
-      for available_sku in sku_details:
-        print(available_sku)
+    func _on_product_details_query_completed(product_details):
+      for available_product in product_details:
+        print(available_product)
 
-    func _on_sku_details_query_error(response_id, error_message, skus_queried):
-        print("on_sku_details_query_error id:", response_id, " message: ",
-                error_message, " skus: ", skus_queried)
+    func _on_product_details_query_error(response_id, error_message, products_queried):
+        print("on_product_details_query_error id:", response_id, " message: ",
+                error_message, " products: ", products_queried)
 
 
 Query user purchases
@@ -214,9 +214,9 @@ Purchase fields:
     // PBL V4 replaced getSku with getSkus to support multi-sku purchases,
     // use the first entry for "sku" and generate an array for "skus"
     ArrayList<String> skus = purchase.getSkus();
-    dictionary.put("sku", skus.get(0));
+    dictionary.put("sku", skus.get(0)); # Not available in plugin
     String[] skusArray = skus.toArray(new String[0]);
-    dictionary.put("skus", skusArray);
+    dictionary.put("products", productsArray);
     dictionary.put("is_acknowledged", purchase.isAcknowledged());
     dictionary.put("is_auto_renewing", purchase.isAutoRenewing());
 
@@ -263,7 +263,7 @@ Example use of ``consumePurchase()``:
 ::
 
     func _process_purchase(purchase):
-        if purchase.sku == "my_consumable_iap_item" and purchase.purchase_state == PurchaseState.PURCHASED:
+        if "my_consumable_iap_item" in purchase.products and purchase.purchase_state == PurchaseState.PURCHASED:
             # Add code to store payment so we can reconcile the purchase token
             # in the completion callback against the original purchase
             payment.consumePurchase(purchase.purchase_token)
@@ -297,7 +297,7 @@ Example use of ``acknowledgePurchase()``:
 ::
 
     func _process_purchase(purchase):
-        if purchase.sku == "my_one_time_iap_item" and \
+        if "my_one_time_iap_item" in purchase.products and \
                 purchase.purchase_state == PurchaseState.PURCHASED and \
                 not purchase.is_acknowledged:
             # Add code to store payment so we can reconcile the purchase token

+ 7 - 7
tutorials/plugins/editor/3d_gizmos.rst

@@ -30,7 +30,7 @@ This would be a basic setup:
 
 ::
 
-    # MyCustomGizmoPlugin.gd
+    # my_custom_gizmo_plugin.gd
     extends EditorNode3DGizmoPlugin
 
 
@@ -45,7 +45,7 @@ This would be a basic setup:
     extends EditorPlugin
 
 
-    const MyCustomGizmoPlugin = preload("res://addons/my-addon/MyCustomGizmoPlugin.gd")
+    const MyCustomGizmoPlugin = preload("res://addons/my-addon/my_custom_gizmo_plugin.gd")
 
     var gizmo_plugin = MyCustomGizmoPlugin.new()
 
@@ -126,7 +126,7 @@ So the final plugin would look somewhat like this:
     extends EditorNode3DGizmoPlugin
 
 
-    const MyCustomNode3D = preload("res://addons/my-addon/MyCustomNode3D.gd")
+    const MyCustomNode3D = preload("res://addons/my-addon/my_custom_node_3d.gd")
 
 
     func _init():
@@ -177,12 +177,12 @@ for the Node3D nodes we want to target.
 
 ::
 
-    # MyCustomGizmoPlugin.gd
+    # my_custom_gizmo_plugin.gd
     extends EditorNode3DGizmoPlugin
 
 
-    const MyCustomNode3D = preload("res://addons/my-addon/MyCustomNode3D.gd")
-    const MyCustomGizmo = preload("res://addons/my-addon/MyCustomGizmo.gd")
+    const MyCustomNode3D = preload("res://addons/my-addon/my_custom_node_3d.gd")
+    const MyCustomGizmo = preload("res://addons/my-addon/my_custom_gizmo.gd")
 
 
     func _init():
@@ -201,7 +201,7 @@ This way all the gizmo logic and drawing methods can be implemented in a new cla
 
 ::
 
-    # MyCustomGizmo.gd
+    # my_custom_gizmo.gd
     extends EditorNode3DGizmo
 
 

BIN
tutorials/plugins/editor/img/installing_plugins_assetlib_tab.png


BIN
tutorials/plugins/editor/img/installing_plugins_assetlib_tab.webp


BIN
tutorials/plugins/editor/img/installing_plugins_project_settings.png


BIN
tutorials/plugins/editor/img/installing_plugins_project_settings.webp


BIN
tutorials/plugins/editor/img/making_plugins-create_plugin_dialog.png


BIN
tutorials/plugins/editor/img/making_plugins-create_plugin_dialog.webp


BIN
tutorials/plugins/editor/img/making_plugins-custom_dock.png


BIN
tutorials/plugins/editor/img/making_plugins-custom_dock.webp


BIN
tutorials/plugins/editor/img/making_plugins-custom_node_console.png


BIN
tutorials/plugins/editor/img/making_plugins-custom_node_console.webp


BIN
tutorials/plugins/editor/img/making_plugins-custom_node_create.png


BIN
tutorials/plugins/editor/img/making_plugins-custom_node_create.webp


BIN
tutorials/plugins/editor/img/making_plugins-my_custom_dock_scene.png


BIN
tutorials/plugins/editor/img/making_plugins-my_custom_dock_scene.webp


BIN
tutorials/plugins/editor/img/making_plugins-my_custom_mode_folder.png


BIN
tutorials/plugins/editor/img/making_plugins-my_custom_mode_folder.webp


BIN
tutorials/plugins/editor/img/making_plugins-project_settings.png


BIN
tutorials/plugins/editor/img/making_plugins-project_settings.webp


+ 13 - 15
tutorials/plugins/editor/import_plugins.rst

@@ -195,7 +195,7 @@ plugin:
 
 ::
 
-    func get_preset_count():
+    func _get_preset_count():
         return Presets.size()
 
 The :ref:`_get_preset_count() <class_EditorImportPlugin_method__get_preset_count>` method
@@ -205,8 +205,8 @@ now, but we can make this method future-proof by returning the size of our
 
 ::
 
-    func _get_preset_name(preset):
-        match preset:
+    func _get_preset_name(preset_index):
+        match preset_index:
             Presets.DEFAULT:
                 return "Default"
             _:
@@ -228,8 +228,8 @@ you do this you have to be careful when you add more presets.
 
 ::
 
-    func _get_import_options(preset):
-        match preset:
+    func _get_import_options(path, preset_index):
+        match preset_index:
             Presets.DEFAULT:
                 return [{
                            "name": "use_red_anyway",
@@ -260,20 +260,20 @@ shows the possible keys:
 
 The ``name`` and ``default_value`` keys are **mandatory**, the rest are optional.
 
-Note that the ``get_import_options`` method receives the preset number, so you
+Note that the ``_get_import_options`` method receives the preset number, so you
 can configure the options for each different preset (especially the default
 value). In this example we use the ``match`` statement, but if you have lots of
 options and the presets only change the value you may want to create the array
 of options first and then change it based on the preset.
 
-.. warning:: The ``get_import_options`` method is called even if you don't
-             define presets (by making ``get_preset_count`` return zero). You
+.. warning:: The ``_get_import_options`` method is called even if you don't
+             define presets (by making ``_get_preset_count`` return zero). You
              have to return an array even it's empty, otherwise you can get
              errors.
 
 ::
 
-    func _get_option_visibility(option, options):
+    func _get_option_visibility(path, option_name, options):
         return true
 
 For the
@@ -300,8 +300,6 @@ method. Our sample code is a bit long, so let's split in a few parts:
 
         var line = file.get_line()
 
-        file.close()
-
 The first part of our import method opens and reads the source file. We use the
 :ref:`FileAccess <class_FileAccess>` class to do that, passing the ``source_file``
 parameter which is provided by the editor.
@@ -340,13 +338,13 @@ as the value we got before.
 
 ::
 
-    return ResourceSaver.save(material, "%s.%s" % [save_path, get_save_extension()])
+    return ResourceSaver.save(material, "%s.%s" % [save_path, _get_save_extension()])
 
 This is the last part and quite an important one, because here we save the made
 resource to the disk. The path of the saved file is generated and informed by
 the editor via the ``save_path`` parameter. Note that this comes **without** the
 extension, so we add it using :ref:`string formatting <doc_gdscript_printf>`. For
-this we call the ``get_save_extension`` method that we defined earlier, so we
+this we call the ``_get_save_extension`` method that we defined earlier, so we
 can be sure that they won't get out of sync.
 
 We also return the result from the
@@ -376,7 +374,7 @@ would need to do something like the following:
 ::
 
     r_platform_variants.push_back("mobile")
-    return ResourceSaver.save(mobile_material, "%s.%s.%s" % [save_path, "mobile", get_save_extension()])
+    return ResourceSaver.save(mobile_material, "%s.%s.%s" % [save_path, "mobile", _get_save_extension()])
 
 The ``r_gen_files`` argument is meant for extra files that are generated during
 your import process and need to be kept. The editor will look at it to
@@ -391,7 +389,7 @@ in a different file:
 
     var next_pass = StandardMaterial3D.new()
     next_pass.albedo_color = color.inverted()
-    var next_pass_path = "%s.next_pass.%s" % [save_path, get_save_extension()]
+    var next_pass_path = "%s.next_pass.%s" % [save_path, _get_save_extension()]
 
     err = ResourceSaver.save(next_pass, next_pass_path)
     if err != OK:

+ 7 - 7
tutorials/plugins/editor/inspector_plugins.rst

@@ -52,7 +52,7 @@ you should remove the instance you have added by calling
 
 
     func _enter_tree():
-        plugin = preload("res://addons/my_inspector_plugin/MyInspectorPlugin.gd").new()
+        plugin = preload("res://addons/my_inspector_plugin/my_inspector_plugin.gd").new()
         add_inspector_plugin(plugin)
 
 
@@ -87,7 +87,7 @@ you should remove the instance you have added by calling
 Interacting with the inspector
 ------------------------------
 
-To interact with the inspector dock, your ``MyInspectorPlugin.gd`` script must
+To interact with the inspector dock, your ``my_inspector_plugin.gd`` script must
 extend the :ref:`class_EditorInspectorPlugin` class. This class provides several
 virtual methods that affect how the inspector handles properties.
 
@@ -112,10 +112,10 @@ specifically add :ref:`class_EditorProperty`-based controls.
 .. tabs::
  .. code-tab:: gdscript GDScript
 
-    # MyInspectorPlugin.gd
+    # my_inspector_plugin.gd
     extends EditorInspectorPlugin
 
-    var RandomIntEditor = preload("res://addons/my_inspector_plugin/RandomIntEditor.gd")
+    var RandomIntEditor = preload("res://addons/my_inspector_plugin/random_int_editor.gd")
 
 
     func _can_handle(object):
@@ -149,8 +149,8 @@ specifically add :ref:`class_EditorProperty`-based controls.
             return true;
         }
 
-        public override bool _ParseProperty(GodotObject @object, Variant.Type type, 
-            string name, PropertyHint hintType, string hintString, 
+        public override bool _ParseProperty(GodotObject @object, Variant.Type type,
+            string name, PropertyHint hintType, string hintString,
             PropertyUsageFlags usageFlags, bool wide)
         {
             // We handle properties of type integer.
@@ -197,7 +197,7 @@ followed by ``set_bottom_editor()`` to position it below the name.
 .. tabs::
  .. code-tab:: gdscript GDScript
 
-    # RandomIntEditor.gd
+    # random_int_editor.gd
     extends EditorProperty
 
 

+ 4 - 5
tutorials/plugins/editor/installing_plugins.rst

@@ -15,7 +15,7 @@ The preferred way to find Godot plugins is to use the
 browsed online, it's more convenient to use it directly from the editor.
 To do so, click the **AssetLib** tab at the top of the editor:
 
-.. image:: img/installing_plugins_assetlib_tab.png
+.. image:: img/installing_plugins_assetlib_tab.webp
 
 You can also find assets on code hosting websites such as GitHub.
 
@@ -58,11 +58,10 @@ Enabling a plugin
 
 To enable the freshly installed plugin, open **Project > Project Settings** at
 the top of the editor then go the **Plugins** tab. If the plugin was packaged
-correctly, you should see it in the list of plugins. Click on the gray
-**Inactive** text and choose **Active** to enable the plugin. The word
-**Active** will display in green to confirm the plugin was enabled.
+correctly, you should see it in the list of plugins. Click on the
+**Enable** checkbox to enable the plugin.
 
-.. image:: img/installing_plugins_project_settings.png
+.. image:: img/installing_plugins_project_settings.webp
 
 
 You can use the plugin immediately after enabling it; there's no need to restart

+ 2 - 2
tutorials/plugins/editor/making_main_screen_plugins.rst

@@ -124,7 +124,7 @@ Add a script to the button like this:
     extends Button
 
 
-    func _on_PrintHello_pressed():
+    func _on_print_hello_pressed():
         print("Hello from the main screen plugin!")
 
  .. code-tab:: csharp
@@ -134,7 +134,7 @@ Add a script to the button like this:
     [Tool]
     public partial class PrintHello : Button
     {
-        public void OnPrintHelloPressed()
+        private void OnPrintHelloPressed()
         {
             GD.Print("Hello from the main screen plugin!");
         }

+ 13 - 13
tutorials/plugins/editor/making_plugins.rst

@@ -32,11 +32,11 @@ placing them where they need to be.
 
 In the main toolbar, click the ``Project`` dropdown. Then click
 ``Project Settings...``. Go to the ``Plugins`` tab and then click
-on the ``Create`` button in the top-right.
+on the ``Create New Plugin`` button in the top-right.
 
 You will see the dialog appear, like so:
 
-.. image:: img/making_plugins-create_plugin_dialog.png
+.. image:: img/making_plugins-create_plugin_dialog.webp
 
 The placeholder text in each field describes how it affects the plugin's
 creation of the files and the config file's values.
@@ -75,7 +75,7 @@ To continue with the example, use the following values:
 
 You should end up with a directory structure like this:
 
-.. image:: img/making_plugins-my_custom_mode_folder.png
+.. image:: img/making_plugins-my_custom_mode_folder.webp
 
 ``plugin.cfg`` is an INI file with metadata about your plugin.
 The name and description help people understand what it does.
@@ -209,7 +209,7 @@ That's it for our basic button. You can save this as ``my_button.gd`` inside the
 plugin folder. You'll also need a 16×16 icon to show in the scene tree. If you
 don't have one, you can grab the default one from the engine and save it in your
 `addons/my_custom_node` folder as `icon.png`, or use the default Godot logo
-(`preload("res://icon.png")`). You can also use SVG icons if desired.
+(`preload("res://icon.svg")`).
 
 .. image:: img/making_plugins-custom_node_icon.png
 
@@ -265,13 +265,13 @@ With that done, the plugin should already be available in the plugin list in the
 
 Then try it out by adding your new node:
 
-.. image:: img/making_plugins-custom_node_create.png
+.. image:: img/making_plugins-custom_node_create.webp
 
 When you add the node, you can see that it already has the script you created
 attached to it. Set a text to the button, save and run the scene. When you
 click the button, you can see some text in the console:
 
-.. image:: img/making_plugins-custom_node_console.png
+.. image:: img/making_plugins-custom_node_console.webp
 
 A custom dock
 ^^^^^^^^^^^^^
@@ -319,7 +319,7 @@ The name of the root node will also be the name that appears on the dock tab,
 so be sure to give it a short and descriptive name.
 Also, don't forget to add some text to your button.
 
-.. image:: img/making_plugins-my_custom_dock_scene.png
+.. image:: img/making_plugins-my_custom_dock_scene.webp
 
 Save this scene as ``my_dock.tscn``. Now, we need to grab the scene we created
 then add it as a dock in the editor. For this, you can rely on the function
@@ -394,16 +394,16 @@ Checking the results
 
 It's now time to check the results of your work. Open the **Project
 Settings** and click on the **Plugins** tab. Your plugin should be the only one
-on the list. If it is not showing, click on the **Update** button in the
-top-right corner.
+on the list.
 
-.. image:: img/making_plugins-project_settings.png
+.. image:: img/making_plugins-project_settings.webp
 
-You can see the plugin is inactive on the **Status** column; click on the status
-to select **Active**. The dock should become visible before you even close
+You can see the plugin is not enabled.
+Click the **Enable** checkbox to activate the plugin.
+The dock should become visible before you even close
 the settings window. You should now have a custom dock:
 
-.. image:: img/making_plugins-custom_dock.png
+.. image:: img/making_plugins-custom_dock.webp
 
 Going beyond
 ~~~~~~~~~~~~

+ 1 - 1
tutorials/plugins/editor/visual_shader_plugins.rst

@@ -32,7 +32,7 @@ all you need to initialize your plugin.
 
 ::
 
-    # PerlinNoise3D.gd
+    # perlin_noise_3d.gd
     @tool
     extends VisualShaderNodeCustom
     class_name VisualShaderNodePerlinNoise3D

+ 2 - 0
tutorials/rendering/viewports.rst

@@ -1,3 +1,5 @@
+:article_outdated: True
+
 .. _doc_viewports:
 
 Using Viewports

+ 17 - 4
tutorials/scripting/gdextension/gdextension_cpp_example.rst

@@ -351,9 +351,22 @@ loaded for each platform and the entry function for the module. It is called ``g
 
     [libraries]
 
-    linux.64="res://bin/libgdexample.linux.64.so"
-    windows.x86_64="res://bin/libgdexample.windows.x86_64.dll"
-    macos="res://bin/libgdexample.macos.framework"
+    macos.debug = "res://bin/libgdexample.macos.template_debug.framework"
+    macos.release = "res://bin/libgdexample.macos.template_release.framework"
+    windows.debug.x86_32 = "res://bin/libgdexample.windows.template_debug.x86_32.dll"
+    windows.release.x86_32 = "res://bin/libgdexample.windows.template_release.x86_32.dll"
+    windows.debug.x86_64 = "res://bin/libgdexample.windows.template_debug.x86_64.dll"
+    windows.release.x86_64 = "res://bin/libgdexample.windows.template_release.x86_64.dll"
+    linux.debug.x86_64 = "res://bin/libgdexample.linux.template_debug.x86_64.so"
+    linux.release.x86_64 = "res://bin/libgdexample.linux.template_release.x86_64.so"
+    linux.debug.arm64 = "res://bin/libgdexample.linux.template_debug.arm64.so"
+    linux.release.arm64 = "res://bin/libgdexample.linux.template_release.arm64.so"
+    linux.debug.rv64 = "res://bin/libgdexample.linux.template_debug.rv64.so"
+    linux.release.rv64 = "res://bin/libgdexample.linux.template_release.rv64.so"
+    android.debug.x86_64 = "res://bin/libgdexample.android.template_debug.x86_64.so"
+    android.release.x86_64 = "res://bin/libgdexample.android.template_release.x86_64.so"
+    android.debug.arm64 = "res://bin/libgdexample.android.template_debug.arm64.so"
+    android.release.arm64 = "res://bin/libgdexample.android.template_release.arm64.so"
 
 This file contains a ``configuration`` section that controls the entry function of the module.
 
@@ -442,7 +455,7 @@ show the methods we end up changing, don't remove the lines we're omitting:
         ClassDB::add_property("GDExample", PropertyInfo(Variant::FLOAT, "amplitude"), "set_amplitude", "get_amplitude");
     }
 
-    void GDExample::GDExample() {
+    GDExample::GDExample() {
         // Initialize any variables here.
         time_passed = 0.0;
         amplitude = 10.0;

+ 158 - 100
tutorials/scripting/gdscript/gdscript_basics.rst

@@ -204,7 +204,7 @@ in case you want to take a look under the hood.
 +------------+---------------------------------------------------------------------------------------------------------------------------------------------------+
 | preload    | Preloads a class or variable. See `Classes as resources`_.                                                                                        |
 +------------+---------------------------------------------------------------------------------------------------------------------------------------------------+
-| await      | Waits for a signal or a coroutine to finish. See `Awaiting for signals`_.                                                                         |
+| await      | Waits for a signal or a coroutine to finish. See `Awaiting for signals or coroutines`_.                                                           |
 +------------+---------------------------------------------------------------------------------------------------------------------------------------------------+
 | yield      | Previously used for coroutines. Kept as keyword for transition.                                                                                   |
 +------------+---------------------------------------------------------------------------------------------------------------------------------------------------+
@@ -226,73 +226,116 @@ Operators
 
 The following is the list of supported operators and their precedence.
 
-+---------------------------------------------------------------------------------------+-------------------------------------------+
-| **Operator**                                                                          | **Description**                           |
-+=======================================================================================+===========================================+
-| ``x[index]``                                                                          | Subscription (highest priority)           |
-+---------------------------------------------------------------------------------------+-------------------------------------------+
-| ``x.attribute``                                                                       | Attribute reference                       |
-+---------------------------------------------------------------------------------------+-------------------------------------------+
-| ``foo()``                                                                             | Function call                             |
-+---------------------------------------------------------------------------------------+-------------------------------------------+
-| ``is``                                                                                | Instance type checker                     |
-+---------------------------------------------------------------------------------------+-------------------------------------------+
-| ``**``                                                                                | Power operator                            |
-|                                                                                       |                                           |
-|                                                                                       | Multiplies value by itself ``x`` times,   |
-|                                                                                       | similar to calling ``pow`` built-in       |
-|                                                                                       | function                                  |
-+---------------------------------------------------------------------------------------+-------------------------------------------+
-| ``~``                                                                                 | Bitwise NOT                               |
-+---------------------------------------------------------------------------------------+-------------------------------------------+
-| ``-x``                                                                                | Negative / Unary negation                 |
-+---------------------------------------------------------------------------------------+-------------------------------------------+
-| ``*`` ``/`` ``%``                                                                     | Multiplication / Division / Remainder     |
-|                                                                                       |                                           |
-|                                                                                       | These operators have the same behavior    |
-|                                                                                       | as C++. Integer division is truncated     |
-|                                                                                       | rather than returning a fractional        |
-|                                                                                       | number, and the % operator is only        |
-|                                                                                       | available for ints (``fmod`` for floats), |
-|                                                                                       | and is additionally used for Format       |
-|                                                                                       | Strings                                   |
-+---------------------------------------------------------------------------------------+-------------------------------------------+
-| ``+``                                                                                 | Addition / Concatenation of arrays        |
-+---------------------------------------------------------------------------------------+-------------------------------------------+
-| ``-``                                                                                 | Subtraction                               |
-+---------------------------------------------------------------------------------------+-------------------------------------------+
-| ``<<`` ``>>``                                                                         | Bit shifting                              |
-+---------------------------------------------------------------------------------------+-------------------------------------------+
-| ``&``                                                                                 | Bitwise AND                               |
-+---------------------------------------------------------------------------------------+-------------------------------------------+
-| ``^``                                                                                 | Bitwise XOR                               |
-+---------------------------------------------------------------------------------------+-------------------------------------------+
-| ``|``                                                                                 | Bitwise OR                                |
-+---------------------------------------------------------------------------------------+-------------------------------------------+
-| ``<`` ``>`` ``==`` ``!=`` ``>=`` ``<=``                                               | Comparisons                               |
-+---------------------------------------------------------------------------------------+-------------------------------------------+
-| ``in``                                                                                | Inclusion checker (when used with         |
-|                                                                                       | control flow keywords or in a             |
-|                                                                                       | standalone expression)                    |
-|                                                                                       |                                           |
-|                                                                                       | Content iterator (when used with the      |
-|                                                                                       | for_ keyword)                             |
-+---------------------------------------------------------------------------------------+-------------------------------------------+
-| ``not`` ``!``                                                                         | Boolean NOT and its                       |
-|                                                                                       | :ref:`aliases<boolean_operators>`         |
-+---------------------------------------------------------------------------------------+-------------------------------------------+
-| ``and`` ``&&``                                                                        | Boolean AND and its                       |
-|                                                                                       | :ref:`aliases<boolean_operators>`         |
-+---------------------------------------------------------------------------------------+-------------------------------------------+
-| ``or`` ``||``                                                                         | Boolean OR and its                        |
-|                                                                                       | :ref:`aliases<boolean_operators>`         |
-+---------------------------------------------------------------------------------------+-------------------------------------------+
-| ``if x else``                                                                         | Ternary if/else                           |
-+---------------------------------------------------------------------------------------+-------------------------------------------+
-| ``as``                                                                                | Type casting                              |
-+---------------------------------------------------------------------------------------+-------------------------------------------+
-| ``=`` ``+=`` ``-=`` ``*=`` ``/=`` ``%=`` ``**=`` ``&=`` ``^=`` ``|=`` ``<<=`` ``>>=`` | Assignment (lowest priority)              |
-+---------------------------------------------------------------------------------------+-------------------------------------------+
++---------------------------------------+-----------------------------------------------------------------------------+
+| **Operator**                          | **Description**                                                             |
++=======================================+=============================================================================+
+| ``(`` ``)``                           | Grouping (highest priority)                                                 |
+|                                       |                                                                             |
+|                                       | Parentheses are not really an operator, but allow you to explicitly specify |
+|                                       | the precedence of an operation.                                             |
++---------------------------------------+-----------------------------------------------------------------------------+
+| ``x[index]``                          | Subscription                                                                |
++---------------------------------------+-----------------------------------------------------------------------------+
+| ``x.attribute``                       | Attribute reference                                                         |
++---------------------------------------+-----------------------------------------------------------------------------+
+| ``foo()``                             | Function call                                                               |
++---------------------------------------+-----------------------------------------------------------------------------+
+| ``await x``                           | `Awaiting for signals or coroutines`_                                       |
++---------------------------------------+-----------------------------------------------------------------------------+
+| ``x is Node``                         | Type checking                                                               |
+|                                       |                                                                             |
+|                                       | See also :ref:`is_instance_of() <class_@GDScript_method_is_instance_of>`    |
+|                                       | function.                                                                   |
++---------------------------------------+-----------------------------------------------------------------------------+
+| ``x ** y``                            | Power                                                                       |
+|                                       |                                                                             |
+|                                       | Multiplies ``x`` by itself ``y`` times, similar to calling                  |
+|                                       | :ref:`pow() <class_@GlobalScope_method_pow>` function.                      |
+|                                       |                                                                             |
+|                                       | **Note:** In GDScript, the ``**`` operator is                               |
+|                                       | `left-associative <https://en.wikipedia.org/wiki/Operator_associativity>`_. |
+|                                       | See a detailed note after the table.                                        |
++---------------------------------------+-----------------------------------------------------------------------------+
+| ``~x``                                | Bitwise NOT                                                                 |
++---------------------------------------+-----------------------------------------------------------------------------+
+| | ``+x``                              | Identity / Negation                                                         |
+| | ``-x``                              |                                                                             |
++---------------------------------------+-----------------------------------------------------------------------------+
+| | ``x * y``                           | Multiplication / Division / Remainder                                       |
+| | ``x / y``                           |                                                                             |
+| | ``x % y``                           | The ``%`` operator is additionally used for                                 |
+|                                       | :ref:`format strings <doc_gdscript_printf>`.                                |
+|                                       |                                                                             |
+|                                       | **Note:** These operators have the same behavior as C++, which may be       |
+|                                       | unexpected for users coming from Python, JavaScript, etc. See a detailed    |
+|                                       | note after the table.                                                       |
++---------------------------------------+-----------------------------------------------------------------------------+
+| | ``x + y``                           | Addition (or Concatenation) / Subtraction                                   |
+| | ``x - y``                           |                                                                             |
++---------------------------------------+-----------------------------------------------------------------------------+
+| | ``x << y``                          | Bit shifting                                                                |
+| | ``x >> y``                          |                                                                             |
++---------------------------------------+-----------------------------------------------------------------------------+
+| ``x & y``                             | Bitwise AND                                                                 |
++---------------------------------------+-----------------------------------------------------------------------------+
+| ``x ^ y``                             | Bitwise XOR                                                                 |
++---------------------------------------+-----------------------------------------------------------------------------+
+| ``x | y``                             | Bitwise OR                                                                  |
++---------------------------------------+-----------------------------------------------------------------------------+
+| | ``x == y``                          | Comparison                                                                  |
+| | ``x != y``                          |                                                                             |
+| | ``x < y``                           | See a detailed note after the table.                                        |
+| | ``x > y``                           |                                                                             |
+| | ``x <= y``                          |                                                                             |
+| | ``x >= y``                          |                                                                             |
++---------------------------------------+-----------------------------------------------------------------------------+
+| | ``x in y``                          | Inclusion checking                                                          |
+| | ``x not in y``                      |                                                                             |
+|                                       | ``in`` is also used with the for_ keyword as part of the syntax.            |
++---------------------------------------+-----------------------------------------------------------------------------+
+| | ``not x``                           | Boolean NOT and its :ref:`unrecommended <boolean_operators>` alias          |
+| | ``!x``                              |                                                                             |
++---------------------------------------+-----------------------------------------------------------------------------+
+| | ``x and y``                         | Boolean AND and its :ref:`unrecommended <boolean_operators>` alias          |
+| | ``x && y``                          |                                                                             |
++---------------------------------------+-----------------------------------------------------------------------------+
+| | ``x or y``                          | Boolean OR and its :ref:`unrecommended <boolean_operators>` alias           |
+| | ``x || y``                          |                                                                             |
++---------------------------------------+-----------------------------------------------------------------------------+
+| ``true_expr if cond else false_expr`` | Ternary if/else                                                             |
++---------------------------------------+-----------------------------------------------------------------------------+
+| ``x as Node``                         | `Type casting <casting_>`_                                                  |
++---------------------------------------+-----------------------------------------------------------------------------+
+| | ``x = y``                           | Assignment (lowest priority)                                                |
+| | ``x += y``                          |                                                                             |
+| | ``x -= y``                          | You cannot use an assignment operator inside an expression.                 |
+| | ``x *= y``                          |                                                                             |
+| | ``x /= y``                          |                                                                             |
+| | ``x **= y``                         |                                                                             |
+| | ``x %= y``                          |                                                                             |
+| | ``x &= y``                          |                                                                             |
+| | ``x |= y``                          |                                                                             |
+| | ``x ^= y``                          |                                                                             |
+| | ``x <<= y``                         |                                                                             |
+| | ``x >>= y``                         |                                                                             |
++---------------------------------------+-----------------------------------------------------------------------------+
+
+.. note::
+
+    The behavior of some operators may differ from what you expect:
+
+    1. If both operands of the ``/`` operator are :ref:`int <class_int>`, then integer division is performed instead of fractional. For example ``5 / 2 == 2``, not ``2.5``.
+       If this is not desired, use at least one :ref:`float <class_float>` literal (``x / 2.0``), cast (``float(x) / y``), or multiply by ``1.0`` (``x * 1.0 / y``).
+    2. The ``%`` operator is only available for ints, for floats use the :ref:`fmod() <class_@GlobalScope_method_fmod>` function.
+    3. For negative values, the ``%`` operator and ``fmod()`` use `truncation <https://en.wikipedia.org/wiki/Truncation>`_ instead of rounding towards negative infinity.
+       This means that the remainder has a sign. If you need the remainder in a mathematical sense, use the :ref:`posmod() <class_@GlobalScope_method_posmod>` and
+       :ref:`fposmod() <class_@GlobalScope_method_fposmod>` functions instead.
+    4. The ``**`` operator is `left-associative <https://en.wikipedia.org/wiki/Operator_associativity>`_. This means that ``2 ** 2 ** 3`` is equal to ``(2 ** 2) ** 3``.
+       Use parentheses to explicitly specify precedence you need, for example ``2 ** (2 ** 3)``.
+    5. The ``==`` and ``!=`` operators sometimes allow you to compare values of different types (for example, ``1 == 1.0`` is true), but in other cases it can cause
+       a runtime error. If you're not sure about the types of the operands, you can safely use the :ref:`is_same() <class_@GlobalScope_method_is_same>` function
+       (but note that it is more strict about types and references). To compare floats, use the :ref:`is_equal_approx() <class_@GlobalScope_method_is_equal_approx>`
+       and :ref:`is_zero_approx() <class_@GlobalScope_method_is_zero_approx>` functions instead.
 
 Literals
 ~~~~~~~~
@@ -348,6 +391,13 @@ For instance, you can use it to export a value to the editor::
 For more information about exporting properties, read the :ref:`GDScript exports <doc_gdscript_exports>`
 article.
 
+Any constant expression compatible with the required argument type can be passed as an annotation argument value::
+
+    const MAX_SPEED = 120.0
+
+    @export_range(0.0, 0.5 * MAX_SPEED)
+    var initial_speed: float = 0.25 * MAX_SPEED
+
 Annotations can be specified one per line or all in the same line. They affect
 the next statement that isn't an annotation. Annotations can have arguments sent
 between parentheses and separated by commas.
@@ -355,10 +405,10 @@ between parentheses and separated by commas.
 Both of these are the same::
 
     @onready
-    @export_node_path(TextEdit, LineEdit)
+    @export_node_path("TextEdit", "LineEdit")
     var input_field
 
-    @onready @export_node_path(TextEdit, LineEdit) var input_field
+    @onready @export_node_path("TextEdit", "LineEdit") var input_field
 
 .. _doc_gdscript_onready_annotation:
 
@@ -503,7 +553,7 @@ There are two ways to represent an escaped Unicode character above 0xFFFF:
 Also, using ``\`` followed by a newline inside a string will allow you to continue it in the next line, without
 inserting a newline character in the string itself.
 
-GDScript also supports :ref:`doc_gdscript_printf`.
+GDScript also supports :ref:`format strings <doc_gdscript_printf>`.
 
 :ref:`StringName <class_StringName>`
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -1190,6 +1240,10 @@ Basic syntax::
         [pattern](s):
             [block]
 
+.. warning::
+
+    ``match`` is more type strict than the ``==`` operator. For example ``1`` will **not** match ``1.0``. The only exception is ``String`` vs ``StringName`` matching:
+    for example, the String ``"hello"`` is considered equal to the StringName ``&"hello"``.
 
 **Crash-course for people who are familiar with switch statements**:
 
@@ -1203,6 +1257,10 @@ Basic syntax::
 The patterns are matched from top to bottom.
 If a pattern matches, the first corresponding block will be executed. After that, the execution continues below the ``match`` statement.
 
+.. note::
+
+    The special ``continue`` behavior in ``match`` supported in 3.x was removed in Godot 4.0.
+
 There are 6 pattern types:
 
 - Constant pattern
@@ -1322,7 +1380,7 @@ By default, all script files are unnamed classes. In this case, you can only
 reference them using the file's path, using either a relative or an absolute
 path. For example, if you name a script file ``character.gd``::
 
-   # Inherit from 'Character.gd'.
+   # Inherit from 'character.gd'.
 
    extends "res://path/to/character.gd"
 
@@ -1341,7 +1399,7 @@ editor. For that, you use the ``class_name`` keyword. You can optionally use
 the ``@icon`` annotation with a path to an image, to use it as an icon. Your
 class will then appear with its new icon in the editor::
 
-   # Item.gd
+   # item.gd
 
    @icon("res://interface/icons/item.png")
    class_name Item
@@ -1457,7 +1515,7 @@ explicit constructor::
 
 This is better explained through examples. Consider this scenario::
 
-    # State.gd (inherited class).
+    # state.gd (inherited class).
     var entity = null
     var message = null
 
@@ -1470,8 +1528,8 @@ This is better explained through examples. Consider this scenario::
         message = m
 
 
-    # Idle.gd (inheriting class).
-    extends "State.gd"
+    # idle.gd (inheriting class).
+    extends "state.gd"
 
 
     func _init(e=null, m=null):
@@ -1481,17 +1539,17 @@ This is better explained through examples. Consider this scenario::
 
 There are a few things to keep in mind here:
 
-1. If the inherited class (``State.gd``) defines a ``_init`` constructor that takes
-   arguments (``e`` in this case), then the inheriting class (``Idle.gd``) *must*
-   define ``_init`` as well and pass appropriate parameters to ``_init`` from ``State.gd``.
-2. ``Idle.gd`` can have a different number of arguments than the base class ``State.gd``.
-3. In the example above, ``e`` passed to the ``State.gd`` constructor is the same ``e`` passed
-   in to ``Idle.gd``.
-4. If ``Idle.gd``'s ``_init`` constructor takes 0 arguments, it still needs to pass some value
-   to the ``State.gd`` base class, even if it does nothing. This brings us to the fact that you
+1. If the inherited class (``state.gd``) defines a ``_init`` constructor that takes
+   arguments (``e`` in this case), then the inheriting class (``idle.gd``) *must*
+   define ``_init`` as well and pass appropriate parameters to ``_init`` from ``state.gd``.
+2. ``idle.gd`` can have a different number of arguments than the base class ``state.gd``.
+3. In the example above, ``e`` passed to the ``state.gd`` constructor is the same ``e`` passed
+   in to ``idle.gd``.
+4. If ``idle.gd``'s ``_init`` constructor takes 0 arguments, it still needs to pass some value
+   to the ``state.gd`` base class, even if it does nothing. This brings us to the fact that you
    can pass expressions to the base constructor as well, not just variables, e.g.::
 
-    # Idle.gd
+    # idle.gd
 
     func _init():
         super(5)
@@ -1572,8 +1630,8 @@ Example::
         set(value):
             milliseconds = value * 1000
 
-Using the variable name inside its own setter or getter will directly access the underlying member, so it
-won't generate infinite recursion and saves you from explicitly declaring another variable::
+Using the variable's name to set it inside its own setter or to get it inside its own getter will directly access the underlying member,
+so it won't generate infinite recursion and saves you from explicitly declaring another variable::
 
     signal changed(new_value)
     var warns_when_changed = "some value":
@@ -1703,16 +1761,16 @@ signals of nodes like :ref:`class_Button` or :ref:`class_RigidBody3D`.
 
 In the example below, we connect the ``health_depleted`` signal from a
 ``Character`` node to a ``Game`` node. When the ``Character`` node emits the
-signal, the game node's ``_on_Character_health_depleted`` is called::
+signal, the game node's ``_on_character_health_depleted`` is called::
 
-    # Game.gd
+    # game.gd
 
     func _ready():
         var character_node = get_node('Character')
-        character_node.health_depleted.connect(_on_Character_health_depleted)
+        character_node.health_depleted.connect(_on_character_health_depleted)
 
 
-    func _on_Character_health_depleted():
+    func _on_character_health_depleted():
         get_tree().reload_current_scene()
 
 You can emit as many arguments as you want along with a signal.
@@ -1721,12 +1779,12 @@ Here is an example where this is useful. Let's say we want a life bar on screen
 to react to health changes with an animation, but we want to keep the user
 interface separate from the player in our scene tree.
 
-In our ``Character.gd`` script, we define a ``health_changed`` signal and emit
+In our ``character.gd`` script, we define a ``health_changed`` signal and emit
 it with :ref:`Signal.emit() <class_Signal_method_emit>`, and from
 a ``Game`` node higher up our scene tree, we connect it to the ``Lifebar`` using
 the :ref:`Signal.connect() <class_Signal_method_connect>` method::
 
-    # Character.gd
+    # character.gd
 
     ...
     signal health_changed
@@ -1743,7 +1801,7 @@ the :ref:`Signal.connect() <class_Signal_method_connect>` method::
 
 ::
 
-    # Lifebar.gd
+    # lifebar.gd
 
     # Here, we define a function to use as a callback when the
     # character's health_changed signal is emitted.
@@ -1766,7 +1824,7 @@ node in this case.
 
 ::
 
-    # Game.gd
+    # game.gd
 
     func _ready():
         var character_node = get_node('Character')
@@ -1804,7 +1862,7 @@ taken by each character on the screen, like ``Player1 took 22 damage.``. The
 damage. So when we connect the signal to the in-game console, we can add the
 character's name in the binds array argument::
 
-    # Game.gd
+    # game.gd
 
     func _ready():
         var character_node = get_node('Character')
@@ -1814,7 +1872,7 @@ character's name in the binds array argument::
 
 Our ``BattleLog`` node receives each element in the binds array as an extra argument::
 
-    # BattleLog.gd
+    # battle_log.gd
 
     func _on_Character_health_changed(old_value, new_value, character_name):
         if not new_value <= old_value:
@@ -1824,11 +1882,11 @@ Our ``BattleLog`` node receives each element in the binds array as an extra argu
         label.text += character_name + " took " + str(damage) + " damage."
 
 
-Awaiting for signals
-~~~~~~~~~~~~~~~~~~~~
+Awaiting for signals or coroutines
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 The ``await`` keyword can be used to create `coroutines <https://en.wikipedia.org/wiki/Coroutine>`_
-which waits until a signal is emitted before continuing execution. Using the ``await`` keyword with a signal or a
+which wait until a signal is emitted before continuing execution. Using the ``await`` keyword with a signal or a
 call to a function that is also a coroutine will immediately return the control to the caller. When the signal is
 emitted (or the called coroutine finishes), it will resume execution from the point on where it stopped.
 

+ 6 - 6
tutorials/scripting/gdscript/static_typing.rst

@@ -33,9 +33,9 @@ who work with your code should always pass an ``Item`` to the
 
 ::
 
-    # In 'Item.gd'.
+    # In 'item.gd'.
     class_name Item
-    # In 'Inventory.gd'.
+    # In 'inventory.gd'.
     class_name Inventory
 
 
@@ -123,11 +123,11 @@ script you want to use as a type in a constant:
 
 ::
 
-    const Rifle = preload("res://player/weapons/Rifle.gd")
+    const Rifle = preload("res://player/weapons/rifle.gd")
     var my_rifle: Rifle
 
 The second method is to use the ``class_name`` keyword when you create.
-For the example above, your Rifle.gd would look like this:
+For the example above, your rifle.gd would look like this:
 
 ::
 
@@ -235,7 +235,7 @@ You can also use your own nodes as return types:
 
 ::
 
-    # Inventory.gd
+    # inventory.gd
 
     # Adds an item to the inventory and returns it.
     func add(reference: Item, amount: int) -> Item:
@@ -316,7 +316,7 @@ a ``body_entered`` signal in a dynamic style:
 
 ::
 
-    func _on_Area2D_body_entered(body):
+    func _on_area_2d_body_entered(body):
         pass
 
 And the same callback, with type hints:

Certains fichiers n'ont pas été affichés car il y a eu trop de fichiers modifiés dans ce diff