diff --git a/.github/workflows/sync_class_ref.yml b/.github/workflows/sync_class_ref.yml new file mode 100644 index 000000000..6d6b6843a --- /dev/null +++ b/.github/workflows/sync_class_ref.yml @@ -0,0 +1,68 @@ +name: Sync Class Reference + +on: + workflow_dispatch: + # Scheduled updates only run on the default/master branch. + schedule: + # Run it at night (European time) every Saturday. + # The offset is there to try and avoid the high load times. + - cron: '15 3 * * 6' + +# Make sure jobs cannot overlap. +concurrency: + group: classref-sync-ci + cancel-in-progress: true + +jobs: + build: + name: Update class reference files based on the engine revision + runs-on: ubuntu-latest + env: + engine_rev: 'master' + + steps: + - name: Checkout the documentation repository + uses: actions/checkout@v3 + + - name: Checkout the engine repository + uses: actions/checkout@v3 + with: + repository: 'godotengine/godot' + # Use the appropriate branch for the documentation version. + ref: ${{ env.engine_rev }} + path: './.engine-src' + + - name: Store the engine revision + id: 'engine' + run: | + cd ./.engine-src + hash=$(git rev-parse HEAD) + hash_short=$(git rev-parse --short HEAD) + echo "Checked out godotengine/godot at $hash" + echo "rev_hash=$hash" >> $GITHUB_OUTPUT + echo "rev_hash_short=$hash_short" >> $GITHUB_OUTPUT + + - name: Remove old documentation + run: | + rm ./classes/class_*.rst + + - name: Build new documentation + run: | + ./.engine-src/doc/tools/make_rst.py --color -o ./classes -l en ./.engine-src/doc/classes ./.engine-src/modules + + - name: Submit a pull-request + uses: peter-evans/create-pull-request@v5 + with: + commit-message: 'classref: Sync with current ${{ env.engine_rev }} branch (${{ steps.engine.outputs.rev_hash_short }})' + branch: 'classref/sync-${{ steps.engine.outputs.rev_hash_short }}' + add-paths: './classes' + delete-branch: true + + # Configure the commit author. + author: 'Godot Organization ' + committer: 'Godot Organization ' + + # Configure the pull-request. + title: 'classref: Sync with current ${{ env.engine_rev }} branch (${{ steps.engine.outputs.rev_hash_short }})' + body: 'Update Godot API online class reference to match the engine at https://github.com/godotengine/godot/commit/${{ steps.engine.outputs.rev_hash }} (`${{ env.engine_rev }}`).' + labels: 'area:class reference,bug,enhancement' diff --git a/_static/css/custom.css b/_static/css/custom.css index b7374e02f..b2134a155 100644 --- a/_static/css/custom.css +++ b/_static/css/custom.css @@ -103,6 +103,16 @@ --highlight-operator-color: #666666; --highlight-string-color: #4070a0; + --copybtn-background-color: #f6f8fa; + --copybtn-background-color-hover: #f3f4f6; + --copybtn-border-color: #d5d8da; + --copybtn-border-color-hover: #d5d8da; + --copybtn-icon-color: #57606a; + --copybtn-icon-color-success: #1a7f37; + --copybtn-tooltip-background-color: #24292f; + --copybtn-box-shadow: 0 1px 0 rgba(27,31,36,0.04), inset 0 1px 0 rgba(255,255,255,0.25); + --copybtn-border-color-success: #2da44e; + --contribute-background-color: #d7dee8; --contribute-text-color: #646e72; @@ -221,6 +231,16 @@ --highlight-operator-color: #abc8ff; --highlight-string-color: #ffeca1; + --copybtn-background-color: #2a303c; + --copybtn-background-color-hover: #3e4450; + --copybtn-border-color: #3e4450; + --copybtn-border-color-hover: #8b949e; + --copybtn-icon-color: #8b949e; + --copybtn-icon-color-success: #3fb950; + --copybtn-tooltip-background-color: #6e7681; + --copybtn-box-shadow: 0 0 transparent, 0 0 transparent; + --copybtn-border-color-success: #238636; + --contribute-background-color: #25282d; --contribute-text-color: #7f939b; @@ -1674,3 +1694,38 @@ p + .classref-constant { .wy-menu-vertical p.caption + ul.active { display: block; } + +.highlight button.copybtn { + background-color: var(--copybtn-background-color); + border-color: var(--copybtn-border-color); + box-shadow: var(--copybtn-box-shadow); + width: 32px; + height: 32px; + right: 0; + top: 0; + margin: 12.25px; +} +.highlight button.copybtn:hover { + background-color: var(--copybtn-background-color-hover); + border-color: var(--copybtn-border-color-hover); +} +.highlight button.copybtn svg { + position: absolute; + left: 3.5px; + top: 3.5px; + color: var(--copybtn-icon-color); + pointer-events: none; +} +.highlight button.copybtn.success { + border-color: var(--copybtn-border-color-success); + box-shadow: 0 0 0 0.2em rgb(52 208 88 / 40%); +} +.highlight button.copybtn.success svg { + color: var(--copybtn-icon-color-success); +} +.o-tooltip--left:after { + background-color: var(--copybtn-tooltip-background-color); + color: #ffffff; + border-radius: 6px; + padding: 0.5em 0.75em; +} diff --git a/_templates/layout.html b/_templates/layout.html index 65225fbf3..268c4ca38 100644 --- a/_templates/layout.html +++ b/_templates/layout.html @@ -28,14 +28,14 @@ {%- block document %}
{% if godot_is_latest or godot_show_article_status %} -
+
{% if godot_is_latest %}
-

Attention

+

Attention: Here be dragons

- You are reading the latest - (unstable) version of this documentation, which may document features not available - or compatible with Godot 3.x. + This is the latest + (unstable) version of this documentation, which may document features + not available in or compatible with released stable versions of Godot.

{% endif %} - {% if godot_show_article_status %} + {% if godot_show_article_status and not godot_is_latest %}
+ {% if meta and meta.get('article_outdated') == 'True' %}

Work in progress

- Godot documentation is being updated to reflect the latest changes in version - {{ godot_version }}. Some documentation pages may - still state outdated information. This banner will tell you if you're reading one of such pages. + The content of this page was not yet updated for Godot + {{ godot_version }} + and may be outdated. If you know how to improve this page or you can confirm + that it's up to date, feel free to open a pull request.

+ {% else %} +

Up to date

- {% if meta and meta.get('article_outdated') == 'True' %} - The contents of this page can be outdated. If you know how to improve this page or you can confirm - that it's up to date, feel free to open a pull request. - {% else %} - The contents of this page are up to date. If you can still find outdated information, please - open an issue. - {% endif %} + This page is up to date for Godot {{ godot_version }}. + If you still find outdated information, please open an issue.

