diff --git a/.github/workflows/build_offline_docs.yml b/.github/workflows/build_offline_docs.yml
index fc74d9829bd..b5df48b671e 100644
--- a/.github/workflows/build_offline_docs.yml
+++ b/.github/workflows/build_offline_docs.yml
@@ -8,6 +8,9 @@ on:
jobs:
build:
+ # Don't run scheduled runs on forks unless the CI_OFFLINE_DOCS_CRON variable is set to 'true'.
+ # Manual runs can still be triggered as normal.
+ if: ${{ github.repository_owner == 'godotengine' || github.event_name != 'schedule' || vars.CI_OFFLINE_DOCS_CRON == 'true' }}
runs-on: ubuntu-22.04
strategy:
matrix:
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 347815490da..178a651f94a 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -10,23 +10,16 @@ concurrency:
jobs:
build:
- runs-on: ubuntu-20.04
+ runs-on: ubuntu-22.04
steps:
- name: Checkout
uses: actions/checkout@v4
- - name: Install dependencies
- run: |
- # Install tools used by `_tools/format.sh`.
- sudo apt-get -qq update
- sudo apt-get -qq install dos2unix recode
- sudo pip3 install -r requirements.txt
- sudo pip3 install codespell
+ - name: Style checks via pre-commit
+ uses: pre-commit/action@v3.0.1
- - name: Linter checks
- run: |
- bash _tools/format.sh
- codespell -I _tools/codespell-ignore.txt -x _tools/codespell-ignore-lines.txt -S tutorials/i18n/locales.rst {about,community,contributing,getting_started,tutorials}/**/*.rst
+ - name: Install dependencies
+ run: sudo pip3 install -r requirements.txt
- name: Migrate to Redot
run: |
diff --git a/.github/workflows/sync_class_ref.yml b/.github/workflows/sync_class_ref.yml
index 86de73ba0bd..a392ae67c76 100644
--- a/.github/workflows/sync_class_ref.yml
+++ b/.github/workflows/sync_class_ref.yml
@@ -10,6 +10,9 @@ concurrency:
jobs:
build:
+ # Don't run scheduled runs on forks unless the CI_SYNC_CLASS_REF_CRON variable is set to 'true'.
+ # Manual runs can still be triggered as normal.
+ if: ${{ github.repository_owner == 'godotengine' || github.event_name != 'schedule' || vars.CI_SYNC_CLASS_REF_CRON == 'true' }}
name: Update class reference files based on the engine revision
runs-on: ubuntu-latest
env:
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
new file mode 100644
index 00000000000..80693445812
--- /dev/null
+++ b/.pre-commit-config.yaml
@@ -0,0 +1,17 @@
+default_language_version:
+ python: python3
+
+repos:
+ - repo: https://github.com/codespell-project/codespell
+ rev: v2.3.0
+ hooks:
+ - id: codespell
+ files: ^(about|community|contributing|getting_started|tutorials)/.*\.rst$
+ additional_dependencies: [tomli]
+
+ - repo: https://github.com/pre-commit/pre-commit-hooks
+ rev: v5.0.0
+ hooks:
+ - id: fix-byte-order-marker
+ - id: mixed-line-ending
+ args: ['--fix=lf']
diff --git a/_static/css/algolia.css b/_static/css/algolia.css
deleted file mode 100644
index d27f55e8852..00000000000
--- a/_static/css/algolia.css
+++ /dev/null
@@ -1,6 +0,0 @@
-.wy-nav-side { overflow: visible; }
-.wy-side-scroll { overflow-x: inherit; }
-
-.algolia-autocomplete {
- display: block !important;
-}
diff --git a/_templates/layout.html b/_templates/layout.html
index 2ae409ae886..280976a13ed 100644
--- a/_templates/layout.html
+++ b/_templates/layout.html
@@ -13,16 +13,6 @@
{% block linktags -%}
- {% if godot_inject_language_links -%}
- {% for alternate_lang in godot_docs_supported_languages -%}
- {# Convert to ISO 639-1 format, e.g. zh_CN -> zh-cn -#}
- {% set alternate_lang_href = alternate_lang.lower().replace("_", "-") -%}
-
- {% endfor -%}
-
-
-
- {% endif -%}
{{ super() }}
{% endblock -%}
diff --git a/_tools/codespell-dict.txt b/_tools/codespell-dict.txt
new file mode 100644
index 00000000000..f8e93f339d9
--- /dev/null
+++ b/_tools/codespell-dict.txt
@@ -0,0 +1 @@
+anti-aliasing->antialiasing
diff --git a/_tools/format.sh b/_tools/format.sh
deleted file mode 100755
index 1b0e22f0be3..00000000000
--- a/_tools/format.sh
+++ /dev/null
@@ -1,42 +0,0 @@
-#!/usr/bin/env bash
-
-set -uo pipefail
-IFS=$'\n\t'
-
-# Loops through all text files tracked by Git.
-git grep -zIl '' |
-while IFS= read -rd '' f; do
- # Exclude csproj and hdr files.
- if [[ "$f" == *"csproj" ]]; then
- continue
- elif [[ "$f" == *"hdr" ]]; then
- continue
- fi
- # Ensures that files are UTF-8 formatted.
- recode UTF-8 "$f" 2> /dev/null
- # Ensures that files have LF line endings.
- dos2unix "$f" 2> /dev/null
- # Ensures that files do not contain a BOM.
- sed -i '1s/^\xEF\xBB\xBF//' "$f"
- # Ensures that files end with newline characters.
- tail -c1 < "$f" | read -r _ || echo >> "$f";
-done
-
-git diff > patch.patch
-FILESIZE="$(stat -c%s patch.patch)"
-MAXSIZE=5
-
-# If no patch has been generated all is OK, clean up, and exit.
-if (( FILESIZE < MAXSIZE )); then
- printf "Files in this commit comply with the formatting rules.\n"
- rm -f patch.patch
- exit 0
-fi
-
-# A patch has been created, notify the user, clean up, and exit.
-printf "\n*** The following differences were found between the code "
-printf "and the formatting rules:\n\n"
-cat patch.patch
-printf "\n*** Aborting, please fix your commit(s) with 'git commit --amend' or 'git rebase -i '\n"
-rm -f patch.patch
-exit 1
diff --git a/about/docs_changelog.rst b/about/docs_changelog.rst
index 61b7f2b610c..64072d47390 100644
--- a/about/docs_changelog.rst
+++ b/about/docs_changelog.rst
@@ -13,6 +13,52 @@ added since version 3.0.
.. note:: This document only contains new pages so not all changes are reflected,
many pages have been substantially updated but are not reflected in this document.
+New pages since version 4.2
+---------------------------
+
+About
+^^^^^
+
+- :ref:`doc_system_requirements`
+
+2D
+^^
+
+- :ref:`doc_2d_parallax`
+
+Contributing
+^^^^^^^^^^^^
+
+- :ref:`doc_handling_compatibility_breakages`
+- :ref:`doc_ways_to_contribute`
+
+GDExtension
+^^^^^^^^^^^
+
+- :ref:`doc_gdextension_file`
+- :ref:`doc_gdextension_docs_system`
+
+Migrating
+^^^^^^^^^
+
+- :ref:`doc_upgrading_to_godot_4.3`
+
+Rendering
+^^^^^^^^^
+
+- :ref:`doc_compositor`
+
+XR
+^^
+
+- :ref:`doc_a_better_xr_start_script`
+- :ref:`doc_openxr_passthrough`
+- :ref:`doc_xr_next_steps`
+- :ref:`doc_openxr_settings`
+- :ref:`doc_openxr_composition_layers`
+- :ref:`doc_openxr_body_tracking`
+
+
New pages since version 4.1
---------------------------
diff --git a/about/faq.rst b/about/faq.rst
index a5864dba9b4..a491bdbb854 100644
--- a/about/faq.rst
+++ b/about/faq.rst
@@ -167,6 +167,38 @@ The main reasons for creating a custom scripting language for Godot were:
GDScript was designed to curtail the issues above, and more.
+.. _doc_faq_which_programming_language_is_fastest:
+
+Which programming language is fastest?
+--------------------------------------
+
+In most games, the *scripting language* itself is not the cause of performance
+problems. Instead, performance is slowed by inefficient algorithms (which are
+slow in all languages), by GPU performance, or by the common C++ engine code
+like physics or navigation. All languages supported by Godot are fast enough for
+general-purpose scripting. You should choose a language based on other factors,
+like ease-of-use, familiarity, platform support, or language features.
+
+In general, the performance of C# and GDScript is within the same order of
+magnitude, and C++ is faster than both.
+
+Comparing GDScript performance to C# is tricky, since C# can be faster in some
+specific cases. The C# *language* itself tends to be faster than GDScript, which
+means that C# can be faster in situations with few calls to Godot engine code.
+However, C# can be slower than GDScript when making many Godot API calls, due
+to the cost of *marshalling*. C#'s performance can also be brought down by garbage
+collection which occurs at random and unpredictable moments. This can result in
+stuttering issues in complex projects, and is not exclusive to Godot.
+
+C++, using :ref:`GDExtension `, will almost always be
+faster than either C# or GDScript. However, C++ is less easy to use than C# or
+GDScript, and is slower to develop with.
+
+You can also use multiple languages within a single project, with
+:ref:`cross-language scripting `, or by using
+GDExtension and scripting languages together. Be aware that doing so comes with
+its own complications.
+
What 3D model formats does Godot support?
-----------------------------------------
diff --git a/about/list_of_features.rst b/about/list_of_features.rst
index 1fa78622871..f365861bd21 100644
--- a/about/list_of_features.rst
+++ b/about/list_of_features.rst
@@ -10,8 +10,8 @@ This page aims to list **all** features currently supported by Godot.
.. note::
This page lists features supported by the current stable version of
- Godot. Some of these features may not be available in the
- `LTS release series (3.x) `__.
+ Godot. Some of these features are not available in the
+ `3.x release series `__.
Platforms
---------
@@ -30,8 +30,7 @@ Platforms
on an old enough base distribution.
- Official binaries are compiled using the
`Godot Engine buildroot `__,
- allowing for binaries that work across common Linux distributions
- (including LTS variants).
+ allowing for binaries that work across common Linux distributions.
- Android (editor support is experimental).
- :ref:`Web browsers `. Experimental in 4.0,
@@ -367,7 +366,7 @@ Rendering
- ETC2 (not supported on macOS).
- S3TC (not supported on mobile/Web platforms).
-**Anti-aliasing:**
+**Antialiasing:**
- Temporal :ref:`antialiasing ` (TAA).
- AMD FidelityFX Super Resolution 2.2 :ref:`antialiasing ` (FSR2),
@@ -487,7 +486,7 @@ Scripting
- Use any build system and language features you wish.
- Actively developed GDExtension bindings for `D `__,
- `Haxe `__, `Swift `__, and `Rust `__
+ `Swift `__, and `Rust `__
bindings provided by the community. (Some of these bindings may be experimental and not production-ready).
Audio
diff --git a/community/asset_library/submitting_to_assetlib.rst b/community/asset_library/submitting_to_assetlib.rst
index 89a38c03ad3..c4c5c5ae76c 100644
--- a/community/asset_library/submitting_to_assetlib.rst
+++ b/community/asset_library/submitting_to_assetlib.rst
@@ -211,12 +211,6 @@ You can check all assets currently pending a review `here `_,
- or the official Discord server.
-
You will be informed when your asset is reviewed. If it was rejected,
you will be told why that may have been, and you will be able to submit it again
with the appropriate changes.
diff --git a/community/tutorials.rst b/community/tutorials.rst
index 8a8467a43b6..18d61d28899 100644
--- a/community/tutorials.rst
+++ b/community/tutorials.rst
@@ -3,7 +3,10 @@
Tutorials and resources
=======================
-This is a list of third-party tutorials and resources created by the Godot community. For resources, remember that there is the official `Godot Asset Library `_ full of official and community resources too! Also, have a look at this `huge list over at Reddit `_.
+This is a list of third-party tutorials and resources created by the Godot
+community. For resources, remember that there is the official
+`Godot Asset Library `_ full of
+official and community resources too!
Think there is something missing here? Feel free to submit a `Pull Request `_ as always.
diff --git a/conf.py b/conf.py
index cb6b7457720..57613a1de2d 100644
--- a/conf.py
+++ b/conf.py
@@ -9,7 +9,7 @@
# -- General configuration ------------------------------------------------
-needs_sphinx = "1.3"
+needs_sphinx = "8.1"
# Sphinx extension module names and templates location
sys.path.append(os.path.abspath("_extensions"))
@@ -63,6 +63,9 @@
# Specify the site name for the Open Graph extension.
ogp_site_name = "Godot Engine documentation"
+ogp_social_cards = {
+ "enable": False
+}
if not os.getenv("SPHINX_NO_GDSCRIPT"):
extensions.append("gdscript")
@@ -158,7 +161,6 @@
# -- Options for HTML output ----------------------------------------------
html_theme = "sphinx_rtd_theme"
-html_theme_path = [sphinx_rtd_theme.get_html_theme_path()]
if on_rtd:
using_rtd_theme = True
@@ -168,8 +170,11 @@
"logo_only": True,
# Collapse navigation (False makes it tree-like)
"collapse_navigation": False,
- # Hide the documentation version name/number under the logo
- "display_version": False,
+ # Remove version and language picker beneath the title
+ "version_selector": False,
+ "language_selector": False,
+ # Set Flyout menu to attached
+ "flyout_display": "attached",
}
html_title = supported_languages[language] % ( "(" + version + ")" )
@@ -181,13 +186,9 @@
"github_repo": "godot-docs", # Repo name
"github_version": "4.3", # Version
"conf_py_path": "/", # Path in the checkout to the docs root
- "godot_inject_language_links": True,
- "godot_docs_supported_languages": list(supported_languages.keys()),
"godot_docs_title": supported_languages[language],
"godot_docs_basepath": "https://docs.godotengine.org/",
"godot_docs_suffix": ".html",
- "godot_default_lang": "en",
- "godot_canonical_version": "stable",
# Distinguish local development website from production website.
# This prevents people from looking for changes on the production website after making local changes :)
"godot_title_prefix": "" if on_rtd else "(DEV) ",
@@ -211,16 +212,14 @@
# These paths are either relative to html_static_path
# or fully qualified paths (e.g. https://...)
html_css_files = [
- 'css/algolia.css',
- 'https://cdn.jsdelivr.net/npm/docsearch.js@2/dist/cdn/docsearch.min.css',
- "css/custom.css?10", # Increment the number at the end when the file changes to bust the cache.
+ "css/custom.css",
]
if not on_rtd:
html_css_files.append("css/dev.css")
html_js_files = [
- "js/custom.js?7", # Increment the number at the end when the file changes to bust the cache.
+ "js/custom.js",
]
# Output file base name for HTML help builder
diff --git a/contributing/development/code_style_guidelines.rst b/contributing/development/code_style_guidelines.rst
index 05b1686b806..567b73eaef7 100644
--- a/contributing/development/code_style_guidelines.rst
+++ b/contributing/development/code_style_guidelines.rst
@@ -61,6 +61,8 @@ You need to use **clang-format 17** to be compatible with Godot's format. Later
be suitable, but previous versions may not support all used options, or format
some things differently, leading to style issues in pull requests.
+.. _doc_code_style_guidelines_pre_commit_hook:
+
Pre-commit hook
^^^^^^^^^^^^^^^
diff --git a/contributing/development/compiling/compiling_for_ios.rst b/contributing/development/compiling/compiling_for_ios.rst
index 6cd9686f73c..c5d370daff6 100644
--- a/contributing/development/compiling/compiling_for_ios.rst
+++ b/contributing/development/compiling/compiling_for_ios.rst
@@ -20,9 +20,6 @@ Requirements
Xcode and need to install iOS support, go to *Xcode -> Settings... -> Platforms*.
- Go to *Xcode -> Settings... -> Locations -> Command Line Tools* and select
an installed version. Even if one is already selected, re-select it.
-
-If you are building the ``master`` branch:
-
- Download and follow README instructions to build a static ``.xcframework``
from the `MoltenVK SDK `__.
@@ -49,46 +46,40 @@ If you are building the ``master`` branch:
Compiling
---------
-Open a Terminal, go to the root dir of the engine source code and type:
+Open a Terminal, go to the root folder of the engine source code and type
+the following to compile a debug build:
::
- scons platform=ios target=template_debug
+ scons platform=ios target=template_debug generate_bundle=yes
-for a debug build, or:
+To compile a release build:
::
- scons platform=ios target=template_release
-
-for a release build (check ``platform/ios/detect.py`` for the compiler
-flags used for each configuration).
+ scons platform=ios target=template_release generate_bundle=yes
-Alternatively, you can run
+Alternatively, you can run the following command for Xcode simulator libraries (optional):
::
- scons platform=ios target=template_debug ios_simulator=yes arch=x86_64
scons platform=ios target=template_debug ios_simulator=yes arch=arm64
+ scons platform=ios target=template_debug ios_simulator=yes arch=x86_64 generate_bundle=yes
-for a Simulator libraries.
+These simulator libraries cannot be used to run the exported project on the
+target device. Instead, they can be used to run the exported project directly on
+your Mac while still testing iOS platform-specific functionality.
To create an Xcode project like in the official builds, you need to use the
template located in ``misc/dist/ios_xcode``. The release and debug libraries
-should be placed in ``libgodot.ios.debug.xcframework`` and ``libgodot.ios.release.xcframework`` respectively.
-
-::
-
- cp -r misc/dist/ios_xcode .
-
- cp libgodot.ios.template_debug.arm64.a ios_xcode/libgodot.ios.debug.xcframework/ios-arm64/libgodot.a
- lipo -create libgodot.ios.template_debug.arm64.simulator.a libgodot.ios.template_debug.x86_64.simulator.a -output ios_xcode/libgodot.ios.debug.xcframework/ios-arm64_x86_64-simulator/libgodot.a
-
- cp libgodot.ios.template_release.arm64.a ios_xcode/libgodot.ios.release.xcframework/ios-arm64/libgodot.a
- lipo -create libgodot.ios.template_release.arm64.simulator.a libgodot.ios.template_release.x86_64.simulator.a -output ios_xcode/libgodot.ios.release.xcframework/ios-arm64_x86_64-simulator/libgodot.a
-
-The MoltenVK static ``.xcframework`` folder must also be placed in the ``ios_xcode``
-folder once it has been created.
+should be placed in ``libgodot.ios.debug.xcframework`` and
+``libgodot.ios.release.xcframework`` respectively. This process can be automated
+by using the ``generate_bundle=yes`` option on the *last* SCons command used to
+build export templates (so that all binaries can be included).
+
+The MoltenVK static ``.xcframework`` folder must also be placed in the
+``ios_xcode`` folder once it has been created. MoltenVK is always statically
+linked on iOS; there is no dynamic linking option available, unlike macOS.
Run
---
diff --git a/contributing/development/compiling/compiling_for_linuxbsd.rst b/contributing/development/compiling/compiling_for_linuxbsd.rst
index f3fcbc3f368..20638c0e8e4 100644
--- a/contributing/development/compiling/compiling_for_linuxbsd.rst
+++ b/contributing/development/compiling/compiling_for_linuxbsd.rst
@@ -248,6 +248,12 @@ Start a terminal, go to the root dir of the engine source code and type:
``linuxbsd``. If you are looking to compile Godot 3.x, make sure to use the
`3.x branch of this documentation `__.
+.. tip::
+ If you are compiling Godot to make changes or contribute to the engine,
+ you may want to use the SCons options ``dev_build=yes`` or ``dev_mode=yes``.
+ See :ref:`doc_introduction_to_the_buildsystem_development_and_production_aliases`
+ for more info.
+
If all goes well, the resulting binary executable will be placed in the
"bin" subdirectory. This executable file contains the whole engine and
runs without any dependencies. Executing it will bring up the Project
@@ -573,34 +579,3 @@ running ``scons -h``, then looking for options starting with ``builtin_``.
across Linux distributions anymore. Do not use this approach for creating
binaries you intend to distribute to others, unless you're creating a
package for a Linux distribution.
-
-Using Pyston for faster development
------------------------------------
-
-You can use `Pyston `__ to run SCons. Pyston is a JIT-enabled
-implementation of the Python language (which SCons is written in). It is currently
-only compatible with Linux. Pyston can speed up incremental builds significantly,
-often by a factor between 1.5× and 2×. Pyston can be combined with Clang and LLD
-to get even faster builds.
-
-- Download the `latest portable Pyston release `__.
-- Extract the portable ``.tar.gz`` to a set location, such as ``$HOME/.local/opt/pyston/`` (create folders as needed).
-- Use ``cd`` to reach the extracted Pyston folder from a terminal,
- then run ``./pyston -m pip install scons`` to install SCons within Pyston.
-- To make SCons via Pyston easier to run, create a symbolic link of its wrapper
- script to a location in your ``PATH`` environment variable::
-
- ln -s ~/.local/opt/pyston/bin/scons ~/.local/bin/pyston-scons
-
-- Instead of running ``scons ``, run ``pyston-scons ``
- to compile Godot.
-
-If you can't run ``pyston-scons`` after creating the symbolic link,
-make sure ``$HOME/.local/bin/`` is part of your user's ``PATH`` environment variable.
-
-.. note::
-
- Alternatively, you can run ``python -m pip install pyston_lite_autoload``
- then run SCons as usual. This will automatically load a subset of Pyston's
- optimizations in any Python program you run. However, this won't bring as
- much of a performance improvement compared to installing "full" Pyston.
diff --git a/contributing/development/compiling/compiling_for_macos.rst b/contributing/development/compiling/compiling_for_macos.rst
index 65ae80af523..5e984641f16 100644
--- a/contributing/development/compiling/compiling_for_macos.rst
+++ b/contributing/development/compiling/compiling_for_macos.rst
@@ -59,6 +59,12 @@ To support both architectures in a single "Universal 2" binary, run the above tw
lipo -create bin/godot.macos.editor.x86_64 bin/godot.macos.editor.arm64 -output bin/godot.macos.editor.universal
+.. tip::
+ If you are compiling Godot to make changes or contribute to the engine,
+ you may want to use the SCons options ``dev_build=yes`` or ``dev_mode=yes``.
+ See :ref:`doc_introduction_to_the_buildsystem_development_and_production_aliases`
+ for more info.
+
If all goes well, the resulting binary executable will be placed in the
``bin/`` subdirectory. This executable file contains the whole engine and
runs without any dependencies. Executing it will bring up the Project
@@ -119,70 +125,46 @@ To build macOS export templates, you have to compile using the targets without
the editor: ``target=template_release`` (release template) and
``target=template_debug``.
-Official templates are universal binaries which support both Intel x86_64 and
-ARM64 architectures. You can also create export templates that support only one
-of those two architectures by leaving out the ``lipo`` step below.
+Official templates are *Universal 2* binaries which support both ARM64 and Intel
+x86_64 architectures.
-- For Intel x86_64::
+- To support ARM64 (Apple Silicon) + Intel x86_64::
- scons platform=macos target=template_release arch=x86_64
+ scons platform=macos target=template_debug arch=arm64
+ scons platform=macos target=template_release arch=arm64
scons platform=macos target=template_debug arch=x86_64
+ scons platform=macos target=template_release arch=x86_64 generate_bundle=yes
-- For Arm64 (Apple M1)::
+- To support ARM64 (Apple Silicon) only (smaller file size, but less compatible with older hardware)::
- scons platform=macos target=template_release arch=arm64
scons platform=macos target=template_debug arch=arm64
-
-To support both architectures in a single "Universal 2" binary, run the above
-two commands blocks and then use ``lipo`` to bundle them together::
-
- lipo -create bin/godot.macos.template_release.x86_64 bin/godot.macos.template_release.arm64 -output bin/godot.macos.template_release.universal
- lipo -create bin/godot.macos.template_debug.x86_64 bin/godot.macos.template_debug.arm64 -output bin/godot.macos.template_debug.universal
+ scons platform=macos target=template_release arch=arm64 generate_bundle=yes
To create an ``.app`` bundle like in the official builds, you need to use the
-template located in ``misc/dist/macos_template.app``. The release and debug
-builds should be placed in ``macos_template.app/Contents/MacOS`` with the names
-``godot_macos_release.universal`` and ``godot_macos_debug.universal`` respectively. You can do so
-with the following commands (assuming a universal build, otherwise replace the
-``.universal`` extension with the one of your arch-specific binaries)::
-
- cp -r misc/dist/macos_template.app .
- mkdir -p macos_template.app/Contents/MacOS
- cp bin/godot.macos.template_release.universal macos_template.app/Contents/MacOS/godot_macos_release.universal
- cp bin/godot.macos.template_debug.universal macos_template.app/Contents/MacOS/godot_macos_debug.universal
- chmod +x macos_template.app/Contents/MacOS/godot_macos*
+template located in ``misc/dist/macos_template.app``. This process can be automated by using
+the ``generate_bundle=yes`` option on the *last* SCons command used to build export templates
+(so that all binaries can be included). This option also takes care of calling ``lipo`` to create
+an *Universal 2* binary from two separate ARM64 and x86_64 binaries (if both were compiled beforehand).
.. note::
- If you are building the ``master`` branch, you also need to include support
- for the MoltenVK Vulkan portability library. By default, it will be linked
- statically from your installation of the Vulkan SDK for macOS.
- You can also choose to link it dynamically by passing ``use_volk=yes`` and
- including the dynamic library in your ``.app`` bundle::
+ You also need to include support for the MoltenVK Vulkan portability
+ library. By default, it will be linked statically from your installation of
+ the Vulkan SDK for macOS. You can also choose to link it dynamically by
+ passing ``use_volk=yes`` and including the dynamic library in your ``.app``
+ bundle::
mkdir -p macos_template.app/Contents/Frameworks
cp /macOS/libs/libMoltenVK.dylib macos_template.app/Contents/Frameworks/libMoltenVK.dylib
+ In most cases, static linking should be preferred as it makes distribution
+ easier. The main upside of dynamic linking is that it allows updating
+ MoltenVK without having to recompile export templates.
+
You can then zip the ``macos_template.app`` folder to reproduce the ``macos.zip``
template from the official Godot distribution::
- zip -q -9 -r macos.zip macos_template.app
-
-Using Pyston for faster development
------------------------------------
-
-You can use `Pyston `__ to run SCons. Pyston is a
-JIT-enabled implementation of the Python language (which SCons is written in).
-Its "full" version is currently only compatible with Linux, but Pyston-lite is
-also compatible with macOS (both x86 and ARM). Pyston can speed up incremental
-builds significantly, often by a factor between 1.5× and 2×. Pyston can be
-combined with alternative linkers such as LLD or Mold to get even faster builds.
-
-To install Pyston-lite, run ``python -m pip install pyston_lite_autoload`` then
-run SCons as usual. This will automatically load a subset of Pyston's
-optimizations in any Python program you run. However, this won't bring as much
-of a performance improvement compared to installing "full" Pyston (which
-currently can't be done on macOS).
+ zip -r9 macos.zip macos_template.app
Cross-compiling for macOS from Linux
------------------------------------
diff --git a/contributing/development/compiling/compiling_for_web.rst b/contributing/development/compiling/compiling_for_web.rst
index 89e1a1e916c..e6d9bcf4098 100644
--- a/contributing/development/compiling/compiling_for_web.rst
+++ b/contributing/development/compiling/compiling_for_web.rst
@@ -125,7 +125,7 @@ server requirements.
python platform/web/serve.py
This will serve the contents of the ``bin/`` folder and open the default web
- browser automatically. In the page that opens, access ``godot.tools.html``
+ browser automatically. In the page that opens, access ``godot.editor.html``
and you should be able to test the web editor this way.
Note that for production use cases, this Python-based web server should not
diff --git a/contributing/development/compiling/compiling_for_windows.rst b/contributing/development/compiling/compiling_for_windows.rst
index d212027a75e..7b26863bb3b 100644
--- a/contributing/development/compiling/compiling_for_windows.rst
+++ b/contributing/development/compiling/compiling_for_windows.rst
@@ -146,6 +146,12 @@ the engine source code (using ``cd``) and type:
.. note:: When compiling with multiple CPU threads, SCons may warn about
pywin32 being missing. You can safely ignore this warning.
+.. tip::
+ If you are compiling Godot to make changes or contribute to the engine,
+ you may want to use the SCons options ``dev_build=yes`` or ``dev_mode=yes``.
+ See :ref:`doc_introduction_to_the_buildsystem_development_and_production_aliases`
+ for more info.
+
If all goes well, the resulting binary executable will be placed in
``C:\godot\bin\`` with the name ``godot.windows.editor.x86_32.exe`` or
``godot.windows.editor.x86_64.exe``. By default, SCons will build a binary matching
diff --git a/contributing/development/compiling/getting_source.rst b/contributing/development/compiling/getting_source.rst
index 36e4e420454..f5d2ee35cd3 100644
--- a/contributing/development/compiling/getting_source.rst
+++ b/contributing/development/compiling/getting_source.rst
@@ -32,8 +32,8 @@ the following in a terminal:
::
git clone https://github.com/godotengine/godot.git
- # You can add the --depth 1 argument to omit the commit history.
- # Faster, but not all Git operations (like blame) will work.
+ # You can add the --depth 1 argument to omit the commit history (shallow clone).
+ # A shallow clone is faster, but not all Git operations (like blame) will work.
For any stable release, visit the `release page `__
and click on the link for the release you want.
@@ -42,13 +42,24 @@ You can then download and extract the source from the download link on the page.
With ``git``, you can also clone a stable release by specifying its branch or tag
after the ``--branch`` (or just ``-b``) argument::
- # Clone the continuously maintained stable branch (`3.x` as of writing).
- git clone https://github.com/godotengine/godot.git -b 3.x
+ # Clone the continuously maintained stable branch (`4.3` as of writing).
+ git clone https://github.com/godotengine/godot.git -b 4.3
- # Clone the `3.2.3-stable` tag. This is a fixed revision that will never change.
- git clone https://github.com/godotengine/godot.git -b 3.2.3-stable
+ # Clone the `4.3-stable` tag. This is a fixed revision that will never change.
+ git clone https://github.com/godotengine/godot.git -b 4.3-stable
-There are also generally branches besides ``master`` for each major version.
+ # After cloning, optionally go to a specific commit.
+ # This can be used to access the source code at a specific point in time,
+ # e.g. for development snapshots, betas and release candidates.
+ cd godot
+ git checkout f4af8201bac157b9d47e336203d3e8a8ef729de2
+
+The `maintenance branches `__
+are used to release further patches on each minor version.
+
+You can get the source code for each release and pre-release in ``.tar.xz`` format from
+`godotengine/godot-builds on GitHub `__.
+This lacks version control information but has a slightly smaller download size.
After downloading the Godot source code,
you can :ref:`continue to compiling Godot `.
diff --git a/contributing/development/compiling/index.rst b/contributing/development/compiling/index.rst
index cba84bb22d2..ecc93854079 100644
--- a/contributing/development/compiling/index.rst
+++ b/contributing/development/compiling/index.rst
@@ -19,6 +19,7 @@ The articles below should help you navigate configuration options available, as
prerequisites required to compile Godot exactly the way you need.
.. rubric:: Basics of building Godot
+ :heading-level: 2
Let's start with basics, and learn how to get Godot's source code, and then which options
to use to compile it regardless of your target platform.
@@ -31,6 +32,7 @@ to use to compile it regardless of your target platform.
introduction_to_the_buildsystem
.. rubric:: Building for target platforms
+ :heading-level: 2
Below you can find instructions for compiling the engine for your specific target platform.
Note that Godot supports cross-compilation, which means you can compile it for a target platform
@@ -50,6 +52,7 @@ will try their best to cover all possible situations.
compiling_for_web
.. rubric:: Other compilation targets and options
+ :heading-level: 2
Some additional universal compilation options require further setup. Namely, while Godot
does have C#/.NET support as a part of its main codebase, it does not get compiled by
diff --git a/contributing/development/compiling/introduction_to_the_buildsystem.rst b/contributing/development/compiling/introduction_to_the_buildsystem.rst
index 2b01c0f8a59..73ec7587f7f 100644
--- a/contributing/development/compiling/introduction_to_the_buildsystem.rst
+++ b/contributing/development/compiling/introduction_to_the_buildsystem.rst
@@ -139,6 +139,8 @@ run projects but does not include the editor or the Project Manager.
scons platform= target=editor/template_debug/template_release
+.. _doc_introduction_to_the_buildsystem_development_and_production_aliases:
+
Development and production aliases
----------------------------------
diff --git a/contributing/development/configuring_an_ide/visual_studio_code.rst b/contributing/development/configuring_an_ide/visual_studio_code.rst
index 165b2a14b2e..2c40ede2e4f 100644
--- a/contributing/development/configuring_an_ide/visual_studio_code.rst
+++ b/contributing/development/configuring_an_ide/visual_studio_code.rst
@@ -139,6 +139,22 @@ To run and debug the project you need to create a new configuration in the ``lau
"preLaunchTask": "build"
}
+ .. code-tab:: js Mac
+
+ {
+ "name": "Launch Project",
+ "type": "lldb",
+ "request": "custom",
+ "targetCreateCommands": [
+ "target create ${workspaceFolder}/bin/godot.macos.editor.dev.x86_64"
+ ],
+ // Change the arguments below for the project you want to test with.
+ // To run the project instead of editing it, remove the "--editor" argument.
+ "processCreateCommands": [
+ "process launch -- --editor --path path-to-your-godot-project-folder"
+ ]
+ }
+
.. figure:: img/vscode_2_launch.json.png
:figclass: figure-w480
:align: center
diff --git a/contributing/development/core_and_modules/custom_platform_ports.rst b/contributing/development/core_and_modules/custom_platform_ports.rst
index 80a1e09a8fe..3c24193d234 100644
--- a/contributing/development/core_and_modules/custom_platform_ports.rst
+++ b/contributing/development/core_and_modules/custom_platform_ports.rst
@@ -82,7 +82,7 @@ for reference.
class to get much of the work done automatically.
If the platform is not UNIX-like, you might use the
- `Windows port `
+ `Windows port `__
as a reference.
**detect.py file**
@@ -131,7 +131,8 @@ games.
platform's screen resolution feature (if relevant). Any attempt to create
or manipulate other window IDs can be rejected.
- *If the target platform supports the graphics APIs in question:* Rendering
- context for `Vulkan `__,
+ context for `Vulkan `__,
+ `Direct3D 12 `__
`OpenGL 3.3 or OpenGL ES 3.0 `__.
- Input handlers for `keyboard `__
and `controller `__.
@@ -157,8 +158,8 @@ games.
is displayed at the top of the editor when one-click deploy is set up for the
target platform.
-If the target platform doesn't support running Vulkan, OpenGL 3.3 or OpenGL ES 3.0,
-you have two options:
+If the target platform doesn't support running Vulkan, Direct3D 12, OpenGL 3.3,
+or OpenGL ES 3.0, you have two options:
- Use a library at run-time to translate Vulkan or OpenGL calls to another graphics API.
For example, `MoltenVK `__ is used on macOS
diff --git a/contributing/development/core_and_modules/custom_resource_format_loaders.rst b/contributing/development/core_and_modules/custom_resource_format_loaders.rst
index 9066fbdb6e7..fd78c193bca 100644
--- a/contributing/development/core_and_modules/custom_resource_format_loaders.rst
+++ b/contributing/development/core_and_modules/custom_resource_format_loaders.rst
@@ -269,7 +269,7 @@ calls into ``std::istream``.
.. code-block:: cpp
- #include "core/os/file_access.h"
+ #include "core/io/file_access.h"
#include
#include
@@ -304,7 +304,7 @@ References
- `istream `_
- `streambuf `_
-- `core/io/file_access.h `_
+- `core/io/file_access.h `_
Registering the new file format
-------------------------------
diff --git a/contributing/development/core_and_modules/index.rst b/contributing/development/core_and_modules/index.rst
index a9727d8758d..e4d94472850 100644
--- a/contributing/development/core_and_modules/index.rst
+++ b/contributing/development/core_and_modules/index.rst
@@ -7,6 +7,7 @@ The following pages are meant to introduce the global organization of Godot Engi
source code, and give useful tips for extending and fixing the engine on the C++ side.
.. rubric:: Getting started with Godot's source code
+ :heading-level: 2
This section covers the basics that you will encounter in (almost) every source file.
@@ -25,6 +26,7 @@ This section covers the basics that you will encounter in (almost) every source
scripting_development
.. rubric:: Extending Godot by modifying its source code
+ :heading-level: 2
This section covers what you can do by modifying Godot's C++ source code.
diff --git a/contributing/development/core_and_modules/internal_rendering_architecture.rst b/contributing/development/core_and_modules/internal_rendering_architecture.rst
index b2c8e0b791d..75ab68ef643 100644
--- a/contributing/development/core_and_modules/internal_rendering_architecture.rst
+++ b/contributing/development/core_and_modules/internal_rendering_architecture.rst
@@ -228,8 +228,8 @@ 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.
-It is possible to use the use of OpenGL ES 3.0 directly on desktop platforms
-using the ``--rendering-driver opengl3_es`` command line argument, although this
+It is possible to use OpenGL ES 3.0 directly on desktop platforms
+by passing the ``--rendering-driver opengl3_es`` command line argument, although this
will only work on graphics drivers that feature native OpenGL ES support (such
as Mesa).
diff --git a/contributing/development/core_and_modules/object_class.rst b/contributing/development/core_and_modules/object_class.rst
index e2afbdad761..ffa69908cbf 100644
--- a/contributing/development/core_and_modules/object_class.rst
+++ b/contributing/development/core_and_modules/object_class.rst
@@ -274,7 +274,7 @@ References:
Resources
----------
-:ref:`Resource ` inherits from Reference, so all resources
+:ref:`Resource ` inherits from RefCounted, so all resources
are reference counted. Resources can optionally contain a path, which
reference a file on disk. This can be set with ``resource.set_path(path)``,
though this is normally done by the resource loader. No two different
diff --git a/contributing/development/core_and_modules/variant_class.rst b/contributing/development/core_and_modules/variant_class.rst
index 7bd8e3460e0..e0e165899e6 100644
--- a/contributing/development/core_and_modules/variant_class.rst
+++ b/contributing/development/core_and_modules/variant_class.rst
@@ -6,22 +6,21 @@ Variant class
About
-----
-Variant is the most important datatype of Godot, it's the most important
-class in the engine. A Variant takes up only 20 bytes and can store
-almost any engine datatype inside of it. Variants are rarely used to
-hold information for long periods of time, instead they are used mainly
-for communication, editing, serialization and generally moving data
-around.
+Variant is the most important datatype in Godot. A Variant takes up only 24
+bytes on 64-bit platforms (20 bytes on 32-bit platforms) and can store almost
+any engine datatype inside of it. Variants are rarely used to hold information
+for long periods of time, instead they are used mainly for communication,
+editing, serialization and generally moving data around.
A Variant can:
-- Store almost any datatype
+- Store almost any datatype.
- Perform operations between many variants (GDScript uses Variant as
its atomic/native datatype).
-- Be hashed, so it can be compared quickly to other variants
-- Be used to convert safely between datatypes
+- Be hashed, so it can be compared quickly to other variants.
+- Be used to convert safely between datatypes.
- Be used to abstract calling methods and their arguments (Godot
- exports all its functions through variants)
+ exports all its functions through variants).
- Be used to defer calls or move data between threads.
- Be serialized as binary and stored to disk, or transferred via
network.
@@ -34,27 +33,122 @@ Basically, thanks to the Variant class, writing Godot itself was a much,
much easier task, as it allows for highly dynamic constructs not common
of C++ with little effort. Become a friend of Variant today.
-References:
-~~~~~~~~~~~
+.. note::
+
+ All types within Variant except Nil and Object **cannot** be ``null`` and
+ must always store a valid value. These types within Variant are therefore
+ called *non-nullable* types.
+
+ One of the Variant types is *Nil* which can only store the value ``null``.
+ Therefore, it is possible for a Variant to contain the value ``null``, even
+ though all Variant types excluding Nil and Object are non-nullable.
+
+References
+~~~~~~~~~~
- `core/variant/variant.h `__
-Containers: Dictionary and Array
+List of variant types
+---------------------
+
+These types are available in Variant:
+
++---------------------------------+---------------------------+
+| Type | Notes |
++=================================+===========================+
+| Nil (can only store ``null``) | Nullable type |
++---------------------------------+---------------------------+
+| :ref:`class_bool` | |
++---------------------------------+---------------------------+
+| :ref:`class_int` | |
++---------------------------------+---------------------------+
+| :ref:`class_float` | |
++---------------------------------+---------------------------+
+| :ref:`class_string` | |
++---------------------------------+---------------------------+
+| :ref:`class_vector2` | |
++---------------------------------+---------------------------+
+| :ref:`class_vector2i` | |
++---------------------------------+---------------------------+
+| :ref:`class_rect2` | 2D counterpart of AABB |
++---------------------------------+---------------------------+
+| :ref:`class_rect2i` | |
++---------------------------------+---------------------------+
+| :ref:`class_vector3` | |
++---------------------------------+---------------------------+
+| :ref:`class_vector3i` | |
++---------------------------------+---------------------------+
+| :ref:`class_transform2d` | |
++---------------------------------+---------------------------+
+| :ref:`class_vector4` | |
++---------------------------------+---------------------------+
+| :ref:`class_vector4i` | |
++---------------------------------+---------------------------+
+| :ref:`class_plane` | |
++---------------------------------+---------------------------+
+| :ref:`class_quaternion` | |
++---------------------------------+---------------------------+
+| :ref:`class_aabb` | 3D counterpart of Rect2 |
++---------------------------------+---------------------------+
+| :ref:`class_basis` | |
++---------------------------------+---------------------------+
+| :ref:`class_transform3d` | |
++---------------------------------+---------------------------+
+| :ref:`class_projection` | |
++---------------------------------+---------------------------+
+| :ref:`class_color` | |
++---------------------------------+---------------------------+
+| :ref:`class_stringname` | |
++---------------------------------+---------------------------+
+| :ref:`class_nodepath` | |
++---------------------------------+---------------------------+
+| :ref:`class_rid` | |
++---------------------------------+---------------------------+
+| :ref:`class_object` | Nullable type |
++---------------------------------+---------------------------+
+| :ref:`class_callable` | |
++---------------------------------+---------------------------+
+| :ref:`class_signal` | |
++---------------------------------+---------------------------+
+| :ref:`class_dictionary` | |
++---------------------------------+---------------------------+
+| :ref:`class_array` | |
++---------------------------------+---------------------------+
+| :ref:`class_packedbytearray` | |
++---------------------------------+---------------------------+
+| :ref:`class_packedint32array` | |
++---------------------------------+---------------------------+
+| :ref:`class_packedint64array` | |
++---------------------------------+---------------------------+
+| :ref:`class_packedfloat32array` | |
++---------------------------------+---------------------------+
+| :ref:`class_packedfloat64array` | |
++---------------------------------+---------------------------+
+| :ref:`class_packedstringarray` | |
++---------------------------------+---------------------------+
+| :ref:`class_packedvector2array` | |
++---------------------------------+---------------------------+
+| :ref:`class_packedvector3array` | |
++---------------------------------+---------------------------+
+| :ref:`class_packedcolorarray` | |
++---------------------------------+---------------------------+
+| :ref:`class_packedvector4array` | |
++---------------------------------+---------------------------+
+
+Containers: Array and Dictionary
--------------------------------
-Both are implemented using variants. A Dictionary can match any datatype
-used as key to any other datatype. An Array just holds an array of
-Variants. Of course, a Variant can also hold a Dictionary and an Array
-inside, making it even more flexible.
+Both :ref:`class_array` and :ref:`class_dictionary` are implemented using
+variants. A Dictionary can match any datatype used as key to any other datatype.
+An Array just holds an array of Variants. Of course, a Variant can also hold a
+Dictionary or an Array inside, making it even more flexible.
Modifications to a container will modify all references to
-it. A Mutex should be created to lock it if multi threaded access is
-desired.
-
-Copy-on-write (COW) mode support for containers was dropped with Godot 3.0.
+it. A Mutex should be created to lock it if
+:ref:`multi-threaded access ` is desired.
-References:
-~~~~~~~~~~~
+References
+~~~~~~~~~~
- `core/variant/dictionary.h `__
- `core/variant/array.h `__
diff --git a/contributing/development/editor/creating_icons.rst b/contributing/development/editor/creating_icons.rst
index 451616aca3f..cdb6047311d 100644
--- a/contributing/development/editor/creating_icons.rst
+++ b/contributing/development/editor/creating_icons.rst
@@ -47,24 +47,9 @@ Icon optimization
~~~~~~~~~~~~~~~~~
Because the editor renders SVGs once at load time, they need to be small
-in size so they can be efficiently parsed. Editor icons must be first
-optimized before being added to the engine, to do so:
-
-1. Install `svgcleaner `__
- by downloading a binary from its
- `Releases tab `__
- and placing it into a location in your ``PATH`` environment variable.
-
-2. Run the command below, replacing ``svg_source.svg`` with the path to your
- SVG file (which can be a relative or absolute path):
-
- .. code-block:: bash
-
- svgcleaner --multipass svg_source.svg svg_optimized.svg
-
-The ``--multipass`` switch improves compression, so make sure to include it.
-The optimized icon will be saved to ``svg_optimized.svg``. You can also change
-the destination parameter to any relative or absolute path you'd like.
+in size so they can be efficiently parsed. When the
+:ref:`pre-commit hook ` runs, it automatically optimizes
+the SVG using `svgo `_.
.. note::
diff --git a/contributing/documentation/contributing_to_the_documentation.rst b/contributing/documentation/contributing_to_the_documentation.rst
index 396276fa56d..cec46a00526 100644
--- a/contributing/documentation/contributing_to_the_documentation.rst
+++ b/contributing/documentation/contributing_to_the_documentation.rst
@@ -49,9 +49,11 @@ contribute, you should also read:
Contributing changes
--------------------
-**Pull Requests should use the** ``master`` **branch by default.** Only make Pull
-Requests against other branches (e.g. ``2.1`` or ``3.0``) if your changes only
-apply to that specific version of Godot.
+**Pull requests should use the** ``master`` **branch by default.** Only make pull
+requests against other branches (e.g. ``3.6`` or ``4.2``) if your changes only
+apply to that specific version of Godot. After a pull request is merged into
+``master``, it will usually be cherry-picked into the current stable branch by
+documentation maintainers.
Though less convenient to edit than a wiki, this Git repository is where we
write the documentation. Having direct access to the source files in a revision
@@ -81,20 +83,29 @@ and to log in to use it. Once logged in, you can propose change like so:
1. Click the **Edit on GitHub** button.
-2. On the GitHub page you're taken to, click the pencil icon in the top-right
- corner near the **Raw**, **Blame**, and **Delete** buttons. It has the
- tooltip "Fork this project and edit the file".
+2. On the GitHub page you're taken to, make sure the current branch is "master".
+ Click the pencil icon in the top-right corner
+ near the **Raw**, **Blame**, and **Delete** buttons.
+ It has the tooltip "Fork this project and edit the file".
3. Edit the text in the text editor.
-4. At the bottom of the web page, summarize the changes you made and click the
- button **Propose file change**. Make sure to replace the placeholder "Update file.rst"
- by a short but clear one-line description, as this is the commit title.
+4. Click "Commit changes...", summarize the changes you made
+ and make sure to replace the placeholder "Update file.rst" by a short
+ but clear one-line description, as this is the commit title.
+ Click the button **Propose changes**.
5. On the following screens, click the **Create pull request** button until you
see a message like *Username wants to merge 1 commit into godotengine:master
from Username:patch-1*.
+.. note::
+
+ If there are more commits than your own in the pull request
+ it is likely that your branch was created using the wrong origin,
+ due to "master" not being the current branch in step 2.
+ You will need to rebase your branch to "master" or create a new branch.
+
Another contributor will review your changes and merge them into the docs if
they're good. They may also make changes or ask you to do so before merging.
diff --git a/contributing/workflow/bug_triage_guidelines.rst b/contributing/workflow/bug_triage_guidelines.rst
index 41f75ba34d4..ae4a5776b15 100644
--- a/contributing/workflow/bug_triage_guidelines.rst
+++ b/contributing/workflow/bug_triage_guidelines.rst
@@ -34,7 +34,8 @@ to both issues and pull requests.
Labels
~~~~~~
-The following labels are currently defined in the Godot repository:
+The following `labels `__ are
+currently defined in the Godot repository:
**Categories:**
@@ -58,16 +59,19 @@ The following labels are currently defined in the Godot repository:
- *Discussion*: the issue is not consensual and needs further
discussion to define what exactly should be done to address the
topic.
-- *Documentation*: issue related to the documentation. Mainly to request
- enhancements in the API documentation. Issues related to the ReadTheDocs
- documentation should be filed on the
- `godot-docs `_ repository.
+- *Documentation*: related to the documentation. PRs with this label improve the
+ class reference. Issues with this label are either for wrong documentation, or
+ are user-reported "bugs" that are actually limitations to be further documented.
+ Often paired with *Discussion*. Issues related to the ReadTheDocs documentation
+ should be filed on the `godot-docs `_ repository.
- *Enhancement*: describes a proposed enhancement to an existing
functionality.
- *Feature proposal*: describes a wish for a new feature to be
implemented. Note that the main Godot repository no longer accepts
feature requests. Please use
`godot-proposals `__ instead.
+ PRs which add new features but do not have a corresponding proposal use this
+ label.
- *For PR meeting*: the issue needs to be discussed in a pull request meeting.
These meetings are public and are held on the `Godot Contributors Chat `_.
- *Good first issue*: the issue is *assumed* to be an easy one to fix, which makes
@@ -81,6 +85,7 @@ The following labels are currently defined in the Godot repository:
on different hardware/software configurations or even that the steps to
reproduce are not certain.
- *Needs work*: the pull request needs additional work before it can be merged.
+ Also for issues that are very incomplete, such as missing reproduction steps.
- *Performance*: issues that directly impact engine or editor performance.
Can also be used for pull requests that improve performance or add low-end-friendly options.
Should not be coupled with *Usability*.
@@ -124,7 +129,7 @@ describe an issue or pull request.
- *Input*: relates to the input system.
- *Multiplayer*: relates to multiplayer (high-level networking) systems.
- *Navigation*: relates to the navigation system (including A* and navmeshes).
-- *Network*: relates to (lot-level) networking.
+- *Network*: relates to (low-level) networking.
- *Particles*: particles, particle systems and their editors.
- *Physics*: relates to the physics engine (2D/3D).
- *Plugin*: relates to problems encountered while writing plugins.
@@ -153,7 +158,7 @@ Documentation labels
~~~~~~~~~~~~~~~~~~~~
In the `documentation repository `__, we
-use the following labels:
+use the following `labels `__:
- *Archived*: either a duplicate of another issue, or invalid. Such an
issue would also be closed.
diff --git a/contributing/workflow/pr_workflow.rst b/contributing/workflow/pr_workflow.rst
index 0f373d3676f..040cdc9031e 100644
--- a/contributing/workflow/pr_workflow.rst
+++ b/contributing/workflow/pr_workflow.rst
@@ -97,9 +97,6 @@ To clone your fork from GitHub, use the following command:
git clone https://github.com/USERNAME/godot
-.. note:: In our examples, the "$" character denotes the command line prompt
- on typical UNIX shells. It is not part of the command and should
- not be typed.
After a little while, you should have a ``godot`` directory in your current
working directory. Move into it using the ``cd`` command:
diff --git a/getting_started/first_2d_game/02.player_scene.rst b/getting_started/first_2d_game/02.player_scene.rst
index 20799618811..24612d023bb 100644
--- a/getting_started/first_2d_game/02.player_scene.rst
+++ b/getting_started/first_2d_game/02.player_scene.rst
@@ -20,8 +20,16 @@ what the object *is*. Click the "Other Node" button and add an :ref:`Area2D
.. image:: img/add_node.webp
-Godot will display a warning icon next to the node in the scene tree. You can
-ignore it for now. We will address it later.
+When you add the ``Area2D`` node, Godot will display the following **warning icon**
+next to it in the scene tree:
+
+.. image:: img/no_shape_warning.webp
+
+This warning tells us that the ``Area2D`` node requires a shape to detect collisions or overlaps.
+We can **ignore the warning temporarily** because we will first set up the player's visuals
+(using an animated sprite). Once the visuals are ready, we will add a collision shape as a child
+node. This will allow us to accurately size and position the shape based on the sprite’s appearance.
+
With ``Area2D`` we can detect objects that overlap or run into the player.
Change the node's name to ``Player`` by double-clicking on it. Now that we've
@@ -98,6 +106,9 @@ When you're finished, your ``Player`` scene should look like this:
.. image:: img/player_scene_nodes.webp
+Once this is done, the warning on the ``Area2D`` node will disappear, as it now has
+a shape assigned and can interact with other objects.
+
Make sure to save the scene again after these changes.
In the next part, we'll add a script to the player node to move and animate it.
diff --git a/getting_started/first_2d_game/05.the_main_game_scene.rst b/getting_started/first_2d_game/05.the_main_game_scene.rst
index a450ad2f8cb..ae4f2e775ee 100644
--- a/getting_started/first_2d_game/05.the_main_game_scene.rst
+++ b/getting_started/first_2d_game/05.the_main_game_scene.rst
@@ -224,10 +224,6 @@ Note that a new instance must be added to the scene using ``add_child()``.
// We also specified this function name in PascalCase in the editor's connection window.
private void OnMobTimerTimeout()
{
- // Note: Normally it is best to use explicit types rather than the `var`
- // keyword. However, var is acceptable to use here because the types are
- // obviously Mob and PathFollow2D, since they appear later on the line.
-
// Create a new instance of the Mob scene.
Mob mob = MobScene.Instantiate();
diff --git a/getting_started/first_2d_game/img/no_shape_warning.webp b/getting_started/first_2d_game/img/no_shape_warning.webp
new file mode 100644
index 00000000000..5caa74b0778
Binary files /dev/null and b/getting_started/first_2d_game/img/no_shape_warning.webp differ
diff --git a/getting_started/first_3d_game/02.player_input.rst b/getting_started/first_3d_game/02.player_input.rst
index a9d49650ec7..558f94d7068 100644
--- a/getting_started/first_3d_game/02.player_input.rst
+++ b/getting_started/first_3d_game/02.player_input.rst
@@ -84,6 +84,8 @@ Save the scene as ``player.tscn``
With the nodes ready, we can almost get coding. But first, we need to define
some input actions.
+.. _doc_first_3d_game_input_actions:
+
Creating input actions
----------------------
diff --git a/getting_started/step_by_step/signals.rst b/getting_started/step_by_step/signals.rst
index 5a0e512632f..9d07f0ffdcf 100644
--- a/getting_started/step_by_step/signals.rst
+++ b/getting_started/step_by_step/signals.rst
@@ -147,8 +147,8 @@ methods "_on_node_name_signal_name". Here, it'll be "_on_button_pressed".
.. note::
- If you are using an external editor (such as VS Code) this
- automatic code generation might not work. In this case you need to to connect
+ If you are using an external editor (such as VS Code), this
+ automatic code generation might not work. In this case, you need to connect
the signal via code as explained in the next section.
Click the Connect button to complete the signal connection and jump to the
diff --git a/pyproject.toml b/pyproject.toml
new file mode 100644
index 00000000000..0797f2a0766
--- /dev/null
+++ b/pyproject.toml
@@ -0,0 +1,8 @@
+[tool.ruff]
+line-length = 120
+
+[tool.codespell]
+dictionary = ["_tools/codespell-dict.txt", "-"]
+ignore-words = "_tools/codespell-ignore.txt"
+exclude-file = "_tools/codespell-ignore-lines.txt"
+skip = "tutorials/i18n/locales.rst"
diff --git a/requirements.txt b/requirements.txt
index bc435feb316..0c6e5e279e3 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -3,29 +3,22 @@
# https://github.com/readthedocs/readthedocs.org/blob/master/requirements/docs.txt
# Base dependencies
-pygments==2.15.1
+pygments==2.18.0
# Sphinx base and RTD theme.
-sphinx==4.4.0
-sphinx_rtd_theme==1.1.1
+sphinx==8.1.3
+sphinx_rtd_theme==3.0.1
# Sphinx extensions.
# Code tabs extension to display codeblocks in different languages as tabs.
-sphinx-tabs==3.4.0
+sphinx-tabs==3.4.7
# Adds a 'copy' button to the right of codeblocks.
-sphinx-copybutton==0.5.1
+sphinx-copybutton==0.5.2
# Custom 404 error page (more useful than the default).
-sphinx-notfound-page==0.8.3
+sphinx-notfound-page==1.0.4
# Adds Open Graph tags in the HTML `` tag.
-sphinxext-opengraph==0.7.5
-
-# These get pulled in by Sphinx, we need to pin these as higher versions require Sphinx 5.0+.
-sphinxcontrib-applehelp==1.0.4
-sphinxcontrib-htmlhelp==2.0.1
-sphinxcontrib-qthelp==1.0.3
-sphinxcontrib-serializinghtml==1.1.5
-sphinxcontrib-devhelp==1.0.2
+sphinxext-opengraph==0.9.1
# `.. video::` directive support to embed videos in documentation pages.
-sphinxcontrib-video==0.2.1rc0
+sphinxcontrib-video==0.2.1
diff --git a/tutorials/2d/2d_antialiasing.rst b/tutorials/2d/2d_antialiasing.rst
index 8170f04a699..7180b5b7510 100644
--- a/tutorials/2d/2d_antialiasing.rst
+++ b/tutorials/2d/2d_antialiasing.rst
@@ -77,8 +77,8 @@ affect** the following kinds of aliasing in any way:
- Aliasing in font rendering.
MSAA can be enabled in the Project Settings by changing the value of the
-**Rendering > Anti Aliasing > Quality > MSAA 2D** setting. It's important to change
-the value of the **MSAA 2D** setting and not **MSAA 3D**, as these are entirely
+:ref:`Rendering > Anti Aliasing > Quality > MSAA 2D`
+setting. It's important to change the value of the **MSAA 2D** setting and not **MSAA 3D**, as these are entirely
separate settings.
Comparison between no antialiasing (left) and various MSAA levels (right). The
diff --git a/tutorials/2d/2d_parallax.rst b/tutorials/2d/2d_parallax.rst
index ca8fea699d8..a5d85a93b19 100644
--- a/tutorials/2d/2d_parallax.rst
+++ b/tutorials/2d/2d_parallax.rst
@@ -1,4 +1,4 @@
-.. doc_2d_parallax:
+.. _doc_2d_parallax:
2D Parallax
===========
@@ -78,8 +78,11 @@ do?
Make the viewport smaller
^^^^^^^^^^^^^^^^^^^^^^^^^
-The simplest answer is to make the viewport the same size or smaller than your textures. Click on
-``Project -> Project Settings -> Window`` and change the viewport height and width to match your background.
+The simplest answer is to make the viewport the same size or smaller than your textures.
+In **Project Settings > Display > Window**, change the
+:ref:`Viewport Width`
+and :ref:`Viewport Height`
+settings to match your background.
.. image:: img/2d_parallax_size_viewport.webp
diff --git a/tutorials/2d/custom_drawing_in_2d.rst b/tutorials/2d/custom_drawing_in_2d.rst
index c50fc0d8bec..ccb39cff4f8 100644
--- a/tutorials/2d/custom_drawing_in_2d.rst
+++ b/tutorials/2d/custom_drawing_in_2d.rst
@@ -254,9 +254,9 @@ You will have to code a function to perform this and draw it yourself.
The following instructions use a fixed set of coordinates that could be too small
for high resolution screens (larger than 1080p). If that is your case, and the
- drawing is too small consider increasing your window scale in
- ``Menu > Project > Project settings > display/window/stretch/scale`` to adjust
- the project to a higher resolution (a 2 or 4 scale tends to work well).
+ drawing is too small consider increasing your window scale in the project setting
+ :ref:`Display > Window > Stretch > Scale`
+ to adjust the project to a higher resolution (a 2 or 4 scale tends to work well).
Drawing a custom polygon shape
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -487,7 +487,7 @@ You should get the following output:
Unlike ``draw_polygon()``, polylines can only have a single unique color
for all its points (the second argument). This method has 2 additional
arguments: the width of the line (which is as small as possible by default)
-and enabling or disabling the anti-aliasing (it is disabled by default).
+and enabling or disabling the antialiasing (it is disabled by default).
The order of the ``_draw`` calls is important- like with the Node positions on
the tree hierarchy, the different shapes will be drawn from top to bottom,
diff --git a/tutorials/2d/img/2d_editor_guidelines.webp b/tutorials/2d/img/2d_editor_guidelines.webp
new file mode 100644
index 00000000000..26d86067f49
Binary files /dev/null and b/tutorials/2d/img/2d_editor_guidelines.webp differ
diff --git a/tutorials/2d/img/2d_editor_viewport.webp b/tutorials/2d/img/2d_editor_viewport.webp
new file mode 100644
index 00000000000..6bc63280fee
Binary files /dev/null and b/tutorials/2d/img/2d_editor_viewport.webp differ
diff --git a/tutorials/2d/img/2d_editor_viewport_with_viewmenu.webp b/tutorials/2d/img/2d_editor_viewport_with_viewmenu.webp
new file mode 100644
index 00000000000..4a83707b184
Binary files /dev/null and b/tutorials/2d/img/2d_editor_viewport_with_viewmenu.webp differ
diff --git a/tutorials/2d/img/2d_platformer_demo.webp b/tutorials/2d/img/2d_platformer_demo.webp
new file mode 100644
index 00000000000..e1dbd886b7a
Binary files /dev/null and b/tutorials/2d/img/2d_platformer_demo.webp differ
diff --git a/tutorials/2d/img/2d_ruler_with_snap.webp b/tutorials/2d/img/2d_ruler_with_snap.webp
new file mode 100644
index 00000000000..dd33e5719c1
Binary files /dev/null and b/tutorials/2d/img/2d_ruler_with_snap.webp differ
diff --git a/tutorials/2d/img/2d_snapping_options.webp b/tutorials/2d/img/2d_snapping_options.webp
new file mode 100644
index 00000000000..1081a06bfb8
Binary files /dev/null and b/tutorials/2d/img/2d_snapping_options.webp differ
diff --git a/tutorials/2d/img/2d_snapping_options_menu.webp b/tutorials/2d/img/2d_snapping_options_menu.webp
new file mode 100644
index 00000000000..3c8c29d7bd4
Binary files /dev/null and b/tutorials/2d/img/2d_snapping_options_menu.webp differ
diff --git a/tutorials/2d/img/2d_toolbar.webp b/tutorials/2d/img/2d_toolbar.webp
new file mode 100644
index 00000000000..6b1c18efc4f
Binary files /dev/null and b/tutorials/2d/img/2d_toolbar.webp differ
diff --git a/tutorials/2d/img/3d_in_2d_demo_editor.webp b/tutorials/2d/img/3d_in_2d_demo_editor.webp
new file mode 100644
index 00000000000..960a79cfb84
Binary files /dev/null and b/tutorials/2d/img/3d_in_2d_demo_editor.webp differ
diff --git a/tutorials/2d/index.rst b/tutorials/2d/index.rst
index d90628551ee..61c9d6aa151 100644
--- a/tutorials/2d/index.rst
+++ b/tutorials/2d/index.rst
@@ -7,9 +7,12 @@
:maxdepth: 1
:name: toc-learn-features-2d
+ introduction_to_2d
canvas_layers
2d_transforms
+.. _doc_2d_rendering:
+
Rendering
---------
diff --git a/tutorials/2d/introduction_to_2d.rst b/tutorials/2d/introduction_to_2d.rst
new file mode 100644
index 00000000000..47bd4e25249
--- /dev/null
+++ b/tutorials/2d/introduction_to_2d.rst
@@ -0,0 +1,316 @@
+.. _doc_introduction_to_2d:
+
+Introduction to 2D
+==================
+
+Godot's 2D game development tools include a dedicated 2D rendering engine, physics system,
+and features tailored specifically for creating 2D experiences. You can efficiently design
+levels with the TileMap system, animate characters with 2D sprite or Cutout animation,
+and leverage 2D lighting for dynamic scene illumination. The built-in 2D particle system
+allows you to create complex visual effects, and Godot also supports custom shaders to
+enhance your graphics. These features, combined with Godot's accessibility and
+flexibility, provide a solid foundation for creating engaging 2D games.
+
+.. figure:: img/2d_platformer_demo.webp
+
+ 2D Platformer Demo available on the Asset Library.
+
+This page will show you the 2D workspace and how you can get to know it.
+
+.. tip:: If you would like to get an introduction to 3D, see :ref:`doc_introduction_to_3d`.
+
+2D workspace
+~~~~~~~~~~~~
+
+You will use the 2D workspace to work with 2D scenes, design levels, or create user
+interfaces.
+To switch to the 2D workspace, you can either select a 2D node from the scene tree,
+or use the workspace selector located at the top edge of the editor:
+
+.. image:: img/2d_editor_viewport.webp
+
+Similar to 3D, you can use the tabs below the workspace selector to change between currently
+opened scenes or create a new one using the plus (+) button. The left and right docks should
+be familiar from :ref:`editor introduction `.
+
+Below the scene selector is the main toolbar, and beneath the main toolbar
+is the 2D viewport.
+
+You can drag and drop compatible nodes from the FileSystem dock to add them to the
+viewport as nodes.
+Dragging and dropping adds the dragged node as a sibling of the selected node
+(if the root node is selected, adds as a child).
+Keeping :kbd:`Shift` pressed when dropping adds the node as a child of the selected node.
+Holding :kbd:`Alt` when dropping adds the node as a child of the root node.
+If :kbd:`Alt + Shift` is held when dropping, the node type can be selected if
+applicable.
+
+
+Main toolbar
+------------
+
+Some buttons in the main toolbar are the same as those in the 3D workspace. A brief explanation
+is given with the shortcut if the mouse cursor is hovered over a button for one second.
+Some buttons may have additional functionality if another keypress is performed.
+A recap of main functionality of each button with its default shortcut is provided below
+from left to right:
+
+.. image:: img/2d_toolbar.webp
+
+- **Select Mode** (:kbd:`Q`): Allows selection of nodes in the viewport. Left clicking on a node
+ in the viewport selects it.
+ Left clicking and dragging a rectangle selects all nodes within the rectangle's boundaries,
+ once released.
+ Holding :kbd:`Shift` while selecting adds more nodes to the selection.
+ Clicking on a selected node while holding :kbd:`Shift` deselects the node.
+ In this mode, you can drag the selected node(s) to move, press :kbd:`Ctrl` to switch to the
+ rotation mode temporarily, or use the red circles to scale it. If multiple nodes are
+ selected, only movement and rotation are possible. In this mode, rotation and scaling
+ will not use the snapping options if snapping is enabled.
+- **Move Mode** (:kbd:`W`): Enables move (or translate) mode for the selected nodes. See
+ :ref:`doc_introduction_to_2d_the_viewport` for more details.
+- **Rotate Mode** (:kbd:`E`): Enables rotation mode for the selected nodes. See
+ :ref:`doc_introduction_to_2d_the_viewport` for more details.
+- **Scale Mode** (:kbd:`R`): Enables scaling and displays scaling gizmos in both
+ axes for the selected node(s). See :ref:`doc_introduction_to_2d_the_viewport` for more details.
+- **Show list of selectable nodes at position clicked**: As the description suggests,
+ this provides a list of selectable nodes at the clicked position as a context menu, if
+ there is more than one node in the clicked area.
+- **Rotation pivot**: Sets the rotation pivot to rotate node(s) around.
+ An added node has its rotation pivot at ``x: 0``, ``y: 0``, by default, with
+ exceptions. For example, the default pivot for a :ref:`Sprite2D ` is its
+ center if the ``centered`` property is set to ``true``. If you would like to change the
+ rotation pivot of a node, click this button and choose a new location by left clicking.
+ The node rotates considering this point. If you have multiple nodes selected, this icon
+ will add a temporary pivot to be used commonly by all selected nodes. Pressing :kbd:`Shift`
+ and clicking this button will create the pivot at the center of selected nodes. If any of
+ the snap options are enabled, the pivot will also snap to them it when dragged.
+- **Pan Mode** (:kbd:`G`): Allows you to navigate in the viewport without accidentally selecting any nodes.
+ In other modes, you can also hold :kbd:`Space` and drag with the left mouse button to do the same.
+- **Ruler Mode**: After enabling, click on the viewport to display the current global
+ x and y coordinates. Dragging from a position to another one measures the distance in pixels.
+ If you drag diagonally, it will draw a triangle and show the separate distances in terms
+ of x, y, and total distance to the target, including the angles to the axes in degrees.
+ The :kbd:`R` key also activates the ruler. If snapping is enabled, it also displays the
+ measurements in terms of grid count:
+
+.. figure:: img/2d_ruler_with_snap.webp
+
+ Using ruler with snapping enabled.
+
+- **Use Smart Snap**: Toggles smart snapping for move, rotate, and scale modes; and
+ the rotation pivot. Customize it using the three-dot menu next to the snap tools.
+- **Use Grid Snap**: Toggles snapping to grid for move and scale mode, rotation pivot,
+ and the ruler. Customize it using the three-dot menu next to the snap tools.
+
+You can customize the grid settings so that move mode, rotate mode, scale mode, ruler,
+and rotation pivot uses snapping.
+Use the three-dot menu for this:
+
+.. image:: img/2d_snapping_options_menu.webp
+
+- **Use Rotation Snap**: Toggles snapping using the configured rotation setting.
+- **Use Scale Snap**: Toggles snapping using the configured scaling step setting.
+- **Snap Relative**: Toggles the usage of snapping based on the selected node's current
+ transform values. For example, if the grids are set to 32x32 pixels and if the selected node
+ is located at ``x: 1, y: 1``, then, enabling this option will temporarily shift the grids by
+ ``x: 1, y: 1``.
+- **Use Pixel Snap**: Toggles the use of subpixels for snapping. If enabled, the position values
+ will be integers, disabling will enable subpixel movement as decimal values. For the runtime
+ property, consider checking `Project Settings > Rendering > 2D > Snapping` property for
+ Node2D nodes, and `Project Settings > GUI > General > Snap Controls to Pixels` for
+ Control nodes.
+- **Smart Snapping**: Provides a set of options to snap to specific positions if they are enabled:
+
+ - Snap to Parent: Snaps to parent's edges. For example, scaling a child control node while
+ this is enabled will snap to the boundaries of the parent.
+ - Snap to Node Anchor: Snaps to the node's anchor. For example, if anchors of a control
+ node is positioned at different positions, enabling this will snap to the sides and
+ corners of the anchor.
+ - Snap to Node Sides: Snaps to the node's sides, such as for the rotation pivot or anchor
+ positioning.
+ - Snap to Node Center: Snaps to the node's center, such as for the rotation pivot or
+ anchor positioning.
+ - Snap to Other Nodes: Snaps to other nodes while moving or scaling. Useful to align nodes
+ in the editor.
+ - Snap to Guides: Snaps to custom guides drawn using the horizontal or vertical ruler. More
+ on the ruler and guides below.
+
+.. image:: img/2d_snapping_options.webp
+
+- **Configure Snap**: Opens the window shown above, offering a set of snapping parameters.
+
+ - Grid Offset: Allows you to shift grids with respect to the origin. ``x`` and ``y`` can
+ be adjusted separately.
+ - Grid Step: The distance between each grid in pixels. ``x`` and ``y`` can be adjusted separately.
+ - Primary Line Every: The number of grids in-between to draw infinite lines as indication of
+ main lines.
+ - Rotation Offset: Sets the offset to shift rotational snapping.
+ - Rotation Step: Defines the snapping degree. E.g., 15 means the node will rotate and snap
+ at multiples of 15 degrees if rotation snap is enabled and the rotate mode is used.
+ - Scale Step: Determines the scaling increment factor. For example, if it is 0.1, it will
+ change the scaling at 0.1 steps if scaling snap is enabled and the scaling mode is used.
+
+- **Lock selected nodes** (:kbd:`Ctrl + L`). Locks the selected nodes, preventing selection and movement in the
+ viewport. Clicking the button again (or using :kbd:`Ctrl + Shift + L`) unlocks the selected
+ nodes. Locked nodes can only be selected in the scene tree.
+ They can easily be identified by a padlock next to their node names in the scene tree.
+ Clicking on this padlock also unlocks the nodes.
+- **Group selected nodes** (:kbd:`Ctrl + G`). This allows selection of the root node if any
+ of the children are selected. Using :kbd:`Ctrl + G` ungroups them. Additionally, clicking
+ the ungroup button in the scene tree performs the same action.
+- **Skeleton Options**: Provides options to work with Skeleton2D and Bone2D.
+
+ - Show Bones: Toggles the visibility of bones for the selected node.
+ - Make Bone2D Node(s) from Node(s): Converts selected node(s) into Bone2D.
+
+.. seealso:: To learn more about Skeletons, see :ref:`doc_cutout_animation`.
+
+- **Project Camera Override**: Temporarily replaces the active camera in the level
+ (e.g., the camera following the player) with the camera in the editor's viewport, allowing
+ you to move freely and inspect the level's different parts, while the game is running.
+
+- **View** menu: Provides options to control the viewport view. Since its options
+ depend heavily on the viewport, it is covered in the :ref:`doc_introduction_to_2d_the_viewport`
+ section.
+
+Next to the View menu, additional buttons may be visible. In the toolbar image
+at the beginning of this chapter, an additional *Sprite2D* button appears because a
+Sprite2D is selected. This menu provides some quick actions and tools to
+work on a specific node or selection. For example, while drawing a polygon, it
+provides buttons to add, modify, or remove points.
+
+
+Coordinate system
+-----------------
+
+In the 2D editor, unlike 3D, there are only two axes: ``x`` and ``y``. Also, the viewing
+angle is fixed.
+
+In the viewport, you will see two lines in two colors going across the screen infinitely:
+red for the x-axis, and green for the y-axis.
+In Godot, going right and down are positive directions.
+Where these two lines intersect is the origin: ``x: 0, y: 0``.
+
+A root node will have its origin at this position once added.
+Switching to the `move` or `scale` modes after selecting a node will display the gizmos at the
+node's offset position.
+The gizmos will point to the positive directions of the x and y axes.
+In the move mode, you can drag the green line to move only in the ``y`` axis.
+Similarly, you can hold the red line to move only in the ``x`` axis.
+
+In the scale mode, the gizmos will have a square shape. You can hold and drag the green and
+red squares to scale the nodes in the ``y`` or ``x`` axes.
+Dragging in a negative direction flips the node horizontally or vertically.
+
+.. _doc_introduction_to_2d_the_viewport:
+
+2D Viewport
+-----------
+
+The viewport will be the area you spend the most time if you plan to design levels or user
+interfaces visually:
+
+.. image:: img/2d_editor_viewport_with_viewmenu.webp
+
+Middle-clicking and dragging the mouse will pan the view.
+The scrollbars on the right or bottom of the viewport also move the view.
+Alternatively, the :kbd:`G` or :kbd:`Space` keys can be used.
+If you enable `Editor Settings > Editors > Panning > Simple Panning`, you can activate
+panning directly with :kbd:`Space` only, without requiring dragging.
+
+The viewport has buttons on the top-left.
+**Center View** centers the selected node(s) in the screen. Useful if you have a large scene
+with many nodes, and want to see the node selected in the scene tree.
+Next to it are the zoom controls. **-** zooms out, **+** zooms in, and clicking on the number
+with percentage defaults to 100%.
+Alternatively, you can use middle-mouse scrolling to zoom in (scroll up) and out (scroll down).
+
+The black bars at the viewport's left and top edges are the **rulers**. You can use them to
+orient yourself in the viewport.
+By default, the rulers will display the pixel coordinates of the viewport, numbered at
+100 pixel steps. Changing the zoom factor will change the shown values.
+Enabling `Grid Snap` or changing the snapping options will update the ruler's scaling and
+the shown values.
+
+You can also create multiple custom guides to help you make measurements or align
+nodes with them:
+
+.. image:: img/2d_editor_guidelines.webp
+
+If you have at least one node in the scene, you can create guides by dragging from the horizontal
+or vertical ruler towards the viewport. A purple guide will appear, showing its position, and will
+remain there when you release the mouse. You can create both horizontal and vertical guides
+simultaneously by dragging from the gray square at the rulers' intersection. Guides can be
+repositioned by dragging them back to their respective rulers, and they can be removed by
+dragging them all the way back to the ruler.
+
+You can also enable snapping to the created guides using the `Smart Snap` menu.
+
+.. note:: If you cannot create a line, or do not see previously created guides, make sure that
+ they are visible by checking the `View` menu of the viewport. :kbd:`Y` toggles their visibility,
+ by default. Also, make sure you have at least one node in the scene.
+
+Depending on the tool chosen in the toolbar, left-clicking will have a primary action in the
+viewport.
+For example, the `Select Mode` will select the left-clicked node in the viewport.
+Sometimes, left-clicking can be combined with a modifier (e.g., :kbd:`Ctrl`, or :kbd:`Shift`) to
+perform secondary actions.
+For example, keeping :kbd:`Shift` pressed while dragging a node in the Select or Move modes will
+try to snap the node in a single axis while moving.
+
+Right clicking in the viewport provides two options to create a node or instantiate a scene
+at the chosen position.
+If at least one node is selected, right clicking also provides the option to move the selected
+node(s) to this position.
+
+
+Viewport has a **View** menu which provides several options to change the look of the viewport:
+
+- **Grid**: Allows you to show grids all the time, only when using snapping, or not at all. You
+ can also toggle them with the provided option.
+- **Show Helpers**: Toggles the temporary display of an outline of the node, with the previous
+ transform properties (position, scaling, or rotation) if a transform operation has been
+ initiated. For `Control` nodes, it also shows the sizing parameters. Useful to see the deltas.
+- **Show Rulers**: Toggles the visibility of horizontal and vertical rulers. See
+ :ref:`doc_introduction_to_2d_the_viewport` more on rulers.
+- **Show Guides**: Toggles the visibility of created guides. See
+ :ref:`doc_introduction_to_2d_the_viewport` for on how to create them.
+- **Show Origin**: Toggles the display of the green and red origin lines drawn at ``x: 0, y: 0``.
+- **Show Viewport**: Toggles the visibility of the game's default
+ viewport, indicated by an indigo-colored rectangle. It is also the default window size on desktop
+ platforms, which can be changed by going to `Project Settings > Display > Window > Size` and
+ setting `Viewport Width` and `Viewport Height`.
+- **Gizmos**: Toggles the visibility of `Position` (shown with cross icon), `Lock`
+ (shown with padlock), `Groups` (shown with two squares), and `Transformation` (shown with
+ green and red lines) indicators.
+- **Center Selection**: The same as the **Center View** button inside the viewport. Centers the selected
+ node(s) in the view. :kbd:`F` is the default shortcut.
+- **Frame to Selection**: Similar to `Center Selection`, but also changes the zoom factor to fit the
+ contents in the screen. :kbd:`Shift + F` is the default shortcut.
+- **Clear Guides**: Deletes all guides from the screen. You will need to recreate them if
+ you plan to use them later.
+- **Preview Canvas Scale**: Toggles the preview for scaling of canvas in the editor when the zoom
+ factor or view of the viewport changes. Useful to see how the controls will look like after scaling
+ and moving, without running the game.
+- **Preview Theme**: Allows to choose from the available themes to change the look of control items
+ in the editor, without requiring to run the game.
+
+
+Node2D and Control node
+~~~~~~~~~~~~~~~~~~~~~~~
+
+:ref:`CanvasItem ` is the base node for 2D. :ref:`Node2D ` is the base node
+for 2D game objects, and :ref:`Control ` is the base node
+for everything GUI. For 3D, Godot uses the :ref:`Node3D ` node.
+
+3D in 2D
+--------
+
+It is possible to display 3D scenes in 2D screen. This is achieved by adding a
+:ref:`SubViewport ` as a child.
+Then, you can drag a 3D scene as a child of the SubViewport:
+
+.. image:: img/3d_in_2d_demo_editor.webp
+
+.. seealso:: You can check the demo on: `3D in 2D Viewport demo `__.
diff --git a/tutorials/2d/using_tilesets.rst b/tutorials/2d/using_tilesets.rst
index b8afbc116b0..054676916c8 100644
--- a/tutorials/2d/using_tilesets.rst
+++ b/tutorials/2d/using_tilesets.rst
@@ -168,7 +168,7 @@ sounds), particle effects, and more.
Scene tiles come with a greater performance overhead compared to atlases, as
every scene is instanced individually for every placed tile.
- It's recommended to use only scene tiles when necessary. To draw sprites in a
+ It's recommended to only use scene tiles when necessary. To draw sprites in a
tile without any kind of advanced manipulation,
:ref:`use atlases instead `.
@@ -257,7 +257,7 @@ TileSet resource, choose **Merge (Keep Original Atlases)** instead.
Adding collision, navigation and occlusion to the TileSet
---------------------------------------------------------
-We've now successfully created a basic TileSet. We could start using in the
+We've now successfully created a basic TileSet. We could start using it in the
TileMapLayer node now, but it currently lacks any form of collision detection.
This means the player and other objects could walk straight through the floor or
walls.
@@ -436,7 +436,7 @@ corners or edges of platforms, floors, etc. While these can be placed manually,
this quickly becomes tedious. Handling this situation with procedurally
generated levels can also be difficult and require a lot of code.
-Godot offers *terrains* to perform this kind of tile connections automatically.
+Godot offers *terrains* to perform this kind of tile connection automatically.
This allows you to have the "correct" tile variants automatically used.
Terrains are grouped into terrain sets. Each terrain set is assigned a mode from
diff --git a/tutorials/3d/3d_antialiasing.rst b/tutorials/3d/3d_antialiasing.rst
index 24582b28241..ff7bc165213 100644
--- a/tutorials/3d/3d_antialiasing.rst
+++ b/tutorials/3d/3d_antialiasing.rst
@@ -65,8 +65,8 @@ moderate performance cost, but it's effective at reducing aliasing on
transparent materials without introducing any blurriness.
MSAA can be enabled in the Project Settings by changing the value of the
-**Rendering > Anti Aliasing > Quality > MSAA 3D** setting. It's important to change
-the value of the **MSAA 3D** setting and not **MSAA 2D**, as these are entirely
+:ref:`Rendering > Anti Aliasing > Quality > MSAA 3D`
+setting. It's important to change the value of the **MSAA 3D** setting and not **MSAA 2D**, as these are entirely
separate settings.
Comparison between no antialiasing (left) and various MSAA levels (right).
@@ -103,8 +103,9 @@ downside of TAA is that it can exhibit *ghosting* artifacts behind moving
objects. Rendering at a higher framerate will allow TAA to converge faster,
therefore making those ghosting artifacts less visible.
-Temporal antialiasing can be enabled in the Project Settings by changing the
-value of the **Rendering > Anti Aliasing > Quality > Use TAA** setting.
+Temporal antialiasing can be enabled in the Project Settings by changing the value of the
+:ref:`Rendering > Anti Aliasing > Quality > TAA`
+setting.
Comparison between no antialiasing (left) and TAA (right):
@@ -164,9 +165,9 @@ as an in-game option may still be worthwhile for players with low-end GPUs.
FXAA introduces a moderate amount of blur when enabled (more than TAA when
still, but less than TAA when the camera is moving).
-FXAA can be enabled in the Project Settings by changing the
-value of the **Rendering > Anti Aliasing > Quality > Screen Space AA** setting to
-**FXAA**.
+FXAA can be enabled in the Project Settings by changing the value of the
+:ref:`Rendering > Anti Aliasing > Quality > Screen Space AA`
+setting to ``FXAA``.
Comparison between no antialiasing (left) and FXAA (right):
@@ -187,9 +188,11 @@ The downside of SSAA is its *extremely* high cost. This cost generally makes
SSAA difficult to use for game purposes, but you may still find supersampling
useful for :ref:`offline rendering `.
-Supersample antialiasing is performed by increasing the **Rendering > Scaling 3D
-> Scale** advanced project setting above ``1.0`` while ensuring
-**Rendering > Scaling 3D > Mode** is set to **Bilinear** (the default).
+Supersample antialiasing is performed by increasing the
+:ref:`Rendering > Scaling 3D > Scale`
+advanced project setting above ``1.0`` while ensuring
+:ref:`Rendering > Scaling 3D > Mode`
+is set to ``Bilinear`` (the default).
Since the scale factor is defined per-axis, a scale factor of ``1.5`` will result
in 2.25× SSAA while a scale factor of ``2.0`` will result in 4× SSAA. Since Godot
uses the hardware's own bilinear filtering to perform the downsampling, the result
diff --git a/tutorials/3d/3d_rendering_limitations.rst b/tutorials/3d/3d_rendering_limitations.rst
index b3d5fef7e81..a5d6407466b 100644
--- a/tutorials/3d/3d_rendering_limitations.rst
+++ b/tutorials/3d/3d_rendering_limitations.rst
@@ -46,8 +46,9 @@ rendering, where banding may be visible when using smooth gradient textures.
There are two main ways to alleviate banding:
-- If using the Forward+ or Forward Mobile rendering methods, enable **Use
- Debanding** in the advanced Project Settings. This applies a fullscreen debanding
+- If using the Forward+ or Forward Mobile rendering methods, enable
+ :ref:`Use Debanding`
+ in **Project Settings > Rendering > Anti Aliasing**. This applies a fullscreen debanding
shader as a post-processing effect and is very cheap.
- Alternatively, bake some noise into your textures. This is mainly effective in
2D, e.g. for vignetting effects. In 3D, you can also use a `custom debanding
diff --git a/tutorials/3d/environment_and_post_processing.rst b/tutorials/3d/environment_and_post_processing.rst
index ff84da5226f..bcd223c6299 100644
--- a/tutorials/3d/environment_and_post_processing.rst
+++ b/tutorials/3d/environment_and_post_processing.rst
@@ -653,7 +653,8 @@ There are 2 ways to use glow in 2D:
rendering output.
- To enable HDR in 2D, open the Project Settings, enable
- **Rendering > Viewport > HDR 2D** then restart the editor.
+ :ref:`Rendering > Viewport > HDR 2D`
+ then restart the editor.
- If you want to maximize performance, you can leave HDR disabled for 2D
rendering. However, you will have less control on which objects glow.
@@ -676,10 +677,10 @@ There are 2 ways to use glow in 2D:
.. warning::
The 2D renderer renders in linear color space if the
- **Rendering > Viewport > HDR 2D** project setting is enabled, so
- ``source_color`` must also be used for uniform samplers that are
- used as color input in ``canvas_item`` shaders. If this is not done,
- the texture will appear washed out.
+ :ref:`Rendering > Viewport > HDR 2D`
+ project setting is enabled, so the ``source_color`` hint must also be used
+ for uniform samplers that are used as color input in ``canvas_item`` shaders.
+ If this is not done, the texture will appear washed out.
If 2D HDR is disabled, ``source_color`` will keep working correctly in
``canvas_item`` shaders, so it's recommend to use it when relevant either
diff --git a/tutorials/3d/global_illumination/reflection_probes.rst b/tutorials/3d/global_illumination/reflection_probes.rst
index 8f3eb1f8de7..ce8a2068687 100644
--- a/tutorials/3d/global_illumination/reflection_probes.rst
+++ b/tutorials/3d/global_illumination/reflection_probes.rst
@@ -187,9 +187,9 @@ reflection probe rendering. As many reflection probes as desired can be added (a
performance allows). However, there's still a default limit of 512 *clustered
elements* that can be present in the current camera view. A clustered element is
an omni light, a spot light, a :ref:`decal ` or a
-:ref:`reflection probe `. This limit can be increased by
-adjusting the **Rendering > Limits > Cluster Builder > Max Clustered Elements**
-advanced project setting.
+:ref:`reflection probe `. This limit can be increased by adjusting
+:ref:`Max Clustered Elements`
+in **Project Settings > Rendering > Limits > Cluster Builder**.
When using the Forward Mobile backend, only 8 reflection probes can be applied on each
individual Mesh *resource*. If there are more reflection probes affecting a single mesh,
diff --git a/tutorials/3d/img/spatial_material7.png b/tutorials/3d/img/spatial_material7.png
deleted file mode 100644
index 009f9cebbc5..00000000000
Binary files a/tutorials/3d/img/spatial_material7.png and /dev/null differ
diff --git a/tutorials/3d/img/spatial_material7.webp b/tutorials/3d/img/spatial_material7.webp
new file mode 100644
index 00000000000..ffb8f2c0c33
Binary files /dev/null and b/tutorials/3d/img/spatial_material7.webp differ
diff --git a/tutorials/3d/img/spring_arm_camera_collision.webp b/tutorials/3d/img/spring_arm_camera_collision.webp
new file mode 100644
index 00000000000..7d08a6545da
Binary files /dev/null and b/tutorials/3d/img/spring_arm_camera_collision.webp differ
diff --git a/tutorials/3d/img/spring_arm_camera_motion_cast.webp b/tutorials/3d/img/spring_arm_camera_motion_cast.webp
new file mode 100644
index 00000000000..997e33e49d5
Binary files /dev/null and b/tutorials/3d/img/spring_arm_camera_motion_cast.webp differ
diff --git a/tutorials/3d/img/spring_arm_camera_shape.webp b/tutorials/3d/img/spring_arm_camera_shape.webp
new file mode 100644
index 00000000000..5d27501be0a
Binary files /dev/null and b/tutorials/3d/img/spring_arm_camera_shape.webp differ
diff --git a/tutorials/3d/img/spring_arm_children.webp b/tutorials/3d/img/spring_arm_children.webp
new file mode 100644
index 00000000000..9cae7422fdd
Binary files /dev/null and b/tutorials/3d/img/spring_arm_children.webp differ
diff --git a/tutorials/3d/img/spring_arm_editor_setup.webp b/tutorials/3d/img/spring_arm_editor_setup.webp
new file mode 100644
index 00000000000..dc38a255e4b
Binary files /dev/null and b/tutorials/3d/img/spring_arm_editor_setup.webp differ
diff --git a/tutorials/3d/img/spring_arm_length_setup.webp b/tutorials/3d/img/spring_arm_length_setup.webp
new file mode 100644
index 00000000000..67c6a3bec99
Binary files /dev/null and b/tutorials/3d/img/spring_arm_length_setup.webp differ
diff --git a/tutorials/3d/img/spring_arm_pivot_setup.webp b/tutorials/3d/img/spring_arm_pivot_setup.webp
new file mode 100644
index 00000000000..6c0505c068f
Binary files /dev/null and b/tutorials/3d/img/spring_arm_pivot_setup.webp differ
diff --git a/tutorials/3d/img/spring_arm_position_length.webp b/tutorials/3d/img/spring_arm_position_length.webp
new file mode 100644
index 00000000000..14f0d843dcd
Binary files /dev/null and b/tutorials/3d/img/spring_arm_position_length.webp differ
diff --git a/tutorials/3d/img/spring_arm_shape.webp b/tutorials/3d/img/spring_arm_shape.webp
new file mode 100644
index 00000000000..f55e287bf6d
Binary files /dev/null and b/tutorials/3d/img/spring_arm_shape.webp differ
diff --git a/tutorials/3d/index.rst b/tutorials/3d/index.rst
index 0c9c2164e75..c0d0d60a11d 100644
--- a/tutorials/3d/index.rst
+++ b/tutorials/3d/index.rst
@@ -12,6 +12,8 @@
procedural_geometry/index
3d_text
+.. _doc_3d_rendering:
+
Rendering
---------
@@ -54,3 +56,4 @@ Tools
csg_tools
using_gridmaps
+ spring_arm
diff --git a/tutorials/3d/introduction_to_3d.rst b/tutorials/3d/introduction_to_3d.rst
index 674e5f5e24f..5f876139c21 100644
--- a/tutorials/3d/introduction_to_3d.rst
+++ b/tutorials/3d/introduction_to_3d.rst
@@ -19,10 +19,9 @@ which are almost identical to their 2D counterparts.
`Github repository `__ or the
:ref:`Asset Library `.
-In 3D, math is a little more complex than in 2D, so also checking the
-:ref:`doc_vector_math` entry in the wiki (which was especially created for game
-developers, not mathematicians or engineers) will help pave the way for you
-to develop 3D games efficiently.
+In 3D, math is a little more complex than in 2D. For an introduction to the
+relevant math written for game developers, not mathemeticians or engineers,
+check out :ref:`doc_vector_math` and :ref:`doc_using_transforms`.
3D workspace
~~~~~~~~~~~~
diff --git a/tutorials/3d/lights_and_shadows.rst b/tutorials/3d/lights_and_shadows.rst
index 6f3b31b2add..67609d328ff 100644
--- a/tutorials/3d/lights_and_shadows.rst
+++ b/tutorials/3d/lights_and_shadows.rst
@@ -61,9 +61,9 @@ real-time lighting. As many lights as desired can be added (as long as
performance allows). However, there's still a default limit of 512 *clustered
elements* that can be present in the current camera view. A clustered element is
an omni light, a spot light, a :ref:`decal ` or a
-:ref:`reflection probe `. This limit can be increased by
-adjusting the **Rendering > Limits > Cluster Builder > Max Clustered Elements**
-advanced project setting.
+:ref:`reflection probe `. This limit can be increased by adjusting
+:ref:`Max Clustered Elements`
+in **Project Settings > Rendering > Limits > Cluster Builder**.
When using the Forward Mobile renderer, there is a limitation of 8 OmniLights +
8 SpotLights per mesh resource. There is also a limit of 256 OmniLights + 256
@@ -72,10 +72,12 @@ currently cannot be changed.
When using the Compatibility renderer, up to 8 OmniLights + 8 SpotLights can be
rendered per mesh resource. This limit can be increased in the advanced Project
-Settings by adjusting **Rendering > Limits > OpenGL > Max Renderable Lights**
-and/or **Rendering > Limits > OpenGL > Max Lights Per Object** at the cost of
-performance and longer shader compilation times. The limit can also be decreased
-to reduce shader compilation times and improve performance slightly.
+Settings by adjusting
+:ref:`Max Renderable Elements`
+and/or :ref:`Max Lights per Object`
+in **Rendering > Limits > OpenGL**, at the cost of performance and longer shader
+compilation times. The limit can also be decreased to reduce shader compilation
+times and improve performance slightly.
With all rendering methods, up to 8 DirectionalLights can be visible at a time.
However, each additional DirectionalLight with shadows enabled will reduce the
diff --git a/tutorials/3d/particles/index.rst b/tutorials/3d/particles/index.rst
index 83c60fe6aad..44542fda7ed 100644
--- a/tutorials/3d/particles/index.rst
+++ b/tutorials/3d/particles/index.rst
@@ -8,8 +8,8 @@ Particle systems (3D)
This section of the tutorial covers (3D) GPU-accelerated particle systems. Most of the things
discussed here apply to CPU particles as well.
-Introduction
-------------
+.. rubric:: Introduction
+ :heading-level: 2
You can use particle systems to simulate complex physical effects like fire, sparks,
smoke, magical effects, and many more. They are very well suited for creating dynamic and organic
@@ -22,8 +22,8 @@ parameters and behaviors.
Every particle system you create in Godot consists of two main parts: particles and emitters.
-Particles
-~~~~~~~~~
+.. rubric:: Particles
+ :heading-level: 3
A particle is the visible part of a particle system. It's what you see on the screen when a particle
system is active: The tiny specks of dust, the flames of a fire, the glowing orbs of a magical
@@ -32,16 +32,16 @@ single system. You can randomize a particle's size, its speed and movement direc
color over the course of its lifetime. When you think of a fire, you can think of all the little
embers flying away from it as individual particles.
-Emitters
-~~~~~~~~
+.. rubric:: Emitters
+ :heading-level: 3
An emitter is what's creating the particles. Emitters are usually not visible, but they can have
a shape. That shape controls where and how particles are spawned, for example whether they should fill
a room like dust or shoot away from a single point like a fountain. Going back to the fire example,
an emitter would be the heat at the center of the fire that creates the embers and the flames.
-Node overview
-~~~~~~~~~~~~~
+.. rubric:: Node overview
+ :heading-level: 3
.. figure:: img/particle_nodes.webp
:alt: A list of nodes related to 3D particles
@@ -75,8 +75,8 @@ colliders by hand. If you want particles to collide with large outdoor scenes, y
objects in it and uses that for large-scale particle collisions.
-Basic usage
------------
+.. rubric:: Basic usage
+ :heading-level: 2
.. toctree::
:maxdepth: 1
@@ -86,8 +86,8 @@ Basic usage
properties
process_material_properties
-Advanced topics
----------------
+.. rubric:: Advanced topics
+ :heading-level: 2
.. toctree::
:maxdepth: 1
diff --git a/tutorials/3d/particles/properties.rst b/tutorials/3d/particles/properties.rst
index 601aca71f8b..fca3abe9641 100644
--- a/tutorials/3d/particles/properties.rst
+++ b/tutorials/3d/particles/properties.rst
@@ -98,7 +98,7 @@ property has no effect.
:alt: Particles running at low FPS
:align: right
- Interpolation on (left) vs. off (right)
+ Interpolation off (left) vs. on (right)
The ``Fixed FPS`` property limits how often the particle system is processed. This includes
property updates as well as collision and attractors. This can improve performance a lot,
diff --git a/tutorials/3d/spring_arm.rst b/tutorials/3d/spring_arm.rst
new file mode 100644
index 00000000000..2bc0e0635aa
--- /dev/null
+++ b/tutorials/3d/spring_arm.rst
@@ -0,0 +1,125 @@
+:article_outdated: False
+
+.. _doc_spring_arm:
+
+Third-person camera with spring arm
+===================================
+
+Introduction
+------------
+
+3D games will often have a third-person camera that follows and
+rotates around something such as a player character or a vehicle.
+
+In Godot, this can be done by setting a :ref:`Camera3D ` as a child of a node.
+However, if you try this without any extra steps you'll notice that the camera clips through geometry and hides the scene.
+
+This is where the :ref:`SpringArm3D ` node comes in.
+
+What is a spring arm?
+---------------------
+
+A spring arm has two main components that affect its behavior.
+
+The "length" of the spring arm is how far from its global position to check for collisions:
+
+.. image:: img/spring_arm_position_length.webp
+
+The "shape" of the spring arm is what it uses to check for collisions. The spring arm will "sweep" this shape from its origin out towards its length.
+
+.. image:: img/spring_arm_shape.webp
+
+The spring arm tries to keep all of its children at the end of its length. When the shape collides with something, the children are instead placed at or near that collision point:
+
+.. image:: img/spring_arm_children.webp
+
+Spring arm with a camera
+------------------------
+
+When a camera is placed as a child of a spring arm, a pyramid representing the camera will be used as the shape.
+
+This pyramid represents the **near plane** of the camera:
+
+.. image:: img/spring_arm_camera_shape.webp
+
+.. note:: If the spring arm is given a specific shape, then that shape will **always** be used.
+
+ The camera's shape is only used if the camera is a **direct child** of the spring arm.
+
+ If no shape is provided and the camera is not a direct child, the spring arm will fall back to using a ray cast which is inaccurate for camera collisions and not recommended.
+
+Every physics process frame, the spring arm will perform a motion cast to check if anything is collided with:
+
+.. image:: img/spring_arm_camera_motion_cast.webp
+
+When the shape hits something, the camera will be placed at or near the collision point:
+
+.. image:: img/spring_arm_camera_collision.webp
+
+Setting up the spring arm and camera
+------------------------------------
+
+Let's add a spring arm camera setup to the platformer demo.
+
+.. note:: You can download the Platformer 3D demo on `GitHub `_ or using the `Asset Library `_.
+
+In general, for a third-person camera setup, you will have three nodes as children of the node that you're following:
+
+- `Node3D` (the "pivot point" for the camera)
+
+ - `SpringArm3D`
+
+ - `Camera3D`
+
+Open the ``player/player.tscn`` scene. Set these up as children of our player and give them unique names so we can find them in our script. **Make sure to delete the existing camera node!**
+
+.. image:: img/spring_arm_editor_setup.webp
+
+Let's move the pivot point up by ``2`` on the Y-axis so that it's not on the ground:
+
+.. image:: img/spring_arm_pivot_setup.webp
+
+
+Give the spring arm a length of ``3`` so that it is placed behind the character:
+
+.. image:: img/spring_arm_length_setup.webp
+
+.. note:: Leave the **Shape** of the spring arm as ````. This way, it will use the camera's pyramid shape.
+
+ If you want, you can also try other shapes - a sphere is a common choice since it slides smoothly along edges.
+
+Update the top of ``player/player.gd`` to grab the camera and the pivot points by their unique names:
+
+.. code-block:: gdscript
+ :caption: player/player.gd
+
+ # Comment out this existing camera line.
+ # @onready var _camera := $Target/Camera3D as Camera3D
+
+ @onready var _camera := %Camera3D as Camera3D
+ @onready var _camera_pivot := %CameraPivot as Node3D
+
+Add an ``_unhandled_input`` function to check for camera movement and then rotate the pivot point accordingly:
+
+.. code-block:: gdscript
+ :caption: player/player.gd
+
+ @export_range(0.0, 1.0) var mouse_sensitivity = 0.01
+ @export var tilt_limit = deg_to_rad(75)
+
+
+ func _unhandled_input(event: InputEvent) -> void:
+ if event is InputEventMouseMotion:
+ _camera_pivot.rotation.x -= event.relative.y * mouse_sensitivity
+ # Prevent the camera from rotating too far up or down.
+ _camera_pivot.rotation.x = clampf(_camera_pivot.rotation.x, -tilt_limit, tilt_limit)
+ _camera_pivot.rotation.y += -event.relative.x * mouse_sensitivity
+
+By rotating the pivot point, the spring arm will also be rotated and it will change where the camera is positioned.
+Run the game and notice that mouse movement now rotates the camera around the character. If the camera moves into a wall, it collides with it.
+
+.. video:: video/spring_arm_camera.webm
+ :alt: Camera attached to a spring arm colliding with walls
+ :autoplay:
+ :loop:
+ :muted:
diff --git a/tutorials/3d/standard_material_3d.rst b/tutorials/3d/standard_material_3d.rst
index 963e6184d44..456acc963bb 100644
--- a/tutorials/3d/standard_material_3d.rst
+++ b/tutorials/3d/standard_material_3d.rst
@@ -295,13 +295,10 @@ Specifies how the specular blob will be rendered. The specular blob
represents the shape of a light source reflected in the object.
* **SchlickGGX:** The most common blob used by PBR 3D engines nowadays.
-* **Blinn:** Common in previous-generation engines.
- Not worth using nowadays, but left here for the sake of compatibility.
-* **Phong:** Same as above.
* **Toon:** Creates a toon blob, which changes size depending on roughness.
* **Disabled:** Sometimes the blob gets in the way. Begone!
-.. image:: img/spatial_material7.png
+.. image:: img/spatial_material7.webp
Disable Ambient Light
~~~~~~~~~~~~~~~~~~~~~
@@ -658,6 +655,12 @@ make it black and unshaded, reverse culling (Cull Front), and add some grow:
.. image:: img/spatial_material11.png
+.. note::
+
+ For Grow to work as expected, the mesh must have connected faces with shared
+ vertices, or "smooth shading". If the mesh has disconnected faces with unique
+ vertices, or "flat shading", the mesh will appear to have gaps when using Grow.
+
Transform
---------
diff --git a/tutorials/3d/using_decals.rst b/tutorials/3d/using_decals.rst
index 2d39e40c57a..01812341ae6 100644
--- a/tutorials/3d/using_decals.rst
+++ b/tutorials/3d/using_decals.rst
@@ -234,8 +234,9 @@ away from the camera (and may have little to no impact on the final scene
rendering). Using node groups, you can also prevent non-essential decorative
decals from spawning based on user configuration.
-The way decals are rendered also has an impact on performance. The **Rendering >
-Textures > Decals > Filter** advanced project setting lets you control how decal
+The way decals are rendered also has an impact on performance. The
+:ref:`Rendering > Textures > Decals > Filter`
+advanced project setting lets you control how decal
textures should be filtered. **Nearest/Linear** does not use mipmaps. However,
decals will look grainy at a distance. **Nearest/Linear Mipmaps** will look
smoother at a distance, but decals will look blurry when viewed from oblique
@@ -262,9 +263,9 @@ decal rendering. As many decals as desired can be added (as long as
performance allows). However, there's still a default limit of 512 *clustered
elements* that can be present in the current camera view. A clustered element is
an omni light, a spot light, a :ref:`decal ` or a
-:ref:`reflection probe `. This limit can be increased by
-adjusting the **Rendering > Limits > Cluster Builder > Max Clustered Elements**
-advanced project setting.
+:ref:`reflection probe `. This limit can be increased by adjusting
+:ref:`Max Clustered Elements`
+in **Project Settings > Rendering > Limits > Cluster Builder**.
When using the Forward Mobile backend, only 8 decals can be applied on each
individual Mesh *resource*. If there are more decals affecting a single mesh,
diff --git a/tutorials/3d/using_transforms.rst b/tutorials/3d/using_transforms.rst
index c3e9f113638..1041109ae3e 100644
--- a/tutorials/3d/using_transforms.rst
+++ b/tutorials/3d/using_transforms.rst
@@ -201,6 +201,8 @@ To rotate relative to object space (the node's own transform), use the following
// Rotate around the object's local X axis by 0.1 radians.
RotateObjectLocal(new Vector3(1, 0, 0), 0.1f);
+The axis should be defined in the local coordinate system of the object. For example, to rotate around the object's local X, Y, or Z axes, use ``Vector3.RIGHT`` for the X-axis, ``Vector3.UP`` for the Y-axis, and ``Vector3.FORWARD`` for the Z-axis.
+
Precision errors
================
diff --git a/tutorials/3d/video/spring_arm_camera.webm b/tutorials/3d/video/spring_arm_camera.webm
new file mode 100644
index 00000000000..d507416cebd
Binary files /dev/null and b/tutorials/3d/video/spring_arm_camera.webm differ
diff --git a/tutorials/animation/2d_skeletons.rst b/tutorials/animation/2d_skeletons.rst
index 396cf327103..d9831b4bfe9 100644
--- a/tutorials/animation/2d_skeletons.rst
+++ b/tutorials/animation/2d_skeletons.rst
@@ -13,8 +13,7 @@ and most 3D modeling applications support it. For 2D, as this function is not
used as often, it's difficult to find mainstream software aimed for this.
One option is to create animations in third-party software such as Spine or
-Dragonbones. From Godot 3.1 onwards, though, this functionality is supported
-built-in.
+Dragonbones. This functionality is also supported built-in.
Why would you want to do skeletal animations directly in Godot? The answer is
that there are many advantages to it:
diff --git a/tutorials/animation/animation_tree.rst b/tutorials/animation/animation_tree.rst
index 547ee62d435..bd9fb8d00e7 100644
--- a/tutorials/animation/animation_tree.rst
+++ b/tutorials/animation/animation_tree.rst
@@ -12,9 +12,6 @@ function calling, audio and sub-animation tracks, is pretty much unique.
However, the support for blending those animations via ``AnimationPlayer`` is relatively limited, as only a fixed cross-fade transition time can be set.
-:ref:`AnimationTree ` is a new node introduced in Godot 3.1 to deal with advanced transitions.
-It supersedes the ancient ``AnimationTreePlayer``, while adding a huge amount of features and flexibility.
-
Creating an AnimationTree
-------------------------
diff --git a/tutorials/assets_pipeline/importing_3d_scenes/available_formats.rst b/tutorials/assets_pipeline/importing_3d_scenes/available_formats.rst
index 45b52cf3852..83c478d07e6 100644
--- a/tutorials/assets_pipeline/importing_3d_scenes/available_formats.rst
+++ b/tutorials/assets_pipeline/importing_3d_scenes/available_formats.rst
@@ -156,7 +156,9 @@ the built-in Collada support may still work for simple scenes without animation.
For complex scenes or scenes that contain animations, Godot provides a
`Blender plugin `_
-that will correctly export COLLADA scenes for use in Godot.
+that will correctly export COLLADA scenes for use in Godot. This plugin is
+not maintained or supported in Godot 4.x, but may still work depending on your
+Godot and Blender versions.
Importing OBJ files in Godot
----------------------------
diff --git a/tutorials/audio/audio_buses.rst b/tutorials/audio/audio_buses.rst
index 9412410223e..f1aa2c47d92 100644
--- a/tutorials/audio/audio_buses.rst
+++ b/tutorials/audio/audio_buses.rst
@@ -88,6 +88,16 @@ Finally, toggle the **Playing** property to **On** and sound will flow.
Adding effects
--------------
+.. warning::
+
+ This feature is not supported on the web platform if the AudioStreamPlayer's
+ playback mode is set to **Sample**, which is the default. It will only work if the
+ playback mode is set to **Stream**, at the cost of increased latency if threads
+ are not enabled.
+
+ See :ref:`Audio playback in the Exporting for the Web documentation `
+ for details.
+
Audio buses can contain all sorts of effects. These effects modify the sound in
one way or another and are applied in order.
diff --git a/tutorials/audio/audio_streams.rst b/tutorials/audio/audio_streams.rst
index 05fdcb8e84c..a4b9f8537ba 100644
--- a/tutorials/audio/audio_streams.rst
+++ b/tutorials/audio/audio_streams.rst
@@ -80,6 +80,16 @@ Unlike for 2D, the 3D version of AudioStreamPlayer has a few more advanced optio
Reverb buses
~~~~~~~~~~~~
+.. warning::
+
+ This feature is not supported on the web platform if the AudioStreamPlayer's
+ playback mode is set to **Sample**, which is the default. It will only work if the
+ playback mode is set to **Stream**, at the cost of increased latency if threads
+ are not enabled.
+
+ See :ref:`Audio playback in the Exporting for the Web documentation `
+ for details.
+
Godot allows for 3D audio streams that enter a specific Area3D node to send dry
and wet audio to separate buses. This is useful when you have several reverb
configurations for different types of rooms. This is done by enabling this type
@@ -102,6 +112,16 @@ that effect.
Doppler
~~~~~~~
+.. warning::
+
+ This feature is not supported on the web platform if the AudioStreamPlayer's
+ playback mode is set to **Sample**, which is the default. It will only work if the
+ playback mode is set to **Stream**, at the cost of increased latency if threads
+ are not enabled.
+
+ See :ref:`Audio playback in the Exporting for the Web documentation `
+ for details.
+
When the relative velocity between an emitter and listener changes, this is
perceived as an increase or decrease in the pitch of the emitted sound.
Godot can track velocity changes in the AudioStreamPlayer3D and Camera nodes.
diff --git a/tutorials/audio/recording_with_microphone.rst b/tutorials/audio/recording_with_microphone.rst
index cca0a26f1b2..012e64b11fd 100644
--- a/tutorials/audio/recording_with_microphone.rst
+++ b/tutorials/audio/recording_with_microphone.rst
@@ -12,7 +12,7 @@ A simple demo is included in the official demo projects and will be used as
support for this tutorial:
``_.
-You will need to enable audio input in the project settings ``Project Settings -> Audio -> Driver -> Enable Input``, or you'll just get empty audio files.
+You will need to enable audio input in the :ref:`Audio > Driver > Enable Input` project setting, or you'll just get empty audio files.
The structure of the demo
-------------------------
diff --git a/tutorials/audio/sync_with_audio.rst b/tutorials/audio/sync_with_audio.rst
index 8a789d6576b..9cd090c75d6 100644
--- a/tutorials/audio/sync_with_audio.rst
+++ b/tutorials/audio/sync_with_audio.rst
@@ -23,7 +23,9 @@ The most common way to reduce latency is to shrink the audio buffers (again, by
This is a common tradeoff, so Godot ships with sensible defaults that should not need to be altered.
-The problem, in the end, is not this slight delay but synchronizing graphics and audio for games that require it. Beginning with Godot 3.2, some helpers were added to obtain more precise playback timing.
+The problem, in the end, is not this slight delay but synchronizing graphics and
+audio for games that require it. Some helpers are available to obtain more
+precise playback timing.
Using the system clock to sync
------------------------------
diff --git a/tutorials/best_practices/scenes_versus_scripts.rst b/tutorials/best_practices/scenes_versus_scripts.rst
index f0abd2515b0..713075404c4 100644
--- a/tutorials/best_practices/scenes_versus_scripts.rst
+++ b/tutorials/best_practices/scenes_versus_scripts.rst
@@ -118,8 +118,6 @@ There are two systems for registering types:
- Engine developers must add support for languages manually (both name exposure and
runtime accessibility).
- - Godot 3.1+ only.
-
- The Editor scans project folders and registers any exposed names for all
scripting languages. Each scripting language must implement its own
support for exposing this information.
diff --git a/tutorials/editor/default_key_mapping.rst b/tutorials/editor/default_key_mapping.rst
index f5f2a9ea448..28213830ca4 100644
--- a/tutorials/editor/default_key_mapping.rst
+++ b/tutorials/editor/default_key_mapping.rst
@@ -7,22 +7,25 @@
Default editor shortcuts
========================
-Many of Godot Editor functions can be executed with keyboard shortcuts. This page
+
+Many Godot editor functions can be executed with keyboard shortcuts. This page
lists functions which have associated shortcuts by default, but many others are
available for customization in editor settings as well. To change keys associated
-with these and other actions navigate to ``Editor -> Editor Settings -> Shortcuts``.
+with these and other actions navigate to **Editor > Editor Settings > Shortcuts**.
While some actions are universal, a lot of shortcuts are specific to individual
tools. For this reason it is possible for some key combinations to be assigned
to more than one function. The correct action will be performed depending on the
context.
-.. note:: While Windows and Linux builds of the editor share most of the default settings,
- some shortcuts may differ for macOS version. This is done for better integration
- of the editor into macOS ecosystem. Users fluent with standard shortcuts on that
- OS should find Godot Editor's default key mapping intuitive.
+.. note::
+
+ While Windows and Linux builds of the editor share most of the default settings,
+ some shortcuts may differ for macOS version. This is done for better integration
+ of the editor into macOS ecosystem. Users fluent with standard shortcuts on that
+ OS should find Godot Editor's default key mapping intuitive.
-General Editor Actions
+General editor actions
----------------------
+-----------------------+-------------------------------+------------------------------+----------------------------------+
@@ -86,9 +89,35 @@ General Editor Actions
+-----------------------+-------------------------------+------------------------------+----------------------------------+
| Expand Bottom Panel | :kbd:`Shift + F12` | :kbd:`Shift + F12` | ``editor/bottom_panel_expand`` |
+-----------------------+-------------------------------+------------------------------+----------------------------------+
+| Command Palette | :kbd:`Ctrl + Shift + P` | :kbd:`Cmd + Shift + P` | ``editor/command_palette`` |
++-----------------------+-------------------------------+------------------------------+----------------------------------+
-2D / Canvas Item Editor
------------------------
+Bottom panels
+-------------
+
+Only bottom panels that are always available have a default shortcut assigned.
+Others must be manually bound in the Editor Settings if desired.
+
++-----------------------------------+-----------------+-----------------+-----------------------------------------------------+
+| Action name | Windows, Linux | macOS | Editor setting |
++===================================+=================+=================+=====================================================+
+| Toggle Last Opened Panel | :kbd:`Ctrl + J` | :kbd:`Ctrl + J` | ``editor/toggle_last_opened_bottom_panel`` |
++-----------------------------------+-----------------+-----------------+-----------------------------------------------------+
+| Toggle Animation Bottom Panel | :kbd:`Alt + N` | :kbd:`Alt + N` | ``bottom_panels/toggle_animation_bottom_panel`` |
++-----------------------------------+-----------------+-----------------+-----------------------------------------------------+
+| Toggle Audio Bottom Panel | :kbd:`Alt + A` | :kbd:`Alt + A` | ``bottom_panels/toggle_audio_bottom_panel`` |
++-----------------------------------+-----------------+-----------------+-----------------------------------------------------+
+| Toggle Debugger Bottom Panel | :kbd:`Alt + D` | :kbd:`Alt + D` | ``bottom_panels/toggle_debugger_bottom_panel`` |
++-----------------------------------+-----------------+-----------------+-----------------------------------------------------+
+| Toggle FileSystem Bottom Panel | :kbd:`Alt + F` | :kbd:`Alt + F` | ``bottom_panels/toggle_filesystem_bottom_panel`` |
++-----------------------------------+-----------------+-----------------+-----------------------------------------------------+
+| Toggle Output Bottom Panel | :kbd:`Alt + O` | :kbd:`Alt + O` | ``bottom_panels/toggle_output_bottom_panel`` |
++-----------------------------------+-----------------+-----------------+-----------------------------------------------------+
+| Toggle Shader Editor Bottom Panel | :kbd:`Alt + S` | :kbd:`Alt + S` | ``bottom_panels/toggle_shader_editor_bottom_panel`` |
++-----------------------------------+-----------------+-----------------+-----------------------------------------------------+
+
+2D / CanvasItem editor
+----------------------
+------------------------------+-------------------------+------------------------+--------------------------------------------------------+
| Action name | Windows, Linux | macOS | Editor setting |
@@ -142,7 +171,7 @@ General Editor Actions
.. _doc_default_key_mapping_shortcuts_spatial_editor:
-3D / Spatial Editor
+3D / Spatial editor
-------------------
+------------------------------------+-----------------------+----------------------+--------------------------------------------------+
@@ -217,7 +246,7 @@ General Editor Actions
| 4 Viewports | :kbd:`Ctrl + 4` | :kbd:`Cmd + 4` | ``spatial_editor/4_viewports`` |
+------------------------------------+-----------------------+----------------------+--------------------------------------------------+
-Text Editor
+Text editor
-----------
+---------------------------+---------------------------------+----------------------------------+-------------------------------------------------+
@@ -300,7 +329,7 @@ Text Editor
| Contextual Help | :kbd:`Alt + F1` | :kbd:`Opt + Shift + Space` | ``script_text_editor/contextual_help`` |
+---------------------------+---------------------------------+----------------------------------+-------------------------------------------------+
-Script Editor
+Script editor
-------------
+----------------------+---------------------------------+---------------------------------+----------------------------------------+
@@ -347,7 +376,7 @@ Script Editor
| Reset Zoom | :kbd:`Ctrl + 0` | :kbd:`Cmd + 0` | ``script_editor/reset_zoom`` |
+----------------------+---------------------------------+---------------------------------+----------------------------------------+
-Editor Output
+Editor output
-------------
+----------------+-------------------------+------------------------+-------------------------+
@@ -371,7 +400,7 @@ Debugger
| Continue | :kbd:`F12` | :kbd:`F12` | ``debugger/continue`` |
+-------------+----------------+------------+------------------------+
-File Dialog
+File dialog
-----------
+---------------------+--------------------------+--------------------------+-------------------------------------+
@@ -395,14 +424,14 @@ File Dialog
+---------------------+--------------------------+--------------------------+-------------------------------------+
| Delete | :kbd:`Del` | :kbd:`Cmd + BkSp` | ``file_dialog/delete`` |
+---------------------+--------------------------+--------------------------+-------------------------------------+
-| Focus Path | :kbd:`Ctrl + D` | :kbd:`Cmd + D` | ``file_dialog/focus_path`` |
+| Focus Path | :kbd:`Ctrl + L` | :kbd:`Cmd + Shift + G` | ``file_dialog/focus_path`` |
+---------------------+--------------------------+--------------------------+-------------------------------------+
| Move Favorite Up | :kbd:`Ctrl + Up Arrow` | :kbd:`Cmd + Up Arrow` | ``file_dialog/move_favorite_up`` |
+---------------------+--------------------------+--------------------------+-------------------------------------+
| Move Favorite Down | :kbd:`Ctrl + Down Arrow` | :kbd:`Cmd + Down Arrow` | ``file_dialog/move_favorite_down`` |
+---------------------+--------------------------+--------------------------+-------------------------------------+
-FileSystem Dock
+FileSystem dock
---------------
+-------------+-----------------+-------------------+-------------------------------+
@@ -415,7 +444,7 @@ FileSystem Dock
| Delete | :kbd:`Del` | :kbd:`Cmd + BkSp` | ``filesystem_dock/delete`` |
+-------------+-----------------+-------------------+-------------------------------+
-Scene Tree Dock
+Scene tree dock
---------------
+----------------+--------------------------+-------------------------+----------------------------------+
@@ -438,7 +467,7 @@ Scene Tree Dock
| Move Down | :kbd:`Ctrl + Down Arrow` | :kbd:`Cmd + Down Arrow` | ``scene_tree/move_down`` |
+----------------+--------------------------+-------------------------+----------------------------------+
-Animation Track Editor
+Animation track editor
----------------------
+----------------------+---------------------------+--------------------------+-----------------------------------------------------+
@@ -455,8 +484,8 @@ Animation Track Editor
| Go to Previous Step | :kbd:`Ctrl + Left Arrow` | :kbd:`Cmd + Left Arrow` | ``animation_editor/goto_prev_step`` |
+----------------------+---------------------------+--------------------------+-----------------------------------------------------+
-Tile Map Editor
----------------
+TileMap editor
+--------------
+-------------------+-----------------+-------------------+---------------------------------------+
| Action name | Windows, Linux | macOS | Editor setting |
@@ -494,7 +523,7 @@ Tile Map Editor
| Rotate Right | :kbd:`X` | :kbd:`X` | ``tiles_editor/rotate_tile_right`` |
+-------------------+-----------------+-------------------+---------------------------------------+
-Tileset Editor
+TileSet Editor
--------------
+---------------------+----------------+---------------+----------------------------------------+
@@ -520,3 +549,24 @@ Tileset Editor
+---------------------+----------------+---------------+----------------------------------------+
| Z Index Mode | :kbd:`8` | :kbd:`8` | ``tileset_editor/editmode_z_index`` |
+---------------------+----------------+---------------+----------------------------------------+
+
+Project manager
+---------------
+
++---------------------+-----------------+-------------------+------------------------------------+
+| Action name | Windows, Linux | macOS | Editor setting |
++=====================+=================+===================+====================================+
+| New Project | :kbd:`Ctrl + N` | :kbd:`Cmd + N` | ``project_manager/new_project`` |
++---------------------+-----------------+-------------------+------------------------------------+
+| Import Project | :kbd:`Ctrl + I` | :kbd:`Cmd + I` | ``project_manager/import_project`` |
++---------------------+-----------------+-------------------+------------------------------------+
+| Scan for Projects | :kbd:`Ctrl + S` | :kbd:`Cmd + S` | ``project_manager/scan_projects`` |
++---------------------+-----------------+-------------------+------------------------------------+
+| Edit Project | :kbd:`Ctrl + E` | :kbd:`Cmd + E` | ``project_manager/edit_project`` |
++---------------------+-----------------+-------------------+------------------------------------+
+| Run Project | :kbd:`Ctrl + R` | :kbd:`Cmd + R` | ``project_manager/run_project`` |
++---------------------+-----------------+-------------------+------------------------------------+
+| Rename Project | :kbd:`F2` | :kbd:`Enter` | ``project_manager/rename_project`` |
++---------------------+-----------------+-------------------+------------------------------------+
+| Remove Project | :kbd:`Delete` | :kbd:`Cmd + BkSp` | ``project_manager/remove_project`` |
++---------------------+-----------------+-------------------+------------------------------------+
diff --git a/tutorials/editor/project_manager.rst b/tutorials/editor/project_manager.rst
index 7e559759470..c454faf84f3 100644
--- a/tutorials/editor/project_manager.rst
+++ b/tutorials/editor/project_manager.rst
@@ -33,10 +33,11 @@ Creating and importing projects
To create a new project:
1. Click the **Create** button on the top-left of the window.
-2. Give the project a name, choose an empty folder on your computer to save the
- files. Alternatively, you can enable **Create Folder** option to automatically create
- a new sub-folder with the project name, following the directory naming convention
- set in the settings. An empty folder will show a green tick on the right.
+2. Give the project a name, then open the file browser using the **Browse** button,
+ and choose an empty folder on your computer to save the files. Alternatively,
+ you can enable **Create Folder** option to automatically create a new sub-folder
+ with the project name, following the directory naming convention set in the
+ settings. An empty folder will show a green tick on the right.
3. Select one of the rendering backends (this can also be changed later).
4. Click the **Create & Edit** button to create the project folder and open it in the editor.
@@ -49,8 +50,9 @@ To create a new project:
Using the file browser
~~~~~~~~~~~~~~~~~~~~~~
-Click the **Browse** button to open Godot's file browser.
-You can pick a location or type the folder's path in the **Path** field, after choosing a drive.
+From the **Create New Project** window, click the **Browse** button to open
+Godot's file browser. You can pick a location or type the folder's path in the
+**Path** field, after choosing a drive.
Left of the path field on the top row contains arrows to navigate backward and forward through the last
visited locations.
diff --git a/tutorials/editor/using_the_web_editor.rst b/tutorials/editor/using_the_web_editor.rst
index 075d9b34aca..164bbd317be 100644
--- a/tutorials/editor/using_the_web_editor.rst
+++ b/tutorials/editor/using_the_web_editor.rst
@@ -5,8 +5,8 @@
Using the Web editor
====================
-Since Godot 3.3, there is a `Web editor `__
-you can use to work on new or existing projects.
+There is a `Web editor `__ you can use to work
+on new or existing projects.
.. note::
@@ -69,7 +69,8 @@ of the Web platform:
.. seealso::
See the
- `list of open issues on GitHub related to the web editor `__ for a list of known bugs.
+ `list of open issues on GitHub related to the web editor `__
+ for a list of known bugs.
Importing a project
-------------------
diff --git a/tutorials/export/exporting_for_android.rst b/tutorials/export/exporting_for_android.rst
index 2ba96076477..2a95927f4b9 100644
--- a/tutorials/export/exporting_for_android.rst
+++ b/tutorials/export/exporting_for_android.rst
@@ -100,6 +100,9 @@ There are two types of icons required by Godot:
- **Main Icon:** The "classic" icon. This will be used on all Android versions up to Android 8 (Oreo), exclusive. Must be at least 192×192 px.
- **Adaptive Icons:** Starting from Android 8 (inclusive), `Adaptive Icons `_ were introduced. Applications will need to include separate background and foreground icons to have a native look. The user's launcher application will control the icon's animation and masking. Must be at least 432×432 px.
+- **Themed Icons:** Starting from Android 13 (inclusive), Themed Icons were introduced. Applications will need to include a monochrome icon to enable this feature. The user's launcher application will control the icon's theme. Must be at least 432×432 px.
+
+.. caution:: It is mandatory to provide a monochrome icon. Failure to do so will result in the default Godot monochrome icon being used.
.. seealso:: It's important to adhere to some rules when designing adaptive icons. `Google Design has provided a nice article `_ that helps to understand those rules and some of the capabilities of adaptive icons.
@@ -110,6 +113,7 @@ If you don't provide some of the requested icons, Godot will replace them using
- **Main Icon:** Provided main icon -> Project icon -> Default Godot main icon.
- **Adaptive Icon Foreground:** Provided foreground icon -> Provided main icon -> Project icon -> Default Godot foreground icon.
- **Adaptive Icon Background:** Provided background icon -> Default Godot background icon.
+- **Adaptive Icon Monochrome:** Provided monochrome icon -> Default Godot monochrome icon.
It's highly recommended to provide all the requested icons with their specified resolutions.
This way, your application will look great on all Android devices and versions.
@@ -117,8 +121,11 @@ This way, your application will look great on all Android devices and versions.
Exporting for Google Play Store
-------------------------------
-Uploading an APK to Google's Play Store requires you to sign using a non-debug
-keystore file; such file can be generated like this:
+All new apps uploaded to Google Play after August 2021 must be an AAB (Android App Bundle)
+file.
+
+Uploading an AAB or APK to Google's Play Store requires you to sign using a non-debug
+keystore file; such a file can be generated like this:
.. code-block:: shell
@@ -126,7 +133,7 @@ keystore file; such file can be generated like this:
This keystore and key are used to verify your developer identity, remember the password and keep it in a safe place!
It is suggested to use only upper and lowercase letters and numbers. Special characters may cause errors.
-Use Google's Android Developer guides to learn more about `APK signing `__.
+Use Google's Android Developer guides to learn more about `app signing `__.
Now fill in the following forms in your Android Export Presets:
@@ -140,22 +147,17 @@ Don't forget to uncheck the **Export With Debug** checkbox while exporting.
.. image:: img/export-with-debug-button.png
-Optimizing the APK size
------------------------
-
-By default, the APK will contain native libraries for both ARMv7 and ARMv8
-architectures. This increases its size significantly. To create a smaller APK,
-uncheck either **Armeabi-v 7a** or **Arm 64 -v 8a** in your project's Android
-export preset. This will create an APK that only contains a library for
-a single architecture. Note that applications targeting ARMv7 can also run on
-ARMv8 devices, but the opposite is not true.
-
-Since August 2019, Google Play requires all applications to be available in
-64-bit form. This means you cannot upload an APK that contains *just* an ARMv7
-library. To solve this, you can upload several APKs to Google Play using its
-`Multiple APK support `__.
-Each APK should target a single architecture; creating an APK for ARMv7
-and ARMv8 is usually sufficient to cover most devices in use today.
+Optimizing the file size
+------------------------
+
+If you're working with APKs and not AABs, by default, the APK will contain native
+libraries for both ARMv7 and ARMv8 architectures. This increases its size significantly.
+To create a smaller file, uncheck either **Armeabi-v 7a** or **Arm 64 -v 8a** in
+your project's Android export preset. This will create an APK that only contains
+a library for a single architecture. Note that applications targeting ARMv7 can
+also run on ARMv8 devices, but the opposite is not true. The reason you don't do
+this to save space with AABs is that Google automatically splits up the AAB on their
+backend, so the user only downloads what they need.
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
diff --git a/tutorials/export/exporting_for_macos.rst b/tutorials/export/exporting_for_macos.rst
index ddc3c60a4e7..54240469a00 100644
--- a/tutorials/export/exporting_for_macos.rst
+++ b/tutorials/export/exporting_for_macos.rst
@@ -11,7 +11,7 @@ Exporting for macOS
macOS apps exported with the official export templates are exported as a single "Universal 2" binary ``.app`` bundle, a folder with a specific structure which stores the executable, libraries and all the project files.
This bundle can be exported as is, packed in a ZIP archive or DMG disk image (only supported when exporting from a computer running macOS).
-`Universal binaries for macOS support both Intel x86_64 and ARM64 (Apple silicon, i.e. M1) architectures `__.
+`Universal binaries for macOS support both Intel x86_64 and ARM64 (Apple Silicon) architectures `__.
Requirements
------------
diff --git a/tutorials/export/exporting_for_web.rst b/tutorials/export/exporting_for_web.rst
index b582f80f13e..9383c16dfde 100644
--- a/tutorials/export/exporting_for_web.rst
+++ b/tutorials/export/exporting_for_web.rst
@@ -11,8 +11,7 @@ Exporting for the Web
HTML5 export allows publishing games made in Godot Engine to the browser.
This requires support for `WebAssembly
-`__, `WebGL `__ and
-`SharedArrayBuffer `_
+`__ and `WebGL 2.0 `__
in the user's browser.
.. attention::
@@ -26,28 +25,61 @@ in the user's browser.
with :kbd:`F12` (:kbd:`Cmd + Option + I` on macOS), to view
**debug information** like JavaScript, engine, and WebGL errors.
-.. attention::
+.. seealso::
+
+ See the
+ `list of open issues on GitHub related to the web export `__
+ for a list of known bugs.
+
+Export file name
+----------------
- Godot 4's HTML5 exports currently cannot run on macOS and iOS due to upstream bugs
- with SharedArrayBuffer and WebGL 2.0. We recommend using
- :ref:`macOS ` and :ref:`iOS `
- native export functionality instead, as it will also result in better performance.
+We suggest users to export their Web projects with ``index.html`` as the file name.
+``index.html`` is usually the default file loaded by web servers when accessing the
+parent directory, usually hiding the name of that file.
- Godot 3's HTML5 exports are more compatible with various browsers in
- general, especially when using the GLES2 rendering backend (which only
- requires WebGL 1.0).
+.. attention::
+
+ The Godot 4 Web export expects some files to be named the same name as the one set in the
+ initial export. Some issues could occur if some exported files are renamed, including the
+ main HTML file.
WebGL version
-------------
Godot 4.0 and later can only target WebGL 2.0 (using the Compatibility rendering
-method). There is no stable way to run Vulkan applications on the web yet.
+method). Forward+/Mobile are not supported on the web platform, as these
+rendering methods are designed around modern low-level graphics APIs. Godot
+currently does not support WebGPU, which is a prerequisite for allowing
+Forward+/Mobile to run on the web platform.
See `Can I use WebGL 2.0 `__ for a list of browser
versions supporting WebGL 2.0. Note that Safari has several issues with WebGL
2.0 support that other browsers don't have, so we recommend using a
Chromium-based browser or Firefox if possible.
+.. _doc_exporting_for_web_audio_playback:
+
+Audio playback
+--------------
+
+Since Godot 4.3, audio playback is done using the Web Audio API on the web
+platform. This **Sample** playback mode allows for low latency even when the
+project is exported without thread support, but it has several limitations:
+
+- AudioEffects are not supported.
+- :ref:`Reverberation and doppler ` effects are not supported.
+- Procedural audio generation is not supported.
+- Positional audio may not always work correctly depending on the node's properties.
+
+To use Godot's own audio playback system on the web platform, you can change the
+default playback mode using the **Audio > General > Default Playback Type.web**
+project setting, or change the **Playback Type** property to **Stream** on an
+:ref:`class_AudioStreamPlayer`, :ref:`class_AudioStreamPlayer2D` or
+:ref:`class_AudioStreamPlayer3D` node. This leads to increased latency
+(especially when thread support is disabled), but it allows the full suite
+of Godot's audio features to work.
+
.. _doc_javascript_export_options:
Export options
@@ -60,7 +92,7 @@ game in the default browser for testing.
If your project uses GDExtension **Extension Support** needs to be enabled.
If you plan to use :ref:`VRAM compression ` make sure that
-**Vram Texture Compression** is enabled for the targeted platforms (enabling
+**VRAM Texture Compression** is enabled for the targeted platforms (enabling
both **For Desktop** and **For Mobile** will result in a bigger, but more
compatible export).
@@ -78,6 +110,59 @@ JavaScript APIs, include CSS, or run JavaScript code.
To customize the generated file, use the **Custom HTML shell**
option.
+.. _doc_exporting_for_web_thread_extension_support:
+
+Thread and extension support
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+If **Thread Support** is enabled, the exported project will be able to
+:ref:`make use of multithreading ` to improve
+performance. This also allows for low-latency audio playback
+when the playback type is set to **Stream** (instead of the default **Sample**
+that is used in web exports). Enabling this feature requires the use of
+cross-origin isolation headers, which are described in the
+:ref:`doc_exporting_for_web_serving_the_files` section below.
+
+If **Extensions Support** is enabled, :ref:`GDExtensions `
+will be able to be loaded. Note that GDExtensions still need to be specifically
+compiled for the web platform to work. Like thread support, enabling this feature
+requires the use of cross-origin isolation headers.
+
+Exporting as a Progressive Web App (PWA)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+If **Progressive Web App > Enable** is enabled, it will have several effects:
+
+- Configure high-resolution icons, a display mode and screen orientation. These
+ are configured at the end of the Progressive Web App section in the export
+ options. These options are used if the user adds the project to their device's
+ homescreen, which is common on mobile platforms. This is also supported on
+ desktop platforms, albeit in a more limited capacity.
+
+- Allow the project to be loaded without an Internet connection if it has been
+ loaded at least once beforehand. This works thanks to the *service worker*
+ that is installed when the project is first loaded in the user's browser. This
+ service worker provides a local fallback when no Internet connection is
+ available.
+
+ - Note that web browsers can choose to evict the cached data if the user runs
+ low on disk space, or if the user hasn't opened the project for a while.
+ To ensure data is cached for a longer duration, the user can bookmark the page,
+ or ideally add it to their device's home screen.
+
+ - If the offline data is not available because it was evicted from the cache,
+ you can configure an **Offline Page** that will be displayed in this case.
+ The page must be in HTML format and will be saved on the client's machine
+ the first time the project is loaded.
+
+- Ensure cross-origin isolation headers are always present, even if the web
+ server hasn't been configured to send them. This allows exports with threads
+ enabled to work when hosted on any website, even if there is no way for you to
+ control the headers it sends.
+
+ - This behavior can be disabled by unchecking **Enable Cross Origin Isolation Headers**
+ in the Progressive Web App section.
+
Limitations
-----------
@@ -141,7 +226,7 @@ player to click, tap or press a key/button to enable audio, for instance when di
.. seealso:: Google offers additional information about their `Web Audio autoplay
policies `__.
- Apple's Safari team also posted additional information about their `Auto-Play Policy Changes for macOS
+ Apple's Safari team also posted additional information about their `Auto-Play Policy Changes for macOS
`__.
.. warning:: Access to microphone requires a
@@ -205,8 +290,8 @@ used, see :ref:`doc_customizing_html5_shell`.
.. warning::
- To ensure low audio latency and the ability to use :ref:`class_Thread` in web exports,
- Godot 4 web exports always use
+ If either :ref:`thread support or extension support `
+ are enabled, the exported project will require
`SharedArrayBuffer `__.
This requires a :ref:`secure context `,
while also requiring the following CORS headers to be set when serving the files:
@@ -217,11 +302,13 @@ used, see :ref:`doc_customizing_html5_shell`.
Cross-Origin-Embedder-Policy: require-corp
If you don't control the web server or are unable to add response headers,
- use `coi-serviceworker `__
- as a workaround.
+ check **Progressive Web App > Enable** in the export options. This applies
+ a service worker-based workaround that allows the project to run by
+ simulating the presence of these response headers. A secure context
+ is still required in this case.
- If the client doesn't receive the required response headers,
- **the project will not run**.
+ If the client doesn't receive the required response headers or the service
+ worker-based workaround is not applied, **the project will not run**.
The generated ``.html`` file can be used as ``DirectoryIndex`` in Apache
servers and can be renamed to e.g. ``index.html`` at any time. Its name is
@@ -289,7 +376,8 @@ supported on your web server for further file size savings.
Interacting with the browser and JavaScript
-------------------------------------------
-See the :ref:`dedicated page ` on how to interact with JavaScript and access some unique Web browser features.
+See the :ref:`dedicated page ` on how to interact
+with JavaScript and access some unique Web browser features.
Environment variables
---------------------
diff --git a/tutorials/export/exporting_for_windows.rst b/tutorials/export/exporting_for_windows.rst
index 33b78934c1c..a3d317ec9dd 100644
--- a/tutorials/export/exporting_for_windows.rst
+++ b/tutorials/export/exporting_for_windows.rst
@@ -24,7 +24,7 @@ Code signing
Godot is capable of automatic code signing on export. To do this you must have the
``Windows SDK`` (on Windows) or `osslsigncode `__
(on any other OS) installed. You will also need a package signing certificate,
-information on creating one can be found `here `__.
+information on creating one can be found `here `__.
.. warning::
diff --git a/tutorials/inputs/controllers_gamepads_joysticks.rst b/tutorials/inputs/controllers_gamepads_joysticks.rst
index 37e7124cfcb..74099f0d153 100644
--- a/tutorials/inputs/controllers_gamepads_joysticks.rst
+++ b/tutorials/inputs/controllers_gamepads_joysticks.rst
@@ -136,10 +136,6 @@ use ``Input.is_action_pressed()``:
held, ``Input.is_action_just_pressed()`` will only return ``true`` for one
frame after the button has been pressed.
-In Godot versions before 3.4, such as 3.3, ``Input.get_vector()`` and
-``Input.get_axis()`` aren't available. Only ``Input.get_action_strength()``
-and ``Input.is_action_pressed()`` are available in Godot 3.3.
-
Vibration
---------
diff --git a/tutorials/inputs/custom_mouse_cursor.rst b/tutorials/inputs/custom_mouse_cursor.rst
index 36fb6f5e39e..0964ca29397 100644
--- a/tutorials/inputs/custom_mouse_cursor.rst
+++ b/tutorials/inputs/custom_mouse_cursor.rst
@@ -7,17 +7,14 @@ You might want to change the appearance of the mouse cursor in your game in
order to suit the overall design. There are two ways to customize the mouse
cursor:
-1. Using project settings
-2. Using a script
-
-Using project settings is a simpler (but more limited) way to customize the mouse cursor.
-The second way is more customizable, but involves scripting:
+1. Using project settings. This is simpler, but more limited.
+2. Using a script. This is more customizable, but involves scripting.
.. note::
You could display a "software" mouse cursor by hiding the mouse cursor and
moving a Sprite2D to the cursor position in a ``_process()`` method, but
- this will add at least one frame of latency compared to an "hardware" mouse
+ this will add at least one frame of latency compared to a "hardware" mouse
cursor. Therefore, it's recommended to use the approach described here
whenever possible.
@@ -27,18 +24,20 @@ The second way is more customizable, but involves scripting:
Using project settings
----------------------
-Open project settings, go to Display>Mouse Cursor. You will see Custom Image, Custom Image Hotspot
-and Tooltip Position Offset.
+Open the **Project Settings** and go to **Display > Mouse Cursor**. You will see the settings
+:ref:`Custom Image `,
+:ref:`Custom Image Hotspot `,
+and :ref:`Tooltip Position Offset `.
.. image:: img/cursor_project_settings.webp
-Custom Image is the desired image that you would like to set as the mouse cursor.
-Custom Hotspot is the point in the image that you would like to use as the cursor's detection point.
+**Custom Image** is the desired image that you would like to set as the mouse cursor.
+**Custom Hotspot** is the point in the image that you would like to use as the cursor's detection point.
.. warning::
The custom image **must** be 256×256 pixels at most. To avoid rendering
- issues, sizes lower than or equal to 128×128 are recommended.
+ issues, sizes of 128×128 or smaller are recommended.
On the web platform, the maximum allowed cursor image size is 128×128.
@@ -68,18 +67,23 @@ Create a Node and attach the following script.
.. code-tab:: csharp
- public override void _Ready()
- {
- // Load the custom images for the mouse cursor.
- var arrow = ResourceLoader.Load("res://arrow.png");
- var beam = ResourceLoader.Load("res://beam.png");
-
- // Changes only the arrow shape of the cursor.
- // This is similar to changing it in the project settings.
- Input.SetCustomMouseCursor(arrow);
+ using Godot;
- // Changes a specific shape of the cursor (here, the I-beam shape).
- Input.SetCustomMouseCursor(beam, Input.CursorShape.Ibeam);
+ public partial class MyNode : Node
+ {
+ public override void _Ready()
+ {
+ // Load the custom images for the mouse cursor.
+ var arrow = ResourceLoader.Load("res://arrow.png");
+ var beam = ResourceLoader.Load("res://beam.png");
+
+ // Changes only the arrow shape of the cursor.
+ // This is similar to changing it in the project settings.
+ Input.SetCustomMouseCursor(arrow);
+
+ // Changes a specific shape of the cursor (here, the I-beam shape).
+ Input.SetCustomMouseCursor(beam, Input.CursorShape.Ibeam);
+ }
}
.. seealso::
@@ -90,6 +94,6 @@ Create a Node and attach the following script.
Cursor list
-----------
-As documented in the :ref:`Input ` class (see the **CursorShape**
-enum), there are multiple mouse cursors you can define. Which ones you want to
-use depends on your use case.
+There are multiple mouse cursors you can define, documented in the
+:ref:`Input.CursorShape ` enum. Which ones you want to use
+depends on your use case.
diff --git a/tutorials/inputs/handling_quit_requests.rst b/tutorials/inputs/handling_quit_requests.rst
index fae7f3cde32..e470e5f3f55 100644
--- a/tutorials/inputs/handling_quit_requests.rst
+++ b/tutorials/inputs/handling_quit_requests.rst
@@ -60,8 +60,10 @@ at any time by either the user or the OS. A way to plan ahead for this
possibility is to utilize ``NOTIFICATION_APPLICATION_PAUSED`` in order to
perform any needed actions as the app is being suspended.
+.. note:: On iOS, you only have approximately 5 seconds to finish a task started by this signal. If you go over this allotment, iOS will kill the app instead of pausing it.
+
On Android, pressing the Back button will exit the application if
-**Application > Config > Quit** On Go Back is checked in the Project Settings
+**Application > Config > Quit On Go Back** is checked in the Project Settings
(which is the default). This will fire ``NOTIFICATION_WM_GO_BACK_REQUEST``.
diff --git a/tutorials/inputs/inputevent.rst b/tutorials/inputs/inputevent.rst
index 8f49916ffeb..1116a902549 100644
--- a/tutorials/inputs/inputevent.rst
+++ b/tutorials/inputs/inputevent.rst
@@ -194,10 +194,10 @@ There are several specialized types of InputEvent, described in the table below:
| | as feedback. (more on this below) |
+-------------------------------------------------------------------+-----------------------------------------+
-Actions
--------
+Input actions
+-------------
-Actions are a grouping of zero or more InputEvents into a commonly
+Input actions are a grouping of zero or more InputEvents into a commonly
understood title (for example, the default "ui_left" action grouping both joypad-left input and a keyboard's left arrow key). They are not required to represent an
InputEvent but are useful because they abstract various inputs when
programming the game logic.
@@ -239,6 +239,12 @@ The Input singleton has a method for this:
// Feedback.
Input.ParseInputEvent(ev);
+
+.. seealso::
+
+ See :ref:`doc_first_3d_game_input_actions` for a tutorial on adding input
+ actions in the project settings.
+
InputMap
--------
diff --git a/tutorials/io/img/groups.png b/tutorials/io/img/groups.png
deleted file mode 100644
index 0658058aba9..00000000000
Binary files a/tutorials/io/img/groups.png and /dev/null differ
diff --git a/tutorials/io/img/groups.webp b/tutorials/io/img/groups.webp
new file mode 100644
index 00000000000..2805512f8fc
Binary files /dev/null and b/tutorials/io/img/groups.webp differ
diff --git a/tutorials/io/saving_games.rst b/tutorials/io/saving_games.rst
index 27347278dcd..0776d93d3be 100644
--- a/tutorials/io/saving_games.rst
+++ b/tutorials/io/saving_games.rst
@@ -34,7 +34,7 @@ We will start by adding objects we wish to save to the "Persist" group. We can
do this through either the GUI or script. Let's add the relevant nodes using the
GUI:
-.. image:: img/groups.png
+.. image:: img/groups.webp
Once this is done, when we need to save the game, we can get all objects
to save them and then tell them all to save with this script:
@@ -61,7 +61,7 @@ Serializing
The next step is to serialize the data. This makes it much easier to
read from and store to disk. In this case, we're assuming each member of
group Persist is an instanced node and thus has a path. GDScript
-has helper class :ref:`JSON` to convert between dictionary and string,
+has the helper class :ref:`JSON` to convert between dictionary and string.
Our node needs to contain a save function that returns this data.
The save function will look like this:
diff --git a/tutorials/math/matrices_and_transforms.rst b/tutorials/math/matrices_and_transforms.rst
index 05f4c0dd879..7443dd012aa 100644
--- a/tutorials/math/matrices_and_transforms.rst
+++ b/tutorials/math/matrices_and_transforms.rst
@@ -352,7 +352,7 @@ from X*1 + Y*-1, which is (1, 0) - (1, 1), or (1 - 1, 0 - 1), or (0, -1).
This matches up with our observation of where the top-right corner
of the image is.
-Hopefully you now fully understand the how a transformation matrix affects
+Hopefully you now fully understand how a transformation matrix affects
the object, and the relationship between the basis vectors and how the
object's "UV" or "intra-coordinates" have their world position changed.
diff --git a/tutorials/math/random_number_generation.rst b/tutorials/math/random_number_generation.rst
index c28b05d1a8b..a12f43eb3a1 100644
--- a/tutorials/math/random_number_generation.rst
+++ b/tutorials/math/random_number_generation.rst
@@ -84,6 +84,7 @@ across runs:
public override void _Ready()
{
GD.Seed(12345);
+ // To use a string as a seed, you can hash it to a number.
GD.Seed("Hello world".Hash());
}
@@ -108,9 +109,9 @@ Let's look at some of the most commonly used functions and methods to generate
random numbers in Godot.
The function :ref:`randi() ` returns a random
-number between 0 and 2^32-1. Since the maximum value is huge, you most likely
-want to use the modulo operator (``%``) to bound the result between 0 and the
-denominator:
+number between ``0`` and ``2^32 - 1``. Since the maximum value is huge, you most
+likely want to use the modulo operator (``%``) to bound the result between 0 and
+the denominator:
.. tabs::
.. code-tab:: gdscript GDScript
@@ -134,7 +135,7 @@ number between 0 and 1. This is useful to implement a
:ref:`doc_random_number_generation_weighted_random_probability` system, among
other things.
-:ref:`randfn() ` returns a random
+:ref:`randfn() ` returns a random
floating-point number following a `normal distribution
`__. This means the returned
value is more likely to be around the mean (0.0 by default),
@@ -144,16 +145,12 @@ varying by the deviation (1.0 by default):
.. code-tab:: gdscript GDScript
# Prints a random floating-point number from a normal distribution with a mean 0.0 and deviation 1.0.
- var random = RandomNumberGenerator.new()
- random.randomize()
- print(random.randfn())
+ print(randfn())
.. code-tab:: csharp
- // Prints a normally distributed floating-point number between 0.0 and 1.0.
- var random = new RandomNumberGenerator();
- random.Randomize();
- GD.Print(random.Randfn());
+ // Prints a random floating-point number from a normal distribution with a mean of 0.0 and deviation of 1.0.
+ GD.Print(GD.Randfn());
:ref:`randf_range() ` takes two arguments
``from`` and ``to``, and returns a random floating-point number between ``from``
@@ -165,28 +162,31 @@ and ``to``:
# Prints a random floating-point number between -4 and 6.5.
print(randf_range(-4, 6.5))
-:ref:`RandomNumberGenerator.randi_range()
-` takes two arguments ``from``
+ .. code-tab:: csharp
+
+ // Prints a random floating-point number between -4 and 6.5.
+ GD.Print(GD.RandfRange(-4, 6.5));
+
+:ref:`randi_range() ` takes two arguments ``from``
and ``to``, and returns a random integer between ``from`` and ``to``:
.. tabs::
.. code-tab:: gdscript GDScript
# Prints a random integer between -10 and 10.
- var random = RandomNumberGenerator.new()
- random.randomize()
- print(random.randi_range(-10, 10))
+ print(randi_range(-10, 10))
.. code-tab:: csharp
- // Prints a random integer number between -10 and 10.
- random.Randomize();
- GD.Print(random.RandiRange(-10, 10));
+ // Prints a random integer between -10 and 10.
+ GD.Print(GD.RandiRange(-10, 10));
Get a random array element
--------------------------
-We can use random integer generation to get a random element from an array:
+We can use random integer generation to get a random element from an array,
+or use the :ref:`Array.pick_random` method
+to do it for us:
.. tabs::
.. code-tab:: gdscript GDScript
@@ -194,12 +194,14 @@ We can use random integer generation to get a random element from an array:
var _fruits = ["apple", "orange", "pear", "banana"]
func _ready():
- randomize()
-
for i in range(100):
# Pick 100 fruits randomly.
print(get_fruit())
+ for i in range(100):
+ # Pick 100 fruits randomly, this time using the `Array.pick_random()`
+ # helper method. This has the same behavior as `get_fruit()`.
+ print(_fruits.pick_random())
func get_fruit():
var random_fruit = _fruits[randi() % _fruits.size()]
@@ -209,29 +211,37 @@ We can use random integer generation to get a random element from an array:
.. code-tab:: csharp
- private string[] _fruits = { "apple", "orange", "pear", "banana" };
+ // Use Godot's Array type instead of a BCL type so we can use `PickRandom()` on it.
+ private Godot.Collections.Array _fruits = new Godot.Collections.Array { "apple", "orange", "pear", "banana" };
public override void _Ready()
{
- GD.Randomize();
-
for (int i = 0; i < 100; i++)
{
// Pick 100 fruits randomly.
GD.Print(GetFruit());
}
+
+ for (int i = 0; i < 100; i++)
+ {
+ // Pick 100 fruits randomly, this time using the `Array.PickRandom()`
+ // helper method. This has the same behavior as `GetFruit()`.
+ GD.Print(_fruits.PickRandom());
+ }
}
public string GetFruit()
{
- string randomFruit = _fruits[GD.Randi() % _fruits.Length];
+ string randomFruit = _fruits[GD.Randi() % _fruits.Size()];
// Returns "apple", "orange", "pear", or "banana" every time the code runs.
// We may get the same fruit multiple times in a row.
return randomFruit;
}
To prevent the same fruit from being picked more than once in a row, we can add
-more logic to this method:
+more logic to the above method. In this case, we can't use
+:ref:`Array.pick_random` since it lacks a way to
+prevent repetition:
.. tabs::
.. code-tab:: gdscript GDScript
@@ -241,8 +251,6 @@ more logic to this method:
func _ready():
- randomize()
-
# Pick 100 fruits randomly.
for i in range(100):
print(get_fruit())
@@ -251,7 +259,7 @@ more logic to this method:
func get_fruit():
var random_fruit = _fruits[randi() % _fruits.size()]
while random_fruit == _last_fruit:
- # The last fruit was picked, try again until we get a different fruit.
+ # The last fruit was picked. Try again until we get a different fruit.
random_fruit = _fruits[randi() % _fruits.size()]
# Note: if the random element to pick is passed by reference,
@@ -270,8 +278,6 @@ more logic to this method:
public override void _Ready()
{
- GD.Randomize();
-
for (int i = 0; i < 100; i++)
{
// Pick 100 fruits randomly.
@@ -284,7 +290,7 @@ more logic to this method:
string randomFruit = _fruits[GD.Randi() % _fruits.Length];
while (randomFruit == _lastFruit)
{
- // The last fruit was picked, try again until we get a different fruit.
+ // The last fruit was picked. Try again until we get a different fruit.
randomFruit = _fruits[GD.Randi() % _fruits.Length];
}
@@ -316,8 +322,6 @@ We can apply similar logic from arrays to dictionaries as well:
func _ready():
- randomize()
-
for i in range(20):
print(get_metal())
@@ -341,8 +345,6 @@ floating-point number between 0.0 and 1.0. We can use this to create a
.. code-tab:: gdscript GDScript
func _ready():
- randomize()
-
for i in range(100):
print(get_item_rarity())
@@ -364,8 +366,6 @@ floating-point number between 0.0 and 1.0. We can use this to create a
public override void _Ready()
{
- GD.Randomize();
-
for (int i = 0; i < 100; i++)
{
GD.Print(GetItemRarity());
@@ -383,7 +383,7 @@ floating-point number between 0.0 and 1.0. We can use this to create a
}
else if (randomFloat < 0.95f)
{
- // 15% chance of being returned
+ // 15% chance of being returned.
return "Uncommon";
}
else
@@ -393,6 +393,44 @@ floating-point number between 0.0 and 1.0. We can use this to create a
}
}
+You can also get a weighted random *index* using the
+:ref:`rand_weighted() ` method
+on a RandomNumberGenerator instance. This returns a random integer
+between 0 and the size of the array that is passed as a parameter. Each value in the
+array is a floating-point number that represents the *relative* likelihood that it
+will be returned as an index. A higher value means the value is more likely to be
+returned as an index, while a value of ``0`` means it will never be returned as an index.
+
+For example, if ``[0.5, 1, 1, 2]`` is passed as a parameter, then the method is twice
+as likely to return ``3`` (the index of the value ``2``) and twice as unlikely to return
+``0`` (the index of the value ``0.5``) compared to the indices ``1`` and ``2``.
+
+Since the returned value matches the array's size, it can be used as an index to
+get a value from another array as follows:
+
+.. tabs::
+ .. code-tab:: gdscript GDScript
+
+ # Prints a random element using the weighted index that is returned by `rand_weighted()`.
+ # Here, "apple" will be returned twice as rarely as "orange" and "pear".
+ # "banana" is twice as common as "orange" and "pear", and four times as common as "apple".
+ var fruits = ["apple", "orange", "pear", "banana"]
+ var probabilities = [0.5, 1, 1, 2];
+
+ var random = RandomNumberGenerator.new()
+ print(fruits[random.rand_weighted(probabilities)])
+
+ .. code-tab:: csharp
+
+ // Prints a random element using the weighted index that is returned by `RandWeighted()`.
+ // Here, "apple" will be returned twice as rarely as "orange" and "pear".
+ // "banana" is twice as common as "orange" and "pear", and four times as common as "apple".
+ string[] fruits = { "apple", "orange", "pear", "banana" };
+ float[] probabilities = { 0.5, 1, 1, 2 };
+
+ var random = new RandomNumberGenerator();
+ GD.Print(fruits[random.RandWeighted(probabilities)]);
+
.. _doc_random_number_generation_shuffle_bags:
"Better" randomness using shuffle bags
@@ -413,7 +451,6 @@ ends up empty. When that happens, you reinitialize it to its default value::
func _ready():
- randomize()
_fruits_full = _fruits.duplicate()
_fruits.shuffle()
@@ -456,7 +493,6 @@ terrain. Godot provides :ref:`class_fastnoiselite` for this, which supports
var _noise = FastNoiseLite.new()
func _ready():
- randomize()
# Configure the FastNoiseLite instance.
_noise.noise_type = FastNoiseLite.NoiseType.TYPE_SIMPLEX_SMOOTH
_noise.seed = randi()
@@ -474,7 +510,6 @@ terrain. Godot provides :ref:`class_fastnoiselite` for this, which supports
public override void _Ready()
{
- GD.Randomize();
// Configure the FastNoiseLite instance.
_noise.NoiseType = NoiseTypeEnum.SimplexSmooth;
_noise.Seed = (int)GD.Randi();
diff --git a/tutorials/math/vectors_advanced.rst b/tutorials/math/vectors_advanced.rst
index 1d0b80ed302..58372106721 100644
--- a/tutorials/math/vectors_advanced.rst
+++ b/tutorials/math/vectors_advanced.rst
@@ -23,7 +23,7 @@ because of its usage. (Just like we call (0,0) the Origin!).
The plane passes by the origin and the
surface of it is perpendicular to the unit vector (or *normal*). The
-side towards the vector points to is the positive half-space, while the
+side the vector points to is the positive half-space, while the
other side is the negative half-space. In 3D this is exactly the same,
except that the plane is an infinite surface (imagine an infinite, flat
sheet of paper that you can orient and is pinned to the origin) instead
diff --git a/tutorials/migrating/upgrading_to_godot_4.rst b/tutorials/migrating/upgrading_to_godot_4.rst
index a5bb987f3d2..57f7b99f7dc 100644
--- a/tutorials/migrating/upgrading_to_godot_4.rst
+++ b/tutorials/migrating/upgrading_to_godot_4.rst
@@ -71,9 +71,10 @@ in future Godot releases:
manually change it to GodotPhysics. There are no plans to re-add Bullet physics
in core, but a third-party add-on could be created for it thanks to
GDExtension.
-- Rendering in 2D is no longer performed in HDR, which means "overbright"
- modulate values have no visible effect. This is planned to be restored at some
- point in the future.
+- By default, rendering in 2D is no longer performed in HDR, which means
+ "overbright" modulate values have no visible effect. Since Godot 4.2, you can
+ enable the project setting :ref:`HDR 2D`
+ to perform 2D rendering in HDR. See also :ref:`doc_environment_and_post_processing_using_glow_in_2d`.
- While rendering still happens in HDR in 3D when using the Forward Plus or
Forward Mobile backends, Viewports cannot return HDR data anymore. This is
planned to be restored at some point in the future.
@@ -509,13 +510,15 @@ environment effect and its visual knobs remain within the Environment resource.
Updating shaders
^^^^^^^^^^^^^^^^
-There have been some changes to shaders that aren't covered by the upgrade tool.
+There have been some changes to shaders that aren't covered by the upgrade tool.
+You will need to make some manual changes, especially if your shader uses coordinate
+space transformations or a custom ``light()`` function.
The ``.shader`` file extension is no longer supported, which means you must
rename ``.shader`` files to ``.gdshader`` and update references accordingly in
scene/resource files using an external text editor.
-Some notable renames you will need to perform in shaders are:
+Some notable changes you will need to perform in shaders are:
- Texture filter and repeat modes are now set on individual uniforms, rather
than the texture files themselves.
@@ -524,9 +527,22 @@ Some notable renames you will need to perform in shaders are:
- :ref:`Built in matrix variables were renamed. `
- Particles shaders no longer use the ``vertex()`` processor function. Instead
they use ``start()`` and ``process()``.
+- In the Forward+ and Mobile renderers, normalized device coordinates now have a Z-range of ``[0.0,1.0]``
+ instead of ``[-1.0,1.0]``. When reconstructing NDC from ``SCREEN_UV`` and depth, use
+ ``vec3 ndc = vec3(SCREEN_UV * 2.0 - 1.0, depth);`` instead of
+ ``vec3 ndc = vec3(SCREEN_UV, depth) * 2.0 - 1.0;``. The Compatibility renderer is unchanged,
+ using the same NDC Z-range as 3.x.
+- The lighting model changed. If your shader has a custom ``light()`` function,
+ you may need to make changes to get the same visual result.
+- In 4.3 and up, the reverse Z depth buffer technique is now implemented, which
+ may break advanced shaders. See
+ `Introducing Reverse Z (AKA I'm sorry for breaking your shader) `__.
See :ref:`doc_shading_language` for more information.
+This list is not exhaustive. If you made all the changes mentioned here and your
+shader still doesn't work, try asking for help in one of the `community channels `__.
+
Updating scripts to take backwards-incompatible changes into account
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/tutorials/performance/thread_safe_apis.rst b/tutorials/performance/thread_safe_apis.rst
index 174dfc3dbeb..4ef605e2992 100644
--- a/tutorials/performance/thread_safe_apis.rst
+++ b/tutorials/performance/thread_safe_apis.rst
@@ -55,7 +55,9 @@ Rendering
---------
Instancing nodes that render anything in 2D or 3D (such as Sprite) is *not* thread-safe by default.
-To make rendering thread-safe, set the **Rendering > Driver > Thread Model** project setting to **Multi-Threaded**.
+To make rendering thread-safe, set the
+:ref:`Rendering > Driver > Thread Model`
+project setting to **Multi-Threaded**.
Note that the Multi-Threaded thread model has several known bugs, so it may not be usable
in all scenarios.
diff --git a/tutorials/performance/using_multimesh.rst b/tutorials/performance/using_multimesh.rst
index 9e9d355ad16..b48e8cd0d49 100644
--- a/tutorials/performance/using_multimesh.rst
+++ b/tutorials/performance/using_multimesh.rst
@@ -17,8 +17,7 @@ MultiMeshes
-----------
A :ref:`MultiMesh` is a single draw primitive that can draw up to millions
-of objects in one go. It's extremely efficient because it uses the GPU hardware to do this
-(in OpenGL ES 2.0, it's less efficient because there is no hardware support for it, though).
+of objects in one go. It's extremely efficient because it uses the GPU hardware to do this.
The only drawback is that there is no *screen* or *frustum* culling possible for individual instances.
This means, that millions of objects will be *always* or *never* drawn, depending on the visibility
diff --git a/tutorials/physics/physics_introduction.rst b/tutorials/physics/physics_introduction.rst
index b16b97754ad..cc9ce2704dc 100644
--- a/tutorials/physics/physics_introduction.rst
+++ b/tutorials/physics/physics_introduction.rst
@@ -132,7 +132,7 @@ These properties can be configured via code, or by editing them in the Inspector
Keeping track of what you're using each layer for can be difficult, so you
may find it useful to assign names to the layers you're using. Names can
-be assigned in Project Settings -> Layer Names.
+be assigned in **Project Settings > Layer Names**.
.. image:: img/physics_layer_names.png
@@ -180,6 +180,12 @@ would be as follows::
# (2^(1-1)) + (2^(3-1)) + (2^(4-1)) = 1 + 4 + 8 = 13
pow(2, 1-1) + pow(2, 3-1) + pow(2, 4-1)
+Export annotations can be used to export bitmasks in the editor with a user-friendly GUI::
+
+ @export_flags_2d_physics var layers_2d_physics
+
+Additional export annotations are available for render and navigation layers, in both 2D and 3D. See :ref:`doc_gdscript_exports_exporting_bit_flags`.
+
Area2D
------
@@ -229,7 +235,7 @@ You can modify a rigid body's behavior via properties such as "Mass",
"Friction", or "Bounce", which can be set in the Inspector.
The body's behavior is also affected by the world's properties, as set in
-`Project Settings -> Physics`, or by entering an :ref:`Area2D `
+**Project Settings > Physics**, or by entering an :ref:`Area2D `
that is overriding the global physics properties.
When a rigid body is at rest and hasn't moved for a while, it goes to sleep.
diff --git a/tutorials/physics/troubleshooting_physics_issues.rst b/tutorials/physics/troubleshooting_physics_issues.rst
index 4735814fe23..6ebaea74bb3 100644
--- a/tutorials/physics/troubleshooting_physics_issues.rst
+++ b/tutorials/physics/troubleshooting_physics_issues.rst
@@ -27,7 +27,8 @@ other solutions you can try:
speed. The faster the object moves, the larger the collision shape should
extend outside of the object to ensure it can collide with thin walls more
reliably.
-- Increase **Physics Ticks Per Second** in the advanced Project Settings. While
+- Increase :ref:`Physics Ticks per Second`
+ in the advanced Project Settings. While
this has other benefits (such as more stable simulation and reduced input
lag), this increases CPU utilization and may not be viable for mobile/web
platforms. Multipliers of the default value of ``60`` (such as ``120``, ``180``
@@ -44,7 +45,8 @@ causes the simulation to become wobbly, making the objects unable to rest on top
of each other without moving.
Increasing the physics simulation rate can help alleviate this issue. To do so,
-increase **Physics Ticks Per Second** in the advanced Project Settings. Note
+increase :ref:`Physics Ticks per Second`
+in the advanced Project Settings. Note
that increases CPU utilization and may not be viable for mobile/web platforms.
Multipliers of the default value of ``60`` (such as ``120``, ``180`` or ``240``)
should be preferred for a smooth appearance on most displays.
@@ -83,7 +85,9 @@ simulation rate (as making the shape thicker would cause a disconnect between
the RigidBody's visual representation and its collision).
In both cases, increasing the physics simulation rate can also help alleviate
-this issue. To do so, increase **Physics Ticks Per Second** in the advanced
+this issue. To do so, increase
+:ref:`Physics Ticks per Second`
+in the advanced
Project Settings. Note that this increases CPU utilization and may not be viable
for mobile/web platforms. Multipliers of the default value of ``60`` (such as
``120``, ``180`` or ``240``) should be preferred for a smooth appearance on most
@@ -115,7 +119,9 @@ vehicle (due to tunneling), but also that the simulation has little data to work
with in general at such a high speed.
Fast-moving vehicles can benefit a lot from an increased physics simulation
-rate. To do so, increase **Physics Ticks Per Second** in the advanced Project
+rate. To do so, increase
+:ref:`Physics Ticks per Second`
+in the advanced Project
Settings. Note that this increases CPU utilization and may not be viable for
mobile/web platforms. Multipliers of the default value of ``60`` (such as
``120``, ``180`` or ``240``) should be preferred for a smooth appearance on most
@@ -156,6 +162,22 @@ geometry as a collider. Not only this will improve physics simulation
performance significantly, but this can also improve stability by letting you
remove small fixtures and crevices from being considered by collision.
+Framerate suddenly drops to a very low value beyond a certain amount of physics simulation
+------------------------------------------------------------------------------------------
+
+This occurs because the physics engine can't keep up with the expected
+simulation rate. In this case, the framerate will start dropping, but the engine
+is only allowed to simulate a certain number of physics steps per rendered
+frame. This snowballs into a situation where framerate keeps dropping until it
+reaches a very low framerate (typically 1-2 FPS) and is called the *physics
+spiral of death*.
+
+To avoid this, you should check for situations in your project that can cause
+excessive number of physics simulations to occur at the same time (or with
+excessively complex collision shapes). If these situations cannot be avoided,
+you can increase the **Max Physics Steps per Frame** project setting and/or
+reduce **Physics Ticks per Second** to alleviate this.
+
Physics simulation is unreliable when far away from the world origin
--------------------------------------------------------------------
diff --git a/tutorials/platform/android/android_library.rst b/tutorials/platform/android/android_library.rst
index 634df4fc558..deb19a69f70 100644
--- a/tutorials/platform/android/android_library.rst
+++ b/tutorials/platform/android/android_library.rst
@@ -94,7 +94,10 @@ Below we break-down the steps used to create the GLTF Viewer app.
- If using ``gradle``, include the following ``aaptOptions`` configuration under the ``android > defaultConfig`` section of the app's gradle build file. Doing so allows ``gradle`` to include Godot's hidden directories when building the app binary.
- - If your build system does not support including hidden directories, you can `configure the Godot project to not use hidden directories `_ by deselecting ``Project Settings... > Application > Config > Use Hidden Project Data Directory``.
+ - If your build system does not support including hidden directories, you can
+ configure the Godot project to not use hidden directories by deselecting
+ :ref:`Application > Config > Use Hidden Project Data Directory`
+ in the Project Settings.
.. code-block:: groovy
diff --git a/tutorials/platform/web/javascript_bridge.rst b/tutorials/platform/web/javascript_bridge.rst
index a3baf9c282f..375bb6117ae 100644
--- a/tutorials/platform/web/javascript_bridge.rst
+++ b/tutorials/platform/web/javascript_bridge.rst
@@ -1,6 +1,6 @@
.. _doc_web_javascript_bridge:
-The JavaScriptBridge Singleton
+The JavaScriptBridge singleton
==============================
In web builds, the :ref:`JavaScriptBridge ` singleton
@@ -93,6 +93,12 @@ Arguments passed by JavaScript to the callback will be passed as a single Godot
js_event.preventDefault()
js_event.returnValue = ''
+.. warning::
+
+ The number of arguments accepted by the callback method (``_my_callback`` in the above example)
+ **must** match the number of arguments sent by JavaScript. Otherwise, the callback method will
+ not be called.
+
Here is another example that asks the user for the `Notification permission `__
and waits asynchronously to deliver a notification if the permission is
granted:
diff --git a/tutorials/plugins/editor/making_plugins.rst b/tutorials/plugins/editor/making_plugins.rst
index e9bdd9eb27e..760946140b5 100644
--- a/tutorials/plugins/editor/making_plugins.rst
+++ b/tutorials/plugins/editor/making_plugins.rst
@@ -450,12 +450,12 @@ Use the following code to register a singleton from an editor plugin:
const AUTOLOAD_NAME = "SomeAutoload"
- func _enter_tree():
+ func _enable_plugin():
# The autoload can be a scene or script file.
add_autoload_singleton(AUTOLOAD_NAME, "res://addons/my_addon/some_autoload.tscn")
- func _exit_tree():
+ func _disable_plugin():
remove_autoload_singleton(AUTOLOAD_NAME)
.. code-tab:: csharp
@@ -469,13 +469,13 @@ Use the following code to register a singleton from an editor plugin:
// Replace this value with a PascalCase autoload name.
private const string AutoloadName = "SomeAutoload";
- public override void _EnterTree()
+ public override void _EnablePlugin()
{
// The autoload can be a scene or script file.
AddAutoloadSingleton(AutoloadName, "res://addons/MyAddon/SomeAutoload.tscn");
}
- public override void _ExitTree()
+ public override void _DisablePlugin()
{
RemoveAutoloadSingleton(AutoloadName);
}
diff --git a/tutorials/rendering/index.rst b/tutorials/rendering/index.rst
index f6993dafaba..4805593054d 100644
--- a/tutorials/rendering/index.rst
+++ b/tutorials/rendering/index.rst
@@ -3,6 +3,11 @@
Rendering
=========
+.. seealso::
+
+ Most rendering topics are covered in :ref:`2D rendering `
+ and :ref:`3D rendering `.
+
.. toctree::
:maxdepth: 1
:name: toc-learn-features-rendering
diff --git a/tutorials/scripting/c_sharp/c_sharp_basics.rst b/tutorials/scripting/c_sharp/c_sharp_basics.rst
index 224ec48a393..d160c74f539 100644
--- a/tutorials/scripting/c_sharp/c_sharp_basics.rst
+++ b/tutorials/scripting/c_sharp/c_sharp_basics.rst
@@ -90,7 +90,7 @@ In Godot's **Editor → Editor Settings** menu:
In Rider:
- Set **MSBuild version** to **.NET Core**.
-- Install the **Godot support** plugin.
+- If you are using a Rider version below 2024.2, install the **Godot support** plugin. This functionality is now built into Rider.
Visual Studio Code
~~~~~~~~~~~~~~~~~~
@@ -357,11 +357,10 @@ You can read more about this error on the `C# language reference `_,
-the performance of C# in Godot — while generally in the same order of magnitude
-— is roughly **~4×** that of GDScript in some naive cases. C++ is still
-a little faster; the specifics are going to vary according to your use case.
-GDScript is likely fast enough for most general scripting workloads.
+.. seealso::
+
+ For a performance comparison of the languages Godot supports,
+ see :ref:`doc_faq_which_programming_language_is_fastest`.
Most properties of Godot C# objects that are based on ``GodotObject``
(e.g. any ``Node`` like ``Control`` or ``Node3D`` like ``Camera3D``) require native (interop) calls as they talk to
diff --git a/tutorials/scripting/c_sharp/c_sharp_exports.rst b/tutorials/scripting/c_sharp/c_sharp_exports.rst
index a0af83a3e33..9ef4f1de077 100644
--- a/tutorials/scripting/c_sharp/c_sharp_exports.rst
+++ b/tutorials/scripting/c_sharp/c_sharp_exports.rst
@@ -108,7 +108,7 @@ Properties with a backing field use the default value of the backing field.
node with an attached tool script, ``_number`` will be ``2``, and
``NumberWithBackingField`` will return ``5``. This difference may cause
confusing behavior. To avoid this, don't use complex properties. Alternatively,
- if the default value can be explicitly specified, it can be overridden with the
+ if the default value can be explicitly specified, it can be overridden with the
:ref:`_PropertyCanRevert() ` and
:ref:`_PropertyGetRevert() ` methods.
@@ -259,14 +259,30 @@ the slider.
Floats with easing hint
-----------------------
-Display a visual representation of the 'ease()' function
-when editing.
+Display a visual representation of the :ref:`ease`
+function when editing.
.. code-block:: csharp
[Export(PropertyHint.ExpEasing)]
public float TransitionSpeed { get; set; }
+Export with suffix hint
+-----------------------
+
+Display a unit hint suffix for exported variables. Works with numeric types,
+such as floats or vectors:
+
+.. code-block:: csharp
+
+ [Export(PropertyHint.None, "suffix:m/s\u00b2")]
+ public float Gravity { get; set; } = 9.8f;
+ [Export(PropertyHint.None, "suffix:m/s")]
+ public Vector3 Velocity { get; set; }
+
+In the above example, ``\u00b2`` is used to write the "squared" character
+(``²``).
+
Colors
------
@@ -363,7 +379,7 @@ combine multiple flags using logical OR (``|``) are also possible.
.. code-block:: csharp
[Flags]
- public enum MyEnum
+ public enum SpellElements
{
Fire = 1 << 1,
Water = 1 << 2,
@@ -450,7 +466,7 @@ of the selected option (i.e. ``0``, ``1``, or ``2``).
.. code-block:: csharp
[Export(PropertyHint.Enum, "Warrior,Magician,Thief")]
- public int CharacterClass { get; set; };
+ public int CharacterClass { get; set; }
You can add explicit values using a colon:
diff --git a/tutorials/scripting/c_sharp/c_sharp_global_classes.rst b/tutorials/scripting/c_sharp/c_sharp_global_classes.rst
index 8bf12527e86..7a13a551188 100644
--- a/tutorials/scripting/c_sharp/c_sharp_global_classes.rst
+++ b/tutorials/scripting/c_sharp/c_sharp_global_classes.rst
@@ -3,8 +3,11 @@
C# global classes
=================
-Global classes (also known as named scripts) are types registered in Godot's editor so they can be used
-more conveniently.
+Global classes (also known as named scripts) are types registered in Godot's
+editor so they can be used more conveniently.
+:ref:`In GDScript `, this is achieved
+using the ``class_name`` keyword at the top of a script. This page describes how
+to achieve the same effect in C#.
- Global classes show up in the *Add Node* and *Create Resource* dialogs.
- If an :ref:`exported property ` is a global class, the
@@ -22,6 +25,12 @@ Global classes are registered with the ``[GlobalClass]`` attribute.
{
}
+.. warning::
+
+ The file name must match the class name in **case-sensitive** fashion.
+ For example, a global class named "MyNode" must have a file name of
+ ``MyNode.cs``, not ``myNode.cs``.
+
The ``MyNode`` type will be registered as a global class with the same name as the type's name.
.. image:: img/globalclasses_addnode.webp
@@ -84,8 +93,7 @@ will let you create and load instances of this type easily.
.. warning::
The Godot editor will hide these custom classes with names that begin with the prefix
- "Editor" in the 'Create New Node' or 'Create New Scene' dialog windows. The classes
- are available for instantiation at runtime via their class names, but are
- automatically hidden by the editor windows along with the built-in editor nodes used
+ "Editor" in the "Create New Node" or "Create New Scene" dialog windows. The classes
+ are available for instantiation at runtime via their class names, but are
+ automatically hidden by the editor windows along with the built-in editor nodes used
by the Godot editor.
-
diff --git a/tutorials/scripting/c_sharp/diagnostics/index.rst b/tutorials/scripting/c_sharp/diagnostics/index.rst
index 42a68bc1be2..9a45f873190 100644
--- a/tutorials/scripting/c_sharp/diagnostics/index.rst
+++ b/tutorials/scripting/c_sharp/diagnostics/index.rst
@@ -8,8 +8,8 @@ C# diagnostics
Godot includes analyzers that inspect your C# source code to check for invalid
or unsupported code and let you know that something is wrong during build time.
-Rules
------
+.. rubric:: Rules
+ :heading-level: 2
.. toctree::
:maxdepth: 1
diff --git a/tutorials/scripting/creating_script_templates.rst b/tutorials/scripting/creating_script_templates.rst
index d3b1a456239..3e3c6c27d03 100644
--- a/tutorials/scripting/creating_script_templates.rst
+++ b/tutorials/scripting/creating_script_templates.rst
@@ -43,9 +43,9 @@ Project-defined templates
~~~~~~~~~~~~~~~~~~~~~~~~~
The default path to search for templates is the
-``res://script_templates/`` directory. The path can be changed by configuring
-the ``editor/script_templates_search_path`` setting in the
-:ref:`ProjectSettings `, both via code and the editor.
+``res://script_templates/`` directory. The path can be changed by configuring the project setting
+:ref:`Editor > Script > Templates Search Path`,
+both via code and the editor.
If no ``script_templates`` directory is found within a project, it is simply
ignored.
diff --git a/tutorials/scripting/cross_language_scripting.rst b/tutorials/scripting/cross_language_scripting.rst
index 8b193e1b86c..fd9f5bb5537 100644
--- a/tutorials/scripting/cross_language_scripting.rst
+++ b/tutorials/scripting/cross_language_scripting.rst
@@ -16,7 +16,11 @@ The following two scripts will be used as references throughout this page.
extends Node
- var my_field: String = "foo"
+ var my_property: String = "my gdscript value":
+ get:
+ return my_property
+ set(value):
+ my_property = value
signal my_signal
@@ -40,7 +44,7 @@ The following two scripts will be used as references throughout this page.
public partial class MyCSharpNode : Node
{
- public string myField = "bar";
+ public string MyProperty { get; set; } = "my c# value";
[Signal] public delegate void MySignalEventHandler();
@@ -86,8 +90,8 @@ with :ref:`new() `.
.. code-block:: gdscript
- var my_csharp_script = load("res://Path/To/MyCSharpNode.cs")
- var my_csharp_node = my_csharp_script.new()
+ var MyCSharpScript = load("res://Path/To/MyCSharpNode.cs")
+ var my_csharp_node = MyCSharpScript.new()
.. warning::
@@ -112,8 +116,8 @@ be instantiated with :ref:`GDScript.New() `.
.. code-block:: csharp
- GDScript MyGDScript = GD.Load("res://path/to/my_gd_script.gd");
- GodotObject myGDScriptNode = (GodotObject)MyGDScript.New(); // This is a GodotObject.
+ var myGDScript = GD.Load("res://path/to/my_gd_script.gd");
+ var myGDScriptNode = (GodotObject)myGDScript.New(); // This is a GodotObject.
Here we are using an :ref:`class_Object`, but you can use type conversion like
explained in :ref:`doc_c_sharp_features_type_conversion_and_casting`.
@@ -129,22 +133,26 @@ anything to worry about.
.. code-block:: gdscript
- print(my_csharp_node.myField) # bar
- my_csharp_node.myField = "BAR"
- print(my_csharp_node.myField) # BAR
+ # Output: "my c# value".
+ print(my_csharp_node.MyProperty)
+ my_csharp_node.MyProperty = "MY C# VALUE"
+ # Output: "MY C# VALUE".
+ print(my_csharp_node.MyProperty)
Accessing GDScript fields from C#
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
As C# is statically typed, accessing GDScript from C# is a bit more
-convoluted, you will have to use :ref:`GodotObject.Get() `
+convoluted. You will have to use :ref:`GodotObject.Get() `
and :ref:`GodotObject.Set() `. The first argument is the name of the field you want to access.
.. code-block:: csharp
- GD.Print(myGDScriptNode.Get("my_field")); // foo
- myGDScriptNode.Set("my_field", "FOO");
- GD.Print(myGDScriptNode.Get("my_field")); // FOO
+ // Output: "my gdscript value".
+ GD.Print(myGDScriptNode.Get("my_property"));
+ myGDScriptNode.Set("my_property", "MY GDSCRIPT VALUE");
+ // Output: "MY GDSCRIPT VALUE".
+ GD.Print(myGDScriptNode.Get("my_property"));
Keep in mind that when setting a field value you should only use types the
GDScript side knows about.
@@ -163,13 +171,18 @@ If that's impossible, you'll see the following error: ``Invalid call. Nonexisten
.. code-block:: gdscript
- my_csharp_node.PrintNodeName(self) # myGDScriptNode
- # my_csharp_node.PrintNodeName() # This line will fail.
+ # Output: "my_gd_script_node" (or name of node where this code is placed).
+ my_csharp_node.PrintNodeName(self)
+ # This line will fail.
+ # my_csharp_node.PrintNodeName()
- my_csharp_node.PrintNTimes("Hello there!", 2) # Hello there! Hello there!
+ # Outputs "Hello there!" twice, once per line.
+ my_csharp_node.PrintNTimes("Hello there!", 2)
- my_csharp_node.PrintArray(["a", "b", "c"]) # a, b, c
- my_csharp_node.PrintArray([1, 2, 3]) # 1, 2, 3
+ # Output: "a", "b", "c" (one per line).
+ my_csharp_node.PrintArray(["a", "b", "c"])
+ # Output: "1", "2", "3" (one per line).
+ my_csharp_node.PrintArray([1, 2, 3])
Calling GDScript methods from C#
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -181,22 +194,21 @@ to said method.
.. code-block:: csharp
- myGDScriptNode.Call("print_node_name", this); // my_csharp_node
- // myGDScriptNode.Call("print_node_name"); // This line will fail silently and won't error out.
+ // Output: "MyCSharpNode" (or name of node where this code is placed).
+ myGDScriptNode.Call("print_node_name", this);
+ // This line will fail silently and won't error out.
+ // myGDScriptNode.Call("print_node_name");
- myGDScriptNode.Call("print_n_times", "Hello there!", 2); // Hello there! Hello there!
+ // Outputs "Hello there!" twice, once per line.
+ myGDScriptNode.Call("print_n_times", "Hello there!", 2);
string[] arr = new string[] { "a", "b", "c" };
- myGDScriptNode.Call("print_array", arr); // a, b, c
- myGDScriptNode.Call("print_array", new int[] { 1, 2, 3 }); // 1, 2, 3
- // Note how the type of each array entry does not matter as long as it can be handled by the marshaller.
-
-.. warning::
-
- As you can see, if the first argument of the called method is an array,
- you'll need to cast it as ``object``.
- Otherwise, each element of your array will be treated as a single argument
- and the function signature won't match.
+ // Output: "a", "b", "c" (one per line).
+ myGDScriptNode.Call("print_array", arr);
+ // Output: "1", "2", "3" (one per line).
+ myGDScriptNode.Call("print_array", new int[] { 1, 2, 3 });
+ // Note how the type of each array entry does not matter
+ // as long as it can be handled by the marshaller.
.. _connecting_to_signals_cross_language:
diff --git a/tutorials/scripting/debug/overview_of_debugging_tools.rst b/tutorials/scripting/debug/overview_of_debugging_tools.rst
index 954619cbc1e..e0e13e01b8e 100644
--- a/tutorials/scripting/debug/overview_of_debugging_tools.rst
+++ b/tutorials/scripting/debug/overview_of_debugging_tools.rst
@@ -223,7 +223,7 @@ The **Break** button causes a break in the script like a breakpoint would.
a function if possible. Otherwise, it does the same thing as **Step Over**.
The **Debug with External Editor** option lets you debug your game with an external editor.
-This option is also accessible in **Editor Settings > Debugger**.
+You can set a shortcut for it in **Editor Settings > Shortcuts > Debugger**.
When the debugger breaks on a breakpoint, a green triangle arrow is visible in
the script editor's gutter. This arrow indicates the line of code the debugger
@@ -232,8 +232,8 @@ broke on.
Debug project settings
----------------------
-In the project settings, there is a **Debug** category with three subcategories
-which control different things.
+In the project settings, there is a **Debug** category with subcategories which
+control different things. Enable **Advanced Settings** to change these settings.
Settings
++++++++
@@ -242,12 +242,29 @@ These are some general settings such as printing the current FPS
to the **Output** panel, the maximum amount of functions when profiling
and others.
+File Logging
+++++++++++++
+
+These settings allow you to log console output and error messages to files.
+
GDScript
++++++++
These settings allow you to toggle specific GDScript warnings, such as for
+unused variables. You can also turn off warnings completely. See
+:ref:`doc_gdscript_warning_system` for more information.
+
+Shader Language
++++++++++++++++
+
+These settings allow you to toggle specific shader warnings, such as for
unused variables. You can also turn off warnings completely.
+Canvas Items
+++++++++++++
+
+These settings are for canvas item redraw debugging.
+
Shapes
++++++
diff --git a/tutorials/scripting/gdextension/gdextension_docs_system.rst b/tutorials/scripting/gdextension/gdextension_docs_system.rst
index f635a8fdc94..046caba3824 100644
--- a/tutorials/scripting/gdextension/gdextension_docs_system.rst
+++ b/tutorials/scripting/gdextension/gdextension_docs_system.rst
@@ -170,3 +170,31 @@ Currently they supported tags for the GDExtension documentation system are:
``#ff00ff``, see :ref:`doc_bbcode_in_richtextlabel_hex_colors`).
- ``[color={code/name}]{text}[/color]``
+
+
+Publishing documentation online
+-------------------------------
+
+You may want to publish an online reference for your GDExtension, similar to this website.
+The most important step is to build reStructuredText (``.rst``) files from your XML class reference:
+
+.. code-block:: bash
+
+ # You need a version.py file, so download it first.
+ curl -sSLO https://raw.githubusercontent.com/godotengine/godot/refs/heads/master/version.py
+
+ # Edit version.py according to your project before proceeding.
+ # Then, run the rst generator. You'll need to have Python installed for this command to work.
+ curl -sSL https://raw.githubusercontent.com/godotengine/godot/master/doc/tools/make_rst.py | python3 - -o "docs/classes" -l "en" doc_classes
+
+Your ``.rst`` files will now be available in ``docs/classes/``. From here, you can use
+any documentation builder that supports reStructuredText syntax to create a website from them.
+
+`godot-docs `_ uses `Sphinx `_. You can use the repository as a basis to build your own documentation system. The following guide describes the basic steps, but they are not exhaustive: You will need a bit of personal insight to make it work.
+
+1. Add `godot-docs `_ as a submodule to your ``docs/`` folder.
+2. Copy over its ``conf.py``, ``index.rst``, ``.readthedocs.yaml`` files into ``/docs/``. You may later decide to copy over and edit more of godot-docs' files, like ``_templates/layout.html``.
+3. Modify these files according to your project. This mostly involves adjusting paths to point to the ``godot-docs`` subfolder, as well as strings to reflect it's your project rather than Godot you're building the docs for.
+4. Create an account on `readthedocs.org `_. Import your project, and modify its base ``.readthedocs.yaml`` file path to ``/docs/.readthedocs.yaml``.
+
+Once you have completed all these steps, your documentation should be available at ``.readthedocs.io``.
diff --git a/tutorials/scripting/gdscript/gdscript_basics.rst b/tutorials/scripting/gdscript/gdscript_basics.rst
index 76e8560af95..bd6ca5d9fc7 100644
--- a/tutorials/scripting/gdscript/gdscript_basics.rst
+++ b/tutorials/scripting/gdscript/gdscript_basics.rst
@@ -118,15 +118,8 @@ If you have previous experience with statically typed languages such as
C, C++, or C# but never used a dynamically typed one before, it is advised you
read this tutorial: :ref:`doc_gdscript_more_efficiently`.
-Language
---------
-
-In the following, an overview is given to GDScript. Details, such as which
-methods are available to arrays or other objects, should be looked up in
-the linked class descriptions.
-
Identifiers
-~~~~~~~~~~~
+-----------
Any string that restricts itself to alphabetic characters (``a`` to ``z`` and
``A`` to ``Z``), digits (``0`` to ``9``) and ``_`` qualifies as an identifier.
@@ -140,7 +133,7 @@ that are considered "confusable" for ASCII characters and emoji are not allowed
in identifiers.
Keywords
-~~~~~~~~
+--------
The following is the list of keywords supported by the language. Since
keywords are reserved words (tokens), they can't be used as identifiers.
@@ -226,7 +219,7 @@ in case you want to take a look under the hood.
+------------+---------------------------------------------------------------------------------------------------------------------------------------------------+
Operators
-~~~~~~~~~
+---------
The following is the list of supported operators and their precedence. All binary operators are `left-associative `_,
including the ``**`` operator. This means that ``2 ** 2 ** 3`` is equal to ``(2 ** 2) ** 3``. Use parentheses to explicitly specify precedence you need, for
@@ -338,7 +331,7 @@ example ``2 ** (2 ** 3)``. The ternary ``if/else`` operator is right-associative
and :ref:`is_zero_approx() ` functions instead.
Literals
-~~~~~~~~
+--------
+---------------------------------+-------------------------------------------+
| **Example(s)** | **Description** |
@@ -452,7 +445,7 @@ Thus, a string can have a quote that matches the opening one, but only if it's p
GDScript also supports :ref:`format strings `.
Annotations
-~~~~~~~~~~~
+-----------
Annotations are special tokens in GDScript that act as modifiers to a script or
its code and may affect how the script is treated by the Godot engine or
@@ -538,7 +531,7 @@ can replace the above code with a single line::
as an error by default. We do not recommend disabling or ignoring it.
Comments
-~~~~~~~~
+--------
Anything from a ``#`` to the end of the line is ignored and is
considered a comment.
@@ -572,8 +565,23 @@ considered a comment.
The list of highlighted keywords and their colors can be changed in the **Text
Editor > Theme > Comment Markers** section of the Editor Settings.
+Use two hash symbols (``##``) instead of one (``#``) to add a *documentation
+comment*, which will appear in the script documentation and in the inspector
+description of an exported variable. Documentation comments must be placed
+directly *above* a documentable item (such as a member variable), or at the top
+of a file. Dedicated formatting options are also available. See
+:ref:`doc_gdscript_documentation_comments` for details.
+
+
+::
+ ## This comment will appear in the script documentation.
+ var value
+
+ ## This comment will appear in the inspector tooltip, and in the documentation.
+ @export var exported_value
+
Code regions
-~~~~~~~~~~~~
+------------
Code regions are special types of comments that the script editor understands as
*foldable regions*. This means that after writing code region comments, you can
@@ -641,7 +649,7 @@ folding code regions.
group multiple elements together.
Line continuation
-~~~~~~~~~~~~~~~~~
+-----------------
A line of code in GDScript can be continued on the next line by using a backslash
(``\``). Add one at the end of a line and the code on the next line will act like
@@ -684,6 +692,11 @@ null
``null`` is an empty data type that contains no information and can not
be assigned any other value.
+Only types that inherit from Object can have a ``null`` value
+(Object is therefore called a "nullable" type).
+:ref:`Variant types ` must have a valid value at all times,
+and therefore cannot have a ``null`` value.
+
:ref:`bool `
^^^^^^^^^^^^^^^^^^^^^^^^
@@ -880,12 +893,26 @@ native or user class, or enum. Nested array types (like ``Array[Array[int]]``) a
Packed arrays
^^^^^^^^^^^^^
-GDScript arrays are allocated linearly in memory for speed.
-Large arrays (more than tens of thousands of elements) may however cause
-memory fragmentation. If this is a concern, special types of
-arrays are available. These only accept a single data type. They avoid memory
-fragmentation and use less memory, but are atomic and tend to run slower than generic
-arrays. They are therefore only recommended to use for large data sets:
+PackedArrays are generally faster to iterate on and modify compared to a typed
+Array of the same type (e.g. PackedInt64Array versus Array[int]) and consume
+less memory. In the worst case, they are expected to be as fast as an untyped
+Array. Conversely, non-Packed Arrays (typed or not) have extra convenience
+methods such as :ref:`Array.map ` that PackedArrays
+lack. Consult the :ref:`class reference ` for details
+on the methods available. Typed Arrays are generally faster to iterate on and
+modify than untyped Arrays.
+
+While all Arrays can cause memory fragmentation when they become large enough,
+if memory usage and performance (iteration and modification speed) is a concern
+and the type of data you're storing is compatible with one of the ``Packed``
+Array types, then using those may yield improvements. However, if you do not
+have such concerns (e.g. the size of your array does not reach the tens of
+thousands of elements) it is likely more helpful to use regular or typed
+Arrays, as they provide convenience methods that can make your code easier to
+write and maintain (and potentially faster if your data requires such
+operations a lot). If the data you will store is of a known type (including
+your own defined classes), prefer to use a typed Array as it may yield better
+performance in iteration and modification compared to an untyped Array.
- :ref:`PackedByteArray `: An array of bytes (integers from 0 to 255).
- :ref:`PackedInt32Array `: An array of 32-bit integers.
@@ -970,11 +997,8 @@ will set the value of ``x`` to a callable with ``$Sprite2D`` as the object and
You can call it using the ``call`` method: ``x.call(PI)``.
-Data
-----
-
Variables
-~~~~~~~~~
+---------
Variables can exist as class members or local to functions. They are
created with the ``var`` keyword and may, optionally, be assigned a
@@ -1011,7 +1035,7 @@ it will raise an error.
Valid types are:
- Built-in types (Array, Vector2, int, String, etc.).
-- Engine classes (Node, Resource, Reference, etc.).
+- Engine classes (Node, Resource, RefCounted, etc.).
- Constant names if they contain a script resource (``MyScript`` if you declared ``const MyScript = preload("res://my_script.gd")``).
- Other classes in the same script, respecting scope (``InnerClass.NestedClass`` if you declared ``class NestedClass`` inside the ``class InnerClass`` in the same scope).
- Script classes declared with the ``class_name`` keyword.
@@ -1028,7 +1052,7 @@ Valid types are:
the project settings. See :ref:`doc_gdscript_warning_system` for details.
Initialization order
-^^^^^^^^^^^^^^^^^^^^
+~~~~~~~~~~~~~~~~~~~~
Member variables are initialized in the following order:
@@ -1074,7 +1098,7 @@ Member variables are initialized in the following order:
or remove the empty dictionary assignment (``= {}``).
Static variables
-^^^^^^^^^^^^^^^^
+~~~~~~~~~~~~~~~~
A class member variable can be declared static::
@@ -1178,7 +1202,7 @@ and must be placed at the top of the script, before ``class_name`` and ``extends
See also `Static functions`_ and `Static constructor`_.
Casting
-^^^^^^^
+~~~~~~~
Values assigned to typed variables must have a compatible type. If it's needed to
coerce a value to be of a certain type, in particular for object types, you can
@@ -1218,7 +1242,7 @@ the scene tree::
($AnimPlayer as AnimationPlayer).play("walk")
Constants
-~~~~~~~~~
+---------
Constants are values you cannot change when the game is running.
Their value must be known at compile-time. Using the
@@ -1250,7 +1274,7 @@ You can also create constants inside a function, which is useful to name local
magic values.
Enums
-^^^^^
+~~~~~
Enums are basically a shorthand for constants, and are pretty useful if you
want to assign consecutive integers to some constant.
@@ -1293,9 +1317,12 @@ a dictionary can also be used with a named enum.
# prints '[0, 5, 6]'
print(State.values())
+If not assigning a value to a key of an enum it will be assigned the previous value plus one,
+or ``0`` if it is the first entry in the enum. Multiple keys with the same value are allowed.
+
Functions
-~~~~~~~~~
+---------
Functions always belong to a `class `_. The scope priority for
variable look-up is: local → class member → global. The ``self`` variable is
@@ -1354,7 +1381,7 @@ return early with the ``return`` keyword, but they can't return any value.
valid value to return.
Referencing functions
-^^^^^^^^^^^^^^^^^^^^^
+~~~~~~~~~~~~~~~~~~~~~
Functions are first-class values in terms of the :ref:`Callable ` object.
Referencing a function by name without calling it will automatically generate the proper
@@ -1383,7 +1410,7 @@ callable. This can be used to pass functions as arguments.
performance issues on direct function calls.
Lambda functions
-^^^^^^^^^^^^^^^^
+~~~~~~~~~~~~~~~~
Lambda functions allow you to declare functions that do not belong to a class. Instead, a
:ref:`Callable ` object is created and assigned to a variable directly.
@@ -1456,7 +1483,7 @@ Lambda functions capture the local environment::
print(a) # Prints `[1]`.
Static functions
-^^^^^^^^^^^^^^^^
+~~~~~~~~~~~~~~~~
A function can be declared static. When a function is static, it has no access to the instance member variables or ``self``.
A static function has access to static variables. Also static functions are useful to make libraries of helper functions::
@@ -1469,14 +1496,14 @@ Lambda functions cannot be declared static.
See also `Static variables`_ and `Static constructor`_.
Statements and control flow
-~~~~~~~~~~~~~~~~~~~~~~~~~~~
+---------------------------
Statements are standard and can be assignments, function calls, control
flow structures, etc (see below). ``;`` as a statement separator is
entirely optional.
Expressions
-^^^^^^^^^^^
+~~~~~~~~~~~
Expressions are sequences of operators and their operands in orderly fashion. An expression by itself can be a
statement too, though only calls are reasonable to use as statements since other expressions don't have side effects.
@@ -1504,7 +1531,7 @@ Identifiers, attributes, and subscripts are valid assignment targets. Other expr
an assignment.
if/else/elif
-^^^^^^^^^^^^
+~~~~~~~~~~~~
Simple conditions are created by using the ``if``/``else``/``elif`` syntax.
Parenthesis around conditions are allowed, but not required. Given the
@@ -1567,7 +1594,7 @@ use an ``if`` statement combined with the ``in`` operator to accomplish this::
if "varName" in get_parent(): print("varName is defined in parent!")
while
-^^^^^
+~~~~~
Simple loops are created by using ``while`` syntax. Loops can be broken
using ``break`` or continued using ``continue`` (which skips to the next
@@ -1579,7 +1606,7 @@ iteration of the loop without executing any further code in the current iteratio
statement(s)
for
-^^^
+~~~
To iterate through a range, such as an array or table, a *for* loop is
used. When iterating over an array, the current array element is stored in
@@ -1642,7 +1669,7 @@ be manipulated by calling methods on the loop variable.
node.add_to_group("Cool_Group") # This has an effect
match
-^^^^^
+~~~~~
A ``match`` statement is used to branch execution of a program.
It's the equivalent of the ``switch`` statement found in many other languages, but offers some additional features.
@@ -1653,7 +1680,7 @@ It's the equivalent of the ``switch`` statement found in many other languages, b
for example, the String ``"hello"`` is considered equal to the StringName ``&"hello"``.
Basic syntax
-""""""""""""
+^^^^^^^^^^^^
::
@@ -1665,7 +1692,7 @@ Basic syntax
<...>
Crash-course for people who are familiar with switch statements
-"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1. Replace ``switch`` with ``match``.
2. Remove ``case``.
@@ -1673,7 +1700,7 @@ Crash-course for people who are familiar with switch statements
4. Change ``default`` to a single underscore.
Control flow
-""""""""""""
+^^^^^^^^^^^^
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.
@@ -1791,7 +1818,7 @@ The following pattern types are available:
print("Yep, you've taken damage")
Pattern guards
-""""""""""""""
+^^^^^^^^^^^^^^
A *pattern guard* is an optional condition that follows the pattern list
and allows you to make additional checks before choosing a ``match`` branch.
@@ -1823,7 +1850,7 @@ you can specify a pattern guard after the list of patterns with the ``when`` key
- If it's false, then the patterns of the next branch are checked.
Classes
-~~~~~~~
+-------
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
@@ -1897,14 +1924,14 @@ If you want to use ``extends`` too, you can keep both on the same line::
.. warning::
- The Godot editor will hide these custom classes with names that beging with the prefix
- "Editor" in the 'Create New Node' or 'Create New Scene' dialog windows. The classes
- are available for instantiation at runtime via their class names, but are
- automatically hidden by the editor windows along with the built-in editor nodes used
+ The Godot editor will hide these custom classes with names that begin with the prefix
+ "Editor" in the 'Create New Node' or 'Create New Scene' dialog windows. The classes
+ are available for instantiation at runtime via their class names, but are
+ automatically hidden by the editor windows along with the built-in editor nodes used
by the Godot editor.
Inheritance
-^^^^^^^^^^^
+~~~~~~~~~~~
A class (stored as a file) can inherit from:
@@ -1981,7 +2008,7 @@ the function name with the attribute operator::
Signals and notifications can also be useful for these purposes.
Class constructor
-^^^^^^^^^^^^^^^^^
+~~~~~~~~~~~~~~~~~
The class constructor, called on class instantiation, is named ``_init``. If you
want to call the base class constructor, you can also use the ``super`` syntax.
@@ -2034,7 +2061,7 @@ There are a few things to keep in mind here:
super(5)
Static constructor
-^^^^^^^^^^^^^^^^^^
+~~~~~~~~~~~~~~~~~~
A static constructor is a static function ``_static_init`` that is called automatically
when the class is loaded, after the static variables have been initialized::
@@ -2049,7 +2076,7 @@ A static constructor cannot take arguments and must not return any value.
.. _doc_gdscript_basics_inner_classes:
Inner classes
-^^^^^^^^^^^^^
+~~~~~~~~~~~~~
A class file can contain inner classes. Inner classes are defined using the
``class`` keyword. They are instanced using the ``ClassName.new()``
@@ -2076,7 +2103,7 @@ function.
.. _doc_gdscript_classes_as_resources:
Classes as resources
-^^^^^^^^^^^^^^^^^^^^
+~~~~~~~~~~~~~~~~~~~~
Classes stored as files are treated as :ref:`GDScripts `. They
must be loaded from disk to access them in other classes. This is done using
@@ -2095,7 +2122,7 @@ class resource is done by calling the ``new`` function on the class object::
a.some_function()
Exports
-~~~~~~~
+-------
.. note::
@@ -2105,7 +2132,7 @@ Exports
.. _doc_gdscript_basics_setters_getters:
Properties (setters and getters)
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+--------------------------------
Sometimes, you want a class' member variable to do more than just hold data and actually perform
some validation or computation whenever its value changes. It may also be desired to
@@ -2132,7 +2159,7 @@ Example::
code use that name.
Alternative syntax
-^^^^^^^^^^^^^^^^^^
+~~~~~~~~~~~~~~~~~~
Also there is another notation to use existing class functions if you want to split the code from the variable declaration
or you need to reuse the code across multiple properties (but you can't distinguish which property the setter/getter is being called for)::
@@ -2153,7 +2180,7 @@ The setter and getter must use the same notation, mixing styles for the same var
Separated setter/getter functions can have type hints, and the type must match the variable's type or be a wider type.
When setter/getter is not called
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
When a variable is initialized, the value of the initializer will be written directly to the variable.
Including if the ``@onready`` annotation is applied to the variable.
@@ -2191,7 +2218,7 @@ This also applies to the alternative syntax::
.. _doc_gdscript_tool_mode:
Tool mode
-~~~~~~~~~
+---------
By default, scripts don't run inside the editor and only the exported
properties can be changed. In some cases, it is desired that they do run
@@ -2216,7 +2243,7 @@ See :ref:`doc_running_code_in_the_editor` for more information.
.. _doc_gdscript_basics_memory_management:
Memory management
-~~~~~~~~~~~~~~~~~
+-----------------
Godot implements reference counting to free certain instances that are no longer
used, instead of a garbage collector, or requiring purely manual management.
@@ -2264,7 +2291,7 @@ freed.
.. _doc_gdscript_signals:
Signals
-~~~~~~~
+-------
Signals are a tool to emit messages from an object that other objects can react
to. To create custom signals for a class, use the ``signal`` keyword.
@@ -2475,7 +2502,7 @@ This also means that returning a signal from a function that isn't a coroutine w
during runtime.
Assert keyword
-~~~~~~~~~~~~~~
+--------------
The ``assert`` keyword can be used to check conditions in debug builds. These
assertions are ignored in non-debug builds. This means that the expression
diff --git a/tutorials/scripting/gdscript/gdscript_documentation_comments.rst b/tutorials/scripting/gdscript/gdscript_documentation_comments.rst
index 4ba08054b88..83957a93c00 100644
--- a/tutorials/scripting/gdscript/gdscript_documentation_comments.rst
+++ b/tutorials/scripting/gdscript/gdscript_documentation_comments.rst
@@ -73,13 +73,13 @@ Documenting script members
Members that are applicable for documentation:
-- Inner class
-- Constant
-- Function
- Signal
-- Variable
- Enum
- Enum value
+- Constant
+- Variable
+- Function
+- Inner class
Documentation of a script member must immediately precede the member or its annotations
if it has any. The description can have more than one line but every line must start with
@@ -106,6 +106,8 @@ For example::
Alternatively, you can use inline documentation comments::
+ signal my_signal ## My signal.
+
enum MyEnum { ## My enum.
VALUE_A = 0, ## Value A.
VALUE_B = 1, ## Value B.
@@ -115,11 +117,11 @@ Alternatively, you can use inline documentation comments::
var my_var ## My variable.
- signal my_signal ## My signal.
func my_func(): ## My func.
pass
+
class MyClass: ## My class.
pass
@@ -142,9 +144,6 @@ Complete script example
## @tutorial(Tutorial 2): https://example.com/tutorial_2
## @experimental
- ## The description of a constant.
- const GRAVITY = 9.8
-
## The description of a signal.
signal my_signal
@@ -160,6 +159,9 @@ Complete script example
RIGHT = 3,
}
+ ## The description of a constant.
+ const GRAVITY = 9.8
+
## The description of the variable v1.
var v1
diff --git a/tutorials/scripting/gdscript/gdscript_exports.rst b/tutorials/scripting/gdscript/gdscript_exports.rst
index e8577aab82d..85bcf3e4fbc 100644
--- a/tutorials/scripting/gdscript/gdscript_exports.rst
+++ b/tutorials/scripting/gdscript/gdscript_exports.rst
@@ -52,7 +52,7 @@ Resources and nodes can be exported.
@export var resource: Resource
@export var node: Node
-Grouping Exports
+Grouping exports
----------------
It is possible to group your exported properties inside the Inspector
@@ -160,18 +160,68 @@ Allow floats from -10 to 20 and snap the value to multiples of 0.2.
@export_range(-10, 20, 0.2) var k: float
-The limits can be only for the slider if you add the hints "or_greater" and/or "or_less".
+The limits can be made to affect only the slider if you add the hints ``"or_less"``
+and/or ``"or_greater"``. If either these hints are used, it will be possible for
+the user to enter any value or drag the value with the mouse when not using
+the slider, even if outside the specified range.
::
- @export_range(0, 100, 1, "or_greater", "or_less")
+ @export_range(0, 100, 1, "or_less", "or_greater") var l: int
-.. TODO: Document other hint strings usable with export_range.
+The ``"exp"`` hint can be used to make a value have an exponential slider
+instead of a linear slider. This means that when dragging the slider towards
+the right, changes will become progressively faster when dragging the mouse.
+This is useful to make editing values that can be either very small or very large
+easier, at the cost of being less intuitive.
+
+::
+
+ @export_range(0, 100000, 0.01, "exp") var exponential: float
+
+For values that are meant to represent an easing factor, use
+:ref:`doc_gdscript_exports_floats_with_easing_hint` instead.
+
+The ``"hide_slider"`` hint can be used to hide the horizontal bar that
+appears below ``float`` properties, or the up/down arrows that appear besides
+``int`` properties:
+
+::
+
+ @export_range(0, 1000, 0.01, "hide_slider") var no_slider: float
+
+Adding suffixes and handling degrees/radians
+--------------------------------------------
+
+A suffix can also be defined to make the value more self-explanatory in the
+inspector. For example, to define a value that is meant to be configured as
+"meters" (``m``) by the user:
+
+::
+
+ @export_range(0, 100, 1, "suffix:m") var m: int
+
+For angles that are stored in radians but displayed as degrees to the user, use
+the `"radians_as_degrees"` hint:
+
+::
+
+ @export_range(0, 360, 0.1, "radians_as_degrees") var angle: float
+
+This performs automatic conversion when the value is displayed or modified in
+the inspector and also displays a degree (``°``) suffix. This approach is used
+by Godot's own `rotation` properties throughout the editor.
+
+If the angle is stored in degrees instead, use the `"degrees"` hint to display
+the degree symbol while disabling the automatic degrees-to-radians conversion
+when the value is modified from the inspector.
+
+.. _doc_gdscript_exports_floats_with_easing_hint:
Floats with easing hint
-----------------------
-Display a visual representation of the 'ease()' function
+Display a visual representation of the ``ease()`` function
when editing.
::
@@ -248,6 +298,8 @@ It must be noted that even if the script is not being run while in the
editor, the exported properties are still editable. This can be used
in conjunction with a :ref:`script in "tool" mode `.
+.. _doc_gdscript_exports_exporting_bit_flags:
+
Exporting bit flags
-------------------
@@ -372,7 +424,7 @@ Other export variants can also be used when exporting arrays:
::
- @export_range(-360, 360, 0.001, "radians") var laser_angles: Array[float] = []
+ @export_range(-360, 360, 0.001, "degrees") var laser_angles: Array[float] = []
@export_file("*.json") var skill_trees: Array[String] = []
@export_color_no_alpha var hair_colors = PackedColorArray()
@export_enum("Espresso", "Mocha", "Latte", "Capuccino") var barista_suggestions: Array[String] = []
@@ -399,6 +451,32 @@ or :ref:`Node.duplicate() ` is called, unlike non-e
@export_storage var b # Stored in the file, not displayed in the editor.
@export var c: int # Stored in the file, displayed in the editor.
+``@export_custom``
+------------------
+
+If you need more control than what's exposed with the built-in ``@export``
+annotations, you can use ``@export_custom`` instead. This allows defining any
+property hint, hint string and usage flags, with a syntax similar to the one
+used by the editor for built-in nodes.
+
+For example, this exposes the ``altitude`` property with no range limits but a
+``m`` (meter) suffix defined:
+
+::
+
+ @export_custom(PROPERTY_HINT_NONE, "altitude:m") var altitude: Vector3
+
+The above is normally not feasible with the standard ``@export_range`` syntax,
+since it requires defining a range.
+
+See the :ref:`class reference `
+for a list of parameters and their allowed values.
+
+.. warning::
+
+ When using ``@export_custom``, GDScript does not perform any validation on
+ the syntax. Invalid syntax may have unexpected behavior in the inspector.
+
Setting exported variables from a tool script
---------------------------------------------
diff --git a/tutorials/scripting/gdscript/gdscript_format_string.rst b/tutorials/scripting/gdscript/gdscript_format_string.rst
index 8d511d66443..492961b54f8 100644
--- a/tutorials/scripting/gdscript/gdscript_format_string.rst
+++ b/tutorials/scripting/gdscript/gdscript_format_string.rst
@@ -3,21 +3,24 @@
GDScript format strings
=======================
-GDScript offers a feature called *format strings*, which allows reusing text
-templates to succinctly create different but similar strings.
+Godot offers multiple ways to dynamically change the contents of strings:
-Format strings are just like normal strings, except they contain certain
-placeholder character-sequences. These placeholders can then easily be replaced
-by parameters handed to the format string.
+- Format strings: ``var string = "I have %s cats." % "3"``
+- The ``String.format()`` method: ``var string = "I have {} cats.".format([3])``
+- String concatenation: ``var string = "I have " + str(3) + " cats."``
-As an example, with ``%s`` as a placeholder, the format string ``"Hello %s, how
-are you?"`` can easily be changed to ``"Hello World, how are you?"``. Notice
-the placeholder is in the middle of the string; modifying it without format
-strings could be cumbersome.
+This page explains how to use format strings, and briefly explains the ``format()``
+method and string concatenation.
+Format strings
+--------------
-Usage in GDScript
------------------
+*Format strings* are a way to reuse text templates to succinctly create different
+but similar strings.
+
+Format strings are just like normal strings, except they contain certain
+placeholder character sequences such as ``%s``. These placeholders can then
+be replaced by parameters handed to the format string.
Examine this concrete GDScript example:
@@ -38,34 +41,12 @@ string.
The ``%s`` seen in the example above is the simplest placeholder and works for
most use cases: it converts the value by the same method by which an implicit
-String conversion or ``str()`` would convert it. Strings remain unchanged,
-Booleans turn into either ``"True"`` or ``"False"``, an integral or real number
-becomes a decimal, other types usually return their data in a human-readable
-string.
-
-There is also another way to format text in GDScript, namely the ``String.format()``
-method. It replaces all occurrences of a key in the string with the corresponding
-value. The method can handle arrays or dictionaries for the key/value pairs.
-
-Arrays can be used as key, index, or mixed style (see below examples). Order only
-matters when the index or mixed style of Array is used.
-
-A quick example in GDScript:
-
-::
-
- # Define a format string
- var format_string = "We're waiting for {str}"
-
- # Using the 'format' method, replace the 'str' placeholder
- var actual_string = format_string.format({"str": "Godot"})
-
- print(actual_string)
- # Output: "We're waiting for Godot"
-
-There are other `format specifiers`_, but they are only applicable when using
-the ``%`` operator.
+String conversion or :ref:`str() ` would convert
+it. Strings remain unchanged, booleans turn into either ``"True"`` or ``"False"``,
+an ``int`` or ``float`` becomes a decimal, and other types usually return their data
+in a human-readable string.
+There are other `format specifiers`_.
Multiple placeholders
---------------------
@@ -108,19 +89,19 @@ specifier. Apart from ``s``, these require certain types of parameters.
| ``c`` | A single **Unicode character**. Expects an unsigned 8-bit integer |
| | (0-255) for a code point or a single-character string. |
+-------+---------------------------------------------------------------------+
-| ``d`` | A **decimal integral** number. Expects an integral or real number |
+| ``d`` | A **decimal integer**. Expects an integer or a real number |
| | (will be floored). |
+-------+---------------------------------------------------------------------+
-| ``o`` | An **octal integral** number. Expects an integral or real number |
+| ``o`` | An **octal integer**. Expects an integer or a real number |
| | (will be floored). |
+-------+---------------------------------------------------------------------+
-| ``x`` | A **hexadecimal integral** number with **lower-case** letters. |
-| | Expects an integral or real number (will be floored). |
+| ``x`` | A **hexadecimal integer** with **lower-case** letters. |
+| | Expects an integer or a real number (will be floored). |
+-------+---------------------------------------------------------------------+
-| ``X`` | A **hexadecimal integral** number with **upper-case** letters. |
-| | Expects an integral or real number (will be floored). |
+| ``X`` | A **hexadecimal integer** with **upper-case** letters. |
+| | Expects an integer or a real number (will be floored). |
+-------+---------------------------------------------------------------------+
-| ``f`` | A **decimal real** number. Expects an integral or real number. |
+| ``f`` | A **decimal real** number. Expects an integer or a real number. |
+-------+---------------------------------------------------------------------+
| ``v`` | A **vector**. Expects any float or int-based vector object ( |
| | ``Vector2``, ``Vector3``, ``Vector4``, ``Vector2i``, ``Vector3i`` or|
@@ -149,7 +130,7 @@ conditions.
+---------+-------------------------------------------------------------------+
| ``-`` | **Pad to the right** rather than the left. |
+---------+-------------------------------------------------------------------+
-| ``*`` | **Dynamic padding**, expect additional integral parameter to set |
+| ``*`` | **Dynamic padding**, expects additional integer parameter to set |
| | padding or precision after ``.``, see `dynamic padding`_. |
+---------+-------------------------------------------------------------------+
@@ -170,7 +151,7 @@ To pad a string to a minimum length, add an integer to the specifier:
# output: " 12345"
# 5 leading spaces for a total length of 10
-If the integer starts with ``0``, integral values are padded with zeroes
+If the integer starts with ``0``, integer values are padded with zeroes
instead of white space:
::
@@ -180,7 +161,7 @@ instead of white space:
Precision can be specified for real numbers by adding a ``.`` (*dot*) with an
integer following it. With no integer after ``.``, a precision of 0 is used,
-rounding to integral value. The integer to use for padding must appear before
+rounding to integer values. The integer to use for padding must appear before
the dot.
::
@@ -238,12 +219,36 @@ avoid reading it as a placeholder. This is done by doubling the character:
# Output: "Remaining health: 56%"
+String format method
+--------------------
+
+There is also another way to format text in GDScript, namely the
+:ref:`String.format() `
+method. It replaces all occurrences of a key in the string with the corresponding
+value. The method can handle arrays or dictionaries for the key/value pairs.
+
+Arrays can be used as key, index, or mixed style (see below examples). Order only
+matters when the index or mixed style of Array is used.
+
+A quick example in GDScript:
+
+::
+
+ # Define a format string
+ var format_string = "We're waiting for {str}"
+
+ # Using the 'format' method, replace the 'str' placeholder
+ var actual_string = format_string.format({"str": "Godot"})
+
+ print(actual_string)
+ # Output: "We're waiting for Godot"
+
+
Format method examples
-----------------------
+~~~~~~~~~~~~~~~~~~~~~~
The following are some examples of how to use the various invocations of the
-``String.format`` method.
-
+``String.format()`` method.
+------------+-----------+------------------------------------------------------------------------------+-------------------+
| **Type** | **Style** | **Example** | **Result** |
@@ -258,9 +263,9 @@ The following are some examples of how to use the various invocations of the
+------------+-----------+------------------------------------------------------------------------------+-------------------+
| Array | index | ``"Hi, {0} v{1}!".format(["Godette","3.0"])`` | Hi, Godette v3.0! |
+------------+-----------+------------------------------------------------------------------------------+-------------------+
-| Array | mix | ``"Hi, {name} v{0}!".format([3.0, ["name","Godette"]])`` | Hi, Godette v3.0! |
+| Array | mix | ``"Hi, {name} v{0}!".format(["3.0", ["name","Godette"]])`` | Hi, Godette v3.0! |
+------------+-----------+------------------------------------------------------------------------------+-------------------+
-| Array | no index | ``"Hi, {} v{}!".format(["Godette", 3.0], "{}")`` | Hi, Godette v3.0! |
+| Array | no index | ``"Hi, {} v{}!".format(["Godette", "3.0"], "{}")`` | Hi, Godette v3.0! |
+------------+-----------+------------------------------------------------------------------------------+-------------------+
Placeholders can also be customized when using ``String.format``, here's some
@@ -285,3 +290,41 @@ Combining both the ``String.format`` method and the ``%`` operator could be usef
+---------------------------------------------------------------------------+-------------------+
| ``"Hi, {0} v{version}".format({0:"Godette", "version":"%0.2f" % 3.114})`` | Hi, Godette v3.11 |
+---------------------------------------------------------------------------+-------------------+
+
+String concatenation
+--------------------
+
+You can also combine strings by *concatenating* them together, using the ``+``
+operator.
+
+::
+
+ # Define a base string
+ var base_string = "We're waiting for "
+
+ # Concatenate the string
+ var actual_string = base_string + "Godot"
+
+ print(actual_string)
+ # Output: "We're waiting for Godot"
+
+When using string concatenation, values that are not strings must be converted using
+the ``str()`` function. There is no way to specify the string format of converted
+values.
+
+::
+
+ var name_string = "Godette"
+ var version = 3.0
+ var actual_string = "Hi, " + name_string + " v" + str(version) + "!"
+
+ print(actual_string)
+ # Output: "Hi, Godette v3!"
+
+Because of these limitations, format strings or the ``format()`` method are often
+a better choice. In many cases, string concatenation is also less readable.
+
+.. note::
+
+ In Godot's C++ code, GDScript format strings can be accessed using the
+ ``vformat()`` helper function in the :ref:`Variant` header.
diff --git a/tutorials/scripting/gdscript/gdscript_styleguide.rst b/tutorials/scripting/gdscript/gdscript_styleguide.rst
index ce2c6787fe9..9dd84ad05da 100644
--- a/tutorials/scripting/gdscript/gdscript_styleguide.rst
+++ b/tutorials/scripting/gdscript/gdscript_styleguide.rst
@@ -620,7 +620,29 @@ Naming conventions
These naming conventions follow the Godot Engine style. Breaking these will make
your code clash with the built-in naming conventions, leading to inconsistent
-code.
+code. As a summary table:
+
++---------------+----------------+----------------------------------------------------+
+| Type | Convention | Example |
++===============+================+====================================================+
+| File names | snake_case | ``yaml_parser.gd`` |
++---------------+----------------+----------------------------------------------------+
+| Class names | PascalCase | ``class_name YAMLParser`` |
++---------------+----------------+----------------------------------------------------+
+| Node names | PascalCase | ``Camera3D``, ``Player`` |
++---------------+----------------+----------------------------------------------------+
+| Functions | snake_case | ``func load_level():`` |
++---------------+----------------+----------------------------------------------------+
+| Variables | snake_case | ``var particle_effect`` |
++---------------+----------------+----------------------------------------------------+
+| Signals | snake_case | ``signal door_opened`` |
++---------------+----------------+----------------------------------------------------+
+| Constants | CONSTANT_CASE | ``const MAX_SPEED = 200`` |
++---------------+----------------+----------------------------------------------------+
+| Enum names | PascalCase | ``enum Element`` |
++---------------+----------------+----------------------------------------------------+
+| Enum members | CONSTANT_CASE | ``{EARTH, WATER, AIR, FIRE}`` |
++---------------+----------------+----------------------------------------------------+
File names
~~~~~~~~~~
@@ -744,7 +766,7 @@ We suggest to organize GDScript code this way:
01. @tool
02. class_name
03. extends
- 04. # docstring
+ 04. ## docstring
05. signals
06. enums
@@ -917,7 +939,7 @@ in that order.
Static typing
-------------
-Since Godot 3.1, GDScript supports :ref:`optional static typing`.
+GDScript supports :ref:`optional static typing`.
Declared types
~~~~~~~~~~~~~~
diff --git a/tutorials/scripting/gdscript/static_typing.rst b/tutorials/scripting/gdscript/static_typing.rst
index 5cfd0b0720c..133178a714f 100644
--- a/tutorials/scripting/gdscript/static_typing.rst
+++ b/tutorials/scripting/gdscript/static_typing.rst
@@ -198,14 +198,17 @@ To define the type of an ``Array``, enclose the type name in ``[]``.
An array's type applies to ``for`` loop variables, as well as some operators like
``[]``, ``[]=``, and ``+``. Array methods (such as ``push_back``) and other operators
(such as ``==``) are still untyped. Built-in types, native and custom classes,
-and enums may be used as element types. Nested array types are not supported.
+and enums may be used as element types. Nested array types
+(like ``Array[Array[int]]``) are not supported.
+
::
var scores: Array[int] = [10, 20, 30]
var vehicles: Array[Node] = [$Car, $Plane]
var items: Array[Item] = [Item.new()]
- # var arrays: Array[Array] -- disallowed
+ var array_of_arrays: Array[Array] = [[], []]
+ # var arrays: Array[Array[int]] -- disallowed
for score in scores:
# score has type `int`
@@ -381,9 +384,9 @@ Warning system
Detailed documentation about the GDScript warning system has been moved to
:ref:`doc_gdscript_warning_system`.
-From version 3.1, Godot gives you warnings about your code as you write it:
-the engine identifies sections of your code that may lead to issues at runtime,
-but lets you decide whether or not you want to leave the code as it is.
+Godot gives you warnings about your code as you write it. The engine identifies
+sections of your code that may lead to issues at runtime, but lets you decide
+whether or not you want to leave the code as it is.
We have a number of warnings aimed specifically at users of typed GDScript.
By default, these warnings are disabled, you can enable them in Project Settings
@@ -407,10 +410,10 @@ that has a script attached with ``class_name MyScript`` and that ``extends
Node2D``. If we have a reference to the object as a ``Node2D`` (for instance,
as it was passed to us by the physics system), we can first check if the
property and method exist and then set and call them if they do::
-
+
if "some_property" in node_2d:
node_2d.some_property = 20 # Produces UNSAFE_PROPERTY_ACCESS warning.
-
+
if node_2d.has_method("some_function"):
node_2d.some_function() # Produces UNSAFE_METHOD_ACCESS warning.
@@ -420,7 +423,7 @@ in the referenced type - in this case a ``Node2D``. To make these operations
safe, you can first check if the object is of type ``MyScript`` using the
``is`` keyword and then declare a variable with the type ``MyScript`` on
which you can set its properties and call its methods::
-
+
if node_2d is MyScript:
var my_script: MyScript = node_2d
my_script.some_property = 20
@@ -443,7 +446,7 @@ collision area to show the area's name. Once the object enters the collision
area, the physics system sends a signal with a ``Node2D`` object, and the most
straightforward (but not statically typed) solution to do what we want could
be achieved like this::
-
+
func _on_body_entered(body: Node2D) -> void:
body.label.text = name # Produces UNSAFE_PROPERTY_ACCESS warning.
diff --git a/tutorials/scripting/index.rst b/tutorials/scripting/index.rst
index cca739a0c13..3df2ffc8b53 100644
--- a/tutorials/scripting/index.rst
+++ b/tutorials/scripting/index.rst
@@ -11,6 +11,7 @@ sections. For instance, to learn about inputs, we recommend you to read
:ref:`Inputs `.
.. rubric:: Programming languages
+ :heading-level: 2
The sections below each focus on a given programming language.
diff --git a/tutorials/scripting/singletons_autoload.rst b/tutorials/scripting/singletons_autoload.rst
index fdc4be9670a..3ed98d5fa98 100644
--- a/tutorials/scripting/singletons_autoload.rst
+++ b/tutorials/scripting/singletons_autoload.rst
@@ -60,7 +60,7 @@ You can create an Autoload to load a scene or a script that inherits from
.. image:: img/singleton.webp
-To autoload a scene or script, start from the menu and navigate to
+To autoload a scene or script, start from the menu and navigate to
**Project > Project Settings > Globals > Autoload**.
.. image:: img/autoload_tab.webp
@@ -172,7 +172,8 @@ means that the last child of root is always the loaded scene.
func _ready():
var root = get_tree().root
- current_scene = root.get_child(root.get_child_count() - 1)
+ # Using a negative index counts from the end, so this gets the last child node of `root`.
+ current_scene = root.get_child(-1)
.. code-tab:: csharp
@@ -185,7 +186,8 @@ means that the last child of root is always the loaded scene.
public override void _Ready()
{
Viewport root = GetTree().Root;
- CurrentScene = root.GetChild(root.GetChildCount() - 1);
+ // Using a negative index counts from the end, so this gets the last child node of `root`.
+ CurrentScene = root.GetChild(-1);
}
}
diff --git a/tutorials/shaders/advanced_postprocessing.rst b/tutorials/shaders/advanced_postprocessing.rst
index 1f508141524..ed065adb7ca 100644
--- a/tutorials/shaders/advanced_postprocessing.rst
+++ b/tutorials/shaders/advanced_postprocessing.rst
@@ -108,11 +108,6 @@ from ``0.0`` to ``1.0`` in the ``z`` direction when using the Vulkan backend.
Reconstruct the NDC using ``SCREEN_UV`` for the ``x`` and ``y`` axis, and
the depth value for ``z``.
-.. note::
-
- This tutorial assumes the use of the Vulkan renderer, which uses NDCs with a Z-range
- of ``[0.0, 1.0]``. In contrast, OpenGL uses NDCs with a Z-range of ``[-1.0, 1.0]``.
-
.. code-block:: glsl
void fragment() {
@@ -120,6 +115,17 @@ the depth value for ``z``.
vec3 ndc = vec3(SCREEN_UV * 2.0 - 1.0, depth);
}
+.. note::
+
+ This tutorial assumes the use of the Forward+ or Mobile renderers, which both
+ use Vulkan NDCs with a Z-range of ``[0.0, 1.0]``. In contrast, the Compatibility
+ renderer uses OpenGL NDCs with a Z-range of ``[-1.0, 1.0]``. For the Compatibility
+ renderer, replace the NDC calculation with this instead:
+
+ .. code-block:: glsl
+
+ vec3 ndc = vec3(SCREEN_UV, depth) * 2.0 - 1.0;
+
Convert NDC to view space by multiplying the NDC by ``INV_PROJECTION_MATRIX``.
Recall that view space gives positions relative to the camera, so the ``z`` value will give us
the distance to the point.
diff --git a/tutorials/shaders/shader_reference/canvas_item_shader.rst b/tutorials/shaders/shader_reference/canvas_item_shader.rst
index 8a9f081e9fe..dd85b3588e9 100644
--- a/tutorials/shaders/shader_reference/canvas_item_shader.rst
+++ b/tutorials/shaders/shader_reference/canvas_item_shader.rst
@@ -142,15 +142,56 @@ is usually:
Fragment built-ins
^^^^^^^^^^^^^^^^^^
-Certain Nodes (for example, :ref:`Sprite2Ds `) display a texture
-by default. However, when a custom fragment function is attached to these nodes,
-the texture lookup needs to be done manually. Godot provides the texture color
-in the ``COLOR`` built-in variable multiplied by the node's color. To read the
-texture color by itself, you can use:
+COLOR and TEXTURE
+~~~~~~~~~~~~~~~~~
+
+The built-in variable ``COLOR`` is used for a few things:
+
+ - In the ``vertex()`` function, ``COLOR`` contains the color from the vertex
+ primitive multiplied by the CanvasItem's
+ :ref:`modulate` multiplied by the
+ CanvasItem's :ref:`self_modulate`.
+ - In the ``fragment()`` function, the input value ``COLOR`` is that same value
+ multiplied by the color from the default ``TEXTURE`` (if present).
+ - In the ``fragment()`` function, ``COLOR`` is also the final output.
+
+Certain nodes (for example, :ref:`Sprite2D `) display a texture
+by default, for example :ref:`texture `. When
+using a custom ``fragment()`` function, you have a few options on how to sample
+this texture.
+
+To read only the contents of the default texture, ignoring the vertex ``COLOR``:
+
+.. code-block:: glsl
+
+ void fragment() {
+ COLOR = texture(TEXTURE, UV);
+ }
+
+To read the contents of the default texture multiplied by vertex ``COLOR``:
.. code-block:: glsl
- COLOR = texture(TEXTURE, UV);
+ void fragment() {
+ // Equivalent to an empty fragment() function, since COLOR is also the output variable.
+ COLOR = COLOR;
+ }
+
+To read only the vertex ``COLOR`` in ``fragment()``, ignoring the main texture,
+you must pass ``COLOR`` as a varying, then read it in ``fragment()``:
+
+.. code-block:: glsl
+
+ varying vec4 vertex_color;
+ void vertex() {
+ vertex_color = COLOR;
+ }
+ void fragment() {
+ COLOR = vertex_color;
+ }
+
+NORMAL
+~~~~~~
Similarly, if a normal map is used in the :ref:`CanvasTexture `, Godot uses
it by default and assigns its value to the built-in ``NORMAL`` variable. If you are using a normal
@@ -175,7 +216,7 @@ it to the ``NORMALMAP`` property. Godot will handle converting it for use in 2D
+---------------------------------------------+---------------------------------------------------------------+
| in vec2 **TEXTURE_PIXEL_SIZE** | Normalized pixel size of default 2D texture. |
| | For a Sprite2D with a texture of size 64x32px, |
-| | **TEXTURE_PIXEL_SIZE** = ``vec2(1/64, 1/32)`` |
+| | ``TEXTURE_PIXEL_SIZE`` = ``vec2(1/64, 1/32)`` |
+---------------------------------------------+---------------------------------------------------------------+
| in bool **AT_LIGHT_PASS** | Always ``false``. |
+---------------------------------------------+---------------------------------------------------------------+
@@ -206,8 +247,8 @@ it to the ``NORMALMAP`` property. Godot will handle converting it for use in 2D
| inout vec3 **LIGHT_VERTEX** | Same as ``VERTEX`` but can be written to alter lighting. |
| | Z component represents height. |
+---------------------------------------------+---------------------------------------------------------------+
-| inout vec4 **COLOR** | Color from vertex function multiplied by the **TEXTURE** |
-| | color. Also output color value. |
+| inout vec4 **COLOR** | ``COLOR`` from the ``vertex()`` function multiplied by the |
+| | ``TEXTURE`` color. Also output color value. |
+---------------------------------------------+---------------------------------------------------------------+
Light built-ins
diff --git a/tutorials/shaders/shader_reference/shading_language.rst b/tutorials/shaders/shader_reference/shading_language.rst
index ba2ca01d7c0..539666feab9 100644
--- a/tutorials/shaders/shader_reference/shading_language.rst
+++ b/tutorials/shaders/shader_reference/shading_language.rst
@@ -86,6 +86,14 @@ Most GLSL ES 3.0 datatypes are supported:
| | Only supported in Forward+ and Mobile, not Compatibility. |
+----------------------+---------------------------------------------------------------------------------+
+.. warning::
+
+ Local variables are not initialized to a default value such as ``0.0``. If
+ you use a variable without assigning it first, it will contain whatever
+ value was already present at that memory location, and unpredictable visual
+ glitches will appear. However, uniforms and varyings are initialized to a
+ default value.
+
Comments
~~~~~~~~
@@ -155,8 +163,8 @@ Individual scalar members of vector types are accessed via the "x", "y", "z" and
equivalent. Use whatever fits best for your needs.
For matrices, use the ``m[column][row]`` indexing syntax to access each scalar,
-or ``m[idx]`` to access a vector by row index. For example, for accessing the y
-position of an object in a mat4 you use ``m[3][1]``.
+or ``m[column]`` to access a vector by column index. For example, for accessing the
+y-component of the translation from a mat4 transform matrix (4th column, 2nd line) you use ``m[3][1]`` or ``m[3].y``.
Constructing
~~~~~~~~~~~~
@@ -174,7 +182,7 @@ Construction of vector types must always pass:
vec4 a = vec4(0.0);
Construction of matrix types requires vectors of the same dimension as the
-matrix. You can also build a diagonal matrix using ``matx(float)`` syntax.
+matrix, interpreted as columns. You can also build a diagonal matrix using ``matx(float)`` syntax.
Accordingly, ``mat4(1.0)`` is an identity matrix.
.. code-block:: glsl
@@ -375,7 +383,7 @@ accessible outside of the shader.
shader_type spatial;
- const float PI = 3.14159265358979323846;
+ const float GOLDEN_RATIO = 1.618033988749894;
Constants of the ``float`` type must be initialized using ``.`` notation after the
decimal part or by using the scientific notation. The optional ``f`` post-suffix is
@@ -785,6 +793,19 @@ GDScript:
in the shader. It must match *exactly* to the name of the uniform in
the shader or else it will not be recognized.
+.. note:: There is a limit to the total size of shader uniforms that you can use
+ in a single shader. On most desktop platforms, this limit is ``65536``
+ bytes, or 4096 ``vec4`` uniforms. On mobile platforms, the limit is
+ typically ``16384`` bytes, or 1024 ``vec4`` uniforms. Vector uniforms
+ smaller than a ``vec4``, such as ``vec2`` or ``vec3``, are padded to
+ the size of a ``vec4``. Scalar uniforms such as ``int`` or ``float``
+ are not padded, and ``bool`` is padded to the size of an ``int``.
+
+ Arrays count as the total size of their contents. If you need a uniform
+ array that is larger than this limit, consider packing the data into a
+ texture instead, since the *contents* of a texture do not count towards
+ this limit, only the size of the sampler uniform.
+
Any GLSL type except for *void* can be a uniform. Additionally, Godot provides
optional shader hints to make the compiler understand for what the uniform is
used, and how the editor should allow users to modify it.
diff --git a/tutorials/shaders/shader_reference/spatial_shader.rst b/tutorials/shaders/shader_reference/spatial_shader.rst
index 4e14ad78aae..fb0d09eef84 100644
--- a/tutorials/shaders/shader_reference/spatial_shader.rst
+++ b/tutorials/shaders/shader_reference/spatial_shader.rst
@@ -268,8 +268,9 @@ these properties, and if you don't write to them, Godot will optimize away the c
+========================================+==================================================================================================+
| in vec2 **VIEWPORT_SIZE** | Size of viewport (in pixels). |
+----------------------------------------+--------------------------------------------------------------------------------------------------+
-| in vec4 **FRAGCOORD** | Coordinate of pixel center in screen space. ``xy`` specifies position in window, ``z`` |
-| | specifies fragment depth if ``DEPTH`` is not used. Origin is lower-left. |
+| in vec4 **FRAGCOORD** | Coordinate of pixel center in screen space. ``xy`` specifies position in window. Origin is lower |
+| | left. ``z`` specifies fragment depth. It is also used as the output value for the fragment depth |
+| | unless ``DEPTH`` is written to. |
+----------------------------------------+--------------------------------------------------------------------------------------------------+
| in bool **FRONT_FACING** | ``true`` if current face is front facing. |
+----------------------------------------+--------------------------------------------------------------------------------------------------+
diff --git a/tutorials/troubleshooting.rst b/tutorials/troubleshooting.rst
index 8fe6efe5c46..db3db4f12ba 100644
--- a/tutorials/troubleshooting.rst
+++ b/tutorials/troubleshooting.rst
@@ -177,7 +177,7 @@ OpenGL applications by your graphics driver.
- **AMD (Windows):** Open the start menu and choose **AMD Software**. Click the
settings "cog" icon in the top-right corner. Go to the **Graphics** tab,
scroll to the bottom and click **Advanced** to unfold its settings. Disable
- **Morphological Anti-Aliasing**.
+ **Morphological Antialiasing**.
Third-party vendor-independent utilities such as vkBasalt may also force
sharpening or FXAA on all Vulkan applications. You may want to check their
diff --git a/tutorials/ui/bbcode_in_richtextlabel.rst b/tutorials/ui/bbcode_in_richtextlabel.rst
index 6b40540d46c..183f91f8207 100644
--- a/tutorials/ui/bbcode_in_richtextlabel.rst
+++ b/tutorials/ui/bbcode_in_richtextlabel.rst
@@ -812,11 +812,17 @@ Font options
Named colors
~~~~~~~~~~~~
-For tags that allow specifying a color by name you can use names of the constants from
+For tags that allow specifying a color by name, you can use names of the constants from
the built-in :ref:`class_Color` class. Named classes can be specified in a number of
styles using different casings: ``DARK_RED``, ``DarkRed``, and ``darkred`` will give
the same exact result.
+See this image for a list of color constants:
+
+.. image:: /img/color_constants.png
+
+`View at full size `__
+
.. _doc_bbcode_in_richtextlabel_hex_colors:
Hexadecimal color codes
diff --git a/tutorials/ui/gui_containers.rst b/tutorials/ui/gui_containers.rst
index f5aac4ab123..35ec1eb02e0 100644
--- a/tutorials/ui/gui_containers.rst
+++ b/tutorials/ui/gui_containers.rst
@@ -78,7 +78,7 @@ Arranges child controls vertically or horizontally (via :ref:`HBoxContainer ` control, as styleboxes
are used by many controls for their backgrounds and overlays.
+ Different controls will apply StyleBoxes in a different manner. Most notably,
+ ``focus`` styleboxes are drawn as an *overlay* to other styleboxes (such as
+ ``normal`` or ``pressed``) to allow the base stylebox to remain visible.
+ This means the focus stylebox should be designed as an outline or translucent
+ box, so that its background can remain visible.
+
Theme types
~~~~~~~~~~~
@@ -184,8 +190,8 @@ with a custom theme. Custom themes can be applied in two ways: as a project sett
and as a node property throughout the tree of control nodes.
There are two project settings that can be adjusted to affect your entire project:
-:ref:`gui/theme/custom` allows you to
-set a custom project-wide theme, and :ref:`gui/theme/custom_font`
+:ref:`GUI > Theme > Custom` allows you to
+set a custom project-wide theme, and :ref:`GUI > Theme > Custom Font`
does the same to the default fallback font. When a theme item is requested by a control
node the custom project theme, if present, is checked first. Only if it doesn't have
the item the default theme is checked.
diff --git a/tutorials/ui/img/anchor_presets.webp b/tutorials/ui/img/anchor_presets.webp
new file mode 100644
index 00000000000..3d70f72a123
Binary files /dev/null and b/tutorials/ui/img/anchor_presets.webp differ
diff --git a/tutorials/ui/img/layout_dropdown_menu.png b/tutorials/ui/img/layout_dropdown_menu.png
deleted file mode 100644
index 9066aeca417..00000000000
Binary files a/tutorials/ui/img/layout_dropdown_menu.png and /dev/null differ
diff --git a/tutorials/ui/img/margin.png b/tutorials/ui/img/margin.png
deleted file mode 100644
index d28a920c4e3..00000000000
Binary files a/tutorials/ui/img/margin.png and /dev/null differ
diff --git a/tutorials/ui/img/marginaround.png b/tutorials/ui/img/marginaround.png
deleted file mode 100644
index 34f48097f87..00000000000
Binary files a/tutorials/ui/img/marginaround.png and /dev/null differ
diff --git a/tutorials/ui/img/marginend.png b/tutorials/ui/img/marginend.png
deleted file mode 100644
index bcc21eba87d..00000000000
Binary files a/tutorials/ui/img/marginend.png and /dev/null differ
diff --git a/tutorials/ui/img/offset.webp b/tutorials/ui/img/offset.webp
new file mode 100644
index 00000000000..8e8cfd5ac9f
Binary files /dev/null and b/tutorials/ui/img/offset.webp differ
diff --git a/tutorials/ui/img/offset_around.webp b/tutorials/ui/img/offset_around.webp
new file mode 100644
index 00000000000..aab369cce86
Binary files /dev/null and b/tutorials/ui/img/offset_around.webp differ
diff --git a/tutorials/ui/img/offset_end.webp b/tutorials/ui/img/offset_end.webp
new file mode 100644
index 00000000000..460c1e07616
Binary files /dev/null and b/tutorials/ui/img/offset_end.webp differ
diff --git a/tutorials/ui/size_and_anchors.rst b/tutorials/ui/size_and_anchors.rst
index 889f1a7dc05..9ef24784d96 100644
--- a/tutorials/ui/size_and_anchors.rst
+++ b/tutorials/ui/size_and_anchors.rst
@@ -1,4 +1,3 @@
-:article_outdated: True
.. _doc_size_and_anchors:
@@ -10,58 +9,62 @@ resolution, positioning controls would be a simple matter of setting the
position and size of each one of them. Unfortunately, that is rarely the
case.
-Only TVs nowadays have a standard resolution and aspect ratio.
-Everything else, from computer monitors to tablets, portable consoles
-and mobile phones have different resolutions and aspect ratios.
+While some configurations may be more common than others, devices like
+phones, tablets and portable gaming consoles can vary greatly. Therefore,
+we often have to account for different aspect ratios, resolutions and user
+scaling.
-There are several ways to handle this, but for now, let's just imagine
+There are several ways to account for this, but for now, let's just imagine
that the screen resolution has changed and the controls need to be
re-positioned. Some will need to follow the bottom of the screen, others
the top of the screen, or maybe the right or left margins.
.. image:: img/anchors.png
-This is done by editing the *margin* properties of controls. Each
-control has four margins: left, right, bottom, and top, which correspond
+This is done by editing the *anchor offsets* of controls, which behave similar
+to a margin. To access these settings, you will first need to select the *Custom*
+anchor preset.
+
+Each control has four anchor offsets: left, right, bottom, and top, which correspond
to the respective edges of the control. By default, all of
them represent a distance in pixels relative to the top-left corner of
the parent control or (in case there is no parent control) the viewport.
-.. image:: img/margin.png
+.. image:: img/offset.webp
-So to make the control wider you can make the right margin larger and/or
-make the left margin smaller. This lets you set the exact placement
+So to make the control wider you can make the right offset larger and/or
+make the left offset smaller. This lets you set the exact placement
and shape of the control.
-The *anchor* properties adjust where the margin distances are relative *to*.
-Each margin has an individual anchor that can be adjusted from the
+The *anchor* properties adjust where the offsets are relative *to*.
+Each offset has an individual anchor that can be adjusted from the
beginning to the end of the parent. So the vertical (top, bottom) anchors
-adjust from 0 (top of parent) to 1.0 (bottom of parent) with 0.5 being
-the center, and the control margins will be placed relative to that
+adjust from ``0.0`` (top of parent) to ``1.0`` (bottom of parent) with ``0.5`` being
+the center, and the control offsets will be placed relative to that
point. The horizontal (left, right) anchors similarly adjust from left to
right of the parent.
Note that when you wish the edge of a control to be above or left of the
-anchor point, you must change the margin value to be negative.
+anchor point, you must change the offset value to be negative.
-For example: when horizontal anchors are changed to 1, the margin values
+For example: when horizontal anchors are changed to ``1.0``, the offset values
become relative to the top-right corner of the parent control or viewport.
-.. image:: img/marginend.png
+.. image:: img/offset_end.webp
Adjusting the two horizontal or the two vertical anchors to different
values will make the control change size when the parent control does.
Here, the control is set to anchor its bottom-right corner to the
-parent's bottom-right, while the top-left control margins are still
+parent's bottom-right, while the top-left control offsets are still
anchored to the top-left of the parent, so when re-sizing the parent,
-the control will always cover it, leaving a 20 pixel margin:
+the control will always cover it, leaving a 20 pixel offset:
-.. image:: img/marginaround.png
+.. image:: img/offset_around.webp
Centering a control
-------------------
-To center a control in its parent, set its anchors to 0.5 and each margin
+To center a control in its parent, set its anchors to ``0.5`` and each offset
to half of its relevant dimension. For example, the code below shows how
a TextureRect can be centered in its parent:
@@ -99,15 +102,15 @@ a TextureRect can be centered in its parent:
rect.OffsetBottom = textureSize.Y / 2;
AddChild(rect);
-Setting each anchor to 0.5 moves the reference point for the margins to
-the center of its parent. From there, we set negative margins so that
+Setting each anchor to ``0.5`` moves the reference point for the offsets to
+the center of its parent. From there, we set negative offsets so that
the control gets its natural size.
-Layout Presets
+Anchor Presets
--------------
-Instead of manually adjusting the margin and anchor values, you can use the
-toolbar's Layout menu, above the viewport. Besides centering, it gives you many
+Instead of manually adjusting the offset and anchor values, you can use the
+toolbar's Anchor menu, above the viewport. Besides centering, it gives you many
options to align and resize control nodes.
-.. image:: img/layout_dropdown_menu.png
+.. image:: img/anchor_presets.webp
diff --git a/tutorials/xr/a_better_xr_start_script.rst b/tutorials/xr/a_better_xr_start_script.rst
index cc97a695111..5046205e0fa 100644
--- a/tutorials/xr/a_better_xr_start_script.rst
+++ b/tutorials/xr/a_better_xr_start_script.rst
@@ -20,7 +20,7 @@ Signals for our script
We are introducing 3 signals to our script so that our game can add further logic:
- ``focus_lost`` is emitted when the player takes off their headset or when the player enters the menu system of the headset.
-- ``focus_gained`` is emitted when the player puts their headset back on or exists the menu system and returns to the game.
+- ``focus_gained`` is emitted when the player puts their headset back on or exits the menu system and returns to the game.
- ``pose_recentered`` is emitted when the headset requests the players position to be reset.
Our game should react accordingly to these signals.