diff --git a/about/faq.rst b/about/faq.rst index a5864dba9b4..a491bdbb854 100644 --- a/about/faq.rst +++ b/about/faq.rst @@ -167,6 +167,38 @@ The main reasons for creating a custom scripting language for Godot were: GDScript was designed to curtail the issues above, and more. +.. _doc_faq_which_programming_language_is_fastest: + +Which programming language is fastest? +-------------------------------------- + +In most games, the *scripting language* itself is not the cause of performance +problems. Instead, performance is slowed by inefficient algorithms (which are +slow in all languages), by GPU performance, or by the common C++ engine code +like physics or navigation. All languages supported by Godot are fast enough for +general-purpose scripting. You should choose a language based on other factors, +like ease-of-use, familiarity, platform support, or language features. + +In general, the performance of C# and GDScript is within the same order of +magnitude, and C++ is faster than both. + +Comparing GDScript performance to C# is tricky, since C# can be faster in some +specific cases. The C# *language* itself tends to be faster than GDScript, which +means that C# can be faster in situations with few calls to Godot engine code. +However, C# can be slower than GDScript when making many Godot API calls, due +to the cost of *marshalling*. C#'s performance can also be brought down by garbage +collection which occurs at random and unpredictable moments. This can result in +stuttering issues in complex projects, and is not exclusive to Godot. + +C++, using :ref:`GDExtension `, will almost always be +faster than either C# or GDScript. However, C++ is less easy to use than C# or +GDScript, and is slower to develop with. + +You can also use multiple languages within a single project, with +:ref:`cross-language scripting `, or by using +GDExtension and scripting languages together. Be aware that doing so comes with +its own complications. + What 3D model formats does Godot support? ----------------------------------------- diff --git a/community/tutorials.rst b/community/tutorials.rst index 8a8467a43b6..18d61d28899 100644 --- a/community/tutorials.rst +++ b/community/tutorials.rst @@ -3,7 +3,10 @@ Tutorials and resources ======================= -This is a list of third-party tutorials and resources created by the Godot community. For resources, remember that there is the official `Godot Asset Library `_ full of official and community resources too! Also, have a look at this `huge list over at Reddit `_. +This is a list of third-party tutorials and resources created by the Godot +community. For resources, remember that there is the official +`Godot Asset Library `_ full of +official and community resources too! Think there is something missing here? Feel free to submit a `Pull Request `_ as always. diff --git a/contributing/development/compiling/compiling_for_ios.rst b/contributing/development/compiling/compiling_for_ios.rst index 6cd9686f73c..c5d370daff6 100644 --- a/contributing/development/compiling/compiling_for_ios.rst +++ b/contributing/development/compiling/compiling_for_ios.rst @@ -20,9 +20,6 @@ Requirements Xcode and need to install iOS support, go to *Xcode -> Settings... -> Platforms*. - Go to *Xcode -> Settings... -> Locations -> Command Line Tools* and select an installed version. Even if one is already selected, re-select it. - -If you are building the ``master`` branch: - - Download and follow README instructions to build a static ``.xcframework`` from the `MoltenVK SDK `__. @@ -49,46 +46,40 @@ If you are building the ``master`` branch: Compiling --------- -Open a Terminal, go to the root dir of the engine source code and type: +Open a Terminal, go to the root folder of the engine source code and type +the following to compile a debug build: :: - scons platform=ios target=template_debug + scons platform=ios target=template_debug generate_bundle=yes -for a debug build, or: +To compile a release build: :: - scons platform=ios target=template_release - -for a release build (check ``platform/ios/detect.py`` for the compiler -flags used for each configuration). + scons platform=ios target=template_release generate_bundle=yes -Alternatively, you can run +Alternatively, you can run the following command for Xcode simulator libraries (optional): :: - scons platform=ios target=template_debug ios_simulator=yes arch=x86_64 scons platform=ios target=template_debug ios_simulator=yes arch=arm64 + scons platform=ios target=template_debug ios_simulator=yes arch=x86_64 generate_bundle=yes -for a Simulator libraries. +These simulator libraries cannot be used to run the exported project on the +target device. Instead, they can be used to run the exported project directly on +your Mac while still testing iOS platform-specific functionality. To create an Xcode project like in the official builds, you need to use the template located in ``misc/dist/ios_xcode``. The release and debug libraries -should be placed in ``libgodot.ios.debug.xcframework`` and ``libgodot.ios.release.xcframework`` respectively. - -:: - - cp -r misc/dist/ios_xcode . - - cp libgodot.ios.template_debug.arm64.a ios_xcode/libgodot.ios.debug.xcframework/ios-arm64/libgodot.a - lipo -create libgodot.ios.template_debug.arm64.simulator.a libgodot.ios.template_debug.x86_64.simulator.a -output ios_xcode/libgodot.ios.debug.xcframework/ios-arm64_x86_64-simulator/libgodot.a - - cp libgodot.ios.template_release.arm64.a ios_xcode/libgodot.ios.release.xcframework/ios-arm64/libgodot.a - lipo -create libgodot.ios.template_release.arm64.simulator.a libgodot.ios.template_release.x86_64.simulator.a -output ios_xcode/libgodot.ios.release.xcframework/ios-arm64_x86_64-simulator/libgodot.a - -The MoltenVK static ``.xcframework`` folder must also be placed in the ``ios_xcode`` -folder once it has been created. +should be placed in ``libgodot.ios.debug.xcframework`` and +``libgodot.ios.release.xcframework`` respectively. This process can be automated +by using the ``generate_bundle=yes`` option on the *last* SCons command used to +build export templates (so that all binaries can be included). + +The MoltenVK static ``.xcframework`` folder must also be placed in the +``ios_xcode`` folder once it has been created. MoltenVK is always statically +linked on iOS; there is no dynamic linking option available, unlike macOS. Run --- diff --git a/contributing/development/compiling/compiling_for_linuxbsd.rst b/contributing/development/compiling/compiling_for_linuxbsd.rst index f3fcbc3f368..20638c0e8e4 100644 --- a/contributing/development/compiling/compiling_for_linuxbsd.rst +++ b/contributing/development/compiling/compiling_for_linuxbsd.rst @@ -248,6 +248,12 @@ Start a terminal, go to the root dir of the engine source code and type: ``linuxbsd``. If you are looking to compile Godot 3.x, make sure to use the `3.x branch of this documentation `__. +.. tip:: + If you are compiling Godot to make changes or contribute to the engine, + you may want to use the SCons options ``dev_build=yes`` or ``dev_mode=yes``. + See :ref:`doc_introduction_to_the_buildsystem_development_and_production_aliases` + for more info. + If all goes well, the resulting binary executable will be placed in the "bin" subdirectory. This executable file contains the whole engine and runs without any dependencies. Executing it will bring up the Project @@ -573,34 +579,3 @@ running ``scons -h``, then looking for options starting with ``builtin_``. across Linux distributions anymore. Do not use this approach for creating binaries you intend to distribute to others, unless you're creating a package for a Linux distribution. - -Using Pyston for faster development ------------------------------------ - -You can use `Pyston `__ to run SCons. Pyston is a JIT-enabled -implementation of the Python language (which SCons is written in). It is currently -only compatible with Linux. Pyston can speed up incremental builds significantly, -often by a factor between 1.5× and 2×. Pyston can be combined with Clang and LLD -to get even faster builds. - -- Download the `latest portable Pyston release `__. -- Extract the portable ``.tar.gz`` to a set location, such as ``$HOME/.local/opt/pyston/`` (create folders as needed). -- Use ``cd`` to reach the extracted Pyston folder from a terminal, - then run ``./pyston -m pip install scons`` to install SCons within Pyston. -- To make SCons via Pyston easier to run, create a symbolic link of its wrapper - script to a location in your ``PATH`` environment variable:: - - ln -s ~/.local/opt/pyston/bin/scons ~/.local/bin/pyston-scons - -- Instead of running ``scons ``, run ``pyston-scons `` - to compile Godot. - -If you can't run ``pyston-scons`` after creating the symbolic link, -make sure ``$HOME/.local/bin/`` is part of your user's ``PATH`` environment variable. - -.. note:: - - Alternatively, you can run ``python -m pip install pyston_lite_autoload`` - then run SCons as usual. This will automatically load a subset of Pyston's - optimizations in any Python program you run. However, this won't bring as - much of a performance improvement compared to installing "full" Pyston. diff --git a/contributing/development/compiling/compiling_for_macos.rst b/contributing/development/compiling/compiling_for_macos.rst index 65ae80af523..5e984641f16 100644 --- a/contributing/development/compiling/compiling_for_macos.rst +++ b/contributing/development/compiling/compiling_for_macos.rst @@ -59,6 +59,12 @@ To support both architectures in a single "Universal 2" binary, run the above tw lipo -create bin/godot.macos.editor.x86_64 bin/godot.macos.editor.arm64 -output bin/godot.macos.editor.universal +.. tip:: + If you are compiling Godot to make changes or contribute to the engine, + you may want to use the SCons options ``dev_build=yes`` or ``dev_mode=yes``. + See :ref:`doc_introduction_to_the_buildsystem_development_and_production_aliases` + for more info. + If all goes well, the resulting binary executable will be placed in the ``bin/`` subdirectory. This executable file contains the whole engine and runs without any dependencies. Executing it will bring up the Project @@ -119,70 +125,46 @@ To build macOS export templates, you have to compile using the targets without the editor: ``target=template_release`` (release template) and ``target=template_debug``. -Official templates are universal binaries which support both Intel x86_64 and -ARM64 architectures. You can also create export templates that support only one -of those two architectures by leaving out the ``lipo`` step below. +Official templates are *Universal 2* binaries which support both ARM64 and Intel +x86_64 architectures. -- For Intel x86_64:: +- To support ARM64 (Apple Silicon) + Intel x86_64:: - scons platform=macos target=template_release arch=x86_64 + scons platform=macos target=template_debug arch=arm64 + scons platform=macos target=template_release arch=arm64 scons platform=macos target=template_debug arch=x86_64 + scons platform=macos target=template_release arch=x86_64 generate_bundle=yes -- For Arm64 (Apple M1):: +- To support ARM64 (Apple Silicon) only (smaller file size, but less compatible with older hardware):: - scons platform=macos target=template_release arch=arm64 scons platform=macos target=template_debug arch=arm64 - -To support both architectures in a single "Universal 2" binary, run the above -two commands blocks and then use ``lipo`` to bundle them together:: - - lipo -create bin/godot.macos.template_release.x86_64 bin/godot.macos.template_release.arm64 -output bin/godot.macos.template_release.universal - lipo -create bin/godot.macos.template_debug.x86_64 bin/godot.macos.template_debug.arm64 -output bin/godot.macos.template_debug.universal + scons platform=macos target=template_release arch=arm64 generate_bundle=yes To create an ``.app`` bundle like in the official builds, you need to use the -template located in ``misc/dist/macos_template.app``. The release and debug -builds should be placed in ``macos_template.app/Contents/MacOS`` with the names -``godot_macos_release.universal`` and ``godot_macos_debug.universal`` respectively. You can do so -with the following commands (assuming a universal build, otherwise replace the -``.universal`` extension with the one of your arch-specific binaries):: - - cp -r misc/dist/macos_template.app . - mkdir -p macos_template.app/Contents/MacOS - cp bin/godot.macos.template_release.universal macos_template.app/Contents/MacOS/godot_macos_release.universal - cp bin/godot.macos.template_debug.universal macos_template.app/Contents/MacOS/godot_macos_debug.universal - chmod +x macos_template.app/Contents/MacOS/godot_macos* +template located in ``misc/dist/macos_template.app``. This process can be automated by using +the ``generate_bundle=yes`` option on the *last* SCons command used to build export templates +(so that all binaries can be included). This option also takes care of calling ``lipo`` to create +an *Universal 2* binary from two separate ARM64 and x86_64 binaries (if both were compiled beforehand). .. note:: - If you are building the ``master`` branch, you also need to include support - for the MoltenVK Vulkan portability library. By default, it will be linked - statically from your installation of the Vulkan SDK for macOS. - You can also choose to link it dynamically by passing ``use_volk=yes`` and - including the dynamic library in your ``.app`` bundle:: + You also need to include support for the MoltenVK Vulkan portability + library. By default, it will be linked statically from your installation of + the Vulkan SDK for macOS. You can also choose to link it dynamically by + passing ``use_volk=yes`` and including the dynamic library in your ``.app`` + bundle:: mkdir -p macos_template.app/Contents/Frameworks cp /macOS/libs/libMoltenVK.dylib macos_template.app/Contents/Frameworks/libMoltenVK.dylib + In most cases, static linking should be preferred as it makes distribution + easier. The main upside of dynamic linking is that it allows updating + MoltenVK without having to recompile export templates. + You can then zip the ``macos_template.app`` folder to reproduce the ``macos.zip`` template from the official Godot distribution:: - zip -q -9 -r macos.zip macos_template.app - -Using Pyston for faster development ------------------------------------ - -You can use `Pyston `__ to run SCons. Pyston is a -JIT-enabled implementation of the Python language (which SCons is written in). -Its "full" version is currently only compatible with Linux, but Pyston-lite is -also compatible with macOS (both x86 and ARM). Pyston can speed up incremental -builds significantly, often by a factor between 1.5× and 2×. Pyston can be -combined with alternative linkers such as LLD or Mold to get even faster builds. - -To install Pyston-lite, run ``python -m pip install pyston_lite_autoload`` then -run SCons as usual. This will automatically load a subset of Pyston's -optimizations in any Python program you run. However, this won't bring as much -of a performance improvement compared to installing "full" Pyston (which -currently can't be done on macOS). + zip -r9 macos.zip macos_template.app Cross-compiling for macOS from Linux ------------------------------------ diff --git a/contributing/development/compiling/compiling_for_web.rst b/contributing/development/compiling/compiling_for_web.rst index 89e1a1e916c..e6d9bcf4098 100644 --- a/contributing/development/compiling/compiling_for_web.rst +++ b/contributing/development/compiling/compiling_for_web.rst @@ -125,7 +125,7 @@ server requirements. python platform/web/serve.py This will serve the contents of the ``bin/`` folder and open the default web - browser automatically. In the page that opens, access ``godot.tools.html`` + browser automatically. In the page that opens, access ``godot.editor.html`` and you should be able to test the web editor this way. Note that for production use cases, this Python-based web server should not diff --git a/contributing/development/compiling/compiling_for_windows.rst b/contributing/development/compiling/compiling_for_windows.rst index d212027a75e..7b26863bb3b 100644 --- a/contributing/development/compiling/compiling_for_windows.rst +++ b/contributing/development/compiling/compiling_for_windows.rst @@ -146,6 +146,12 @@ the engine source code (using ``cd``) and type: .. note:: When compiling with multiple CPU threads, SCons may warn about pywin32 being missing. You can safely ignore this warning. +.. tip:: + If you are compiling Godot to make changes or contribute to the engine, + you may want to use the SCons options ``dev_build=yes`` or ``dev_mode=yes``. + See :ref:`doc_introduction_to_the_buildsystem_development_and_production_aliases` + for more info. + If all goes well, the resulting binary executable will be placed in ``C:\godot\bin\`` with the name ``godot.windows.editor.x86_32.exe`` or ``godot.windows.editor.x86_64.exe``. By default, SCons will build a binary matching diff --git a/contributing/development/compiling/introduction_to_the_buildsystem.rst b/contributing/development/compiling/introduction_to_the_buildsystem.rst index 2b01c0f8a59..73ec7587f7f 100644 --- a/contributing/development/compiling/introduction_to_the_buildsystem.rst +++ b/contributing/development/compiling/introduction_to_the_buildsystem.rst @@ -139,6 +139,8 @@ run projects but does not include the editor or the Project Manager. scons platform= target=editor/template_debug/template_release +.. _doc_introduction_to_the_buildsystem_development_and_production_aliases: + Development and production aliases ---------------------------------- diff --git a/contributing/development/core_and_modules/custom_resource_format_loaders.rst b/contributing/development/core_and_modules/custom_resource_format_loaders.rst index 9066fbdb6e7..fd78c193bca 100644 --- a/contributing/development/core_and_modules/custom_resource_format_loaders.rst +++ b/contributing/development/core_and_modules/custom_resource_format_loaders.rst @@ -269,7 +269,7 @@ calls into ``std::istream``. .. code-block:: cpp - #include "core/os/file_access.h" + #include "core/io/file_access.h" #include #include @@ -304,7 +304,7 @@ References - `istream `_ - `streambuf `_ -- `core/io/file_access.h `_ +- `core/io/file_access.h `_ Registering the new file format ------------------------------- diff --git a/contributing/development/core_and_modules/internal_rendering_architecture.rst b/contributing/development/core_and_modules/internal_rendering_architecture.rst index b2c8e0b791d..75ab68ef643 100644 --- a/contributing/development/core_and_modules/internal_rendering_architecture.rst +++ b/contributing/development/core_and_modules/internal_rendering_architecture.rst @@ -228,8 +228,8 @@ support Vulkan. OpenGL 3.3 Core Profile is used on desktop platforms to run this driver, as most graphics drivers on desktop don't support OpenGL ES. WebGL 2.0 is used for web exports. -It is possible to use the use of OpenGL ES 3.0 directly on desktop platforms -using the ``--rendering-driver opengl3_es`` command line argument, although this +It is possible to use OpenGL ES 3.0 directly on desktop platforms +by passing the ``--rendering-driver opengl3_es`` command line argument, although this will only work on graphics drivers that feature native OpenGL ES support (such as Mesa). diff --git a/contributing/development/core_and_modules/object_class.rst b/contributing/development/core_and_modules/object_class.rst index e2afbdad761..ffa69908cbf 100644 --- a/contributing/development/core_and_modules/object_class.rst +++ b/contributing/development/core_and_modules/object_class.rst @@ -274,7 +274,7 @@ References: Resources ---------- -:ref:`Resource ` inherits from Reference, so all resources +:ref:`Resource ` inherits from RefCounted, so all resources are reference counted. Resources can optionally contain a path, which reference a file on disk. This can be set with ``resource.set_path(path)``, though this is normally done by the resource loader. No two different diff --git a/getting_started/first_2d_game/02.player_scene.rst b/getting_started/first_2d_game/02.player_scene.rst index 20799618811..24612d023bb 100644 --- a/getting_started/first_2d_game/02.player_scene.rst +++ b/getting_started/first_2d_game/02.player_scene.rst @@ -20,8 +20,16 @@ what the object *is*. Click the "Other Node" button and add an :ref:`Area2D .. image:: img/add_node.webp -Godot will display a warning icon next to the node in the scene tree. You can -ignore it for now. We will address it later. +When you add the ``Area2D`` node, Godot will display the following **warning icon** +next to it in the scene tree: + +.. image:: img/no_shape_warning.webp + +This warning tells us that the ``Area2D`` node requires a shape to detect collisions or overlaps. +We can **ignore the warning temporarily** because we will first set up the player's visuals +(using an animated sprite). Once the visuals are ready, we will add a collision shape as a child +node. This will allow us to accurately size and position the shape based on the sprite’s appearance. + With ``Area2D`` we can detect objects that overlap or run into the player. Change the node's name to ``Player`` by double-clicking on it. Now that we've @@ -98,6 +106,9 @@ When you're finished, your ``Player`` scene should look like this: .. image:: img/player_scene_nodes.webp +Once this is done, the warning on the ``Area2D`` node will disappear, as it now has +a shape assigned and can interact with other objects. + Make sure to save the scene again after these changes. In the next part, we'll add a script to the player node to move and animate it. diff --git a/getting_started/first_2d_game/img/no_shape_warning.webp b/getting_started/first_2d_game/img/no_shape_warning.webp new file mode 100644 index 00000000000..5caa74b0778 Binary files /dev/null and b/getting_started/first_2d_game/img/no_shape_warning.webp differ diff --git a/tutorials/3d/introduction_to_3d.rst b/tutorials/3d/introduction_to_3d.rst index 674e5f5e24f..5f876139c21 100644 --- a/tutorials/3d/introduction_to_3d.rst +++ b/tutorials/3d/introduction_to_3d.rst @@ -19,10 +19,9 @@ which are almost identical to their 2D counterparts. `Github repository `__ or the :ref:`Asset Library `. -In 3D, math is a little more complex than in 2D, so also checking the -:ref:`doc_vector_math` entry in the wiki (which was especially created for game -developers, not mathematicians or engineers) will help pave the way for you -to develop 3D games efficiently. +In 3D, math is a little more complex than in 2D. For an introduction to the +relevant math written for game developers, not mathemeticians or engineers, +check out :ref:`doc_vector_math` and :ref:`doc_using_transforms`. 3D workspace ~~~~~~~~~~~~ diff --git a/tutorials/3d/using_transforms.rst b/tutorials/3d/using_transforms.rst index c3e9f113638..1041109ae3e 100644 --- a/tutorials/3d/using_transforms.rst +++ b/tutorials/3d/using_transforms.rst @@ -201,6 +201,8 @@ To rotate relative to object space (the node's own transform), use the following // Rotate around the object's local X axis by 0.1 radians. RotateObjectLocal(new Vector3(1, 0, 0), 0.1f); +The axis should be defined in the local coordinate system of the object. For example, to rotate around the object's local X, Y, or Z axes, use ``Vector3.RIGHT`` for the X-axis, ``Vector3.UP`` for the Y-axis, and ``Vector3.FORWARD`` for the Z-axis. + Precision errors ================ diff --git a/tutorials/export/exporting_for_android.rst b/tutorials/export/exporting_for_android.rst index 2e90f36a2cd..2a95927f4b9 100644 --- a/tutorials/export/exporting_for_android.rst +++ b/tutorials/export/exporting_for_android.rst @@ -121,8 +121,11 @@ This way, your application will look great on all Android devices and versions. Exporting for Google Play Store ------------------------------- -Uploading an APK to Google's Play Store requires you to sign using a non-debug -keystore file; such file can be generated like this: +All new apps uploaded to Google Play after August 2021 must be an AAB (Android App Bundle) +file. + +Uploading an AAB or APK to Google's Play Store requires you to sign using a non-debug +keystore file; such a file can be generated like this: .. code-block:: shell @@ -130,7 +133,7 @@ keystore file; such file can be generated like this: This keystore and key are used to verify your developer identity, remember the password and keep it in a safe place! It is suggested to use only upper and lowercase letters and numbers. Special characters may cause errors. -Use Google's Android Developer guides to learn more about `APK signing `__. +Use Google's Android Developer guides to learn more about `app signing `__. Now fill in the following forms in your Android Export Presets: @@ -144,22 +147,17 @@ Don't forget to uncheck the **Export With Debug** checkbox while exporting. .. image:: img/export-with-debug-button.png -Optimizing the APK size ------------------------ - -By default, the APK will contain native libraries for both ARMv7 and ARMv8 -architectures. This increases its size significantly. To create a smaller APK, -uncheck either **Armeabi-v 7a** or **Arm 64 -v 8a** in your project's Android -export preset. This will create an APK that only contains a library for -a single architecture. Note that applications targeting ARMv7 can also run on -ARMv8 devices, but the opposite is not true. - -Since August 2019, Google Play requires all applications to be available in -64-bit form. This means you cannot upload an APK that contains *just* an ARMv7 -library. To solve this, you can upload several APKs to Google Play using its -`Multiple APK support `__. -Each APK should target a single architecture; creating an APK for ARMv7 -and ARMv8 is usually sufficient to cover most devices in use today. +Optimizing the file size +------------------------ + +If you're working with APKs and not AABs, by default, the APK will contain native +libraries for both ARMv7 and ARMv8 architectures. This increases its size significantly. +To create a smaller file, uncheck either **Armeabi-v 7a** or **Arm 64 -v 8a** in +your project's Android export preset. This will create an APK that only contains +a library for a single architecture. Note that applications targeting ARMv7 can +also run on ARMv8 devices, but the opposite is not true. The reason you don't do +this to save space with AABs is that Google automatically splits up the AAB on their +backend, so the user only downloads what they need. You can optimize the size further by compiling an Android export template with only the features you need. See :ref:`doc_optimizing_for_size` for more diff --git a/tutorials/export/exporting_for_macos.rst b/tutorials/export/exporting_for_macos.rst index ddc3c60a4e7..54240469a00 100644 --- a/tutorials/export/exporting_for_macos.rst +++ b/tutorials/export/exporting_for_macos.rst @@ -11,7 +11,7 @@ Exporting for macOS macOS apps exported with the official export templates are exported as a single "Universal 2" binary ``.app`` bundle, a folder with a specific structure which stores the executable, libraries and all the project files. This bundle can be exported as is, packed in a ZIP archive or DMG disk image (only supported when exporting from a computer running macOS). -`Universal binaries for macOS support both Intel x86_64 and ARM64 (Apple silicon, i.e. M1) architectures `__. +`Universal binaries for macOS support both Intel x86_64 and ARM64 (Apple Silicon) architectures `__. Requirements ------------ diff --git a/tutorials/inputs/handling_quit_requests.rst b/tutorials/inputs/handling_quit_requests.rst index fae7f3cde32..e470e5f3f55 100644 --- a/tutorials/inputs/handling_quit_requests.rst +++ b/tutorials/inputs/handling_quit_requests.rst @@ -60,8 +60,10 @@ at any time by either the user or the OS. A way to plan ahead for this possibility is to utilize ``NOTIFICATION_APPLICATION_PAUSED`` in order to perform any needed actions as the app is being suspended. +.. note:: On iOS, you only have approximately 5 seconds to finish a task started by this signal. If you go over this allotment, iOS will kill the app instead of pausing it. + On Android, pressing the Back button will exit the application if -**Application > Config > Quit** On Go Back is checked in the Project Settings +**Application > Config > Quit On Go Back** is checked in the Project Settings (which is the default). This will fire ``NOTIFICATION_WM_GO_BACK_REQUEST``. diff --git a/tutorials/io/img/groups.png b/tutorials/io/img/groups.png deleted file mode 100644 index 0658058aba9..00000000000 Binary files a/tutorials/io/img/groups.png and /dev/null differ diff --git a/tutorials/io/img/groups.webp b/tutorials/io/img/groups.webp new file mode 100644 index 00000000000..2805512f8fc Binary files /dev/null and b/tutorials/io/img/groups.webp differ diff --git a/tutorials/io/saving_games.rst b/tutorials/io/saving_games.rst index 27347278dcd..0776d93d3be 100644 --- a/tutorials/io/saving_games.rst +++ b/tutorials/io/saving_games.rst @@ -34,7 +34,7 @@ We will start by adding objects we wish to save to the "Persist" group. We can do this through either the GUI or script. Let's add the relevant nodes using the GUI: -.. image:: img/groups.png +.. image:: img/groups.webp Once this is done, when we need to save the game, we can get all objects to save them and then tell them all to save with this script: @@ -61,7 +61,7 @@ Serializing The next step is to serialize the data. This makes it much easier to read from and store to disk. In this case, we're assuming each member of group Persist is an instanced node and thus has a path. GDScript -has helper class :ref:`JSON` to convert between dictionary and string, +has the helper class :ref:`JSON` to convert between dictionary and string. Our node needs to contain a save function that returns this data. The save function will look like this: diff --git a/tutorials/math/matrices_and_transforms.rst b/tutorials/math/matrices_and_transforms.rst index 05f4c0dd879..7443dd012aa 100644 --- a/tutorials/math/matrices_and_transforms.rst +++ b/tutorials/math/matrices_and_transforms.rst @@ -352,7 +352,7 @@ from X*1 + Y*-1, which is (1, 0) - (1, 1), or (1 - 1, 0 - 1), or (0, -1). This matches up with our observation of where the top-right corner of the image is. -Hopefully you now fully understand the how a transformation matrix affects +Hopefully you now fully understand how a transformation matrix affects the object, and the relationship between the basis vectors and how the object's "UV" or "intra-coordinates" have their world position changed. diff --git a/tutorials/math/random_number_generation.rst b/tutorials/math/random_number_generation.rst index b9abb724979..a12f43eb3a1 100644 --- a/tutorials/math/random_number_generation.rst +++ b/tutorials/math/random_number_generation.rst @@ -33,6 +33,9 @@ Global scope methods are easier to set up, but they don't offer as much control. RandomNumberGenerator requires more code to use, but allows creating multiple instances, each with their own seed and state. +This tutorial uses global scope methods, except when the method only exists in +the RandomNumberGenerator class. + The randomize() method ---------------------- @@ -81,6 +84,7 @@ across runs: public override void _Ready() { GD.Seed(12345); + // To use a string as a seed, you can hash it to a number. GD.Seed("Hello world".Hash()); } @@ -105,9 +109,9 @@ Let's look at some of the most commonly used functions and methods to generate random numbers in Godot. The function :ref:`randi() ` returns a random -number between 0 and 2^32-1. Since the maximum value is huge, you most likely -want to use the modulo operator (``%``) to bound the result between 0 and the -denominator: +number between ``0`` and ``2^32 - 1``. Since the maximum value is huge, you most +likely want to use the modulo operator (``%``) to bound the result between 0 and +the denominator: .. tabs:: .. code-tab:: gdscript GDScript @@ -145,7 +149,7 @@ varying by the deviation (1.0 by default): .. code-tab:: csharp - // Prints a normally distributed floating-point number between 0.0 and 1.0. + // Prints a random floating-point number from a normal distribution with a mean of 0.0 and deviation of 1.0. GD.Print(GD.Randfn()); :ref:`randf_range() ` takes two arguments @@ -174,7 +178,7 @@ and ``to``, and returns a random integer between ``from`` and ``to``: .. code-tab:: csharp - // Prints a random integer number between -10 and 10. + // Prints a random integer between -10 and 10. GD.Print(GD.RandiRange(-10, 10)); Get a random array element @@ -255,7 +259,7 @@ prevent repetition: func get_fruit(): var random_fruit = _fruits[randi() % _fruits.size()] while random_fruit == _last_fruit: - # The last fruit was picked, try again until we get a different fruit. + # The last fruit was picked. Try again until we get a different fruit. random_fruit = _fruits[randi() % _fruits.size()] # Note: if the random element to pick is passed by reference, @@ -286,7 +290,7 @@ prevent repetition: string randomFruit = _fruits[GD.Randi() % _fruits.Length]; while (randomFruit == _lastFruit) { - // The last fruit was picked, try again until we get a different fruit. + // The last fruit was picked. Try again until we get a different fruit. randomFruit = _fruits[GD.Randi() % _fruits.Length]; } @@ -379,7 +383,7 @@ floating-point number between 0.0 and 1.0. We can use this to create a } else if (randomFloat < 0.95f) { - // 15% chance of being returned + // 15% chance of being returned. return "Uncommon"; } else @@ -389,6 +393,44 @@ floating-point number between 0.0 and 1.0. We can use this to create a } } +You can also get a weighted random *index* using the +:ref:`rand_weighted() ` method +on a RandomNumberGenerator instance. This returns a random integer +between 0 and the size of the array that is passed as a parameter. Each value in the +array is a floating-point number that represents the *relative* likelihood that it +will be returned as an index. A higher value means the value is more likely to be +returned as an index, while a value of ``0`` means it will never be returned as an index. + +For example, if ``[0.5, 1, 1, 2]`` is passed as a parameter, then the method is twice +as likely to return ``3`` (the index of the value ``2``) and twice as unlikely to return +``0`` (the index of the value ``0.5``) compared to the indices ``1`` and ``2``. + +Since the returned value matches the array's size, it can be used as an index to +get a value from another array as follows: + +.. tabs:: + .. code-tab:: gdscript GDScript + + # Prints a random element using the weighted index that is returned by `rand_weighted()`. + # Here, "apple" will be returned twice as rarely as "orange" and "pear". + # "banana" is twice as common as "orange" and "pear", and four times as common as "apple". + var fruits = ["apple", "orange", "pear", "banana"] + var probabilities = [0.5, 1, 1, 2]; + + var random = RandomNumberGenerator.new() + print(fruits[random.rand_weighted(probabilities)]) + + .. code-tab:: csharp + + // Prints a random element using the weighted index that is returned by `RandWeighted()`. + // Here, "apple" will be returned twice as rarely as "orange" and "pear". + // "banana" is twice as common as "orange" and "pear", and four times as common as "apple". + string[] fruits = { "apple", "orange", "pear", "banana" }; + float[] probabilities = { 0.5, 1, 1, 2 }; + + var random = new RandomNumberGenerator(); + GD.Print(fruits[random.RandWeighted(probabilities)]); + .. _doc_random_number_generation_shuffle_bags: "Better" randomness using shuffle bags diff --git a/tutorials/math/vectors_advanced.rst b/tutorials/math/vectors_advanced.rst index 1d0b80ed302..58372106721 100644 --- a/tutorials/math/vectors_advanced.rst +++ b/tutorials/math/vectors_advanced.rst @@ -23,7 +23,7 @@ because of its usage. (Just like we call (0,0) the Origin!). The plane passes by the origin and the surface of it is perpendicular to the unit vector (or *normal*). The -side towards the vector points to is the positive half-space, while the +side the vector points to is the positive half-space, while the other side is the negative half-space. In 3D this is exactly the same, except that the plane is an infinite surface (imagine an infinite, flat sheet of paper that you can orient and is pinned to the origin) instead diff --git a/tutorials/performance/using_multimesh.rst b/tutorials/performance/using_multimesh.rst index 9e9d355ad16..b48e8cd0d49 100644 --- a/tutorials/performance/using_multimesh.rst +++ b/tutorials/performance/using_multimesh.rst @@ -17,8 +17,7 @@ MultiMeshes ----------- A :ref:`MultiMesh` is a single draw primitive that can draw up to millions -of objects in one go. It's extremely efficient because it uses the GPU hardware to do this -(in OpenGL ES 2.0, it's less efficient because there is no hardware support for it, though). +of objects in one go. It's extremely efficient because it uses the GPU hardware to do this. The only drawback is that there is no *screen* or *frustum* culling possible for individual instances. This means, that millions of objects will be *always* or *never* drawn, depending on the visibility diff --git a/tutorials/scripting/c_sharp/c_sharp_basics.rst b/tutorials/scripting/c_sharp/c_sharp_basics.rst index 224ec48a393..d160c74f539 100644 --- a/tutorials/scripting/c_sharp/c_sharp_basics.rst +++ b/tutorials/scripting/c_sharp/c_sharp_basics.rst @@ -90,7 +90,7 @@ In Godot's **Editor → Editor Settings** menu: In Rider: - Set **MSBuild version** to **.NET Core**. -- Install the **Godot support** plugin. +- If you are using a Rider version below 2024.2, install the **Godot support** plugin. This functionality is now built into Rider. Visual Studio Code ~~~~~~~~~~~~~~~~~~ @@ -357,11 +357,10 @@ You can read more about this error on the `C# language reference `_, -the performance of C# in Godot — while generally in the same order of magnitude -— is roughly **~4×** that of GDScript in some naive cases. C++ is still -a little faster; the specifics are going to vary according to your use case. -GDScript is likely fast enough for most general scripting workloads. +.. seealso:: + + For a performance comparison of the languages Godot supports, + see :ref:`doc_faq_which_programming_language_is_fastest`. Most properties of Godot C# objects that are based on ``GodotObject`` (e.g. any ``Node`` like ``Control`` or ``Node3D`` like ``Camera3D``) require native (interop) calls as they talk to diff --git a/tutorials/scripting/cross_language_scripting.rst b/tutorials/scripting/cross_language_scripting.rst index 8b193e1b86c..fd9f5bb5537 100644 --- a/tutorials/scripting/cross_language_scripting.rst +++ b/tutorials/scripting/cross_language_scripting.rst @@ -16,7 +16,11 @@ The following two scripts will be used as references throughout this page. extends Node - var my_field: String = "foo" + var my_property: String = "my gdscript value": + get: + return my_property + set(value): + my_property = value signal my_signal @@ -40,7 +44,7 @@ The following two scripts will be used as references throughout this page. public partial class MyCSharpNode : Node { - public string myField = "bar"; + public string MyProperty { get; set; } = "my c# value"; [Signal] public delegate void MySignalEventHandler(); @@ -86,8 +90,8 @@ with :ref:`new() `. .. code-block:: gdscript - var my_csharp_script = load("res://Path/To/MyCSharpNode.cs") - var my_csharp_node = my_csharp_script.new() + var MyCSharpScript = load("res://Path/To/MyCSharpNode.cs") + var my_csharp_node = MyCSharpScript.new() .. warning:: @@ -112,8 +116,8 @@ be instantiated with :ref:`GDScript.New() `. .. code-block:: csharp - GDScript MyGDScript = GD.Load("res://path/to/my_gd_script.gd"); - GodotObject myGDScriptNode = (GodotObject)MyGDScript.New(); // This is a GodotObject. + var myGDScript = GD.Load("res://path/to/my_gd_script.gd"); + var myGDScriptNode = (GodotObject)myGDScript.New(); // This is a GodotObject. Here we are using an :ref:`class_Object`, but you can use type conversion like explained in :ref:`doc_c_sharp_features_type_conversion_and_casting`. @@ -129,22 +133,26 @@ anything to worry about. .. code-block:: gdscript - print(my_csharp_node.myField) # bar - my_csharp_node.myField = "BAR" - print(my_csharp_node.myField) # BAR + # Output: "my c# value". + print(my_csharp_node.MyProperty) + my_csharp_node.MyProperty = "MY C# VALUE" + # Output: "MY C# VALUE". + print(my_csharp_node.MyProperty) Accessing GDScript fields from C# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ As C# is statically typed, accessing GDScript from C# is a bit more -convoluted, you will have to use :ref:`GodotObject.Get() ` +convoluted. You will have to use :ref:`GodotObject.Get() ` and :ref:`GodotObject.Set() `. The first argument is the name of the field you want to access. .. code-block:: csharp - GD.Print(myGDScriptNode.Get("my_field")); // foo - myGDScriptNode.Set("my_field", "FOO"); - GD.Print(myGDScriptNode.Get("my_field")); // FOO + // Output: "my gdscript value". + GD.Print(myGDScriptNode.Get("my_property")); + myGDScriptNode.Set("my_property", "MY GDSCRIPT VALUE"); + // Output: "MY GDSCRIPT VALUE". + GD.Print(myGDScriptNode.Get("my_property")); Keep in mind that when setting a field value you should only use types the GDScript side knows about. @@ -163,13 +171,18 @@ If that's impossible, you'll see the following error: ``Invalid call. Nonexisten .. code-block:: gdscript - my_csharp_node.PrintNodeName(self) # myGDScriptNode - # my_csharp_node.PrintNodeName() # This line will fail. + # Output: "my_gd_script_node" (or name of node where this code is placed). + my_csharp_node.PrintNodeName(self) + # This line will fail. + # my_csharp_node.PrintNodeName() - my_csharp_node.PrintNTimes("Hello there!", 2) # Hello there! Hello there! + # Outputs "Hello there!" twice, once per line. + my_csharp_node.PrintNTimes("Hello there!", 2) - my_csharp_node.PrintArray(["a", "b", "c"]) # a, b, c - my_csharp_node.PrintArray([1, 2, 3]) # 1, 2, 3 + # Output: "a", "b", "c" (one per line). + my_csharp_node.PrintArray(["a", "b", "c"]) + # Output: "1", "2", "3" (one per line). + my_csharp_node.PrintArray([1, 2, 3]) Calling GDScript methods from C# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -181,22 +194,21 @@ to said method. .. code-block:: csharp - myGDScriptNode.Call("print_node_name", this); // my_csharp_node - // myGDScriptNode.Call("print_node_name"); // This line will fail silently and won't error out. + // Output: "MyCSharpNode" (or name of node where this code is placed). + myGDScriptNode.Call("print_node_name", this); + // This line will fail silently and won't error out. + // myGDScriptNode.Call("print_node_name"); - myGDScriptNode.Call("print_n_times", "Hello there!", 2); // Hello there! Hello there! + // Outputs "Hello there!" twice, once per line. + myGDScriptNode.Call("print_n_times", "Hello there!", 2); string[] arr = new string[] { "a", "b", "c" }; - myGDScriptNode.Call("print_array", arr); // a, b, c - myGDScriptNode.Call("print_array", new int[] { 1, 2, 3 }); // 1, 2, 3 - // Note how the type of each array entry does not matter as long as it can be handled by the marshaller. - -.. warning:: - - As you can see, if the first argument of the called method is an array, - you'll need to cast it as ``object``. - Otherwise, each element of your array will be treated as a single argument - and the function signature won't match. + // Output: "a", "b", "c" (one per line). + myGDScriptNode.Call("print_array", arr); + // Output: "1", "2", "3" (one per line). + myGDScriptNode.Call("print_array", new int[] { 1, 2, 3 }); + // Note how the type of each array entry does not matter + // as long as it can be handled by the marshaller. .. _connecting_to_signals_cross_language: diff --git a/tutorials/scripting/debug/overview_of_debugging_tools.rst b/tutorials/scripting/debug/overview_of_debugging_tools.rst index aef754601d6..e0e13e01b8e 100644 --- a/tutorials/scripting/debug/overview_of_debugging_tools.rst +++ b/tutorials/scripting/debug/overview_of_debugging_tools.rst @@ -223,7 +223,7 @@ The **Break** button causes a break in the script like a breakpoint would. a function if possible. Otherwise, it does the same thing as **Step Over**. The **Debug with External Editor** option lets you debug your game with an external editor. -This option is also accessible in **Editor Settings > Debugger**. +You can set a shortcut for it in **Editor Settings > Shortcuts > Debugger**. When the debugger breaks on a breakpoint, a green triangle arrow is visible in the script editor's gutter. This arrow indicates the line of code the debugger diff --git a/tutorials/scripting/gdscript/gdscript_basics.rst b/tutorials/scripting/gdscript/gdscript_basics.rst index 6e008105e91..bd6ca5d9fc7 100644 --- a/tutorials/scripting/gdscript/gdscript_basics.rst +++ b/tutorials/scripting/gdscript/gdscript_basics.rst @@ -565,6 +565,21 @@ considered a comment. The list of highlighted keywords and their colors can be changed in the **Text Editor > Theme > Comment Markers** section of the Editor Settings. +Use two hash symbols (``##``) instead of one (``#``) to add a *documentation +comment*, which will appear in the script documentation and in the inspector +description of an exported variable. Documentation comments must be placed +directly *above* a documentable item (such as a member variable), or at the top +of a file. Dedicated formatting options are also available. See +:ref:`doc_gdscript_documentation_comments` for details. + + +:: + ## This comment will appear in the script documentation. + var value + + ## This comment will appear in the inspector tooltip, and in the documentation. + @export var exported_value + Code regions ------------ @@ -878,12 +893,26 @@ native or user class, or enum. Nested array types (like ``Array[Array[int]]``) a Packed arrays ^^^^^^^^^^^^^ -GDScript arrays are allocated linearly in memory for speed. -Large arrays (more than tens of thousands of elements) may however cause -memory fragmentation. If this is a concern, special types of -arrays are available. These only accept a single data type. They avoid memory -fragmentation and use less memory, but are atomic and tend to run slower than generic -arrays. They are therefore only recommended to use for large data sets: +PackedArrays are generally faster to iterate on and modify compared to a typed +Array of the same type (e.g. PackedInt64Array versus Array[int]) and consume +less memory. In the worst case, they are expected to be as fast as an untyped +Array. Conversely, non-Packed Arrays (typed or not) have extra convenience +methods such as :ref:`Array.map ` that PackedArrays +lack. Consult the :ref:`class reference ` for details +on the methods available. Typed Arrays are generally faster to iterate on and +modify than untyped Arrays. + +While all Arrays can cause memory fragmentation when they become large enough, +if memory usage and performance (iteration and modification speed) is a concern +and the type of data you're storing is compatible with one of the ``Packed`` +Array types, then using those may yield improvements. However, if you do not +have such concerns (e.g. the size of your array does not reach the tens of +thousands of elements) it is likely more helpful to use regular or typed +Arrays, as they provide convenience methods that can make your code easier to +write and maintain (and potentially faster if your data requires such +operations a lot). If the data you will store is of a known type (including +your own defined classes), prefer to use a typed Array as it may yield better +performance in iteration and modification compared to an untyped Array. - :ref:`PackedByteArray `: An array of bytes (integers from 0 to 255). - :ref:`PackedInt32Array `: An array of 32-bit integers. @@ -1006,7 +1035,7 @@ it will raise an error. Valid types are: - Built-in types (Array, Vector2, int, String, etc.). -- Engine classes (Node, Resource, Reference, etc.). +- Engine classes (Node, Resource, RefCounted, etc.). - Constant names if they contain a script resource (``MyScript`` if you declared ``const MyScript = preload("res://my_script.gd")``). - Other classes in the same script, respecting scope (``InnerClass.NestedClass`` if you declared ``class NestedClass`` inside the ``class InnerClass`` in the same scope). - Script classes declared with the ``class_name`` keyword. diff --git a/tutorials/scripting/gdscript/gdscript_styleguide.rst b/tutorials/scripting/gdscript/gdscript_styleguide.rst index 89c4eb4dc4c..9dd84ad05da 100644 --- a/tutorials/scripting/gdscript/gdscript_styleguide.rst +++ b/tutorials/scripting/gdscript/gdscript_styleguide.rst @@ -620,7 +620,29 @@ Naming conventions These naming conventions follow the Godot Engine style. Breaking these will make your code clash with the built-in naming conventions, leading to inconsistent -code. +code. As a summary table: + ++---------------+----------------+----------------------------------------------------+ +| Type | Convention | Example | ++===============+================+====================================================+ +| File names | snake_case | ``yaml_parser.gd`` | ++---------------+----------------+----------------------------------------------------+ +| Class names | PascalCase | ``class_name YAMLParser`` | ++---------------+----------------+----------------------------------------------------+ +| Node names | PascalCase | ``Camera3D``, ``Player`` | ++---------------+----------------+----------------------------------------------------+ +| Functions | snake_case | ``func load_level():`` | ++---------------+----------------+----------------------------------------------------+ +| Variables | snake_case | ``var particle_effect`` | ++---------------+----------------+----------------------------------------------------+ +| Signals | snake_case | ``signal door_opened`` | ++---------------+----------------+----------------------------------------------------+ +| Constants | CONSTANT_CASE | ``const MAX_SPEED = 200`` | ++---------------+----------------+----------------------------------------------------+ +| Enum names | PascalCase | ``enum Element`` | ++---------------+----------------+----------------------------------------------------+ +| Enum members | CONSTANT_CASE | ``{EARTH, WATER, AIR, FIRE}`` | ++---------------+----------------+----------------------------------------------------+ File names ~~~~~~~~~~ diff --git a/tutorials/ui/gui_containers.rst b/tutorials/ui/gui_containers.rst index f5aac4ab123..35ec1eb02e0 100644 --- a/tutorials/ui/gui_containers.rst +++ b/tutorials/ui/gui_containers.rst @@ -78,7 +78,7 @@ Arranges child controls vertically or horizontally (via :ref:`HBoxContainer ` control, as styleboxes are used by many controls for their backgrounds and overlays. + Different controls will apply StyleBoxes in a different manner. Most notably, + ``focus`` styleboxes are drawn as an *overlay* to other styleboxes (such as + ``normal`` or ``pressed``) to allow the base stylebox to remain visible. + This means the focus stylebox should be designed as an outline or translucent + box, so that its background can remain visible. + Theme types ~~~~~~~~~~~