+ {% endif %}
{% endif %}
diff --git a/about/faq.rst b/about/faq.rst index cb80a4ab8..a37fbc913 100644 --- a/about/faq.rst +++ b/about/faq.rst @@ -478,6 +478,35 @@ This custom UI toolkit :ref:`can't be used as a library `. +.. _doc_faq_why_scons: + +Why does Godot use the SCons build system? +------------------------------------------ + +Godot uses the `SCons `__ build system. There are no +plans to switch to a different build system in the near future. There are many +reasons why we have chosen SCons over other alternatives. For example: + +- Godot can be compiled for a dozen different platforms: all PC + platforms, all mobile platforms, many consoles, and WebAssembly. +- Developers often need to compile for several of the platforms **at + the same time**, or even different targets of the same platform. They + can't afford reconfiguring and rebuilding the project each time. + SCons can do this with no sweat, without breaking the builds. +- SCons will *never* break a build no matter how many changes, + configurations, additions, removals etc. +- Godot's build process is not simple. Several files are generated by + code (binders), others are parsed (shaders), and others need to offer + customization (:ref:`modules `). This requires + complex logic which is easier to write in an actual programming language (like Python) + rather than using a mostly macro-based language only meant for building. +- Godot build process makes heavy use of cross-compiling tools. Each + platform has a specific detection process, and all these must be + handled as specific cases with special code written for each. + +Please try to keep an open mind and get at least a little familiar with SCons if +you are planning to build Godot yourself. + .. _doc_faq_why_not_stl: Why does Godot not use STL (Standard Template Library)? @@ -547,7 +576,7 @@ such a case, you should consider a different approach to optimization. The vast majority of games do not need this and Godot provides handy helpers to do the job for most cases when you do. -If a game needs to process such a large amount of objects, our recommendation +If a game needs to process such a large amount of objects, our recommendation is to use C++ and GDExtensions for performance-heavy tasks and GDScript (or C#) for the rest of the game. diff --git a/about/img/troubleshooting_graphics_driver_sharpening.webp b/about/img/troubleshooting_graphics_driver_sharpening.webp new file mode 100644 index 000000000..e199d9c54 Binary files /dev/null and b/about/img/troubleshooting_graphics_driver_sharpening.webp differ diff --git a/about/introduction.rst b/about/introduction.rst index 3df5c1fa0..c6c9accc0 100644 --- a/about/introduction.rst +++ b/about/introduction.rst @@ -6,105 +6,101 @@ Introduction :: func _ready(): - $Label.text = "Hello world!" + print("Hello world!") -Welcome to the official documentation of Godot Engine, the free and open source +Welcome to the official documentation of **Godot Engine**, the free and open source community-driven 2D and 3D game engine! Behind this mouthful, you will find a powerful yet user-friendly tool that you can use to develop any kind of game, for any platform and with no usage restriction whatsoever. -This page gives a broad presentation of the engine and of the contents -of this documentation, so that you know where to start if you are a beginner or -where to look if you need info on a specific feature. +This page gives a broad overview of the engine and of this documentation, +so that you know where to start if you are a beginner or +where to look if you need information on a specific feature. Before you start ---------------- The :ref:`Tutorials and resources ` page lists video tutorials contributed by the community. If you prefer video to text, -those may be worth a look. +consider checking them out. Otherwise, :ref:`Getting Started ` +is a great starting point. In case you have trouble with one of the tutorials or your project, you can find help on the various :ref:`Community channels `, -especially the Godot Discord community and Q&A. +especially the Godot `Discord`_ community and +`Q&A `_. About Godot Engine ------------------ -A game engine is a complex tool, and it is therefore difficult to present Godot -in a few words. Here's a quick synopsis, which you are free to reuse -if you need a quick write-up about Godot Engine. +A game engine is a complex tool and difficult to present in a few words. +Here's a quick synopsis, which you are free to reuse +if you need a quick write-up about Godot Engine: Godot Engine is a feature-packed, cross-platform game engine to create 2D and 3D games from a unified interface. It provides a comprehensive set of - common tools, so users can focus on making games without having to - reinvent the wheel. Games can be exported in one click to a number of - platforms, including the major desktop platforms (Linux, macOS, Windows) - as well as mobile (Android, iOS) and web-based (HTML5) platforms. + common tools, so that users can focus on making games without having to + reinvent the wheel. Games can be exported with one click to a number of + platforms, including the major desktop platforms (Linux, macOS, Windows), + mobile platforms (Android, iOS), as well as Web-based platforms and consoles. - Godot is completely free and open source under the permissive MIT - license. No strings attached, no royalties, nothing. Users' games are - theirs, down to the last line of engine code. Godot's development is fully - independent and community-driven, empowering users to help shape their - engine to match their expectations. It is supported by the `Software - Freedom Conservancy `_ not-for-profit. + Godot is completely free and open source under the :ref:`permissive MIT + license `. No strings attached, no royalties, + nothing. Users' games are theirs, down to the last line of engine code. + Godot's development is fully independent and community-driven, empowering + users to help shape their engine to match their expectations. + It is supported by the `Godot Foundation `_ + not-for-profit. -For a more in-depth view of the engine, you are encouraged to read this -documentation further, especially the :ref:`Getting Started ` series. - -About the documentation ------------------------ - -This documentation is continuously written, corrected, edited, and revamped by -members of the Godot Engine community. It is edited via text files in the -`reStructuredText `_ markup -language and then compiled into a static website/offline document using the -open source `Sphinx `_ and `ReadTheDocs -`_ tools. - -.. note:: You can contribute to Godot's documentation by opening issue tickets - or sending patches via pull requests on its GitHub - `source repository `_, or - translating it into your language on `Hosted Weblate - `_. - -All the contents are under the permissive Creative Commons Attribution 3.0 -(`CC BY 3.0 `_) license, with -attribution to "Juan Linietsky, Ariel Manzur and the Godot Engine community". Organization of the documentation --------------------------------- -This documentation is organized in several sections with an impressively -unbalanced distribution of contents – but the way it is split up should be -relatively intuitive: +This documentation is organized into several sections: -- The **About** section contains this introduction as well as - the information about the engine, its history, its licensing, authors, etc. It +- **About** contains this introduction as well as + information about the engine, its history, its licensing, authors, etc. It also contains the :ref:`doc_faq`. -- The **Getting Started** section is the *raison d'être* of this - documentation, as it contains all the necessary information on using the +- **Getting Started** contains all necessary information on using the engine to make games. It starts with the :ref:`Step by step ` tutorial which should be the entry point for all - new users. -- The **Manual** section can be read as needed, + new users. **This is the best place to start if you're new!** +- The **Manual** can be read or referenced as needed, in any order. It contains feature-specific tutorials and documentation. -- The **Contributing** section gives the information related to contributing to - the engine development, e.g. how to report bugs, help with the documentation, etc. - It also contains subsections intended for advanced users and contributors - to the engine development, with the information on compiling the engine, - contributing to the editor, or developing C++ modules. -- The **Community** section is dedicated to the life of its community. - It points to various community channels like Godot Contributors Chat and - Discord and contains a list of recommended third-party tutorials outside - of this documentation. -- Finally, the **Class reference** is the documentation of the Godot API, - which is also available directly within the engine's script editor. It is - generated automatically from a file in the main source repository, therefore - the generated files of the documentation are not meant to be modified. See - :ref:`doc_updating_the_class_reference` for details. +- **Contributing** gives information related to contributing to + Godot, whether to the core engine, documentation, demos or other parts. + It describes how to report bugs, how contributor workflows are organized, etc. + It also contains sections intended for advanced users and contributors, + with information on compiling the engine, contributing to the editor, + or developing C++ modules. +- **Community** is dedicated to the life of Godot's community. + It points to various community channels like the + `Godot Contributors Chat `_ and + `Discord`_ and contains a list of recommended third-party tutorials and + materials outside of this documentation. +- Finally, the **Class reference** documents the full Godot API, + also available directly within the engine's script editor. + You can find information on all classes, functions, signals and so on here. In addition to this documentation, you may also want to take a look at the various `Godot demo projects `_. -Have fun reading and making games with Godot Engine! +About this documentation +------------------------ + +Members of the Godot Engine community continuously write, correct, edit, and +improve this documentation. We are always looking for more help. You can also +contribute by opening Github issues or translating the documentation into your language. +If you are interested in helping, see :ref:`Ways to contribute ` +and :ref:`Writing documentation `, +or get in touch with the `Documentation team `_ +on `Godot Contributors Chat `_. + +All documentation content is licensed under the permissive Creative Commons Attribution 3.0 +(`CC BY 3.0 `_) license, +with attribution to "*Juan Linietsky, Ariel Manzur, and the Godot Engine community*" +unless otherwise noted. + +*Have fun reading and making games with Godot Engine!* + +.. _Discord: https://discord.gg/4JBkykG diff --git a/about/release_policy.rst b/about/release_policy.rst index dd9cb1a75..b279364d6 100644 --- a/about/release_policy.rst +++ b/about/release_policy.rst @@ -1,13 +1,11 @@ -:article_outdated: True - .. _doc_release_policy: Godot release policy ==================== -Godot's release policy is in constant evolution. What is described below is -intended to give a general idea of what to expect, but what will actually -happen depends on the choices of core contributors, and the needs of the +Godot's release policy is in constant evolution. The description below +provides a general idea of what to expect, but what will actually +happen depends on the choices of core contributors and the needs of the community at a given time. Godot versioning @@ -30,15 +28,14 @@ term adapted to the complexity of a game engine: areas *may* happen in minor versions, but the vast majority of projects should not be affected or require significant porting work. - The reason for this is that as a game engine, Godot covers many areas such - as rendering, physics, scripting, etc., and fixing bugs or implementing new - features in a given area may sometimes require changing the behavior of a - feature, or modifying the interface of a given class, even if the rest of - the engine API remains backwards compatible. + This is because Godot, as a game engine, covers many areas like rendering, + physics, and scripting. Fixing bugs or implementing new features in one area + might sometimes require changing a feature's behavior or modifying a class's + interface, even if the rest of the engine API remains backwards compatible. .. tip:: - Upgrading to a new minor version is therefore recommended for all users, + Upgrading to a new minor version is recommended for all users, but some testing is necessary to ensure that your project still behaves as expected. @@ -64,7 +61,7 @@ further developed for maintenance releases in a Git branch of the same name Release support timeline ------------------------ -Stable branches are supported *at minimum* until the next stable branch is +Stable branches are supported *at least* until the next stable branch is released and has received its first patch update. In practice, we support stable branches on a *best effort* basis for as long as they have active users who need maintenance updates. diff --git a/about/troubleshooting.rst b/about/troubleshooting.rst index 22d1f8fa1..1e4ccd8ed 100644 --- a/about/troubleshooting.rst +++ b/about/troubleshooting.rst @@ -1,5 +1,3 @@ -:article_outdated: True - .. _doc_troubleshooting: Troubleshooting @@ -62,7 +60,7 @@ There are several workarounds for this: The editor or project takes a very long time to start ----------------------------------------------------- -When using one of the the Vulkan-based renderers (Forward+ or Forward Mobile), +When using one of the Vulkan-based renderers (Forward+ or Forward Mobile), the first startup is expected to be relatively long. This is because shaders need to be compiled before they can be cached. Shaders also need to be cached again after updating Godot, after updating graphics drivers or after switching @@ -98,14 +96,52 @@ default values in the NVIDIA Control Panel. To disable this overlay on Linux, open ``nvidia-settings``, go to **X Screen 0 > OpenGL Settings** then uncheck **Enable Graphics API Visual Indicator**. -The project window doesn't appear centered when I run the project ------------------------------------------------------------------ +The editor or project appears overly sharp or blurry +---------------------------------------------------- -This is a `known bug `__. To -resolve this, open **Project > Project Settings**, make sure **Advanced -Settings** is active, and enable **Display > Window -> DPI > Allow hiDPI**. On top of that, make sure your project is configured to -support :ref:`multiple resolutions `. +.. figure:: img/troubleshooting_graphics_driver_sharpening.webp + :align: center + :alt: Correct appearance (left), oversharpened appearance due to graphics driver sharpening (right) + + Correct appearance (left), oversharpened appearance due to graphics driver sharpening (right) + +If the editor or project appears overly sharp, this is likely due to image +sharpening being forced on all Vulkan or OpenGL applications by your graphics +driver. You can disable this behavior in the graphics driver's control panel: + +- **NVIDIA (Windows):** Open the start menu and choose **NVIDIA Control Panel**. + Open the **Manage 3D settings** tab on the left. In the list in the middle, + scroll to **Image Sharpening** and set it to **Sharpening Off**. +- **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 then + disable **Radeon Image Sharpening**. + +If the editor or project appears overly blurry, this is likely due to +:abbr:`FXAA (Fast Approximate AntiAliasing)` being forced on all Vulkan or +OpenGL applications by your graphics driver. + +- **NVIDIA (Windows):** Open the start menu and choose **NVIDIA Control Panel**. + Open the **Manage 3D settings** tab on the left. In the list in the middle, + scroll to **Fast Approximate Antialiasing** and set it to **Application + Controlled**. +- **NVIDIA (Linux):** Open the applications menu and choose **NVIDIA X Server + Settings**. Select to **Antialiasing Settings** on the left, then uncheck + **Enable FXAA**. +- **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**. + +Third-party vendor-independent utilities such as vkBasalt may also force +sharpening or FXAA on all Vulkan applications. You may want to check their +configuration as well. + +After changing options in the graphics driver or third-party utilities, restart +Godot to make the changes effective. + +If you still wish to force sharpening or FXAA on other applications, it's +recommended to do so on a per-application basis using the application profiles +system provided by graphics drivers' control panels. The project works when run from the editor, but fails to load some files when running from an exported copy ----------------------------------------------------------------------------------------------------------- diff --git a/community/tutorials.rst b/community/tutorials.rst index 435c04dbd..4f7a92376 100644 --- a/community/tutorials.rst +++ b/community/tutorials.rst @@ -44,11 +44,12 @@ Video tutorials - `Garbaj `_ (3D, GDScript). - `Kasper Frandsen `_ (3D, Shaders). - `bitbrain `_ (2D, GDScript). +- `Gwizz `_ (2D, GDScript). Text tutorials -------------- -- `FinepointCGI website by Mitch `__ +- `FinepointCGI website by Mitch `__ - `GDScript website by Andrew Wilkes `__ - `Godot Recipes by KidsCanCode `__ - `Steincodes `__ diff --git a/conf.py b/conf.py index ff47fb65b..940f853e8 100644 --- a/conf.py +++ b/conf.py @@ -17,6 +17,7 @@ extensions = [ "sphinx_tabs.tabs", "notfound.extension", "sphinxext.opengraph", + "sphinx_copybutton", ] # Warning when the Sphinx Tabs extension is used with unknown diff --git a/contributing/development/code_style_guidelines.rst b/contributing/development/code_style_guidelines.rst index da22a6d1e..344f67150 100644 --- a/contributing/development/code_style_guidelines.rst +++ b/contributing/development/code_style_guidelines.rst @@ -15,7 +15,7 @@ C++ and Objective-C ------------------- There are no written guidelines, but the code style agreed upon by the -developers is enforced via the `clang-format `__ +developers is enforced via the `clang-format `__ code beautifier, which takes care for you of all our conventions. To name a few: @@ -69,10 +69,10 @@ Here's how to install clang-format: - Linux: It will usually be available out-of-the-box with the clang toolchain packaged by your distribution. If your distro version is not the required one, you can download a pre-compiled version from the - `LLVM website `__, or if you are on - a Debian derivative, use the `upstream repos `__. + `LLVM website `__, or if you are on + a Debian derivative, use the `upstream repos `__. - macOS and Windows: You can download precompiled binaries from the - `LLVM website `__. You may need to add + `LLVM website `__. You may need to add the path to the binary's folder to your system's ``PATH`` environment variable to be able to call ``clang-format`` out of the box. @@ -118,7 +118,7 @@ clang-format automatically, for example each time you save a file. Here is a non-exhaustive list of beautifier plugins for some IDEs: -- Qt Creator: `Beautifier plugin `__ +- Qt Creator: `Beautifier plugin `__ - Visual Studio Code: `Clang-Format `__ - Visual Studio: `ClangFormat `__ - vim: `vim-clang-format `__ @@ -321,7 +321,7 @@ Godot's codebase. always end them with a period. - Reference variable/function names and values using backticks. - Wrap comments to ~100 characters. -- You can use ``TODO:``, ``FIXME:``, ``NOTE:``, or ``HACK:`` as adominitions +- You can use ``TODO:``, ``FIXME:``, ``NOTE:``, or ``HACK:`` as admonitions when needed. **Example:** diff --git a/contributing/development/compiling/compiling_for_windows.rst b/contributing/development/compiling/compiling_for_windows.rst index b98058d35..7c3ee4310 100644 --- a/contributing/development/compiling/compiling_for_windows.rst +++ b/contributing/development/compiling/compiling_for_windows.rst @@ -19,7 +19,7 @@ For compiling under Windows, the following is required: version 2017 or later. VS 2019 is recommended. **Make sure to read "Installing Visual Studio caveats" below or you will have to run/download the installer again.** -- `MinGW-w64 `_ with GCC can be used as an alternative to +- `MinGW-w64 `_ with GCC can be used as an alternative to Visual Studio. Be sure to install/configure it to use the ``posix`` thread model. **Important:** When using MinGW to compile the ``master`` branch, you need GCC 9 or later. - `Python 3.6+ `_. @@ -31,7 +31,7 @@ For compiling under Windows, the following is required: .. note:: If you have `Scoop `_ installed, you can easily install MinGW and other dependencies using the following command:: - scoop install gcc python scons make + scoop install gcc python scons make mingw .. note:: If you have `MSYS2 `_ installed, you can easily install MinGW and other dependencies using the following command:: diff --git a/contributing/development/compiling/cross-compiling_for_ios_on_linux.rst b/contributing/development/compiling/cross-compiling_for_ios_on_linux.rst index c3880aeea..08be816bd 100644 --- a/contributing/development/compiling/cross-compiling_for_ios_on_linux.rst +++ b/contributing/development/compiling/cross-compiling_for_ios_on_linux.rst @@ -15,10 +15,8 @@ Disclaimer While it is possible to compile for iOS on a Linux environment, Apple is very restrictive about the tools to be used (especially hardware-wise), allowing pretty much only their products to be used for development. So -this is **not official**. However, a `statement from Apple in 2010 -`__ -says they relaxed some of the `App Store review guidelines -`__ +this is **not official**. However, in 2010 Apple said they relaxed some of the +`App Store review guidelines `__ to allow any tool to be used, as long as the resulting binary does not download any code, which means it should be OK to use the procedure described here and cross-compiling the binary. @@ -28,7 +26,7 @@ Requirements - `XCode with the iOS SDK `__ (a dmg image, for newer versions a **xip** file is going to be downloaded.) -- `Clang >= 3.5 `__ for your development +- `Clang >= 3.5 `__ for your development machine installed and in the ``PATH``. It has to be version >= 3.5 to target ``arm64`` architecture. - `Fuse `__ for mounting and unmounting diff --git a/contributing/development/compiling/introduction_to_the_buildsystem.rst b/contributing/development/compiling/introduction_to_the_buildsystem.rst index 8e6a623e3..a56a58eed 100644 --- a/contributing/development/compiling/introduction_to_the_buildsystem.rst +++ b/contributing/development/compiling/introduction_to_the_buildsystem.rst @@ -5,45 +5,20 @@ Introduction to the buildsystem .. highlight:: shell -SCons ------ - -Godot uses `SCons `__ to build. We love it, we are not -changing it for anything else. We constantly get requests to move the build -system to CMake, or Visual Studio, but this is not going to happen. There are -many reasons why we have chosen SCons over other alternatives, for example: - -- Godot can be compiled for a dozen different platforms: all PC - platforms, all mobile platforms, many consoles, and WebAssembly. -- Developers often need to compile for several of the platforms **at - the same time**, or even different targets of the same platform. They - can't afford reconfiguring and rebuilding the project each time. - SCons can do this with no sweat, without breaking the builds. -- SCons will *never* break a build no matter how many changes, - configurations, additions, removals etc. -- Godot's build process is not simple. Several files are generated by - code (binders), others are parsed (shaders), and others need to offer - customization (plugins). This requires complex logic which is easier - to write in an actual programming language (like Python) rather than - using a mostly macro-based language only meant for building. -- Godot build process makes heavy use of cross-compiling tools. Each - platform has a specific detection process, and all these must be - handled as specific cases with special code written for each. - -Please try to keep an open mind and get at least a little familiar with it if -you are planning to build Godot yourself. Setup ----- -Please refer to the documentation for :ref:`doc_compiling_for_android`, -:ref:`doc_compiling_for_ios`, :ref:`doc_compiling_for_linuxbsd`, -:ref:`doc_compiling_for_macos`, :ref:`doc_compiling_for_uwp`, -:ref:`doc_compiling_for_web`, and :ref:`doc_compiling_for_windows`. +:ref:`Godot uses the SCons build system. ` +Please refer to the documentation for: -Note that for **Windows/Visual Studio**, you need to use ``x86_x64 Cross Tools -Command Prompt for VS 2017`` or similar, depending on your install, instead of -the standard Windows command prompt to enter the commands below. +- :ref:`doc_compiling_for_android` +- :ref:`doc_compiling_for_ios` +- :ref:`doc_compiling_for_linuxbsd` +- :ref:`doc_compiling_for_macos` +- :ref:`doc_compiling_for_uwp` +- :ref:`doc_compiling_for_web` +- :ref:`doc_compiling_for_windows` Platform selection ------------------ @@ -189,6 +164,12 @@ does not define ``NDEBUG`` (so ``assert()`` works in thirdparty libraries). This flag appends the ``.dev`` suffix (for development) to the generated binary name. +.. seealso:: + + There are additional SCons options to enable *sanitizers*, which are tools + you can enable at compile-time to better debug certain engine issues. + See :ref:`doc_using_sanitizers` for more information. + Debugging symbols ----------------- diff --git a/contributing/development/core_and_modules/binding_to_external_libraries.rst b/contributing/development/core_and_modules/binding_to_external_libraries.rst index dba80931d..905701952 100644 --- a/contributing/development/core_and_modules/binding_to_external_libraries.rst +++ b/contributing/development/core_and_modules/binding_to_external_libraries.rst @@ -8,7 +8,7 @@ Modules The Summator example in :ref:`doc_custom_modules_in_cpp` is great for small, custom modules, but what if you want to use a larger, external library? -Let's look at an example using `Festival `_, +Let's look at an example using `Festival `_, a speech synthesis (text-to-speech) library written in C++. To bind to an external library, set up a module directory similar to the Summator example: diff --git a/contributing/development/core_and_modules/custom_platform_ports.rst b/contributing/development/core_and_modules/custom_platform_ports.rst index 737d21a4c..bd110afed 100644 --- a/contributing/development/core_and_modules/custom_platform_ports.rst +++ b/contributing/development/core_and_modules/custom_platform_ports.rst @@ -68,9 +68,9 @@ Required features of a platform port At the very least, a platform port must have methods from the :ref:`class_OS` singleton implemented to be buildable and usable for headless operation. -A ``logo.png`` (32×32) image must also be present within the platform folder. -This logo is displayed in the Export dialog for each export preset targeting -the platform in question. +A ``logo.svg`` (32×32) vector image must also be present within the platform +folder. This logo is displayed in the Export dialog for each export preset +targeting the platform in question. See `this implementation `__ for the Linux/\*BSD platform as an example. See also the @@ -153,7 +153,7 @@ games. export template binary directly by renaming it to match the PCK file. See the `EditorExportPlatform header `__ for reference. - ``run_icon.png`` (16×16) should be present within the platform folder if + ``run_icon.svg`` (16×16) should be present within the platform folder if :ref:`doc_one-click_deploy` is implemented for the target platform. This icon is displayed at the top of the editor when one-click deploy is set up for the target platform. 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 d5fd2f5ab..3259551dc 100644 --- a/contributing/development/core_and_modules/custom_resource_format_loaders.rst +++ b/contributing/development/core_and_modules/custom_resource_format_loaders.rst @@ -302,8 +302,8 @@ calls into ``std::istream``. References ~~~~~~~~~~ -- `istream `_ -- `streambuf `_ +- `istream `_ +- `streambuf `_ - `core/io/file_access.h `_ Registering the new file format diff --git a/contributing/development/debugging/index.rst b/contributing/development/debugging/index.rst index ab2c374f1..78ababf5f 100644 --- a/contributing/development/debugging/index.rst +++ b/contributing/development/debugging/index.rst @@ -9,6 +9,7 @@ engine code trying to find an underlying issue or an optimization possibility. :name: toc-devel-cpp-debug-profiling using_cpp_profilers + using_sanitizers macos_debug vulkan/index diff --git a/contributing/development/debugging/using_sanitizers.rst b/contributing/development/debugging/using_sanitizers.rst new file mode 100644 index 000000000..3c8a8e920 --- /dev/null +++ b/contributing/development/debugging/using_sanitizers.rst @@ -0,0 +1,176 @@ +.. _doc_using_sanitizers: + +Using sanitizers +================ + +What are sanitizers? +-------------------- + +Sanitizers are static instrumentation tools that help find bugs that traditional +debuggers usually cannot catch. This is particularly useful when combined with +:ref:`doc_unit_testing` in continuous integration. + +Sanitizers can be used on Windows, macOS and Linux by using the Clang (LLVM), +GCC or Visual Studio compilers. +:ref:`Certain platforms ` +may also have their own sanitizers available. +In situations where a single sanitizer is provided by several different compilers, +remember that their output and behavior will differ slightly. + +Using sanitizers on Godot +------------------------- + +Sanitizers **require** recompiling the binary. This means you cannot use +official Godot binaries to run sanitizers. + +When :ref:`compiling ` with any of the sanitizers enabled, +the resulting binary will have the ``.san`` suffix added to its name to +distinguish it from a binary without sanitizers. + +There is a performance impact as many additional runtime checks need to be +performed. Memory utilization will also increase. It is possible to enable +certain combinations of multiple sanitizers in a single build. Beware of the +performance impact when using multiple sanitizers at once though, as the +resulting binary may be excessively slow. + +Certain options can be passed to sanitizers without having to recompile the +binary using environment variables. + +.. _doc_using_sanitizers_address_sanitizer: + +Address sanitizer (ASAN) +------------------------ + +- Available in Clang and GCC. +- **Supported platforms:** Linux, macOS, Windows (Visual Studio), Web +- `Clang ASAN documentation `__ + +The address sanitizer is generally the most frequently used sanitizer. It can +diagnose issues such as buffer overruns and out-of-bounds access. If the engine +crashes with a message such as ``free(): invalid pointer``, this is typically +the result of a buffer overrun. (This message is printed by the C runtime, not +Godot.) + +In certain situations (such as detecting uninitialized memory reads), +the address sanitizer doesn't suffice. The :ref:`doc_using_sanitizers_memory_sanitizer` +should be used instead. + +It is also possible to detect use-after-return situations by specifying the +``ASAN_OPTIONS=detect_stack_use_after_return=1`` environment variable before +*running* Godot (not when compiling it). This increases the address sanitizer's +runtime overhead, so only enable this feature when you actually need it. + +To enable the address sanitizer in a Godot build, pass the ``use_asan=yes`` +SCons option when compiling. Enabling ASAN generally makes the resulting binary +about 2× slower. + +.. warning:: + + Due to a `design decision + `__, + the address, memory and thread sanitizers are mutually exclusive. This means + you can only use one of those sanitizers in a given binary. + +Leak sanitizer (LSAN) +--------------------- + +- Available in Clang and GCC. +- **Supported platforms:** Linux, Web +- `Clang LSAN documentation `__ + +The leak sanitizer can detect memory leaks, which are situations where memory +that is no longer in use is never freed by the running program. This can +potentially lead to out-of-memory situations if the program runs for long +enough. Since Godot may run on +:ref:`dedicated servers ` for months or +even years without a restart, it's important to fix memory leaks when they occur. + +To enable the leak sanitizer in a Godot build, pass the ``use_lsan=yes`` SCons +option when compiling. Enabling LSAN only has a small performance overhead, but +the program will be much slower to exit as leak detection occurs when the +program exits. + +.. _doc_using_sanitizers_memory_sanitizer: + +Memory sanitizer (MSAN) +----------------------- + +- Available in Clang only, not GCC. +- **Supported platforms:** Linux +- `Clang MSAN documentation `__ + +The memory sanitizer complements the +:ref:`doc_using_sanitizers_address_sanitizer`. Unlike the address sanitizer, +the memory sanitizer can detect uninitialized memory reads. + +To enable the memory sanitizer in a Godot build, pass the ``use_msan=yes`` +SCons option when compiling. Enabling MSAN generally makes the resulting binary +about 3× slower. + +.. warning:: + + Due to a `design decision + `__, + the address, memory and thread sanitizers are mutually exclusive. This means + you can only use one of those sanitizers in a given binary. + +Thread sanitizer (TSAN) +----------------------- + +- Available in Clang and GCC. +- **Supported platforms:** Linux, macOS +- `Clang TSAN documentation `__ + +The thread sanitizer is used to track down race conditions related to +multithreading. A race condition is when multiple threads try to modify the same +data at the same time. Since thread scheduling can be ordered in any fashion by +the operating system, this leads to incorrect behavior that only occurs +occasionally (and can be difficult to track as a result). To prevent a race +condition, you need to add a lock to ensure only one thread can access the +shared data at a given time. + +To enable the thread sanitizer in a Godot build, pass the ``use_tsan=yes`` SCons +option when compiling. Enabling TSAN generally makes the resulting binary 10× +slower, while also multiplying memory usage by an approximately 8× factor. + +.. warning:: + + Due to a `design decision + `__, + the address, memory and thread sanitizers are mutually exclusive. This means + you can only use one of those sanitizers in a given binary. + +Undefined behavior sanitizer (UBSAN) +------------------------------------ + +- Available in Clang and GCC. +- **Supported platforms:** Linux, macOS, Web +- `Clang UBSAN documentation `__ + +The undefined behavior sanitizer is used to track down situations where the +program exhibits random and unpredictable behavior. This is due to C/C++ code +that is accepted by the compiler, but is not *correct*. Compiling with a +different set of optimizations can also change the observed results of undefined +behavior. + +To enable the undefined behavior sanitizer in a Godot build, pass the +``use_ubsan=yes`` SCons option when compiling. Enabling UBSAN only has a small +performance overhead. + +.. _doc_using_sanitizers_platform_specific_sanitizers: + +Platform-specific sanitizers +---------------------------- + +Web +^^^ + +When :ref:`compiling for the Web `, +there are 2 additional sanitizer SCons options available: + +- ``use_assertions=yes`` enables runtime Emscripten assertions, which can catch + various issues. +- ``use_safe_heap=yes`` enables `Emscripten's SAFE_HEAP sanitizer `__. + It provides similar functionality to ASAN, but it focuses on issues that + are specific to WebAssembly. ``SAFE_HEAP`` is not guaranteed to be compatible + with ASAN and UBSAN in the same binary, so you may have to build it separately. diff --git a/contributing/development/editor/creating_icons.rst b/contributing/development/editor/creating_icons.rst index 97e72c647..451616aca 100644 --- a/contributing/development/editor/creating_icons.rst +++ b/contributing/development/editor/creating_icons.rst @@ -38,7 +38,7 @@ Color conversion for light editor themes If the user has configured their editor to use a light theme, Godot will convert the icon's colors based on a -`set of predefined color mappings `__. +`set of predefined color mappings `__. This is to ensure the icon always displays with a sufficient contrast rate. Try to restrict your icon's color palette to colors found in the list above. Otherwise, your icon may become difficult to read on a light background. diff --git a/contributing/development/editor/introduction_to_editor_development.rst b/contributing/development/editor/introduction_to_editor_development.rst index 87adc1ed1..9613bcb62 100644 --- a/contributing/development/editor/introduction_to_editor_development.rst +++ b/contributing/development/editor/introduction_to_editor_development.rst @@ -77,7 +77,7 @@ from ``servers/`` and ``core/``, it cannot depend on includes from ``editor/``. Currently, there are some dependencies to ``editor/`` includes in ``scene/`` files, but -`they are in the process of being removed `__. +`they are in the process of being removed `__. Development tips ---------------- diff --git a/contributing/documentation/building_the_manual.rst b/contributing/documentation/building_the_manual.rst index c2f15c6e1..7fe9cb35b 100644 --- a/contributing/documentation/building_the_manual.rst +++ b/contributing/documentation/building_the_manual.rst @@ -24,18 +24,51 @@ Before you get started, make sure that you have: a. Create the virtual environment: - - On Windows, run ``py -m venv godot-docs-venv`` - - On other platforms, run ``python3 -m venv godot-docs-venv`` + .. tabs:: + + .. group-tab:: Windows + + .. code:: pwsh + + py -m venv godot-docs-venv + + .. group-tab:: Other platforms + + .. code:: sh + + python3 -m venv godot-docs-venv b. Activate the virtual environment: - - On Windows, run ``godot-docs-venv\Scripts\activate.bat`` - - On other platforms, run ``source godot-docs-venv/bin/activate`` + .. tabs:: + + .. group-tab:: Windows + + .. code:: pwsh + + godot-docs-venv\Scripts\activate.bat + + .. group-tab:: Other platforms + + .. code:: sh + + source godot-docs-venv/bin/activate c. *(Optional)* Update pre-installed packages: - - On Windows, run ``py -m pip install --upgrade pip setuptools`` - - On other platforms, run ``pip3 install --upgrade pip setuptools`` + .. tabs:: + + .. group-tab:: Windows + + .. code:: pwsh + + py -m pip install --upgrade pip setuptools + + .. group-tab:: Other platforms + + .. code:: sh + + pip3 install --upgrade pip setuptools 2. Clone the docs repo: @@ -61,8 +94,23 @@ Before you get started, make sure that you have: make html -.. note:: On Windows, that command will run ``make.bat`` instead of GNU Make (or - an alternative). + .. note:: + On Windows, that command will run ``make.bat`` instead of GNU Make (or an alternative). + + Alternatively, you can build the documentation by running the sphinx-build program manually: + + .. code:: sh + + sphinx-build -b html ./ _build/html + +The compilation will take some time as the ``classes/`` folder contains hundreds of files. +See :ref:`doc_building_the_manual:performance`. + +You can then browse the documentation by opening ``_build/html/index.html`` in +your web browser. + +Dealing with errors +------------------- If you run into errors, you may try the following command: @@ -70,43 +118,47 @@ If you run into errors, you may try the following command: make SPHINXBUILD=~/.local/bin/sphinx-build html -Building the documentation requires at least 8 GB of RAM to run without disk -swapping, which slows it down. If you have at least 16 GB of RAM, you can speed -up compilation by running: +If you get a ``MemoryError`` or ``EOFError``, you can remove the ``classes/`` folder and +run ``make`` again. +This will drop the class references from the final HTML documentation but will keep the +rest intact. + +.. important:: + If you delete the ``classes/`` folder, do not use ``git add .`` when working on a pull + request or the whole ``classes/`` folder will be removed when you commit. + See `#3157 `__ for more detail. + +.. _doc_building_the_manual:performance: + +Hints for performance +--------------------- + +RAM usage +^^^^^^^^^ + +Building the documentation requires at least 8 GB of RAM to run without disk swapping, +which slows it down. +If you have at least 16 GB of RAM, you can speed up compilation by running: + +.. tabs:: + + .. group-tab:: Windows + + .. code:: pwsh + + set SPHINXOPTS=-j2 && make html + + .. group-tab:: Other platforms + + .. code:: sh + + make html SPHINXOPTS=-j2 + +Specifying a list of files +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +You can specify a list of files to build, which can greatly speed up compilation: .. code:: sh - # On Linux/macOS - make html SPHINXOPTS=-j2 - - # On Windows - set SPHINXOPTS=-j2 && make html - -The compilation will take some time as the ``classes/`` folder contains hundreds -of files. - -You can then browse the documentation by opening ``_build/html/index.html`` in -your web browser. - -If you get a ``MemoryError`` or ``EOFError``, you can remove the -``classes/`` folder and run ``make`` again. This will drop the class references -from the final HTML documentation but will keep the rest intact. - -.. note:: If you delete the ``classes/`` folder, do not use ``git add .`` when - working on a pull request or the whole ``classes/`` folder will be - removed when you commit. See `#3157 - `__ for more - detail. - -Alternatively, you can build the documentation by running the sphinx-build -program manually: - -.. code:: sh - - sphinx-build -b html ./ _build/html - -You can also specify a list of files to build, which can greatly speed up compilation: - -.. code:: sh - - sphinx-build -b html ./ _build/html classes/class_node.rst classes/class_resource.rst + make FILELIST='classes/class_node.rst classes/class_resource.rst' html diff --git a/contributing/documentation/contributing_to_the_documentation.rst b/contributing/documentation/contributing_to_the_documentation.rst index 91b886785..de02b18c8 100644 --- a/contributing/documentation/contributing_to_the_documentation.rst +++ b/contributing/documentation/contributing_to_the_documentation.rst @@ -146,7 +146,7 @@ Sphinx and reStructuredText syntax ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Check Sphinx’s `reST Primer `__ -and the `official reference `__ for +and the `official reference `__ for details on the syntax. Sphinx uses specific reST comments to do specific operations, like defining the diff --git a/contributing/workflow/testing_pull_requests.rst b/contributing/workflow/testing_pull_requests.rst index b2ff55824..f17cdb0dd 100644 --- a/contributing/workflow/testing_pull_requests.rst +++ b/contributing/workflow/testing_pull_requests.rst @@ -69,7 +69,7 @@ to generate a universal download link. - Open the `nightly.link `__ website and paste the URL you just copied into the text field located below the heading **Paste a GitHub link, get a nightly.link!**. After pasting the URL, click **Get links** on the right. - If the the format of the URL you pasted is correct, you should be presented + If the format of the URL you pasted is correct, you should be presented with a page like this: .. image:: img/testing_pull_requests_nightly_link.png diff --git a/getting_started/first_2d_game/02.player_scene.rst b/getting_started/first_2d_game/02.player_scene.rst index e1c0d154a..4c217e940 100644 --- a/getting_started/first_2d_game/02.player_scene.rst +++ b/getting_started/first_2d_game/02.player_scene.rst @@ -58,7 +58,7 @@ Click on the ``Player`` node and add (:kbd:`Ctrl + A`) a child node :ref:`Animat appearance and animations for our player. Notice that there is a warning symbol next to the node. An ``AnimatedSprite2D`` requires a :ref:`SpriteFrames ` resource, which is a list of the animations it can -display. To create one, find the ``Sprite Frames`` property in the Inspector and click +display. To create one, find the ``Sprite Frames`` property under the ``Animation`` tab in the Inspector and click "[empty]" -> "New SpriteFrames". Click again to open the "SpriteFrames" panel: .. image:: img/spriteframes_panel.webp diff --git a/getting_started/first_2d_game/03.coding_the_player.rst b/getting_started/first_2d_game/03.coding_the_player.rst index 8c003d101..d6f63af82 100644 --- a/getting_started/first_2d_game/03.coding_the_player.rst +++ b/getting_started/first_2d_game/03.coding_the_player.rst @@ -475,7 +475,7 @@ Inspector tab to see the list of signals the player can emit: .. image:: img/player_signals.webp Notice our custom "hit" signal is there as well! Since our enemies are going to -be ``RigidBody2D`` nodes, we want the ``body_entered(body: Node)`` signal. This +be ``RigidBody2D`` nodes, we want the ``body_entered(body: Node2D)`` signal. This signal will be emitted when a body contacts the player. Click "Connect.." and the "Connect a Signal" window appears. We don't need to change any of these settings so click "Connect" again. Godot will automatically create a function in diff --git a/getting_started/first_3d_game/06.jump_and_squash.rst b/getting_started/first_3d_game/06.jump_and_squash.rst index 3840a4908..ee49036cd 100644 --- a/getting_started/first_3d_game/06.jump_and_squash.rst +++ b/getting_started/first_3d_game/06.jump_and_squash.rst @@ -237,7 +237,6 @@ With this code, if no collisions occurred on a given frame, the loop won't run. #... # Iterate through all collisions that occurred this frame - # in C this would be for(int i = 0; i < collisions.Count; i++) for index in range(get_slide_collision_count()): # We get one of the collisions with the player var collision = get_slide_collision(index) diff --git a/getting_started/first_3d_game/07.killing_player.rst b/getting_started/first_3d_game/07.killing_player.rst index 124063c5f..c362db846 100644 --- a/getting_started/first_3d_game/07.killing_player.rst +++ b/getting_started/first_3d_game/07.killing_player.rst @@ -208,7 +208,7 @@ Starting with ``Main.gd``. // Choose a random location on the SpawnPath. // We store the reference to the SpawnLocation node. - var mobSpawnLocation = GetNode("SpawnPath/SpawnLocation"); + var mobSpawnLocation = GetNode("SpawnPath/SpawnLocation"); // And give it a random offset. mobSpawnLocation.ProgressRatio = GD.Randf(); @@ -480,7 +480,7 @@ Finally, the longest script, ``Player.gd``: } // Iterate through all collisions that occurred this frame. - for (int index = 0; index < GetSlideCount(); index++) + for (int index = 0; index < GetSlideCollisionCount(); index++) { // We get one of the collisions with the player. KinematicCollision3D collision = GetSlideCollision(index); diff --git a/getting_started/step_by_step/img/signals_13_signals_connection_icon.png b/getting_started/step_by_step/img/signals_13_signals_connection_icon.png deleted file mode 100644 index a473b67a3..000000000 Binary files a/getting_started/step_by_step/img/signals_13_signals_connection_icon.png and /dev/null differ diff --git a/getting_started/step_by_step/img/signals_13_signals_connection_icon.webp b/getting_started/step_by_step/img/signals_13_signals_connection_icon.webp new file mode 100644 index 000000000..84615f2a2 Binary files /dev/null and b/getting_started/step_by_step/img/signals_13_signals_connection_icon.webp differ diff --git a/getting_started/step_by_step/img/signals_14_signals_connection_info.png b/getting_started/step_by_step/img/signals_14_signals_connection_info.png deleted file mode 100644 index 1b586a5cb..000000000 Binary files a/getting_started/step_by_step/img/signals_14_signals_connection_info.png and /dev/null differ diff --git a/getting_started/step_by_step/img/signals_14_signals_connection_info.webp b/getting_started/step_by_step/img/signals_14_signals_connection_info.webp new file mode 100644 index 000000000..0eb336c5e Binary files /dev/null and b/getting_started/step_by_step/img/signals_14_signals_connection_info.webp differ diff --git a/getting_started/step_by_step/instancing.rst b/getting_started/step_by_step/instancing.rst index 02820ed48..cc13849f3 100644 --- a/getting_started/step_by_step/instancing.rst +++ b/getting_started/step_by_step/instancing.rst @@ -45,7 +45,7 @@ you to download the ball's sample project we prepared for you: :download:`instancing.zip `. Extract the archive on your computer. To import it, you need the Project Manager. -The Project Manager is accessed by opening Godot, or if you already have Godot opened, click on *Project -> Quit to Project List* (:kbd:`Ctrl + Shift + Q`) +The Project Manager is accessed by opening Godot, or if you already have Godot opened, click on *Project -> Quit to Project List* (:kbd:`Ctrl + Shift + Q`, :kbd:`Ctrl + Option + Cmd + B` on macOS) In the Project Manager, click the *Import* button to import the project. @@ -88,7 +88,7 @@ Click on it and drag it towards the center of the view. .. image:: img/instancing_ball_moved.png -Play the game by pressing F5. You should see it fall. +Play the game by pressing :kbd:`F5` (:kbd:`Cmd + B` on macOS). You should see it fall. Now, we want to create more instances of the Ball node. With the ball still selected, press :kbd:`Ctrl-D` (:kbd:`Cmd-D` on macOS) to call the duplicate diff --git a/getting_started/step_by_step/nodes_and_scenes.rst b/getting_started/step_by_step/nodes_and_scenes.rst index ebc10ba28..024a0b3d3 100644 --- a/getting_started/step_by_step/nodes_and_scenes.rst +++ b/getting_started/step_by_step/nodes_and_scenes.rst @@ -157,7 +157,7 @@ The application should open in a new window and display the text "Hello World". .. image:: img/nodes_and_scenes_11_final_result.webp -Close the window or press :kbd:`F8` to quit the running scene. +Close the window or press :kbd:`F8` (:kbd:`Cmd + .` on macOS) to quit the running scene. .. note:: diff --git a/getting_started/step_by_step/signals.rst b/getting_started/step_by_step/signals.rst index bed1df8a8..391d2b796 100644 --- a/getting_started/step_by_step/signals.rst +++ b/getting_started/step_by_step/signals.rst @@ -1,5 +1,3 @@ -:article_outdated: True - .. Intention: give the user a first taste of signals. We should write more documentation in the scripting/ section. .. Note: GDScript snippets use one line return instead of two because they're @@ -114,7 +112,7 @@ Double-click the "pressed" signal to open the node connection window. There, you can connect the signal to the Sprite2D node. The node needs a receiver method, a function that Godot will call when the Button emits the signal. The editor generates one for you. By convention, we name these callback -methods "_on_NodeName_signal_name". Here, it'll be "_on_Button_pressed". +methods "_on_node_name_signal_name". Here, it'll be "_on_button_pressed". .. note:: @@ -133,12 +131,12 @@ Click the Connect button to complete the signal connection and jump to the Script workspace. You should see the new method with a connection icon in the left margin. -.. image:: img/signals_13_signals_connection_icon.png +.. image:: img/signals_13_signals_connection_icon.webp If you click the icon, a window pops up and displays information about the connection. This feature is only available when connecting nodes in the editor. -.. image:: img/signals_14_signals_connection_info.png +.. image:: img/signals_14_signals_connection_info.webp Let's replace the line with the ``pass`` keyword with code that'll toggle the node's motion. @@ -152,7 +150,7 @@ the ``not`` keyword to invert the value. .. tabs:: .. code-tab:: gdscript GDScript - func _on_Button_pressed(): + func _on_button_pressed(): set_process(not is_processing()) .. code-tab:: csharp C# @@ -203,7 +201,7 @@ Your complete ``Sprite2D.gd`` code should look like the following. position += velocity * delta - func _on_Button_pressed(): + func _on_button_pressed(): set_process(not is_processing()) .. code-tab:: csharp C# @@ -300,7 +298,7 @@ We can now connect the Timer to the Sprite2D in the ``_ready()`` function. func _ready(): var timer = get_node("Timer") - timer.timeout.connect(_on_Timer_timeout) + timer.timeout.connect(_on_timer_timeout) .. code-tab:: csharp C# @@ -312,13 +310,17 @@ We can now connect the Timer to the Sprite2D in the ``_ready()`` function. The line reads like so: we connect the Timer's "timeout" signal to the node to which the script is attached. When the Timer emits ``timeout``, we want to call -the function ``_on_Timer_timeout()``, that we need to define. Let's add it at the +the function ``_on_timer_timeout()``, that we need to define. Let's add it at the bottom of our script and use it to toggle our sprite's visibility. +.. note:: By convention, we name these callback methods in GDScript as + "_on_node_name_signal_name" and in C# as "OnNodeNameSignalName". + Here, it'll be "_on_timer_timeout" for GDScript and OnTimerTimeout() for C#. + .. tabs:: .. code-tab:: gdscript GDScript - func _on_Timer_timeout(): + func _on_timer_timeout(): visible = not visible .. code-tab:: csharp C# @@ -361,7 +363,7 @@ Here is the complete ``Sprite2D.gd`` file for reference. position += velocity * delta - func _on_Button_pressed(): + func _on_button_pressed(): set_process(not is_processing()) diff --git a/make.bat b/make.bat index c1e71af15..90a24541c 100644 --- a/make.bat +++ b/make.bat @@ -22,7 +22,7 @@ if errorlevel 9009 ( echo.may add the Sphinx directory to PATH. echo. echo.If you don't have Sphinx installed, grab it from - echo.http://sphinx-doc.org/ + echo.https://www.sphinx-doc.org/ exit /b 1 ) diff --git a/requirements.txt b/requirements.txt index c19fdf1cd..dd4a325d8 100644 --- a/requirements.txt +++ b/requirements.txt @@ -13,6 +13,8 @@ sphinx_rtd_theme==1.1.1 # Code tabs extension to display codeblocks in different languages as tabs. sphinx-tabs==3.4.0 +# Adds a 'copy' button to the right of codeblocks. +sphinx-copybutton==0.5.1 # Custom 404 error page (more useful than the default). sphinx-notfound-page==0.8.3 # Adds Open Graph tags in the HTML `` tag. diff --git a/tutorials/2d/2d_lights_and_shadows.rst b/tutorials/2d/2d_lights_and_shadows.rst index 663cd2a01..e8c534248 100644 --- a/tutorials/2d/2d_lights_and_shadows.rst +++ b/tutorials/2d/2d_lights_and_shadows.rst @@ -36,7 +36,7 @@ There are several nodes involved in a complete 2D lighting setup: - :ref:`CanvasModulate ` (to darken the rest of the scene) - :ref:`PointLight2D ` (for omnidirectional or spot lights) -- :ref:`DirectionalLight2D ` (for sunlight or moonlight) +- :ref:`DirectionalLight2D ` (for sunlight or moonlight) - :ref:`LightOccluder2D ` (for light shadow casters) - Other 2D nodes that receive lighting, such as Sprite2D or TileMap. diff --git a/tutorials/2d/canvas_layers.rst b/tutorials/2d/canvas_layers.rst index d72f1881b..1c8797fb0 100644 --- a/tutorials/2d/canvas_layers.rst +++ b/tutorials/2d/canvas_layers.rst @@ -13,7 +13,7 @@ You can arrange canvas items in trees. Each item will inherit its parent's transform: when the parent moves, its children move too. CanvasItem nodes, and nodes inheriting from them, are direct or indirect children of a -:ref:`Viewport `, that display them. +:ref:`Viewport `, that displays them. The Viewport's property :ref:`Viewport.canvas_transform `, diff --git a/tutorials/3d/3d_rendering_limitations.rst b/tutorials/3d/3d_rendering_limitations.rst index 838bb56fa..a63065932 100644 --- a/tutorials/3d/3d_rendering_limitations.rst +++ b/tutorials/3d/3d_rendering_limitations.rst @@ -56,9 +56,15 @@ There are two main ways to alleviate banding: rendered with low color precision, which means it will work when using the Mobile and Compatibility rendering methods. +.. figure:: img/3d_rendering_limitations_banding.webp + :align: center + :alt: Color banding comparison (contrast increased for more visibility) + + Color banding comparison (contrast increased for more visibility) + .. seealso:: - See `Banding in Games: A Noisy Rant `__ + See `Banding in Games: A Noisy Rant (PDF) `__ for more details about banding and ways to combat it. Depth buffer precision @@ -88,6 +94,12 @@ Depending on the scene and viewing conditions, you may also be able to move the Z-fighting objects further apart without the difference being visible to the player. +.. figure:: img/3d_rendering_limitations_z_fighting.webp + :align: center + :alt: Z-fighting comparison (before and after tweaking the scene by offsetting the Label3D away from the floor) + + Z-fighting comparison (before and after tweaking the scene by offsetting the Label3D away from the floor) + .. _doc_3d_rendering_limitations_transparency_sorting: Transparency sorting @@ -133,6 +145,12 @@ this feature. There are still several ways to avoid this problem: distance fade mode **Pixel Dither** or **Object Dither** instead of **PixelAlpha**. This will make the material opaque, which also speeds up rendering. +.. figure:: img/3d_rendering_limitations_transparency_sorting.webp + :align: center + :alt: Transparency sorting comparison (alpha-blended materials on the left, alpha scissor materials on the right) + + Transparency sorting comparison (alpha-blended materials on the left, alpha scissor materials on the right) + Multi-sample antialiasing ------------------------- diff --git a/tutorials/3d/environment_and_post_processing.rst b/tutorials/3d/environment_and_post_processing.rst index 0a5fefa7b..5d820faea 100644 --- a/tutorials/3d/environment_and_post_processing.rst +++ b/tutorials/3d/environment_and_post_processing.rst @@ -349,11 +349,13 @@ The tone mapping options are: Mid- and post-processing effects -------------------------------- -The Environment resource supports many widely-used mid- and post-processing effects. +The Environment resource supports many popular mid- and post-processing effects. .. note:: - Screen-space effects such as SSR, SSAO, SSIL and glow do not operate on + Screen-space effects such as :abbr:`SSR (Screen-Space Reflections)`, + :abbr:`SSAO (Screen-Space Ambient Occlusion)`, + :abbr:`SSIL (Screen-Space Indirect Lighting)` and glow do not operate on geometry that is located outside the camera view or is occluded by other opaque geometry. Consider this when tweaking their settings to avoid distracting changes during gameplay. @@ -397,7 +399,8 @@ A few user-controlled parameters are available to better tweak the technique: Keep in mind that screen-space-reflections only work for reflecting opaque geometry. Transparent materials won't be reflected, as they don't write to the depth buffer. -This also applies to shaders that use ``SCREEN_TEXTURE`` or ``DEPTH_TEXTURE``. +This also applies to shaders that use ``hint_screen_texture`` or ``hint_depth_texture`` +uniforms. Screen-Space Ambient Occlusion (SSAO) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -423,21 +426,21 @@ a narrower path for the light to enter: .. image:: img/environment_ssao.webp It is a common mistake to enable this effect, turn on a light, and not be able to -appreciate it. This is because :abbr:`Screen-Space Ambient Occlusion (SSAO)` +appreciate it. This is because :abbr:`SSAO (Screen-Space Ambient Occlusion)` only acts on *ambient* light. It does not affect direct light. This is why, in the image above, the effect is less noticeable under the direct light (on the left). If you want to force -:abbr:`Screen-Space Ambient Occlusion (SSAO)` to work with direct light too, +:abbr:`SSAO (Screen-Space Ambient Occlusion)` to work with direct light too, use the **Light Affect** parameter. Even though this is not physically correct, some artists like how it looks. -:abbr:`Screen-Space Ambient Occlusion (SSAO)` looks best when combined with a +:abbr:`SSAO (Screen-Space Ambient Occlusion)` looks best when combined with a real source of indirect light, like VoxelGI: .. image:: img/environment_ssao2.webp -Tweaking :abbr:`Screen-Space Ambient Occlusion (SSAO)` is possible with several +Tweaking :abbr:`SSAO (Screen-Space Ambient Occlusion)` is possible with several parameters: .. image:: img/environment_ssao_parameters.webp @@ -448,9 +451,9 @@ parameters: - **Intensity:** The primary screen-space ambient occlusion intensity. Acts as a multiplier for the screen-space ambient occlusion effect. A higher value results in darker occlusion. - Since :abbr:`Screen-Space Ambient Occlusion (SSAO)` is a screen-space effect, + Since :abbr:`SSAO (Screen-Space Ambient Occlusion)` is a screen-space effect, it's recommended to remain conservative with this value. - :abbr:`Screen-Space Ambient Occlusion (SSAO)` that is too strong can be + :abbr:`SSAO (Screen-Space Ambient Occlusion)` that is too strong can be distracting during gameplay. - **Power:** The distribution of occlusion. A higher value results in darker occlusion, similar to **Intensity**, but with a sharper falloff. @@ -467,8 +470,9 @@ parameters: - **Light Affect:** The screen-space ambient occlusion intensity in direct light. In real life, ambient occlusion only applies to indirect light, which means its effects can't be seen in direct light. Values higher than 0 will - make the SSAO effect visible in direct light. Values above ``0.0`` are not - physically accurate, but some artists prefer this effect. + make the :abbr:`SSAO (Screen-Space Ambient Occlusion)` effect visible in + direct light. Values above ``0.0`` are not physically accurate, but some + artists prefer this effect. Screen-Space Indirect Lighting (SSIL) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -476,25 +480,25 @@ Screen-Space Indirect Lighting (SSIL) *This feature is only available when using the Forward+ backend, not Mobile or Compatibility.* -:abbr:`Screen-Space Indirect Lighting (SSIL)` provides indirect lighting for +:abbr:`SSIL (Screen-Space Indirect Lighting)` provides indirect lighting for small details or dynamic geometry that other global illumination techniques cannot cover. This applies to bounced diffuse lighting, but also emissive -materials. When :abbr:`Screen-Space Indirect Lighting (SSIL)` is enabled on its +materials. When :abbr:`SSIL (Screen-Space Indirect Lighting)` is enabled on its own, the effect may not be that noticeable, which is intended. -Instead, :abbr:`Screen-Space Indirect Lighting (SSIL)` is meant to be used as a +Instead, :abbr:`SSIL (Screen-Space Indirect Lighting)` is meant to be used as a *complement* to other global illumination techniques such as VoxelGI, SDFGI and -LightmapGI. :abbr:`Screen-Space Indirect Lighting (SSIL)` also provides +LightmapGI. :abbr:`SSIL (Screen-Space Indirect Lighting)` also provides a subtle ambient occlusion effect, similar to SSAO but with less detail. This feature only provides indirect lighting. It is not a full global illumination solution. This makes it different from screen-space global illumination (SSGI) -offered by other 3D engines. :abbr:`Screen-Space Indirect Lighting (SSIL)` -can be combined with :abbr:`Screen-Space Reflections (SSR)` and/or -:abbr:`Screen-Space Ambient Occlusion (SSAO)` for greater visual quality +offered by other 3D engines. :abbr:`SSIL (Screen-Space Indirect Lighting)` +can be combined with :abbr:`SSR (Screen-Space Reflections)` and/or +:abbr:`SSAO (Screen-Space Ambient Occlusion)` for greater visual quality (at the cost of performance). -Tweaking SSIL is possible with several parameters: +Tweaking :abbr:`SSIL (Screen-Space Indirect Lighting)` is possible with several parameters: - **Radius:** The distance that bounced lighting can travel when using the screen space indirect lighting effect. A larger value will result in light @@ -524,7 +528,7 @@ Mobile or Compatibility.* Signed distance field global illumination (SDFGI) is a form of real-time global illumination. It is not a screen-space effect, which means it can provide global -illumination for off-screen elements (unlike :abbr:`Screen-Space Indirect Lighting (SSIL)`). +illumination for off-screen elements (unlike :abbr:`SSIL (Screen-Space Indirect Lighting)`). .. seealso:: diff --git a/tutorials/3d/img/3d_rendering_limitations_banding.webp b/tutorials/3d/img/3d_rendering_limitations_banding.webp new file mode 100644 index 000000000..d8f04539c Binary files /dev/null and b/tutorials/3d/img/3d_rendering_limitations_banding.webp differ diff --git a/tutorials/3d/img/3d_rendering_limitations_transparency_sorting.webp b/tutorials/3d/img/3d_rendering_limitations_transparency_sorting.webp new file mode 100644 index 000000000..da07ac2cc Binary files /dev/null and b/tutorials/3d/img/3d_rendering_limitations_transparency_sorting.webp differ diff --git a/tutorials/3d/img/3d_rendering_limitations_z_fighting.webp b/tutorials/3d/img/3d_rendering_limitations_z_fighting.webp new file mode 100644 index 000000000..1000a2644 Binary files /dev/null and b/tutorials/3d/img/3d_rendering_limitations_z_fighting.webp differ diff --git a/tutorials/3d/introduction_to_3d.rst b/tutorials/3d/introduction_to_3d.rst index ff53feb3b..c4a1b0606 100644 --- a/tutorials/3d/introduction_to_3d.rst +++ b/tutorials/3d/introduction_to_3d.rst @@ -44,8 +44,8 @@ little more difficult. The content needs to be created with special 3D tools exchange file format to be imported in Godot. This is required since 3D formats are not as standardized as images. -Maually authored models (using 3D modeling software) ----------------------------------------------------- +Manually authored models (using 3D modeling software) +----------------------------------------------------- .. FIXME: Needs update to properly description Godot 3.x workflow (used to reference a non existing doc_importing_3d_meshes importer). diff --git a/tutorials/3d/procedural_geometry/immediatemesh.rst b/tutorials/3d/procedural_geometry/immediatemesh.rst index c5f540279..afb303681 100644 --- a/tutorials/3d/procedural_geometry/immediatemesh.rst +++ b/tutorials/3d/procedural_geometry/immediatemesh.rst @@ -10,30 +10,30 @@ API like SurfaceTool, but it's actually designed to create meshes on the fly. Generating complex geometry (several thousand vertices) with this node is inefficient, even if it's done only once. Instead, it is designed to generate simple geometry that changes every frame. -Before starting, you should clear the geometry by calling ``clear()``. This ensures that +Before starting, you should clear the geometry by calling ``clear_surfaces()``. This ensures that you are not building upon the geometry from the previous frame. If you want to keep geometry between frames, do -not call ``clear()``. +not call ``clear_surfaces()``. -To begin generating geometry you must call ``begin()``. ``begin()`` takes a ``PrimitiveType`` as an argument. +To begin generating geometry you must call ``surface_begin()``. ``surface_begin()`` takes a ``PrimitiveType`` as an argument. ``PrimitiveType`` is an OpenGL concept that instructs the GPU how to arrange the primitive based on the vertices given whether it is triangles, lines, points, etc. A complete list can be found under the :ref:`Mesh ` class reference page. -Once you have called ``begin()`` you are ready to start adding vertices. You add vertices one at a time. -First you add vertex specific attributes such as normals or UVs using ``set_****()`` (e.g. ``set_normal()``). -Then you call ``add_vertex()`` to add a vertex with those attributes. For example: +Once you have called ``surface_begin()`` you are ready to start adding vertices. You add vertices one at a time. +First you add vertex specific attributes such as normals or UVs using ``surface_set_****()`` (e.g. ``surface_set_normal()``). +Then you call ``surface_add_vertex()`` to add a vertex with those attributes. For example: .. tabs:: .. code-tab:: gdscript GDScript # Add a vertex with normal and uv. - set_normal(Vector3(0, 1, 0)) - set_uv(Vector2(1, 1)) - add_vertex(Vector3(0, 0, 1)) + surface_set_normal(Vector3(0, 1, 0)) + surface_set_uv(Vector2(1, 1)) + surface_add_vertex(Vector3(0, 0, 1)) -Only attributes added before the call to ``add_vertex()`` will be included in that vertex. +Only attributes added before the call to ``surface_add_vertex()`` will be included in that vertex. -Finally, once you have added all your vertices call ``end()`` to signal that you have finished generating the mesh. +Finally, once you have added all your vertices call ``surface_end()`` to signal that you have finished generating the mesh. The example code below draws a single triangle. @@ -44,24 +44,24 @@ The example code below draws a single triangle. func _process(_delta): # Clean up before drawing. - clear() + clear_surfaces() # Begin draw. - begin(Mesh.PRIMITIVE_TRIANGLES) + surface_begin(Mesh.PRIMITIVE_TRIANGLES) - # Prepare attributes for add_vertex. - set_normal(Vector3(0, 0, 1)) - set_uv(Vector2(0, 0)) + # Prepare attributes for surface_add_vertex. + surface_set_normal(Vector3(0, 0, 1)) + surface_set_uv(Vector2(0, 0)) # Call last for each vertex, adds the above attributes. - add_vertex(Vector3(-1, -1, 0)) + surface_add_vertex(Vector3(-1, -1, 0)) - set_normal(Vector3(0, 0, 1)) - set_uv(Vector2(0, 1)) - add_vertex(Vector3(-1, 1, 0)) + surface_set_normal(Vector3(0, 0, 1)) + surface_set_uv(Vector2(0, 1)) + surface_add_vertex(Vector3(-1, 1, 0)) - set_normal(Vector3(0, 0, 1)) - set_uv(Vector2(1, 1)) - add_vertex(Vector3(1, 1, 0)) + surface_set_normal(Vector3(0, 0, 1)) + surface_set_uv(Vector2(1, 1)) + surface_add_vertex(Vector3(1, 1, 0)) # End drawing. - end() + surface_end() diff --git a/tutorials/best_practices/logic_preferences.rst b/tutorials/best_practices/logic_preferences.rst index eae0651f7..0b98a5caf 100644 --- a/tutorials/best_practices/logic_preferences.rst +++ b/tutorials/best_practices/logic_preferences.rst @@ -16,7 +16,7 @@ properties such as the node's name or position. A common dilemma is, when should you change those values? It is the best practice to change values on a node before adding it to the -scene tree. Some properties setters have code to update other +scene tree. Some property's setters have code to update other corresponding values, and that code can be slow! For most cases, this code has no impact on your game's performance, but in heavy use cases such as procedural generation, it can bring your game to a crawl. diff --git a/tutorials/editor/managing_editor_features.rst b/tutorials/editor/managing_editor_features.rst index 10bd40e47..f9a8148f9 100644 --- a/tutorials/editor/managing_editor_features.rst +++ b/tutorials/editor/managing_editor_features.rst @@ -27,7 +27,7 @@ will open the **Manage Editor Feature Profiles** window. By default there will be no profile. Click on **Create Profile** and give it a name. You will then see a list of all the features in the Godot editor. -..img:: img/configure_profile.png +.. image:: img/configure_profile.png The first section allows major editor features to be removed, such as the 3D editor or scripting editor. Below the main features is every class and node in @@ -35,7 +35,7 @@ Godot, which can be disabled as well. Click on a node and all of its properties and options will be listed in the **Extra Items** box, these can all be individually disabled. -..img:: img/node_features.png +.. image:: img/node_features.png Sharing a profile ----------------- diff --git a/tutorials/export/exporting_for_android.rst b/tutorials/export/exporting_for_android.rst index 82b74c988..fae254378 100644 --- a/tutorials/export/exporting_for_android.rst +++ b/tutorials/export/exporting_for_android.rst @@ -29,8 +29,8 @@ Download and install the Android SDK. - Ensure that the `required packages `__ are installed as well. - Android SDK Platform-Tools version 30.0.5 or later - - Android SDK Build-Tools version 30.0.3 - - Android SDK Platform 31 + - Android SDK Build-Tools version 33.0.2 + - Android SDK Platform 33 - Android SDK Command-line Tools (latest) - CMake version 3.10.2.4988404 - NDK version r23c (23.2.8568313) @@ -41,7 +41,7 @@ Download and install the Android SDK. :: - sdkmanager --sdk_root= "platform-tools" "build-tools;30.0.3" "platforms;android-31" "cmdline-tools;latest" "cmake;3.10.2.4988404" "ndk;21.4.7075529" + sdkmanager --sdk_root= "platform-tools" "build-tools;33.0.2" "platforms;android-33" "cmdline-tools;latest" "cmake;3.10.2.4988404" "ndk;23.2.8568313" .. note:: @@ -64,6 +64,12 @@ the JDK can be used for this purpose:: This will create a ``debug.keystore`` file in your current directory. You should move it to a memorable location such as ``%USERPROFILE%\.android\``, because you will need its location in a later step. For more information on ``keytool`` usage, see `this Q&A article `__. +.. note:: + + It is important that the password is the same for the keystore and the key. This is a `known Android + studio issue `__ that also + affects Godot projects. + Setting it up in Godot ---------------------- diff --git a/tutorials/inputs/controllers_gamepads_joysticks.rst b/tutorials/inputs/controllers_gamepads_joysticks.rst index 6c8f052cf..b50f801a6 100644 --- a/tutorials/inputs/controllers_gamepads_joysticks.rst +++ b/tutorials/inputs/controllers_gamepads_joysticks.rst @@ -129,7 +129,7 @@ use ``Input.is_action_pressed()``: frame, use ``Input.is_action_just_pressed()`` instead of ``Input.is_action_pressed()``. Unlike ``Input.is_action_pressed()`` which returns ``true`` as long as the input is - held,``Input.is_action_just_pressed()`` will only return ``true`` for one + 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 diff --git a/tutorials/inputs/custom_mouse_cursor.rst b/tutorials/inputs/custom_mouse_cursor.rst index 0de3e88c9..b056cf808 100644 --- a/tutorials/inputs/custom_mouse_cursor.rst +++ b/tutorials/inputs/custom_mouse_cursor.rst @@ -3,7 +3,9 @@ Customizing the mouse cursor ============================ -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: +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 @@ -14,8 +16,8 @@ The second way 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 + 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 cursor. Therefore, it's recommended to use the approach described here whenever possible. @@ -32,7 +34,12 @@ Open project settings, go to Display>Mouse Cursor. You will see Custom Image and 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. -.. note:: The custom image **must** be less than 256x256. +.. 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. + + On the web platform, the maximum allowed cursor image size is 128×128. Using a script -------------- @@ -74,9 +81,10 @@ Create a Node and attach the following script. Input.SetCustomMouseCursor(beam, Input.CursorShape.Ibeam); } -.. note:: - Check :ref:`Input.set_custom_mouse_cursor() `. +.. seealso:: + Check :ref:`Input.set_custom_mouse_cursor() `'s + documentation for more information on usage and platform-specific caveats. Demo project ------------ @@ -87,4 +95,6 @@ https://github.com/guilhermefelipecgs/custom_hardware_cursor 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. +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. diff --git a/tutorials/inputs/inputevent.rst b/tutorials/inputs/inputevent.rst index edff63619..82fce4a65 100644 --- a/tutorials/inputs/inputevent.rst +++ b/tutorials/inputs/inputevent.rst @@ -117,7 +117,7 @@ received input, in order: not. This can be configured through :ref:`Area3D ` properties). In the case of a 2D scene, conceptually the same happens with :ref:`CollisionObject2D._input_event() `. -When sending events to its child and descencand nodes, the viewport will do so, as depicted in +When sending events to its child and descendant nodes, the viewport will do so, as depicted in the following graphic, in a reverse depth-first order, starting with the node at the bottom of the scene tree, and ending at the root node. Excluded from this process are embedded Windows and SubViewports. diff --git a/tutorials/navigation/navigation_introduction_2d.rst b/tutorials/navigation/navigation_introduction_2d.rst index 2b15dfb18..1fb806612 100644 --- a/tutorials/navigation/navigation_introduction_2d.rst +++ b/tutorials/navigation/navigation_introduction_2d.rst @@ -31,6 +31,8 @@ Godot provides the following objects and classes for 2D navigation: - NavRegion RID Reference to a specific navigation region that can hold navigation mesh data. The region can be enabled / disabled or the use restricted with a navigationlayer bitmask. + - NavLink RID + Reference to a specific navigation link that connects two navigation mesh positions over arbitrary distances. - NavAgent RID Reference to a specific avoidance agent with a radius value use solely in avoidance. @@ -38,9 +40,19 @@ The following SceneTree Nodes are available as helpers to work with the Navigati - :ref:`NavigationRegion2D` Node A Node that holds a NavigationPolygon resource that defines a navigation mesh for the NavigationServer2D. - The region can be enabled / disabled. - The use in pathfinding can be further restricted through the navigationlayers bitmask. - Regions can join their navigation meshes by proximity for a combined navigation mesh. + + - The region can be enabled / disabled. + - The use in pathfinding can be further restricted through the navigationlayers bitmask. + - Regions can join their navigation meshes by proximity for a combined navigation mesh. + +- :ref:`NavigationLink2D` Node + A Node that connects two positions on navigation mesh over arbitrary distances for pathfinding. + + - The link can be enabled / disabled. + - The link can be made one-way or bidirectional. + - The use in pathfinding can be further restricted through the navigationlayers bitmask. + + Links tell the pathfinding that a connection exists and at what cost. The actual agent handling and movement needs to happen in custom scripts. - :ref:`NavigationAgent2D` Node An optional helper Node to facilitate common NavigationServer2D API calls for pathfinding and avoidance @@ -133,15 +145,14 @@ NavigationServer2D and a NavigationAgent2D for path movement. if navigation_agent.is_navigation_finished(): return - var current_agent_position: Vector2 = global_transform.origin + var current_agent_position: Vector2 = global_position var next_path_position: Vector2 = navigation_agent.get_next_path_position() var new_velocity: Vector2 = next_path_position - current_agent_position new_velocity = new_velocity.normalized() new_velocity = new_velocity * movement_speed - set_velocity(new_velocity) - + velocity = new_velocity move_and_slide() .. code-tab:: csharp C# diff --git a/tutorials/navigation/navigation_introduction_3d.rst b/tutorials/navigation/navigation_introduction_3d.rst index 2d7a9ebd3..fc71d9a33 100644 --- a/tutorials/navigation/navigation_introduction_3d.rst +++ b/tutorials/navigation/navigation_introduction_3d.rst @@ -34,6 +34,8 @@ Godot provides the following objects and classes for 3D navigation: - NavRegion RID Reference to a specific navigation region that can hold navigation mesh data. The region can be enabled / disabled or the use restricted with a navigationlayer bitmask. + - NavLink RID + Reference to a specific navigation link that connects two navigation mesh positions over arbitrary distances. - NavAgent RID Reference to a specific avoidance agent with a radius value use solely in avoidance. @@ -41,9 +43,19 @@ The following SceneTree Nodes are available as helpers to work with the Navigati - :ref:`NavigationRegion3D` Node A Node that holds a Navigation Mesh resource that defines a navigation mesh for the NavigationServer3D. - The region can be enabled / disabled. - The use in pathfinding can be further restricted through the navigationlayers bitmask. - Regions can join their navigation meshes by proximity for a combined navigation mesh. + + - The region can be enabled / disabled. + - The use in pathfinding can be further restricted through the navigationlayers bitmask. + - Regions can join their navigation meshes by proximity for a combined navigation mesh. + +- :ref:`NavigationLink3D` Node + A Node that connects two positions on navigation mesh over arbitrary distances for pathfinding. + + - The link can be enabled / disabled. + - The link can be made one-way or bidirectional. + - The use in pathfinding can be further restricted through the navigationlayers bitmask. + + Links tell the pathfinding that a connection exists and at what cost. The actual agent handling and movement needs to happen in custom scripts. - :ref:`NavigationAgent3D` Node An optional helper Node to facilitate common NavigationServer3D API calls for pathfinding and avoidance for @@ -138,14 +150,14 @@ a NavigationAgent3D for path movement. if navigation_agent.is_navigation_finished(): return - var current_agent_position: Vector3 = global_transform.origin + var current_agent_position: Vector3 = global_position var next_path_position: Vector3 = navigation_agent.get_next_path_position() var new_velocity: Vector3 = next_path_position - current_agent_position new_velocity = new_velocity.normalized() new_velocity = new_velocity * movement_speed - set_velocity(new_velocity) + velocity = safe_velocity move_and_slide() .. code-tab:: csharp C# diff --git a/tutorials/navigation/navigation_using_navigationagents.rst b/tutorials/navigation/navigation_using_navigationagents.rst index 700626ef7..23e089414 100644 --- a/tutorials/navigation/navigation_using_navigationagents.rst +++ b/tutorials/navigation/navigation_using_navigationagents.rst @@ -157,12 +157,14 @@ This script adds basic navigation movement to a Node3D with a NavigationAgent3D .. code-tab:: gdscript GDScript extends Node3D - # script on agent parent node, connect the agent 'velocity_computed' signal for collision avoidance @export var movement_speed: float = 4.0 @onready var navigation_agent: NavigationAgent3D = get_node("NavigationAgent3D") var movement_delta: float + func _ready() -> void: + navigation_agent.velocity_computed.connect(Callable(_on_velocity_computed)) + func set_movement_target(movement_target: Vector3): navigation_agent.set_target_position(movement_target) @@ -172,13 +174,15 @@ This script adds basic navigation movement to a Node3D with a NavigationAgent3D movement_delta = movement_speed * delta var next_path_position: Vector3 = navigation_agent.get_next_path_position() - var current_agent_position: Vector3 = global_transform.origin + var current_agent_position: Vector3 = global_position var new_velocity: Vector3 = (next_path_position - current_agent_position).normalized() * movement_delta - navigation_agent.set_velocity(new_velocity) + if navigation_agent.avoidance_enabled: + navigation_agent.set_velocity(new_velocity) + else: + _on_velocity_computed(new_velocity) - func _on_NavigationAgent3D_velocity_computed(safe_velocity: Vector3): - # Move Node3D with the computed `safe_velocity` to avoid dynamic obstacles. - global_transform.origin = global_transform.origin.move_toward(global_transform.origin + safe_velocity, movement_delta) + func _on_velocity_computed(safe_velocity: Vector3) -> void: + global_position = global_position.move_toward(global_position + safe_velocity, movement_delta) Actor as CharacterBody3D ~~~~~~~~~~~~~~~~~~~~~~~~ @@ -189,11 +193,12 @@ This script adds basic navigation movement to a CharacterBody3D with a Navigatio .. code-tab:: gdscript GDScript extends CharacterBody3D - # script on agent parent node, connect the agent 'velocity_computed' signal for collision avoidance @export var movement_speed: float = 4.0 @onready var navigation_agent: NavigationAgent3D = get_node("NavigationAgent3D") - var movement_delta: float + + func _ready() -> void: + navigation_agent.velocity_computed.connect(Callable(_on_velocity_computed)) func set_movement_target(movement_target: Vector3): navigation_agent.set_target_position(movement_target) @@ -202,14 +207,15 @@ This script adds basic navigation movement to a CharacterBody3D with a Navigatio if navigation_agent.is_navigation_finished(): return - movement_delta = movement_speed * delta var next_path_position: Vector3 = navigation_agent.get_next_path_position() - var current_agent_position: Vector3 = global_transform.origin - var new_velocity: Vector3 = (next_path_position - current_agent_position).normalized() * movement_delta - navigation_agent.set_velocity(new_velocity) + var current_agent_position: Vector3 = global_position + var new_velocity: Vector3 = (next_path_position - current_agent_position).normalized() * movement_speed + if navigation_agent.avoidance_enabled: + navigation_agent.set_velocity(new_velocity) + else: + _on_velocity_computed(new_velocity) - func _on_NavigationAgent3D_velocity_computed(safe_velocity: Vector3): - # Move CharacterBody3D with the computed `safe_velocity` to avoid dynamic obstacles. + func _on_velocity_computed(safe_velocity: Vector3): velocity = safe_velocity move_and_slide() @@ -222,10 +228,13 @@ This script adds basic navigation movement to a RigidBody3D with a NavigationAge .. code-tab:: gdscript GDScript extends RigidBody3D - # script on agent parent node, connect the agent 'velocity_computed' signal for collision avoidance + @export var movement_speed: float = 4.0 @onready var navigation_agent: NavigationAgent3D = get_node("NavigationAgent3D") + func _ready() -> void: + navigation_agent.velocity_computed.connect(Callable(_on_velocity_computed)) + func set_movement_target(movement_target: Vector3): navigation_agent.set_target_position(movement_target) @@ -234,10 +243,12 @@ This script adds basic navigation movement to a RigidBody3D with a NavigationAge return var next_path_position: Vector3 = navigation_agent.get_next_path_position() - var current_agent_position: Vector3 = global_transform.origin - var new_velocity: Vector3 = (next_path_position - current_agent_position).normalized() * velocity - navigation_agent.set_velocity(new_velocity) + var current_agent_position: Vector3 = global_position + var new_velocity: Vector3 = (next_path_position - current_agent_position).normalized() * movement_speed + if navigation_agent.avoidance_enabled: + navigation_agent.set_velocity(new_velocity) + else: + _on_velocity_computed(new_velocity) - func _on_NavigationAgent3D_velocity_computed(safe_velocity: Vector3): - # Move RigidBody3D with the computed `safe_velocity` to avoid dynamic obstacles. - set_linear_velocity(safe_velocity) + func _on_velocity_computed(safe_velocity: Vector3): + linear_velocity = safe_velocity diff --git a/tutorials/navigation/navigation_using_navigationmeshes.rst b/tutorials/navigation/navigation_using_navigationmeshes.rst index 0ed1e084b..7b8626b5c 100644 --- a/tutorials/navigation/navigation_using_navigationmeshes.rst +++ b/tutorials/navigation/navigation_using_navigationmeshes.rst @@ -158,12 +158,10 @@ navigationmesh from outline data the shapes cannot overlap. if node is CollisionPolygon2D: - var new_collision_outline: PackedVector2Array = PackedVector2Array() var collisionpolygon_transform: Transform2D = node.get_global_transform() - var collisionpolygon: CollisionPolygon2D = node.get_polygon() + var collisionpolygon: PackedVector2Array = node.polygon - for vertex in collisionpolygon: - new_collision_outline.append(collisionpolygon_transform.xform(vertex)) + var new_collision_outline: PackedVector2Array = collisionpolygon_transform * collisionpolygon new_navigation_polygon.add_outline(new_collision_outline) @@ -188,7 +186,7 @@ The following script creates a new 2D navigation region and fills it with proced Vector2(50.0, 0.0), Vector2(50.0, 50.0), Vector2(0.0, 50.0), - ]) + ]) new_navigation_polygon.add_outline(new_outline) new_navigation_polygon.make_polygons_from_outlines() diff --git a/tutorials/networking/http_request_class.rst b/tutorials/networking/http_request_class.rst index a66edadcd..7a999ec9b 100644 --- a/tutorials/networking/http_request_class.rst +++ b/tutorials/networking/http_request_class.rst @@ -1,70 +1,91 @@ -:article_outdated: True - .. _doc_http_request_class: Making HTTP requests ==================== -The :ref:`HTTPRequest ` node is the easiest way to make HTTP requests in Godot. -It is backed by the more low-level :ref:`HTTPClient `, for which a tutorial is available :ref:`here `. +Why use HTTP? +------------- -For the sake of this example, we will create a simple UI with a button, that when pressed will start the HTTP request to the specified URL. +`HTTP requests `_ are useful +to communicate with web servers and other non-Godot programs. + +Compared to Godot's other networking features (like +:ref:`High-level multiplayer `), +HTTP requests have more overhead and take more time to get going, +so they aren't suited for real-time communication, and aren't great to send +lots of small updates as is common for multiplayer gameplay. + +HTTP, however, offers interoperability with external +web resources and is great at sending and receiving large amounts +of data, for example to transfer files like game assets. + +So HTTP may be useful for your game's login system, lobby browser, +to retrieve some information from the web or to download game assets. + +This tutorial assumes some familiarity with Godot and the Godot Editor. +Refer to the :ref:`Introduction ` and the +:ref:`Step by step ` tutorial, especially its +:ref:`Nodes and Scenes ` and +:ref:`Creating your first script ` pages if needed. + +HTTP requests in Godot +---------------------- + +The :ref:`HTTPRequest ` node is the easiest way to make HTTP requests in Godot. +It is backed by the more low-level :ref:`HTTPClient `, +for which a tutorial is available :ref:`here `. + +For this example, we will make an HTTP request to GitHub to retrieve the name +of the latest Godot release. .. warning:: - When exporting to Android, make sure to enable the ``INTERNET`` + When exporting to **Android**, make sure to enable the **Internet** permission in the Android export preset before exporting the project or using one-click deploy. Otherwise, network communication of any kind will be - blocked by Android. + blocked by the Android OS. -Preparing scene ---------------- +Preparing the scene +------------------- -Create a new empty scene, add a CanvasLayer as the root node and add a script to it. Then add two child nodes to it: a Button and an HTTPRequest node. You will need to connect the following signals to the CanvasLayer script: +Create a new empty scene, add a root :ref:`Node ` and add a script to it. +Then add a :ref:`HTTPRequest ` node as a child. -- Button.pressed: When the button is pressed, we will start the request. -- HTTPRequest.request_completed: When the request is completed, we will get the requested data as an argument. +.. image:: img/rest_api_scene.webp -.. image:: img/rest_api_scene.png +Scripting the request +--------------------- -Scripting ---------- - -Below is all the code we need to make it work. The URL points to an online API mocker; it returns a predefined JSON string, which we will then parse to get access to the data. +When the project is started (so in ``_ready()``), we're going to send an HTTP request +to Github using our :ref:`HTTPRequest ` node, +and once the request completes, we're going to parse the returned JSON data, +look for the ``name`` field and print that to console. .. tabs:: .. code-tab:: gdscript GDScript - extends CanvasLayer + extends Node func _ready(): - $HTTPRequest.connect("request_completed", self, "_on_request_completed") - $Button.connect("pressed", self, "_on_Button_pressed") - - func _on_Button_pressed(): - $HTTPRequest.request("http://www.mocky.io/v2/5185415ba171ea3a00704eed") + $HTTPRequest.request_completed.connect(_on_request_completed) + $HTTPRequest.request("https://api.github.com/repos/godotengine/godot/releases/latest") func _on_request_completed(result, response_code, headers, body): - var json = JSON.parse(body.get_string_from_utf8()) - print(json.result) + var json = JSON.parse_string(body.get_string_from_utf8()) + print(json["name"]) .. code-tab:: csharp using Godot; - - public partial class MyCanvasLayer : CanvasLayer + + public partial class MyNode : Node { public override void _Ready() { GetNode("HTTPRequest").RequestCompleted += OnRequestCompleted; - GetNode("Button").Pressed += OnButtonPressed; - } - - private void OnButtonPressed() - { HttpRequest httpRequest = GetNode("HTTPRequest"); - httpRequest.Request("http://www.mocky.io/v2/5185415ba171ea3a00704eed"); + httpRequest.Request("https://api.github.com/repos/godotengine/godot/releases/latest"); } private void OnRequestCompleted(long result, long responseCode, string[] headers, byte[] body) @@ -74,58 +95,60 @@ Below is all the code we need to make it work. The URL points to an online API m } } -With this, you should see ``(hello:world)`` printed on the console; ``hello`` being a key, ``world`` being a value, and both of them are of type :ref:`String `. - +Save the script and the scene, and run the project. +The name of the most recent Godot release on Github should be printed to the output log. For more information on parsing JSON, see the class references for :ref:`JSON `. -Note that you may want to check whether the ``result`` equals ``RESULT_SUCCESS`` and whether a JSON parsing error occurred, see the JSON class reference and :ref:`HTTPRequest ` for more. +Note that you may want to check whether the ``result`` equals ``RESULT_SUCCESS`` +and whether a JSON parsing error occurred, see the JSON class reference and +:ref:`HTTPRequest ` for more. -Of course, you can also set custom HTTP headers. These are given as a string array, with each string containing a header in the format ``"header: value"``. -For example, to set a custom user agent (the HTTP ``user-agent`` header) you could use the following: +You have to wait for a request to finish before sending another one. +Making multiple request at once requires you to have one node per request. +A common strategy is to create and delete HTTPRequest nodes at runtime as necessary. + +Sending data to the server +-------------------------- + +Until now, we have limited ourselves to requesting data from a server. +But what if you need to send data to the server? Here is a common way of doing it: .. tabs:: .. code-tab:: gdscript GDScript - $HTTPRequest.request("http://www.mocky.io/v2/5185415ba171ea3a00704eed", ["user-agent: YourCustomUserAgent"]) + var json = JSON.stringify(data_to_send) + var headers = ["Content-Type: application/json"] + $HTTPRequest.request(url, headers, HTTPClient.METHOD_POST, json) + + .. code-tab:: csharp + + string json = Json.Stringify(dataToSend); + string[] headers = new string[] { "Content-Type: application/json" }; + HttpRequest httpRequest = GetNode("HTTPRequest"); + httpRequest.Request(url, headers, HttpClient.Method.Post, json); + +Setting custom HTTP headers +--------------------------- + +Of course, you can also set custom HTTP headers. These are given as a string array, +with each string containing a header in the format ``"header: value"``. +For example, to set a custom user agent (the HTTP ``User-Agent`` header) you could use the following: + +.. tabs:: + + .. code-tab:: gdscript GDScript + + $HTTPRequest.request("https://api.github.com/repos/godotengine/godot/releases/latest", ["User-Agent: YourCustomUserAgent"]) .. code-tab:: csharp HttpRequest httpRequest = GetNode("HTTPRequest"); - httpRequest.Request("http://www.mocky.io/v2/5185415ba171ea3a00704eed", new string[] { "user-agent: YourCustomUserAgent" }); + httpRequest.Request("https://api.github.com/repos/godotengine/godot/releases/latest", new string[] { "User-Agent: YourCustomUserAgent" }); -Please note that, for SSL/TLS encryption and thus HTTPS URLs to work, you may need to take some steps as described :ref:`here `. +.. warning:: -Also, when calling APIs using authorization, be aware that someone might analyse and decompile your released application and thus may gain access to any embedded authorization information like tokens, usernames or passwords. -That means it is usually not a good idea to embed things such as database access credentials inside your game. Avoid providing information useful to an attacker whenever possible. - -Sending data to server ----------------------- - -Until now, we have limited ourselves to requesting data from a server. But what if you need to send data to the server? Here is a common way of doing it: - -.. tabs:: - - .. code-tab:: gdscript GDScript - - func _make_post_request(url, data_to_send, use_ssl): - # Convert data to json string: - var query = JSON.stringify(data_to_send) - # Add 'Content-Type' header: - var headers = ["Content-Type: application/json"] - $HTTPRequest.request(url, headers, use_ssl, HTTPClient.METHOD_POST, query) - - .. code-tab:: csharp - - public void MakePostRequest(string url, Variant dataToSend, bool useSsl) - { - // Convert data to json string: - string query = Json.Stringify(dataToSend); - // Add 'Content-Type' header: - string[] headers = new string[] { "Content-Type: application/json" }; - HttpRequest httpRequest = GetNode("HTTPRequest"); - httpRequest.Request(url, headers, useSsl, HttpClient.Method.Post, query); - } - -Keep in mind that you have to wait for a request to finish before sending another one. Making multiple request at once requires you to have one node per request. -A common strategy is to create and delete HTTPRequest nodes at runtime as necessary. + Be aware that someone might analyse and decompile your released application and + thus may gain access to any embedded authorization information like tokens, usernames or passwords. + That means it is usually not a good idea to embed things such as database + access credentials inside your game. Avoid providing information useful to an attacker whenever possible. diff --git a/tutorials/networking/img/rest_api_scene.png b/tutorials/networking/img/rest_api_scene.png deleted file mode 100644 index bf53c99a4..000000000 Binary files a/tutorials/networking/img/rest_api_scene.png and /dev/null differ diff --git a/tutorials/networking/img/rest_api_scene.webp b/tutorials/networking/img/rest_api_scene.webp new file mode 100644 index 000000000..53eaeb44b Binary files /dev/null and b/tutorials/networking/img/rest_api_scene.webp differ diff --git a/tutorials/performance/using_multimesh.rst b/tutorials/performance/using_multimesh.rst index dd0614ec6..9e9d355ad 100644 --- a/tutorials/performance/using_multimesh.rst +++ b/tutorials/performance/using_multimesh.rst @@ -63,8 +63,6 @@ efficient for millions of objects, but for a few thousands, GDScript should be f multimesh = MultiMesh.new() # Set the format first. multimesh.transform_format = MultiMesh.TRANSFORM_3D - multimesh.color_format = MultiMesh.COLOR_NONE - multimesh.custom_data_format = MultiMesh.CUSTOM_DATA_NONE # Then resize (otherwise, changing the format is not allowed). multimesh.instance_count = 10000 # Maybe not all of them should be visible at first. @@ -86,8 +84,6 @@ efficient for millions of objects, but for a few thousands, GDScript should be f Multimesh = new MultiMesh(); // Set the format first. Multimesh.TransformFormat = MultiMesh.TransformFormatEnum.Transform3D; - Multimesh.ColorFormat = MultiMesh.ColorFormatEnum.None; - Multimesh.CustomDataFormat = MultiMesh.CustomDataFormatEnum.None; // Then resize (otherwise, changing the format is not allowed) Multimesh.InstanceCount = 1000; // Maybe not all of them should be visible at first. diff --git a/tutorials/performance/vertex_animation/animating_thousands_of_fish.rst b/tutorials/performance/vertex_animation/animating_thousands_of_fish.rst index 432b4ef1e..c26dffc9d 100644 --- a/tutorials/performance/vertex_animation/animating_thousands_of_fish.rst +++ b/tutorials/performance/vertex_animation/animating_thousands_of_fish.rst @@ -26,7 +26,7 @@ Here is the fish we will be using for the example images, you can use any fish m .. image:: img/fish.png -.. note:: The fish model in this tutorial is made by `QuaterniusDev `_ and is +.. note:: The fish model in this tutorial is made by `QuaterniusDev `_ and is shared with a creative commons license. CC0 1.0 Universal (CC0 1.0) Public Domain Dedication https://creativecommons.org/publicdomain/zero/1.0/ diff --git a/tutorials/physics/index.rst b/tutorials/physics/index.rst index 746082c32..4ba2acd29 100644 --- a/tutorials/physics/index.rst +++ b/tutorials/physics/index.rst @@ -16,3 +16,4 @@ Physics collision_shapes_2d collision_shapes_3d large_world_coordinates + troubleshooting_physics_issues diff --git a/tutorials/physics/large_world_coordinates.rst b/tutorials/physics/large_world_coordinates.rst index 9ebe17c95..2fa5cb2d7 100644 --- a/tutorials/physics/large_world_coordinates.rst +++ b/tutorials/physics/large_world_coordinates.rst @@ -1,3 +1,5 @@ +.. _doc_large_world_coordinates: + Large world coordinates ======================= diff --git a/tutorials/physics/troubleshooting_physics_issues.rst b/tutorials/physics/troubleshooting_physics_issues.rst new file mode 100644 index 000000000..4735814fe --- /dev/null +++ b/tutorials/physics/troubleshooting_physics_issues.rst @@ -0,0 +1,166 @@ +.. _doc_troubleshooting_physics_issues: + +Troubleshooting physics issues +============================== + +When working with a physics engine, you may encounter unexpected results. + +While many of these issues can be resolved through configuration, some of them +are the result of engine bugs. For known issues related to the physics engine, +see +`open physics-related issues on GitHub `__. +Looking through `closed issues +`__ +can also help answer questions related to physics engine behavior. + +Objects are passing through each other at high speeds +----------------------------------------------------- + +This is known as *tunneling*. Enabling **Continuous CD** in the RigidBody +properties can sometimes resolve this issue. If this does not help, there are +other solutions you can try: + +- Make your static collision shapes thicker. For example, if you have a thin + floor that the player can't get below in some way, you can make the collider + thicker than the floor's visual representation. +- Modify your fast-moving object's collision shape depending on its movement + 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 + 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`` + or ``240``) should be preferred for a smooth appearance on most displays. + +Stacked objects are unstable and wobbly +--------------------------------------- + +Despite seeming like a simple problem, stable RigidBody simulation with stacked +objects is difficult to implement in a physics engine. This is caused by +integrating forces going against each other. The more stacked objects are +present, the stronger the forces will be against each other. This eventually +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 +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. + +Scaled physics bodies or collision shapes do not collide correctly +------------------------------------------------------------------ + +Godot does not currently support scaling of physics bodies or collision shapes. +As a workaround, change the collision shape's extents instead of changing its +scale. If you want the visual representation's scale to change as well, change +the scale of the underlying visual representation (Sprite2D, MeshInstance3D, …) +and change the collision shape's extents separately. Make sure the collision +shape is not a child of the visual representation in this case. + +Since resources are shared by default, you'll have to make the collision shape +resource unique if you don't want the change to be applied to all nodes using +the same collision shape resource in the scene. This can be done by calling +``duplicate()`` in a script on the collision shape resource *before* changing +its size. + +Thin objects are wobbly when resting on the floor +------------------------------------------------- + +This can be due to one of two causes: + +- The floor's collision shape is too thin. +- The RigidBody's collision shape is too thin. + +In the first case, this can be alleviated by making the floor's collision shape +thicker. For example, if you have a thin floor that the player can't get below +in some way, you can make the collider thicker than the floor's visual +representation. + +In the second case, this can usually only be resolved by increasing the physics +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 +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 +displays. + +Cylinder collision shapes are unstable +-------------------------------------- + +During the transition from Bullet to GodotPhysics in Godot 4, cylinder collision +shapes had to be reimplemented from scratch. However, cylinder collision shapes +are one of the most difficult shapes to support, which is why many other physics +engines don't provide any support for them. There are several known bugs with +cylinder collision shapes currently. + +We recommend using box or capsule collision shapes for characters for now. Boxes +generally provide the best reliability, but have the downside of making the +character take more space diagonally. Capsule collision shapes do not have this +downside, but their shape can make precision platforming more difficult. + +VehicleBody simulation is unstable, especially at high speeds +------------------------------------------------------------- + +When a physics body moves at a high speed, it travels a large distance between +each physics step. For instance, when using the 1 unit = 1 meter convention in +3D, a vehicle moving at 360 km/h will travel 100 units per second. With the +default physics simulation rate of 60 Hz, the vehicle moves by ~1.67 units each +physics tick. This means that small objects may be ignored entirely by the +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 +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 +displays. + +Collision results in bumps when an object moves across tiles +------------------------------------------------------------ + +This is a known issue in the physics engine caused by the object bumping on a +shape's edges, even though that edge is covered by another shape. This can occur +in both 2D and 3D. + +The best way to work around this issue is to create a "composite" collider. This +means that instead of individual tiles having their collision, you create a +single collision shape representing the collision for a group of tiles. +Typically, you should split composite colliders on a per-island basis (which +means each group of touching tiles gets its own collider). + +Using a composite collider can also improve physics simulation performance in +certain cases. However, since the composite collision shape is much more +complex, this may not be a net performance win in all cases. + +Framerate drops when an object touches another object +----------------------------------------------------- + +This is likely due to one of the objects using a collision shape that is too +complex. Convex collision shapes should use a number of shapes as low as +possible for performance reasons. When relying on Godot's automatic generation, +it's possible that you ended up with dozens if not hundreds of shapes created +for a single convex shape collision resource. + +In some cases, replacing a convex collider with a couple of primitive collision +shapes (box, sphere, or capsule) can deliver better performance. + +This issue can also occur with StaticBodies that use very detailed trimesh +(concave) collisions. In this case, use a simplified representation of the level +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. + +Physics simulation is unreliable when far away from the world origin +-------------------------------------------------------------------- + +This is caused by floating-point precision errors, which become more pronounced +as the physics simulation occurs further away from the world origin. This issue +also affects rendering, which results in wobbly camera movement when far away +from the world origin. See :ref:`doc_large_world_coordinates` for more +information. diff --git a/tutorials/platform/android/android_plugin.rst b/tutorials/platform/android/android_plugin.rst index de78cc75d..838433e7c 100644 --- a/tutorials/platform/android/android_plugin.rst +++ b/tutorials/platform/android/android_plugin.rst @@ -97,7 +97,7 @@ The instructions below assumes that you're using Android Studio. local=["local_dep1.aar", "local_dep2.aar"] remote=["example.plugin.android:remote-dep1:0.0.1", "example.plugin.android:remote-dep2:0.0.1"] - custom_maven_repos=["http://repo.mycompany.com/maven2"] + custom_maven_repos=["https://repo.mycompany.com/maven2"] The ``config`` section and fields are required and defined as follow: @@ -125,8 +125,9 @@ Move the plugin configuration file (e.g: ``MyPlugin.gdap``) and, if any, its loc The Godot editor will automatically parse all ``.gdap`` files in the ``res://android/plugins`` directory and show a list of detected and toggleable plugins in the Android export presets window under the **Plugins** section. -.. image:: img/android_export_preset_plugins_section.png +In order to allow GDScript to communicate with your Java Singleton, you must annotate your function with ``@UsedByGodot``. The name called from GDScript must match the function name exactly. There is **no** coercing ``snake_case`` to ``camelCase``. +.. image:: img/android_export_preset_plugins_section.png From your script:: diff --git a/tutorials/platform/consoles.rst b/tutorials/platform/consoles.rst index 09095d287..d2299b24f 100644 --- a/tutorials/platform/consoles.rst +++ b/tutorials/platform/consoles.rst @@ -66,7 +66,7 @@ your games to various consoles. Following is the list of providers: -- `Lone Wolf Technology `_ offers +- `Lone Wolf Technology `_ offers Switch and PS4 porting and publishing of Godot games. - `Pineapple Works `_ offers Switch, Xbox One & Xbox Series X/S (GDK) porting and publishing of Godot games (GDScript/C#). diff --git a/tutorials/plugins/editor/making_plugins.rst b/tutorials/plugins/editor/making_plugins.rst index a3a0c9014..b140805af 100644 --- a/tutorials/plugins/editor/making_plugins.rst +++ b/tutorials/plugins/editor/making_plugins.rst @@ -246,8 +246,8 @@ dialog. For that, change the ``custom_node.gd`` script to the following: { // Initialization of the plugin goes here. // Add the new type with a name, a parent type, a script and an icon. - var script = GD.Load