Explorar o código

Merge branch 'master' into 3.1, excluding 3.2+ specific changes

I went through the diff to try to ensure that no 3.2+ specific changes
are being backported to the stable branch. I might have missed some
things though.
Rémi Verschelde %!s(int64=6) %!d(string=hai) anos
pai
achega
fa784d4ce1
Modificáronse 100 ficheiros con 1403 adicións e 740 borrados
  1. 26 3
      .gitignore
  2. 3 1
      README.md
  3. 22 1
      about/docs_changelog.rst
  4. 7 7
      about/faq.rst
  5. 11 0
      about/introduction.rst
  6. 4 3
      community/channels.rst
  7. 1 1
      community/contributing/code_style_guidelines.rst
  8. 13 0
      community/contributing/documentation_guidelines.rst
  9. 6 2
      community/contributing/updating_the_class_reference.rst
  10. 28 5
      community/tutorials.rst
  11. 1 1
      development/cpp/custom_modules_in_cpp.rst
  12. 1 1
      development/file_formats/tscn.rst
  13. 8 6
      getting_started/editor/external_editor.rst
  14. 16 16
      getting_started/scripting/gdscript/gdscript_advanced.rst
  15. 1 1
      getting_started/scripting/gdscript/gdscript_basics.rst
  16. 1 1
      getting_started/scripting/gdscript/static_typing.rst
  17. 3 3
      getting_started/step_by_step/animations.rst
  18. 1 1
      getting_started/step_by_step/exporting.rst
  19. BIN=BIN
      getting_started/step_by_step/files/dodge_assets.zip
  20. 9 16
      getting_started/step_by_step/filesystem.rst
  21. 1 1
      getting_started/step_by_step/instancing.rst
  22. 1 1
      getting_started/step_by_step/instancing_continued.rst
  23. 1 1
      getting_started/step_by_step/resources.rst
  24. 12 20
      getting_started/step_by_step/scene_tree.rst
  25. 7 0
      getting_started/step_by_step/scenes_and_nodes.rst
  26. 16 11
      getting_started/step_by_step/scripting_continued.rst
  27. 10 125
      getting_started/step_by_step/signals.rst
  28. 2 2
      getting_started/step_by_step/singletons_autoload.rst
  29. 22 19
      getting_started/step_by_step/ui_introduction_to_the_ui_system.rst
  30. 35 2
      getting_started/step_by_step/your_first_game.rst
  31. 3 0
      getting_started/workflow/assets/escn_exporter/skeleton.rst
  32. 3 0
      getting_started/workflow/assets/importing_scenes.rst
  33. 1 1
      getting_started/workflow/best_practices/data_preferences.rst
  34. 17 17
      getting_started/workflow/best_practices/godot_interfaces.rst
  35. 4 4
      getting_started/workflow/best_practices/logic_preferences.rst
  36. 2 0
      index.rst
  37. 8 8
      tutorials/2d/2d_movement.rst
  38. 155 0
      tutorials/2d/2d_sprite_animation.rst
  39. 18 29
      tutorials/2d/canvas_layers.rst
  40. 2 2
      tutorials/2d/custom_drawing_in_2d.rst
  41. BIN=BIN
      tutorials/2d/files/run_animation.zip
  42. BIN=BIN
      tutorials/2d/img/2d_animation_full_animation.png
  43. BIN=BIN
      tutorials/2d/img/2d_animation_new_animation.png
  44. BIN=BIN
      tutorials/2d/img/2d_animation_new_spriteframes.png
  45. BIN=BIN
      tutorials/2d/img/2d_animation_new_track.png
  46. BIN=BIN
      tutorials/2d/img/2d_animation_player-run.png
  47. BIN=BIN
      tutorials/2d/img/2d_animation_run_preview.gif
  48. BIN=BIN
      tutorials/2d/img/2d_animation_running.gif
  49. BIN=BIN
      tutorials/2d/img/2d_animation_setframes.png
  50. BIN=BIN
      tutorials/2d/img/2d_animation_spriteframes.png
  51. BIN=BIN
      tutorials/2d/img/2d_animation_spriteframes_done.png
  52. BIN=BIN
      tutorials/2d/img/2d_animation_tree1.png
  53. BIN=BIN
      tutorials/2d/img/2d_animation_tree2.png
  54. BIN=BIN
      tutorials/2d/img/tilemap_add_tile.png
  55. BIN=BIN
      tutorials/2d/img/tilemap_add_tileset.png
  56. BIN=BIN
      tutorials/2d/img/tilemap_draw.png
  57. BIN=BIN
      tutorials/2d/img/tilemap_menu.png
  58. BIN=BIN
      tutorials/2d/img/tilemap_mode.png
  59. BIN=BIN
      tutorials/2d/img/tilemap_size.png
  60. BIN=BIN
      tutorials/2d/img/tilemap_tool.png
  61. BIN=BIN
      tutorials/2d/img/tileset_add_collision.png
  62. BIN=BIN
      tutorials/2d/img/tileset_atlas.png
  63. BIN=BIN
      tutorials/2d/img/tileset_draw_atlas.png
  64. BIN=BIN
      tutorials/2d/img/tileset_snap.png
  65. BIN=BIN
      tutorials/2d/img/tilesheet.png
  66. 1 0
      tutorials/2d/index.rst
  67. 111 127
      tutorials/2d/using_tilemaps.rst
  68. BIN=BIN
      tutorials/3d/files/gridmap_demo.zip
  69. BIN=BIN
      tutorials/3d/fps_tutorial/img/AnimationPlayerAddPoint.png
  70. BIN=BIN
      tutorials/3d/fps_tutorial/img/AnimationPlayerAddTrack.png
  71. BIN=BIN
      tutorials/3d/fps_tutorial/img/AnimationPlayerCallFuncTrack.png
  72. BIN=BIN
      tutorials/3d/fps_tutorial/img/AnimationPlayerEditPoints.png
  73. BIN=BIN
      tutorials/3d/fps_tutorial/img/AnimationPlayerInsertKey.png
  74. 214 8
      tutorials/3d/fps_tutorial/part_one.rst
  75. 17 37
      tutorials/3d/fps_tutorial/part_two.rst
  76. BIN=BIN
      tutorials/3d/img/multimesh_scene_tree.png
  77. BIN=BIN
      tutorials/3d/img/multimesh_toolbar.png
  78. 2 2
      tutorials/3d/using_multi_mesh_instance.rst
  79. 2 2
      tutorials/3d/using_transforms.rst
  80. 9 9
      tutorials/3d/vertex_animation/animating_thousands_of_fish.rst
  81. 4 4
      tutorials/3d/vertex_animation/controlling_thousands_of_fish.rst
  82. 166 165
      tutorials/animation/cutout_animation.rst
  83. 53 57
      tutorials/audio/audio_buses.rst
  84. 15 17
      tutorials/audio/audio_streams.rst
  85. BIN=BIN
      tutorials/audio/img/audio_buses1.png
  86. BIN=BIN
      tutorials/audio/img/audio_buses2.png
  87. BIN=BIN
      tutorials/audio/img/audio_buses3.png
  88. BIN=BIN
      tutorials/audio/img/audio_buses4.png
  89. BIN=BIN
      tutorials/audio/img/audio_buses5.png
  90. 2 0
      tutorials/content/index.rst
  91. 144 0
      tutorials/content/procedural_geometry.rst
  92. 181 0
      tutorials/gui/gui_containers.rst
  93. BIN=BIN
      tutorials/gui/img/container_example.gif
  94. BIN=BIN
      tutorials/gui/img/container_size_flags.png
  95. BIN=BIN
      tutorials/gui/img/containers_box.png
  96. BIN=BIN
      tutorials/gui/img/containers_center.png
  97. BIN=BIN
      tutorials/gui/img/containers_center_pan.gif
  98. BIN=BIN
      tutorials/gui/img/containers_grid.png
  99. BIN=BIN
      tutorials/gui/img/containers_margin.png
  100. BIN=BIN
      tutorials/gui/img/containers_margin_constants.png

+ 26 - 3
.gitignore

@@ -1,15 +1,38 @@
 _build/
 env/
-extensions/__pycache__/
 __pycache__
 *.pyc
 *~
 .directory
+.vs/
 .vscode/
 *.mo
 
+# Vim temp files
+*.swo
+*.swp
+
+# Geany/geany-plugins files
+*.geany
+.geanyprj
+
 # Finder (macOS) makes these automatically.
 .DS_Store
+__MACOSX
+
+# Windows image file caches
+[Tt]humbs.db
+[Tt]humbs.db:encryptable
+ehthumbs.db
+ehthumbs_vista.db
+
+# Windows shortcuts
+*.lnk
+
+# Windows folder config file
+[Dd]esktop.ini
 
-# And Windows keeps creating these.
-Thumbs.db
+# Windows Recycle Bin used on file shares
+$RECYCLE.BIN/
+logo.h
+*.autosave

+ 3 - 1
README.md

@@ -12,7 +12,9 @@ Though arguably less convenient to edit than a wiki, this git repository is mean
 
 ### Editing existing pages
 
-To edit an existing page, locate its .rst source file and open it in your favorite text editor. You can then commit the changes, push them to your fork and make a pull request. **Note that the pages in `classes/` should not be edited here, they are automatically generated from Godot's [XML class references](https://github.com/godotengine/godot/tree/master/doc/classes).**
+To edit an existing page, locate its .rst source file and open it in your favorite text editor. You can then commit the changes, push them to your fork and make a pull request.
+**Note that the pages in `classes/` should not be edited here, they are automatically generated from Godot's [XML class references](https://github.com/godotengine/godot/tree/master/doc/classes).**
+See [Contribute to the Class Reference](https://docs.godotengine.org/en/latest/community/contributing/updating_the_class_reference.html) for details.
 
 ### Adding new pages
 

+ 22 - 1
about/docs_changelog.rst

@@ -63,6 +63,11 @@ Animation
 - :ref:`2D skeletons <doc_2d_skeletons>`
 - :ref:`AnimationTree <doc_animation_tree>`
 
+GUI
+^^^
+
+- :ref:`Containers <doc_gui_containers>`
+
 Viewports
 ^^^^^^^^^
 
@@ -74,9 +79,14 @@ Shading
 
 - :ref:`Intro to shaders: 2D and 3D water (7 video tutorials) <doc_intro_to_shaders_water_workshop>`
 - :ref:`Migrating to Godot’s shading language <doc_migrating_to_godot_shader_language>`
-- :ref:`Vertex displacement with shaders <doc_vertex_displacement_with_shaders>`
 - :ref:`Advanced post-processing <doc_advanced_postprocessing>`
 
+Your First Shader Series:
+  - :ref:`What are shaders? <doc_what_are_shaders>`
+  - :ref:`Your first CanvasItem shader <doc_your_first_canvasitem_shader>`
+  - :ref:`Your first Spatial shader <doc_your_first_spatial_shader>`
+  - :ref:`Your first Spatial shader: Part 2 <doc_your_second_spatial_shader>`
+
 Shading Reference:
   - :ref:`Shaders <doc_shaders>`
   - :ref:`Shading language <doc_shading_language>`
@@ -99,6 +109,12 @@ Multi-threading
 
 - :ref:`Thread safe APIs <doc_thread_safe_apis>`
 
+Optimization
+^^^^^^^^^^^^
+
+- :ref:`Using MultiMesh <doc_using_multimesh>`
+- :ref:`Using servers <doc_using_servers>`
+
 Miscellaneous
 ^^^^^^^^^^^^^
 
@@ -107,6 +123,11 @@ Miscellaneous
 - :ref:`Change scenes manually <doc_change_scenes_manually>`
 - :ref:`Differences between GLES2 and GLES3 <doc_gles2_gles3_differences>`
 
+Legal
+^^^^^
+
+- :ref:`Complying with Licenses <doc_complying_with_licenses>`
+
 Compiling
 ^^^^^^^^^
 

+ 7 - 7
about/faq.rst

@@ -10,7 +10,7 @@ Godot is `Free and Open-Source Software <https://en.wikipedia.org/wiki/Free_and_
 
 In short:
 
-* You are free to download and use Godot for any purpose, personal, non-profit, commercial, or otherwise;
+* You are free to download and use Godot for any purpose, personal, non-profit, commercial, or otherwise.
 * You are free to modify, distribute, redistribute, and remix Godot to your heart's content, for any reason, both non-commercially and commercially.
 
 All the contents of this accompanying documentation are published under
@@ -153,7 +153,7 @@ As of Godot 3.0, glTF is supported.
 FBX SDK has a `restrictive license <https://www.blender.org/bf/Autodesk_FBX_License.rtf>`_,
 that is incompatible with the `open license <https://opensource.org/licenses/MIT>`_
 provided by Godot. That being said, FBX support could still be provided by third parties
-as a plugin. (See Plugins question above.)
+as a plugin. (See Plugins question below.)
 
 Will [insert closed SDK such as FMOD, GameWorks, etc.] be supported in Godot?
 -----------------------------------------------------------------------------
@@ -168,7 +168,7 @@ anyone else interested in adding those libraries as a module and shipping your
 game with them--as either open- or closed-source.
 
 To see how support for your SDK of choice could still be provided, look at the
-Plugins question above.
+Plugins question below.
 
 If you know of a third-party SDK that is not supported by Godot but that offers
 free and open-source integration, consider starting the integration work yourself.
@@ -198,14 +198,14 @@ This is mostly needed for 2D, as in 3D it's just a matter of Camera XFov or YFov
    resolution, the larger your assets, the more memory they will take
    and the longer the time it will take for loading.
 
-2. Use the stretch options in Godot, 2D stretching with keeping aspect
-   works best. Check the :ref:`doc_multiple_resolutions` tutorial
+2. Use the stretch options in Godot; 2D stretching while keeping aspect
+   ratios works best. Check the :ref:`doc_multiple_resolutions` tutorial
    on how to achieve this.
 
 3. Determine a minimum resolution and then decide if you want your game
    to stretch vertically or horizontally for different aspect ratios, or
-   whether there is a minimum one and you want black bars to appear
-   instead. This is also explained in the previous step.
+   if there is one aspect ratio and you want black bars to appear
+   instead. This is also explained in :ref:`doc_multiple_resolutions`.
 
 4. For user interfaces, use the :ref:`anchoring <doc_size_and_anchors>`
    to determine where controls should stay and move. If UIs are more

+ 11 - 0
about/introduction.rst

@@ -17,6 +17,17 @@ 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.
 
+Before you start
+----------------
+
+The :ref:`Tutorials and resources <doc_community_tutorials>` page lists
+video tutorials contributed by the community. If you prefer video to text,
+those may be worth a look.
+
+In case you have trouble with one of the tutorials or your project,
+you can find help on the various :ref:`Community channels <doc_community_channels>`,
+especially the Godot Discord community, Q&A, and IRC.
+
 About Godot Engine
 ------------------
 

+ 4 - 3
community/channels.rst

@@ -7,7 +7,7 @@ So, where is the Godot community and where can you ask questions and get help?
 
 Note that some of these channels are run and moderated by members of the Godot community or third parties.
 
-A brief overview over these channels is also available on the `website <https://godotengine.org/community>`_.
+A brief overview over these and other channels is also available on the `Godot website <https://godotengine.org/community>`_.
 
 Q&A
 ---
@@ -20,8 +20,9 @@ IRC on Freenode
 - `General: #godotengine <http://webchat.freenode.net/?channels=#godotengine>`_
 - `Engine development: #godotengine-devel <http://webchat.freenode.net/?channels=#godotengine-devel>`_
 - `Documentation: #godotengine-doc <http://webchat.freenode.net/?channels=#godotengine-doc>`_
+- `Pull request meetings: #godotengine-meeting <http://webchat.freenode.net/?channels=#godotengine-meeting>`_
 - `GDNative: #godotengine-gdnative <http://webchat.freenode.net/?channels=#godotengine-gdnative>`_
-- `Webseite/PR: #godotengine-atelier <http://webchat.freenode.net/?channels=#godotengine-atelier>`_
+- `Website and public relations: #godotengine-atelier <http://webchat.freenode.net/?channels=#godotengine-atelier>`_
 - `IRC logs <https://godot.eska.me/irc-logs/>`_
 
 Other chats
@@ -43,4 +44,4 @@ Social networks
 Forum
 -----
 
-- `Forum (godotdevelopers.org) <https://godotdevelopers.org/forum>`_
+- `Forum (godotforums.org) <https://godotforums.org/>`_

+ 1 - 1
community/contributing/code_style_guidelines.rst

@@ -52,7 +52,7 @@ Using clang-format locally
 ~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 First of all, you will need to install clang-format. As of now, you need to use
-**clang-format 6.x** to be compatible with Godot's format. Later versions might
+**clang-format 8.x** to be compatible with Godot's format. Later versions might
 be suitable, but previous versions had bugs that will cause formatting changes
 to the current code base.
 

+ 13 - 0
community/contributing/documentation_guidelines.rst

@@ -35,6 +35,19 @@ reference documentation about the reStructuredText markup language.
              main repository. These files are then later used to generate the
              in-editor documentation as well as the API reference of the
              online docs. Read more here: :ref:`doc_updating_the_class_reference`.
+             
+The 'Edit on Github' link
+-------------------------
+
+If you're reading documentation on ``docs.godotengine.org`` you'll see an 'Edit on GitHub' hyperlink at the top right of the page. Once you've created a GitHub account you can propose changes to a page you're reading as follows:
+
+1. Copy the URL that the GitHub link points to. Part of the URL refers to a version name such as '3.1' or 'latest'. Swap this part for the word 'master' so that the result looks something like this: ``https://github.com/godotengine/godot-docs/blob/master/community/contributing/docs_writing_guidelines.rst``
+2. Load that URL in your browser.
+3. On the GitHub page you're taken to, click the pencil icon. It has the tooltip "Edit the file in a fork of this project".
+4. Complete all the edits you want to make for that page.
+5. Summarise the changes you made in the form at the bottom of the page and click the button labelled 'Propose file change' when done.
+6. On the following screens, click the 'Create pull request' buttons until you see a message like ``Open. yourGitHubUsername wants to merge 1 commit into godotengine:master from yourGitHubUsername:patch-6``
+7. A reviewer will evaluate your changes and incorporate them into the docs if they're judged to improve them. You might also be asked to make modifications to your changes before they're included.
 
 What makes good documentation?
 ------------------------------

+ 6 - 2
community/contributing/updating_the_class_reference.rst

@@ -3,9 +3,11 @@
 Contribute to the Class Reference
 =================================
 
-Godot ships with many nodes and singletons to help you develop your games in GDscript. Each is a class, documented in the :ref:`class reference <toc-class-ref>`. This reference is essential for anyone learning the engine: it is available both online and in the engine.
+Godot ships with many nodes and singletons to help you develop your games. Each is a class, documented in the :ref:`class reference <toc-class-ref>`.
+This reference is essential for anyone learning the engine: it is available both online and in the engine.
 
-But it's incomplete. Some methods, variables and signals lack descriptions. Others changed with recent releases and need updates. The developers can't write the entire reference on their own. Godot needs you, and all of us, to contribute.
+But it's incomplete. Some methods, variables and signals lack descriptions. Others changed with recent releases and need updates.
+The developers can't write the entire reference on their own. Godot needs you, and all of us, to contribute.
 
 **Important:** If you are planning to make larger changes or a more substantial contribution, it is usually a good idea
 to create an issue (or a comment in an existing one) to let others know so they don't start working on the same thing too.
@@ -160,6 +162,8 @@ Edit the file for your chosen class in ``doc/classes/`` to update the class refe
 
 Edit it using your favourite text editor. If you use a code editor, make sure that it doesn't change the indent style: tabs for the XML, and 4 spaces inside BBcode-style blocks. More on that below.
 
+If you need to check that the modifications you've made are correct in the generated documentation, build Godot as described :ref:`here <toc-devel-compiling>`, run the editor and open the help for the page you modified.
+
 How to write the class reference
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 

+ 28 - 5
community/tutorials.rst

@@ -3,22 +3,45 @@
 Tutorials and resources
 =======================
 
-This is a list of third-party tutorials and other resources created by the community
-that may be of interest.
+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 <https://godotengine.org/asset-library/asset>`_ full of official and community resources too! Also have a look at this `huge list over at Reddit <https://www.reddit.com/r/godot/comments/an0iq5/godot_tutorials_list_of_video_and_written/>`_.
+
+Think there is something missing here? Feel free to submit a `Pull Request <https://github.com/godotengine/godot-docs/blob/master/community/resources.rst>`_ as always.
+
+Where to start
+--------------
+
+The Godot video tutorials by `GDQuest <https://www.youtube.com/channel/UCxboW7x0jZqFdvMdCFKTMsQ/playlists>`_, `Game from Scratch <https://www.youtube.com/watch?v=iDEcP8Mc-7s&list=PLS9MbmO_ssyDk79j9ewONxV88fD5e_o5d>`_ and `KidsCanCode <https://www.youtube.com/channel/UCNaPQ5uLX5iIEHUCLmfAgKg/playlists>`_ are well-regarded in the community and often recommended as a gentle introduction to beginners.
+
+If you're interested in Visual Scripting, `Emilio's tutorials <https://www.youtube.com/channel/UC9DR22-qohBDtZ74R3FxOZg>`_ may be worth a look.
+
+Some of the others mentioned below provide more advanced tutorials, e.g. on 3D or shaders.
 
 Video tutorials
 ---------------
 
+- `Emilio <https://www.youtube.com/channel/UC9DR22-qohBDtZ74R3FxOZg>`_
 - `GDQuest <https://www.youtube.com/channel/UCxboW7x0jZqFdvMdCFKTMsQ/playlists>`_
-- `KidsCanCode <https://www.youtube.com/channel/UCNaPQ5uLX5iIEHUCLmfAgKg/playlists>`_
-- `Game from Scratch: Godot 3 Tutorial Series <https://www.youtube.com/watch?v=iDEcP8Mc-7s&list=PLS9MbmO_ssyDk79j9ewONxV88fD5e_o5d>`_
+- `Game Endeavor <https://www.youtube.com/channel/UCLweX1UtQjRjj7rs_0XQ2Eg/videos>`_
+- `Game from Scratch <https://www.youtube.com/watch?v=iDEcP8Mc-7s&list=PLS9MbmO_ssyDk79j9ewONxV88fD5e_o5d>`_
 - `HeartBeast <https://www.youtube.com/watch?v=wETY5_9kFtA&list=PL9FzW-m48fn2jlBu_0DRh7PvAt-GULEmd>`_
+- `Jeremy Bullock <https://www.youtube.com/channel/UCwJw2-V5S1TkBjLQ3_Ws54g>`_
+- `KidsCanCode <https://www.youtube.com/channel/UCNaPQ5uLX5iIEHUCLmfAgKg/playlists>`_
+- `Mister Taft Creates <https://www.youtube.com/playlist?list=PL4vbr3u7UKWqwQlvwvgNcgDL1p_3hcNn2>`_
+- `Miziziziz <https://www.youtube.com/playlist?list=PLmugv6_kd0qN6AyjG245_Pdak4MXKUx88>`_
+- `P1X / Krzysztof Jankowski <https://www.youtube.com/playlist?list=PLvDk7UKhld4xGPovdB4IFtAHYMYjx_-3K>`_
+- `Pigdev <https://www.youtube.com/playlist?list=PLPMN4vCRFdordS3E-3zi0Hdh7pAsbWQ6a>`_
 - `Steincodes <https://www.youtube.com/c/steincodes/playlists>`_
 
 Text tutorials
 --------------
 
-- `KidsCanCode: An ongoing tutorial series <http://kidscancode.org/blog/tags/godot/>`_
+- `KidsCanCode <http://kidscancode.org/blog/tags/godot/>`_
+- `Steincodes <https://steincodes.tumblr.com>`_
+
+Devlogs
+-------
+- `Andrea Catania (Physics & AI) <https://www.youtube.com/channel/UCm4RuvYtgpgFDTCgaEUT5uQ/videos>`_
+- `Bastiaan Olij (AR & VR) <https://www.youtube.com/channel/UCrbLJYzJjDf2p-vJC011lYw/videos>`_
 
 Resources
 ---------

+ 1 - 1
development/cpp/custom_modules_in_cpp.rst

@@ -303,7 +303,7 @@ during runtime with the ``LD_LIBRARY_PATH`` environ variable:
     user@host:~/godot$ ./bin/godot*
 
 **note**: Pay attention you have to ``export`` the environ variable otherwise
-you won't be able to play you project from within the editor.
+you won't be able to play your project from within the editor.
 
 On top of that, it would be nice to be able to select whether to compile our
 module as shared library (for development) or as a part of the Godot binary

+ 1 - 1
development/file_formats/tscn.rst

@@ -12,7 +12,7 @@ indicate to Godot that the file has been exported from another program and
 should not be edited by the user from within Godot.
 
 For those looking for a complete description, the parsing is handled in the
-file `scene_format_text.cpp <https://github.com/godotengine/godot/blob/master/scene/resources/scene_format_text.cpp>`_
+file `resource_format_text.cpp <https://github.com/godotengine/godot/blob/master/scene/resources/resource_format_text.cpp>`_
 in the class :code:`ResourceFormatLoaderText`
 
 File structure

+ 8 - 6
getting_started/editor/external_editor.rst

@@ -3,9 +3,7 @@
 Using an external text editor
 ==============================
 
-While Godot has an inbuilt text editor, some developers have a tendency to
-want to use a text editor they are familiar with. Godot provides this
-option via the options under
+Godot can be used with an external text editor, such as Sublime Text or Visual Studio Code. To select an external text editor via the Godot editor menu:
 ``Editor -> Editor Settings -> Text Editor -> External``
 
 .. image:: img/editor_settings.png
@@ -31,11 +29,15 @@ Some example Exec Flags for various editors include:
 +---------------------+-----------------------------------------------------+
 | Editor              | Exec Flags                                          |
 +=====================+=====================================================+
-| Geany/Kate          | {file} --line {line} --column {col}                 |
+| Geany/Kate          | {file} -\-line {line} -\-column {col}               |
 +---------------------+-----------------------------------------------------+
 | Atom/Sublime Text   | {file}:{line}                                       |
 +---------------------+-----------------------------------------------------+
-| JetBrains Rider     | --line {line} {file}                                |
+| JetBrains Rider     | -\-line {line} {file}                               |
 +---------------------+-----------------------------------------------------+
-| Visual Studio Code  | {project} --goto {file}:{line}:{col}                |
+| Visual Studio Code  | {project} -\-goto {file}:{line}:{col}               |
 +---------------------+-----------------------------------------------------+
+| Vim (gVim)          | "+call cursor({line}, {col})" {file}                |
++---------------------+-----------------------------------------------------+
+
+.. note:: For Visual Studio Code you will have to point to the "code.cmd" file.

+ 16 - 16
getting_started/scripting/gdscript/gdscript_advanced.rst

@@ -425,37 +425,37 @@ functions in your script. An example implementation of a forward iterator follow
 
 ::
 
-    class FwdIterator:
-        var start, curr, end, increment
+    class ForwardIterator:
+        var start
+        var current
+        var end
+        var increment
 
-        func _init(start, stop, inc):
+        func _init(start, stop, increment):
             self.start = start
-            self.curr = start
+            self.current = start
             self.end = stop
-            self.increment = inc
+            self.increment = increment
 
-        func is_done():
-            return (curr < end)
-
-        func do_step():
-            curr += increment
-            return is_done()
+        func should_continue():
+            return (current < end)
 
         func _iter_init(arg):
-            curr = start
-            return is_done()
+            current = start
+            return should_continue()
 
         func _iter_next(arg):
-            return do_step()
+            current += increment
+            return should_continue()
 
         func _iter_get(arg):
-            return curr
+            return current
 
 And it can be used like any other iterator:
 
 ::
 
-    var itr = FwdIterator.new(0, 6, 2)
+    var itr = ForwardIterator.new(0, 6, 2)
     for i in itr:
         print(i) # Will print 0, 2, and 4
 

+ 1 - 1
getting_started/scripting/gdscript/gdscript_basics.rst

@@ -531,7 +531,7 @@ To add a key to an existing dictionary, access it like an existing key and
 assign to it::
 
     var d = {} # Create an empty Dictionary.
-    d.waiting = 14 # Add String "Waiting" as a key and assign the value 14 to it.
+    d.waiting = 14 # Add String "waiting" as a key and assign the value 14 to it.
     d[4] = "hello" # Add integer 4 as a key and assign the String "hello" as its value.
     d["Godot"] = 3.01 # Add String "Godot" as a key and assign the value 3.01 to it.
 

+ 1 - 1
getting_started/scripting/gdscript/static_typing.rst

@@ -288,7 +288,7 @@ And the same callback, with type hints:
     func _on_area_entered(area: CollisionObject2D) -> void:
         pass
 
-You’re free to replace, e.g. the ``PhysicsBody2D``, with your own type,
+You’re free to replace, e.g. the ``CollisionObject2D``, with your own type,
 to cast parameters automatically:
 
 ::

+ 3 - 3
getting_started/step_by_step/animations.rst

@@ -51,7 +51,7 @@ The logo will appear from the top of the screen.
 
 With the animation editor panel open, select the "logo" node and set the
 "Rect / Position" property to ``(118, -400)`` and press the key button next
-to the property:
+to the property to add a keyframe:
 
 .. image:: img/robisplash_anim_logo_inspector_key.png
 
@@ -61,12 +61,12 @@ The keyframe will be added in the animation player editor:
 
 .. image:: img/robisplash_anim_editor_keyframe.png
 
-Move the editor cursor to the end by clicking here:
+Move the editor cursor forward in time by clicking here:
 
 .. image:: img/robisplash_anim_editor_track_cursor.png
 
 Change the logo position to ``(118, 0)`` and add a keyframe again. With two
-keyframes, the animation happens.
+keyframes with different values, the animation happens.
 
 .. image:: img/robisplash_anim_editor_keyframe_2.png
 

+ 1 - 1
getting_started/step_by_step/exporting.rst

@@ -117,7 +117,7 @@ changed:
     func _on_Player_body_entered( body ):
         hide()
         emit_signal("hit")
-        $CollisionShape2D.call_deferred("set_disabled", true)
+        $CollisionShape2D.set_deferred("disabled", true)
 
 Export templates
 ----------------

BIN=BIN
getting_started/step_by_step/files/dodge_assets.zip


+ 9 - 16
getting_started/step_by_step/filesystem.rst

@@ -6,16 +6,10 @@ File system
 Introduction
 ------------
 
-File systems are yet another hot topic in engine development. The
-file system manages how the assets are stored and how they are accessed.
+A file system manages how assets are stored and how they are accessed.
 A well-designed file system also allows multiple developers to edit the
-same source files and assets while collaborating.
-
-Initial versions of the Godot engine (and previous iterations before it was
-named Godot) used a database. Assets were stored in it and assigned an
-ID. Other approaches were tried as well, such as local databases, files with
-metadata, etc. In the end, the simple approach won and now Godot stores
-all assets as files in the file system.
+same source files and assets while collaborating. Godot stores
+all assets as files in its file system.
 
 Implementation
 --------------
@@ -27,12 +21,11 @@ included. If a resource has sub-resources that are built-in, the resource is
 saved in a single file together with all the bundled sub-resources. For
 example, a font resource is often bundled together with the font textures.
 
-In general, the Godot file system avoids using metadata files. The reason for
-this is simple, existing asset managers and VCSs are simply much better than
+The Godot file system avoids using metadata files. Existing asset managers and VCSs are better than
 anything we can implement, so Godot tries its best to play along with SVN,
 Git, Mercurial, Perforce, etc.
 
-Example of a file system contents:
+Example of file system contents:
 
 ::
 
@@ -69,7 +62,7 @@ cumbersome and non-portable. To solve this problem, the special path
 ``res://`` was created.
 
 The path ``res://`` will always point at the project root (where
-project.godot is located, so in fact ``res://project.godot`` is always
+project.godot is located, so ``res://project.godot`` is always
 valid).
 
 This file system is read-write only when running the project locally from
@@ -80,7 +73,7 @@ read-only and writing will no longer be permitted.
 User path
 ---------
 
-Writing to disk is often still needed for various tasks such as saving game
+Writing to disk is still needed for tasks such as saving game
 state or downloading content packs. To this end, the engine ensures that there is a
 special path ``user://`` that is always writable.
 
@@ -90,7 +83,7 @@ Host file system
 Alternatively host file system paths can also be used, but this is not recommended
 for a released product as these paths are not guaranteed to work on all platforms.
 However, using host file system paths can be useful when writing development
-tools in Godot!
+tools in Godot.
 
 Drawbacks
 ---------
@@ -112,5 +105,5 @@ on other platforms, such as Linux, Android, etc. This may also apply to exported
 which use a compressed package to store all files.
 
 It is recommended that your team clearly define a naming convention for files when
-working with Godot! One simple fool-proof convention is to only allow lowercase
+working with Godot. One simple fool-proof convention is to only allow lowercase
 file and path names.

+ 1 - 1
getting_started/step_by_step/instancing.rst

@@ -104,7 +104,7 @@ Press "Play" and notice that all of the instanced balls are now
 much more bouncy. Because the instanced balls are based on the saved scene,
 changes to that scene will affect all instances.
 
-You can also adjust individual instances. Set the bounce value back to ``0.5``
+You can also adjust individual instances. Set the bounce value back to ``0``
 and then in the ``Main`` scene, select one of the instanced balls. Set its
 ``Bounce`` to ``1`` and press "Play".
 

+ 1 - 1
getting_started/step_by_step/instancing_continued.rst

@@ -17,7 +17,7 @@ Design language
 ---------------
 
 But the greatest strength that comes with instancing scenes is that it works
-as an excellent design language. This is pretty much what distinguishes Godot
+as an excellent design language. This distinguishes Godot
 from all the other engines out there. Godot was designed from the ground up
 around this concept.
 

+ 1 - 1
getting_started/step_by_step/resources.rst

@@ -135,7 +135,7 @@ returns the root node of the scene. You can then add it as a child of any other
 node.
 
 The approach has several advantages. As the :ref:`PackedScene.instance()
-<class_PackedScene_method_instance>` function is pretty fast, you can create new
+<class_PackedScene_method_instance>` function is fast, you can create new
 enemies, bullets, effects, etc. without having to load them again from disk each
 time. Remember that, as always, images, meshes, etc. are all shared between the
 scene instances.

+ 12 - 20
getting_started/step_by_step/scene_tree.rst

@@ -6,18 +6,10 @@ SceneTree
 Introduction
 ------------
 
-This is where things start getting abstract, but don't panic. There's
-not much more depth than this.
-
 In previous tutorials, everything revolved around the concept of
-nodes. Scenes are simply a collection of nodes. They become active once
+nodes. Scenes are collections of nodes. They become active once
 they enter the *scene tree*.
 
-This concept deserves going into a little more detail. In fact, the
-scene system is not even a core component of Godot as it is possible to
-skip it and write a script (or C++ code) that talks directly to the
-servers, but making a game that way would be a lot of work.
-
 MainLoop
 --------
 
@@ -46,7 +38,7 @@ game engine over a low level middleware.
 The scene system is the game engine, while the :ref:`OS <class_OS>`
 and servers are the low level API.
 
-In any case, the scene system provides its own main loop to OS,
+The scene system provides its own main loop to OS,
 :ref:`SceneTree <class_SceneTree>`.
 This is automatically instanced and set when running a scene, no need
 to do any extra work.
@@ -64,7 +56,7 @@ important uses:
 
 When a node is part of the Scene Tree, the
 :ref:`SceneTree <class_SceneTree>`
-singleton can be obtained by simply calling
+singleton can be obtained by calling
 :ref:`Node.get_tree() <class_Node_method_get_tree>`.
 
 Root viewport
@@ -85,10 +77,10 @@ two different ways:
         GetTree().GetRoot(); // Access via scene main loop.
         GetNode("/root"); // Access via absolute path.
 
-This node contains the main viewport, anything that is a child of a
+This node contains the main viewport. Anything that is a child of a
 :ref:`Viewport <class_Viewport>`
 is drawn inside of it by default, so it makes sense that the top of all
-nodes is always a node of this type otherwise nothing would be seen!
+nodes is always a node of this type otherwise nothing would be seen.
 
 While other viewports can be created in the scene (for split-screen
 effects and such), this one is the only one that is never created by the
@@ -106,16 +98,16 @@ _enter_tree() and _ready() callbacks (as well as _exit_tree()).
 .. image:: img/activescene.png
 
 When nodes enter the *Scene Tree*, they become active. They get access
-to everything they need to process, get input, display 2D and 3D,
-notifications, play sound, groups, etc. When they are removed from the
-*scene tree*, they lose access.
+to everything they need to process, get input, display 2D and 3D visuals,
+receive and send notifications, play sounds, etc. When they are removed from the
+*scene tree*, they lose these abilities.
 
 Tree order
 ----------
 
 Most node operations in Godot, such as drawing 2D, processing, or getting
 notifications are done in tree order. This means that parents and
-siblings with a smaller rank in the tree order will get notified before
+siblings with a lower rank in the tree order will get notified before
 the current node.
 
 .. image:: img/toptobottom.png
@@ -181,7 +173,7 @@ function
 
 These are quick and useful ways to switch scenes but have the drawback
 that the game will stall until the new scene is loaded and running. At
-some point in your game, it may be desired to create proper loading
+some point in the development of your game, it may be preferable to create proper loading
 screens with progress bar, animated indicators or thread (background)
-loading. This must be done manually using autoloads (see next chapter!)
-and :ref:`doc_background_loading`.
+loading. This must be done manually using autoloads (see next chapter)
+and :ref:`doc_background_loading`.

+ 7 - 0
getting_started/step_by_step/scenes_and_nodes.rst

@@ -162,6 +162,13 @@ demo should finally execute:
 
 Success!
 
+.. note::
+
+    If this doesn't immediately work and you have a hiDPI display on
+    at least one of your monitors, go to
+    **Project → Project Settings → Display → Window** then enable
+    **Allow Hidpi** under **Dpi**.
+
 .. _doc_scenes_and_nodes-configuring_the_project:
 
 Configuring the project

+ 16 - 11
getting_started/step_by_step/scripting_continued.rst

@@ -17,8 +17,7 @@ Idle processing is activated when the method :ref:`Node._process() <class_Node_m
 is found in a script. It can be turned off and on with the
 :ref:`Node.set_process() <class_Node_method_set_process>` function.
 
-This method will be called every time a frame is drawn, so it's fully dependent on
-how many frames per second (FPS) the application is running at:
+This method will be called every time a frame is drawn:
 
 .. tabs::
  .. code-tab:: gdscript GDScript
@@ -34,8 +33,12 @@ how many frames per second (FPS) the application is running at:
         // Do something...
     }
 
-The delta parameter contains the time elapsed in seconds, as a
-floating point, since the previous call to ``_process()``.
+It's important to bear in mind that the frequecy with which ``_process()``
+will be called depends on how many frames per second (FPS) your application
+is running at. This rate can vary over time and devices.
+
+To help manage this variability the ``delta`` parameter contains the time
+elapsed in seconds, as a floating point, since the previous call to ``_process()``.
 
 This parameter can be used to make sure things always take the same
 amount of time, regardless of the game's FPS.
@@ -52,7 +55,7 @@ Physics -> Common -> Physics Fps.
 The function ``_process()``, however, is not synced with physics. Its frame rate is not constant and is dependent
 on hardware and game optimization. Its execution is done after the physics step on single-threaded games.
 
-A simple way to test this is to create a scene with a single Label node,
+A simple way to see the ``_process()`` function at work is to create a scene with a single Label node,
 with the following script:
 
 .. tabs::
@@ -84,13 +87,15 @@ Which will show a counter increasing each frame.
 Groups
 ------
 
-Nodes can be added to groups, as many as desired per node, and is a useful feature for organizing large scenes.
-There are two ways to do this. The first is from the UI, from the Groups button under the Node panel:
+Groups in Godot work like tags you might have come across in other software.
+A node can be added to as many groups as desired. This is a useful feature for
+organizing large scenes. There are two ways to do add nodes to groups. The
+first is from the UI, using the Groups button under the Node panel:
 
 .. image:: img/groups_in_nodes.png
 
-And the second way is from code. One example would be to tag nodes
-which are enemies:
+And the second way is from code. The following script would add the current
+node to the ``enemies`` group as soon as it appeared in the scene tree.
 
 .. tabs::
  .. code-tab:: gdscript GDScript
@@ -145,7 +150,7 @@ like interacting with scenes, their node hierarchy and groups of nodes.
 It allows you to easily switch scenes or reload them,
 to quit the game or pause and unpause it.
 It even comes with interesting signals.
-So check it out if you got some time!
+So check it out if you have some time!
 
 Notifications
 -------------
@@ -310,7 +315,7 @@ used:
         _sprite.Free(); // Immediately removes the node from the scene and frees it.
     }
 
-When a node is freed, it also frees all its children nodes. Because of
+When a node is freed, it also frees all its child nodes. Because of
 this, manually deleting nodes is much simpler than it appears. Free
 the base node and everything else in the subtree goes away with it.
 

+ 10 - 125
getting_started/step_by_step/signals.rst

@@ -15,8 +15,8 @@ button can emit a signal when it's pressed.
 
 Signals are a way to *decouple* your game objects, which leads to better organized
 and more manageable code. Instead of forcing game objects to expect other objects
-to always be present, they can instead emit signals that any interested objects can
-subscribe to and respond.
+to always be present, they can instead emit signals that all interested objects can
+subscribe to and respond to.
 
 Below you can see some examples of how you can use signals in your own projects.
 
@@ -25,8 +25,11 @@ Timer example
 
 To see how signals work, let's try using a :ref:`Timer <class_Timer>` node. Create
 a new scene with a Node and two children: a Timer and a :ref:`Sprite <class_Sprite>`.
-You can use the Godot icon for the Sprite's texture, or any other image you
-like. Attach a script to the root node, but don't add any code to it yet.
+In the Scene dock, rename Node to TimerExample.
+
+For the Sprite's texture, you can use the Godot icon, or any other image you
+like. Do so by selecting ``Load`` in the Sprite's Texture attribute drop-down menu.
+Attach a script to the root node, but don't add any code to it yet.
 
 Your scene tree should look like this:
 
@@ -90,6 +93,8 @@ the signal is received. Let's make the Sprite blink:
     extends Node
 
     func _on_Timer_timeout():
+        # Note: the `$` operator is a shorthand for `get_node()`,
+        # so `$Sprite` is equivalent to `get_node("Sprite")`.
         $Sprite.visible = !$Sprite.visible
 
  .. code-tab:: csharp
@@ -174,7 +179,7 @@ You can also declare your own custom signals in Godot:
 Once declared, your custom signals will appear in the Inspector and can be connected
 in the same way as a node's built-in signals.
 
-To emit a signal via code, use the ``emit`` function:
+To emit a signal via code, use the ``emit_signal`` function:
 
 .. tabs::
  .. code-tab:: gdscript GDScript
@@ -199,126 +204,6 @@ To emit a signal via code, use the ``emit`` function:
         }
     }
 
-Shooting example
-----------------
-
-As another example of signal usage, let's consider a player character that can
-rotate and shoot towards the mouse. Every time the mouse button is clicked,
-we create an instance of the bullet at the player's location. See :ref:`doc_instancing`
-for details.
-
-However, if the bullets are added as children of the player, then they will
-remain "attached" to the player as it rotates:
-
-.. image:: img/signals_shoot1.gif
-
-Instead, we need the bullets to be independent of the player's movement - once
-fired, they should continue traveling in a straight line and the player can no
-longer affect them. Instead of being added to the scene tree as a child of the
-player, it makes more sense to add the bullet as a child of the "main" game
-scene, which may be the player's parent or even further up the tree.
-
-You could do this by adding the bullet directly:
-
-.. tabs::
- .. code-tab:: gdscript GDScript
-
-    var bullet_instance = Bullet.instance()
-    get_parent().add_child(bullet_instance)
-
- .. code-tab:: csharp
-
-    Node bulletInstance = Bullet.Instance();
-    GetParent().AddChild(bulletInstance);
-
-However, this will lead to a different problem. Now if you try and test your
-"Player" scene independently, it will crash on shooting, because there is no
-parent node to access. This makes it a lot harder to test your player code
-independently and also means that if you decide to change your main scene's
-node structure, the player's parent may no longer be the appropriate node to
-receive the bullets.
-
-The solution to this is to use a signal to "emit" the bullets from the player.
-The player then has no need to "know" what happens to the bullets after that -
-whatever node is connected to the signal can "receive" the bullets and take the
-appropriate action to spawn them.
-
-
-Here is the code for the player using signals to emit the bullet:
-
-.. tabs::
- .. code-tab:: gdscript GDScript
-
-    extends Sprite
-
-    signal shoot(bullet, direction, location)
-
-    var Bullet = preload("res://Bullet.tscn")
-
-    func _input(event):
-        if event is InputEventMouseButton:
-            if event.button_index == BUTTON_LEFT and event.pressed:
-                emit_signal("shoot", Bullet, rotation, position)
-
-    func _process(delta):
-        look_at(get_global_mouse_position())
-
- .. code-tab:: csharp
-
-    public class Player : Sprite
-    {
-        [Signal]
-        delegate void Shoot(PackedScene bullet, Vector2 direction, Vector2 location);
-
-        private PackedScene _bullet = GD.Load<PackedScene>("res://Bullet.tscn");
-
-        public override void _Input(InputEvent event)
-        {
-            if (input is InputEventMouseButton mouseButton)
-            {
-                if (mouseButton.ButtonIndex == (int)ButtonList.Left && mouseButton.Pressed)
-                {
-                    EmitSignal(nameof(Shoot), _bullet, Rotation, Position);
-                }
-            }
-        }
-
-        public override _Process(float delta)
-        {
-            LookAt(GetGlobalMousePosition());
-        }
-    }
-
-
-In the main scene, we then connect the player's signal (it will appear in the
-"Node" tab).
-
-.. tabs::
- .. code-tab:: gdscript GDScript
-
-    func _on_Player_shoot(Bullet, direction, location):
-        var b = Bullet.instance()
-        add_child(b)
-        b.rotation = direction
-        b.position = location
-        b.velocity = b.velocity.rotated(direction)
-
- .. code-tab:: csharp
-
-    public void _on_Player_Shoot(PackedScene bullet, Vector2 direction, Vector2 location)
-    {
-        var bulletInstance = (Bullet)bullet.Instance();
-        AddChild(bulletInstance);
-        bulletInstance.Rotation = direction;
-        bulletInstance.Position = location;
-        bulletInstance.Velocity = bulletInstance.Velocity.Rotated(direction);
-    }
-
-Now the bullets will maintain their own movement independent of the player's
-rotation:
-
-.. image:: img/signals_shoot2.gif
-
 Conclusion
 ----------
 

+ 2 - 2
getting_started/step_by_step/singletons_autoload.rst

@@ -33,7 +33,7 @@ Using this concept, you can create objects that:
 -  Can handle switching scenes and between-scene transitions
 -  Act like a singleton, since GDScript does not support global variables by design
 
-Autoloading nodes and scripts caters to this need.
+Autoloading nodes and scripts can give us these characteristics.
 
 AutoLoad
 --------
@@ -270,7 +270,7 @@ and
     }
 
 Run the project and test that you can switch between scenes by pressing
-the button!
+the button.
 
 Note: When scenes are small, the transition is instantaneous. However, if your
 scenes are more complex, they may take a noticeable amount of time to appear. To

+ 22 - 19
getting_started/step_by_step/ui_introduction_to_the_ui_system.rst

@@ -7,10 +7,7 @@ Computer displays, mobile phones, and TV screen come in all shapes and
 sizes. To ship a game, you'll need to support different screen ratios
 and resolutions. It can be hard to build responsive interfaces that
 adapt to all platforms. Thankfully, Godot comes with robust tools to
-design and manage a responsive User Interface. To design your UI, you'll
-use the Control nodes. These are the nodes with green icons in the
-editor. There are dozens of them, to create anything from life bars to
-complex applications. Godot's entire editor and plugins use these nodes.
+design and manage a responsive User Interface.
 
 .. figure:: img/godot_editor_ui.png
 
@@ -18,21 +15,23 @@ complex applications. Godot's entire editor and plugins use these nodes.
 
 This guide will get you started with UI design. You will learn:
 
--  The five most useful control nodes to build your games interface
+-  The five most useful control nodes to build your games' interface
 -  How to work with the anchor of UI elements
 -  How to efficiently place and arrange your user interface using
    containers
--  The five most common containers
+-  The five most common containers (at a later time, you can learn more about containers in
+   the :ref:`GUI Containers <doc_gui_containers>` documentation page).
 
 To learn how to control the interface and connect it to other scripts,
 read :ref:`Build your first game UI in Godot <doc_ui_game_user_interface>`.
 
-Only use Control nodes when you design your interfaces. They have unique
-properties that allow them to work with one another. Other nodes, like
-Node2D, Sprite, etc. will not work. You can still use some nodes that
-work with others, like the AnimationPlayer, Tween or the StreamPlayer.
-Control nodes are CanvasItems like Node2D, so you can apply shaders to
-them.
+To design your UI, you'll use the Control nodes. These are the nodes with green icons in the
+editor. There are dozens of them, for creating anything from life bars to
+complex applications. Godot's editor itself is built using Control nodes.
+
+Control nodes have unique properties that allow them to work well with one another.
+Other visual nodes, like Node2D and Sprite don't have these capabilities. So to
+make your life easier use Control nodes wherever possible when building your UIs.
 
 All control nodes share the same main properties:
 
@@ -75,14 +74,18 @@ TextureRect
 It seems similar to the Sprite node, but it offers multiple scaling modes.
 Set the Stretch Mode property to change its behavior:
 
-- ``Scale On Expand (compat)`` scales the texture to fit the node’s bounding rectangle, only if ``expand`` property is ``true``; otherwise, it behaves like ``Keep`` mode. Default mode for backwards compatibility.
-- ``Scale`` scales the texture to fit the node’s bounding rectangle
-- ``Tile`` makes the texture repeat, but it won't scale
+- ``Scale On Expand (compat)`` scales the texture to fit the node's bounding rectangle,
+  only if ``expand`` property is ``true``; otherwise, it behaves like ``Keep`` mode.
+  Default mode for backwards compatibility.
+- ``Scale`` scales the texture to fit the node's bounding rectangle.
+- ``Tile`` makes the texture repeat, but it won't scale.
 -  ``Keep`` and ``Keep Centered`` force the texture to remain at its
    original size, in the top left corner or the center of the frame
-   respectively
-- ``Keep Aspect`` and ``Keep Aspect Centered`` scales the texture but force it to remain its original aspect ratio, in the top left corner or the center of the frame respectively
-- ``Keep Aspect Covered`` works just like ``Keep Aspect Centered`` but the shorter side fits the bounding rectangle and the other one clips to the node’s limits
+   respectively.
+- ``Keep Aspect`` and ``Keep Aspect Centered`` scales the texture but force it to remain
+  its original aspect ratio, in the top left corner or the center of the frame respectively.
+- ``Keep Aspect Covered`` works just like ``Keep Aspect Centered`` but the shorter side
+  fits the bounding rectangle and the other one clips to the node's limits.
 
 As with Sprite nodes, you can modulate the TextureRect's color. Click
 the ``Modulate`` property and use the color picker.
@@ -195,7 +198,7 @@ Like any properties, you can edit the 4 anchor points in the Inspector,
 but this is not the most convenient way. When you select a control node,
 the layout menu appears above the viewport, in the toolbar. It gives you
 a list of icons to set all 4 anchors with a single click, instead of
-using the inspectors 4 properties. The layout menu will only show up
+using the inspector's 4 properties. The layout menu will only show up
 when you select a control node.
 
 .. figure:: img/layout_menu.png

+ 35 - 2
getting_started/step_by_step/your_first_game.rst

@@ -459,7 +459,7 @@ Add this code to the function:
     func _on_Player_body_entered(body):
         hide()  # Player disappears after being hit.
         emit_signal("hit")
-        $CollisionShape2D.call_deferred("set_disabled", true)
+        $CollisionShape2D.set_deferred("disabled", true)
 
  .. code-tab:: csharp
 
@@ -475,7 +475,7 @@ to disable the player's collision so that we don't trigger the ``hit`` signal
 more than once.
 
 .. Note:: Disabling the area's collision shape can cause an error if it happens
-          in the middle of the engine's collision processing. Using ``call_deferred()``
+          in the middle of the engine's collision processing. Using ``set_deferred()``
           allows us to have Godot wait to disable the shape until it's safe to
           do so.
 
@@ -1125,6 +1125,39 @@ sync with the changing score:
 Now you're ready to play! Click the "Play the Project" button. You will
 be asked to select a main scene, so choose ``Main.tscn``.
 
+Removing old creeps
+~~~~~~~~~~~~~~~~~~~
+
+If you play until "Game Over" and then start a new game the creeps from the
+previous game are still on screen. It would be better if they all disappeared
+at the start of a new game.
+
+We'll use the ``start_game`` signal that's already being emitted by the ``HUD``
+node to remove the remaining creeps. We can't use the editor to connect the
+signal to the mobs in the way we need because there are no ``Mob`` nodes in the
+``Main`` scene tree until we run the game. Instead we'll use code.
+
+Start by adding a new function to ``Mob.gd``. ``queue_free()`` will delete the
+current node at the end of the current frame.
+
+.. tabs::
+ .. code-tab:: gdscript GDScript
+
+    func _on_start_game():
+        queue_free()
+          
+Then in ``Main.gd`` add a new line inside the ``_on_MobTimer_timeout()`` function,
+at the end.
+
+.. tabs::
+ .. code-tab:: gdscript GDScript
+
+    $HUD.connect("start_game", mob, "_on_start_game")
+
+This line tells the new Mob node (referenced by the ``mob`` variable) to respond
+to any ``start_game`` signal emitted by the ``HUD`` node by running its
+``_on_start_game()`` function.
+
 Finishing up
 ------------
 

+ 3 - 0
getting_started/workflow/assets/escn_exporter/skeleton.rst

@@ -15,6 +15,9 @@ rest position (transform in Godot) of bones.
     armature in Blender, so that the exported bone transform be
     consistent between Blender and Godot
 
+It is important that the mesh is not deformed by bones when exporting in Blender. Make sure
+that the skeleton is reset to its T-pose or default rest pose.
+
 Bone Weights
 ------------
 

+ 3 - 0
getting_started/workflow/assets/importing_scenes.rst

@@ -19,6 +19,9 @@ Godot supports the following 3D *scene file fomats*:
 
 Just copy the scene file together with the texture to the project repository, and Godot will do a full import.
 
+It is important that the mesh is not deformed by bones when exporting. Make sure that the skeleton is reset to its T-pose 
+or default rest pose before exporting with your favorite 3D editor.
+
 Why not FBX?
 ~~~~~~~~~~~~
 

+ 1 - 1
getting_started/workflow/best_practices/data_preferences.rst

@@ -240,7 +240,7 @@ tree structures.
     func _notification(p_what):
         match p_what:
             NOTIFICATION_PREDELETE:
-                # destructor
+                # Destructor.
                 for a_child in _children:
                     a_child.free()
 

+ 17 - 17
getting_started/workflow/best_practices/godot_interfaces.rst

@@ -21,13 +21,13 @@ is to get a reference to an existing object from another acquired instance.
 .. tabs::
   .. code-tab:: gdscript GDScript
 
-    var obj = node.object # Property access
-    var obj = node.get_object() # Method access
+    var obj = node.object # Property access.
+    var obj = node.get_object() # Method access.
 
   .. code-tab:: csharp
 
-    Object obj = node.Object; // Property access
-    Object obj = node.GetObject(); // Method access
+    Object obj = node.Object; // Property access.
+    Object obj = node.GetObject(); // Method access.
 
 The same principle applies for :ref:`Reference <class_Reference>` objects.
 While users often access :ref:`Node <class_Node>` and
@@ -207,22 +207,22 @@ Nodes likewise have an alternative access point: the SceneTree.
         public object Prop;
         public void CallMeAfterPropIsInitializedByParent()
         {
-            // Validate prop in one of three ways
+            // Validate prop in one of three ways.
 
-            // Fail with no notification
+            // Fail with no notification.
             if (prop == null)
             {
                 return;
             }
 
-            // Fail with an error message
+            // Fail with an error message.
             if (prop == null)
             {
                 GD.PrintErr("'Prop' wasn't initialized");
                 return;
             }
 
-            // Fail and terminate
+            // Fail and terminate.
             Debug.Assert(Prop, "'Prop' wasn't initialized");
         }
 
@@ -288,7 +288,7 @@ accesses:
   .. tabs::
     .. code-tab:: gdscript GDScript
 
-      # All Objects have duck-typed get, set, and call wrapper methods
+      # All Objects have duck-typed get, set, and call wrapper methods.
       get_parent().set("visible", false)
 
       # Using a symbol accessor, rather than a string in the method call,
@@ -317,7 +317,7 @@ accesses:
   .. tabs::
     .. code-tab:: gdscript GDScript
 
-      var child = GetChild(0)
+      var child = get_child(0)
 
       # Dynamic lookup.
       child.call("set_visible", false)
@@ -353,13 +353,13 @@ accesses:
       # A "Quest" object exists and 1) that it can "complete" or "fail" and
       # that it will have text available before and after each state...
 
-      # 1. Use a name
+      # 1. Use a name.
       var quest = $Quest
       print(quest.text)
       quest.complete() # or quest.fail()
       print(quest.text) # implied new text content
 
-      # 2. Use a group
+      # 2. Use a group.
       for a_child in get_children():
           if a_child.is_in_group("quest"):
               print(quest.text)
@@ -374,10 +374,10 @@ accesses:
 
       Node child = GetChild(0);
 
-      // Dynamic lookup
+      // Dynamic lookup.
       child.Call("SetVisible", false);
 
-      // Dynamic lookup, checks for method existence first
+      // Dynamic lookup, checks for method existence first.
       if (child.HasMethod("SetVisible"))
       {
           child.Call("SetVisible", false);
@@ -395,7 +395,7 @@ accesses:
           child.Call("Reject");
       }
 
-      // Cast check, followed by static lookup
+      // Cast check, followed by static lookup.
       CanvasItem ci = GetParent() as CanvasItem;
       if (ci != null)
       {
@@ -419,13 +419,13 @@ accesses:
       // A "Quest" object exists and 1) that it can "Complete" or "Fail" and
       // that it will have Text available before and after each state...
 
-      // 1. Use a name
+      // 1. Use a name.
       Node quest = GetNode("Quest");
       GD.Print(quest.Get("Text"));
       quest.Call("Complete"); // or "Fail".
       GD.Print(quest.Get("Text")); // Implied new text content.
 
-      // 2. Use a group
+      // 2. Use a group.
       foreach (Node AChild in GetChildren())
       {
           if (AChild.IsInGroup("quest"))

+ 4 - 4
getting_started/workflow/best_practices/logic_preferences.rst

@@ -30,8 +30,8 @@ either? Let's see an example:
     # my_buildings.gd
     extends Node
 
-    # (note how constant scripts/scenes have a different naming scheme than
-    # their property variants).
+    # Note how constant scripts/scenes have a different naming scheme than
+    # their property variants.
 
     # This value is a constant, so it spawns when the Script object loads.
     # The script is preloading the value. The advantage here is that the editor
@@ -73,14 +73,14 @@ either? Let's see an example:
     // C# and other languages have no concept of "preloading".
     public class MyBuildings : Node
     {
-        //This is a read-only field, it can only be assigned when it's declared or during a constructor
+        //This is a read-only field, it can only be assigned when it's declared or during a constructor.
         public readonly PackedScene Building = ResourceLoader.Load<PackedScene>("res://building.tscn");
 
         public PackedScene ABuilding;
 
         public override void _Ready()
         {
-            // Can assign the value during initialization
+            // Can assign the value during initialization.
             ABuilding = GD.Load<PackedScene>("res://office.tscn");
         }
     }

+ 2 - 0
index.rst

@@ -104,8 +104,10 @@ The main documentation for the site is organized into the following sections:
    tutorials/platform/index
    tutorials/threads/index
    tutorials/content/index
+   tutorials/optimization/index
    tutorials/misc/index
    tutorials/debug/index
+   tutorials/legal/index
 
 
 .. toctree::

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

@@ -59,7 +59,7 @@ Add a script to the kinematic body and add the following code:
 
     func _physics_process(delta):
         get_input()
-        move_and_slide(velocity)
+        velocity = move_and_slide(velocity)
 
  .. code-tab:: csharp
 
@@ -94,7 +94,7 @@ Add a script to the kinematic body and add the following code:
         public override void _PhysicsProcess(float delta)
         {
             GetInput();
-            MoveAndSlide(velocity);
+            velocity = MoveAndSlide(velocity);
         }
     }
 
@@ -144,7 +144,7 @@ while up/down moves it forward or backward in whatever direction it's facing.
     func _physics_process(delta):
         get_input()
         rotation += rotation_dir * rotation_speed * delta
-        move_and_slide(velocity)
+        velocity = move_and_slide(velocity)
 
  .. code-tab:: csharp
 
@@ -183,7 +183,7 @@ while up/down moves it forward or backward in whatever direction it's facing.
         {
             GetInput();
             Rotation += rotationDir * RotationSpeed * delta;
-            MoveAndSlide(velocity);
+            velocity = MoveAndSlide(velocity);
         }
     }
 
@@ -224,7 +224,7 @@ is set by the mouse position instead of the keyboard. The character will always
 
     func _physics_process(delta):
         get_input()
-        move_and_slide(velocity)
+        velocity = move_and_slide(velocity)
 
  .. code-tab:: csharp
 
@@ -254,7 +254,7 @@ is set by the mouse position instead of the keyboard. The character will always
         public override void _PhysicsProcess(float delta)
         {
             GetInput();
-            MoveAndSlide(velocity);
+            velocity = MoveAndSlide(velocity);
         }
     }
 
@@ -298,7 +298,7 @@ on the screen will cause the player to move to the target location.
         velocity = (target - position).normalized() * speed
         # rotation = velocity.angle()
         if (target - position).length() > 5:
-            move_and_slide(velocity)
+            velocity = move_and_slide(velocity)
 
  .. code-tab:: csharp
 
@@ -326,7 +326,7 @@ on the screen will cause the player to move to the target location.
             // Rotation = velocity.Angle();
             if ((target - Position).Length() > 5)
             {
-                MoveAndSlide(velocity);
+                velocity = MoveAndSlide(velocity);
             }
         }
     }

+ 155 - 0
tutorials/2d/2d_sprite_animation.rst

@@ -0,0 +1,155 @@
+.. _doc_2d_sprite_animation:
+
+2D Sprite animation
+===================
+
+Introduction
+------------
+
+In this tutorial, you'll learn two different ways to create 2D animated
+characters. Typically, when you create or download an animated character, it
+will come in one of two ways: as individual images or as a single sprite sheet
+containing all the animation's frames. Depending on which type of assets you
+have, you can choose one of the following solutions.
+
+First, we'll use :ref:`AnimatedSprite <class_AnimatedSprite>` to
+animate a collection of individual images. Then, to use a sprite sheet, we'll
+use :ref:`AnimationPlayer <class_AnimationPlayer>` along with the *Animation*
+property of :ref:`Sprite <class_Sprite>`.
+
+.. note:: Art for the following examples by https://opengameart.org/users/ansimuz
+
+Individual images with AnimatedSprite
+-------------------------------------
+
+In this scenario, you have a collection of images, each containing one of your
+character's animation frames. For this example, we'll use the following
+animation:
+
+.. image:: img/2d_animation_run_preview.gif
+
+You can download the images here:
+:download:`run_animation.zip <files/run_animation.zip>`
+
+Unzip the images and place them in your project folder. Set up your scene tree
+with the following nodes:
+
+.. image:: img/2d_animation_tree1.png
+
+.. note:: The root node could also be :ref:`Area2D <class_Area2D>` or
+          :ref:`RigidBody2D <class_RigidBody2D>`. The animation will still be
+          made in the same way. Once the animation is completed, you can
+          assign a shape to the CollisionShape2D. See
+          :ref:`Physics Introduction <doc_physics_introduction>` for more
+          information.
+
+Now select the ``AnimatedSprite`` and in its *SpriteFrames* property, select
+"New SpriteFrames".
+
+.. image:: img/2d_animation_new_spriteframes.png
+
+Click on the new SpriteFrames resource and you'll see a new panel appear at the
+bottom of the editor window:
+
+.. image:: img/2d_animation_spriteframes.png
+
+From the FileSystem dock on the left side, drag the 8 individual images into
+the center part of the SpriteFrames panel. On the left side, change the name
+of the animation from "default" to "run".
+
+.. image:: img/2d_animation_spriteframes_done.png
+
+Back in the Inspector, check the box for the *Playing* property. You should
+now see the animation playing in the viewport. However, it is a bit slow. To
+fix this, change the *Speed (FPS)* setting in the SpriteFrames panel.
+
+You can add additional animations by clicking the "New Animation" button and
+adding additional images.
+
+Controlling the animation
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Once the animation is complete, you can control the animation via code using
+the ``play()`` and ``stop()`` methods. Here is a brief example to play the
+animation while the right arrow key is held, and stop it when the key is
+released.
+
+.. tabs::
+ .. code-tab:: gdscript GDScript
+
+    extends KinematicBody2D
+
+    func _process(delta):
+        if Input.is_action_pressed("ui_right"):
+            $AnimatedSprite.play("run")
+        else:
+            $AnimatedSprite.stop()
+
+
+Sprite sheet with AnimationPlayer
+---------------------------------
+
+In the event you have a sprite sheet containing all of your animation frames,
+you can't easily use ``AnimatedSprite``. Instead, you can use a standard
+:ref:`Sprite <class_Sprite>` node to display the texture, and then animate the
+change from texture to texture with :ref:`AnimationPlayer <class_AnimationPlayer>`.
+
+Consider this sprite sheet, which contains 6 frames of animation:
+
+.. image:: img/2d_animation_player-run.png
+
+Right-click the image and choose "Save Image As" to download, then copy the
+image into your project folder.
+
+Our goal is to display these images one after another in a loop. Start by
+setting up your scene tree:
+
+.. image:: img/2d_animation_tree2.png
+
+.. note:: The root node could also be :ref:`Area2D <class_Area2D>` or
+          :ref:`RigidBody2D <class_RigidBody2D>`. The animation will still be
+          made in the same way. Once the animation is completed, you can
+          assign a shape to the CollisionShape2D. See
+          :ref:`Physics Introduction <doc_physics_introduction>` for more
+          information.
+
+Drag the spritesheet into the Sprite's *Texture* property, and you'll see the
+whole sheet displayed on the screen. To slice it up into individual frames,
+expand the *Animation* section in the Inspector and set the *Hframes* to ``6``.
+*Hframes* and *Vframes* are the number of horizontal and vertical frames in
+your sprite sheet.
+
+.. image:: img/2d_animation_setframes.png
+
+Now try changing the value of the *Frame* property. You'll see that it ranges
+from ``0`` to ``5`` and the image displayed by the Sprite changes accordingly.
+This is the property we'll be animating.
+
+Select the ``AnimationPlayer`` and click the "Animation" button followed by
+"New". Name the new animation "walk". Set the animation length to ``0.6`` and
+click the "Loop" button so that our animation will repeat.
+
+.. image:: img/2d_animation_new_animation.png
+
+Now select the ``Sprite`` node and click the key icon to add a new track.
+
+.. image:: img/2d_animation_new_track.png
+
+Continue adding frames at each point in the timeline (``0.1`` seconds by
+default), until you have all the frames from 0 to 5. You'll see the frames
+actually appearing in the animation track:
+
+.. image:: img/2d_animation_full_animation.png
+
+Press "Play" on the animation to see how it looks.
+
+.. image:: img/2d_animation_running.gif
+
+Summary
+-------
+
+These examples illustrate the two most common situations you'll encounter in
+2D animation. Each has its benefits. Working with ``AnimationPlayer`` is
+a bit more complex, but provides additional functionality, since you can also
+animate other properties like position or scale. Experiment and see which
+works best for your needs.

+ 18 - 29
tutorials/2d/canvas_layers.rst

@@ -9,37 +9,29 @@ Viewport and Canvas items
 Regular 2D nodes, such as :ref:`Node2D <class_Node2D>` or
 :ref:`Control <class_Control>` both inherit from
 :ref:`CanvasItem <class_CanvasItem>`, which is the base for all 2D
-nodes. CanvasItems can be arranged in trees and they will inherit
-their transform. This means that when moving the parent, the children
-will be moved too.
+nodes. CanvasItems can be arranged in trees. Each item will inherit
+its parent's transform. This means that when the parent is moved, the children
+will move too.
 
-These nodes are placed as direct or indirect children of a
+CanvasItem nodes, and nodes inheriting from them, are direct or indirect children of a
 :ref:`Viewport <class_Viewport>`, and will be displayed through it.
 
-Viewport has the property
+A Viewport has the property
 :ref:`Viewport.canvas_transform <class_Viewport_property_canvas_transform>`,
-which allows to transform all the CanvasItem hierarchy by a custom
-:ref:`Transform2D <class_Transform2D>` transform. Nodes such as
+which allows applying a custom
+:ref:`Transform2D <class_Transform2D>` transform to the CanvasItem hierarchy it contains. Nodes such as
 :ref:`Camera2D <class_Camera2D>` work by changing that transform.
 
-Changing the canvas transform is useful because it is a lot more
+Effects like scrolling are best achieved by manipulating the canvas transform property. This approach is more
 efficient than moving the root canvas item (and hence the whole scene).
-Canvas transform is a simple matrix that offsets the whole 2D drawing,
-so it's the most efficient way to do scrolling.
 
-Not enough...
--------------
-
-But this is not enough. There are often situations where the game or
-application may not want *everything* transformed by the canvas
+Usually though, we don't want *everything* in the game or app to be subject to the canvas
 transform. Examples of this are:
 
 -  **Parallax Backgrounds**: Backgrounds that move slower than the rest
    of the stage.
--  **HUD**: Heads-up display, or user interface. If the world moves,
-   the life counter, score, etc. must stay static.
--  **Transitions**: Effects used for transitions (fades, blends) may
-   also want it to remain at a fixed location.
+-  **UI**: Think of a user interface (UI) or Heads-up display (HUD) superimposed on our view of the game world. We want a life counter, score display and other elements to retain their screen positions even when our view of the game world is changing.
+-  **Transitions**: We may want visual effects used for transitions (fades, blends) to remain at a fixed screen location.
 
 How can these problems be solved in a single scene tree?
 
@@ -52,8 +44,8 @@ children and grand-children. Viewport children will draw by default at
 layer "0", while a CanvasLayer will draw at any numeric layer. Layers
 with a greater number will be drawn above those with a smaller number.
 CanvasLayers also have their own transform and do not depend on the
-transform of other layers. This allows the UI to be fixed in-place
-while the world moves.
+transform of other layers. This allows the UI to be fixed in screen-space
+while our view on the game world changes.
 
 An example of this is creating a parallax background. This can be done
 with a CanvasLayer at layer "-1". The screen with the points, life
@@ -66,11 +58,8 @@ Here's a diagram of how it looks:
 CanvasLayers are independent of tree order, and they only depend on
 their layer number, so they can be instantiated when needed.
 
-Performance
------------
-
-Even though there shouldn't be any performance limitation, it is not
-advised to use excessive amount of layers to arrange drawing order of
-nodes. The most optimal way will always be arranging them by tree order.
-2d nodes also have a property for controlling their drawing order
-(see :ref:`Node2D.z_index <class_Node2D_property_z_index>`).
+.. note::   CanvasLayers aren't necessary to control the drawing order of nodes.
+            The standard way to ensuring that a node is  correctly drawn 'in front' or 'behind' others is to manipulate the  
+            order of the nodes in the scene panel. Perhaps counterintuitively, the topmost nodes in the scene panel are drawn
+            on *behind* lower ones in the viewport. 2d nodes also have a property for controlling their drawing order
+            (see :ref:`Node2D.z_index <class_Node2D_property_z_index>`).

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

@@ -434,8 +434,8 @@ smaller value, which directly depends on the rendering speed.
 
         # We only wrap angles when both of them are bigger than 360.
         if angle_from > 360 and angle_to > 360:
-            angle_from = wrap(angle_from, 0, 360)
-            angle_to = wrap(angle_to, 0, 360)
+            angle_from = wrapf(angle_from, 0, 360)
+            angle_to = wrapf(angle_to, 0, 360)
         update()
 
  .. code-tab:: csharp

BIN=BIN
tutorials/2d/files/run_animation.zip


BIN=BIN
tutorials/2d/img/2d_animation_full_animation.png


BIN=BIN
tutorials/2d/img/2d_animation_new_animation.png


BIN=BIN
tutorials/2d/img/2d_animation_new_spriteframes.png


BIN=BIN
tutorials/2d/img/2d_animation_new_track.png


BIN=BIN
tutorials/2d/img/2d_animation_player-run.png


BIN=BIN
tutorials/2d/img/2d_animation_run_preview.gif


BIN=BIN
tutorials/2d/img/2d_animation_running.gif


BIN=BIN
tutorials/2d/img/2d_animation_setframes.png


BIN=BIN
tutorials/2d/img/2d_animation_spriteframes.png


BIN=BIN
tutorials/2d/img/2d_animation_spriteframes_done.png


BIN=BIN
tutorials/2d/img/2d_animation_tree1.png


BIN=BIN
tutorials/2d/img/2d_animation_tree2.png


BIN=BIN
tutorials/2d/img/tilemap_add_tile.png


BIN=BIN
tutorials/2d/img/tilemap_add_tileset.png


BIN=BIN
tutorials/2d/img/tilemap_draw.png


BIN=BIN
tutorials/2d/img/tilemap_menu.png


BIN=BIN
tutorials/2d/img/tilemap_mode.png


BIN=BIN
tutorials/2d/img/tilemap_size.png


BIN=BIN
tutorials/2d/img/tilemap_tool.png


BIN=BIN
tutorials/2d/img/tileset_add_collision.png


BIN=BIN
tutorials/2d/img/tileset_atlas.png


BIN=BIN
tutorials/2d/img/tileset_draw_atlas.png


BIN=BIN
tutorials/2d/img/tileset_snap.png


BIN=BIN
tutorials/2d/img/tilesheet.png


+ 1 - 0
tutorials/2d/index.rst

@@ -13,3 +13,4 @@
    2d_lights_and_shadows
    2d_meshes
    custom_drawing_in_2d
+   2d_sprite_animation

+ 111 - 127
tutorials/2d/using_tilemaps.rst

@@ -6,178 +6,162 @@ Using tilemaps
 Introduction
 ------------
 
-Tilemaps are a simple and quick way to make 2D game levels. Basically,
-you start with a bunch of reference tiles (or pieces) that can be put on a
-grid, as many times each as desired - think of it like a map editor:
-
-.. image:: img/tilemap.png
+A tilemap is a grid of tiles used to create a game's layout. There are several
+benefits to using :ref:`TileMap <class_TileMap>` nodes to design your levels.
+First, they make it possible to draw the layout by "painting' the tiles onto a
+grid, which is much faster than placing individual :ref:`Sprite <class_Sprite>`
+nodes one by one. Second, they allow for much larger levels because they are
+optimized for drawing large numbers of tiles. Finally, you can add collision,
+occlusion, and navigation shapes to tiles, adding additional functionality to
+the TileMap.
+
+.. image:: img/tileset_draw_atlas.png
+
+Project setup
+-------------
 
-Collisions can also be added to the tiles, allowing for both 2D side
-scrolling and top down games.
+This demo we'll use the following tiles taken from Kenney's "Abstract Platformer"
+art pack. You can find the complete set `here <https://kenney.nl/assets/abstract-platformer>`_
+but for this demo we'll stick to this small set.
 
-Making a tileset
-----------------
+.. image:: img/tilesheet.png
 
-To begin, a tileset needs to be made. Here are some tiles for it.
-They are all in the same image for optimization reasons.
-There are so-called *texture packers* that will generate these spritesheets
-out of your separate texture files.
-Having them as separate images also works.
+Create a new project and place the above image in the project folder.
 
-.. image:: img/tileset.png
+When using a tileset, it's important that adjacent tiles match up. Godot's default
+is to import 2D images using an interpolated "filter" mode, which will result in
+ugly borders between the tiles. Select the image and click the Import tab. Turn
+off ``Filter`` and click "Reimport". See :ref:`doc_import_images` for details.
 
-Create a new project and move the above PNG image into the directory. Next,
-go into the image's import settings and turn off ``Filter``, keeping it on will cause
-issues later. ``Mipmaps`` should already be disabled; if not, disable this too.
+TileMap node
+------------
 
-We will be creating a :ref:`TileSet <class_TileSet>`
-resource. While this resource exports properties, it's pretty difficult
-to get complex data into it and maintain it. Here is what it would look like to
-manually edit the resource:
+Add a new :ref:`TileMap <class_TileMap>` node to the scene. By default, a TileMap
+uses a square grid of tiles. You can also use a perspective-based "Isometric" mode
+or define your own custom tile shape.
 
-.. image:: img/tileset_edit_resource.png
+.. image:: img/tilemap_mode.png
 
-There are enough properties to get by. With some effort, editing this
-way can work. But the easiest way to edit and maintain a tileset is exporting
-it from a specially-crafted scene!
+Under the "Cell" section in the Inspector are many properties you can adjust to
+customize your tilemap's behavior:
 
-TileSet scene
--------------
+.. image:: img/tilemap_size.png
 
-Create a new scene with a regular Node or Node2D as root. For each tile you want to define,
-add a sprite node as a child. Since tiles here are 50x50, you should turn on the grid
-(``View -> Show Grid`` or ``G`` key) and enable snap (``Use Snap`` icon or ``Shift + S`` keys).
-Moving tiles with the mouse might still be a bit inaccurate,
-so use your arrow keys as well.
+- ``Cell Size``
+    This defines the size of the grid. This should match the pixel size
+    of your tiles. The default value is ``(64, 64)``.
 
-If more than one tile is present in the source image, make sure to use
-the region property of the sprite to adjust which part of the texture is being
-used.
+- ``YSort``
+    This causes tiles to be drawn in order of their ``Y`` position, so that
+    "lower" tiles are drawn on top of "higher" ones.
 
-Finally, make sure to name your sprite node correctly. This will ensure
-that, in subsequent edits to the tileset (for example, if you've added
-collision, changed the region, etc), the tile will still be **identified
-correctly and updated**. This name should be unique.
+- ``Half Offset`` and ``Tile Origin``
+    These properties affect the position of the tile relative to the grid position.
 
-Sounds like quite a few requirements, so here's a screenshot that shows
-where everything of relevance is:
+- ``Quadrant``
+    Defines the chunk size used for batched drawing. This can negatively
+    affect performance. Don't change it unless you know what you're doing.
 
-.. image:: img/tile_example.png
+- ``Custom Transform``
+    Used to alter the tile's shape. Use this if you have non-square tiles.
 
-Continue adding all the tiles, adjusting the offsets if needed (that is, if you have
-multiple tiles in a single source image). Again, *remember that their names must
-be unique*.
+All of these options can be left at their defaults for this demo.
 
-.. image:: img/tile_example2.png
+Creating a TileSet
+------------------
 
-Collision
----------
+Once you've configured your tilemap, it's time to add a
+:ref:`TileSet <class_TileSet>`. A TileSet is a
+:ref:`Resource <class_Resource>` that contains the data about your
+tiles - their   textures, collision shapes, and other properties. When the game
+runs, the TileMap combines the individual tiles into a single object.
 
-To add collision to a tile, create a StaticBody2D child for each sprite.
-This is a static collision node. Then create a CollisionShape2D or
-CollisionPolygon as a child of the StaticBody2D. The CollisionPolygon is
-recommended because it is easier to edit.
+To add a new TileSet, click on the "Tile Set" property and select "New
+TileSet".
 
-.. image:: img/tile_example3.png
+.. image:: img/tilemap_add_tileset.png
 
-Finally, edit the polygon; this will give the tile a collision and fix
-the warning icon next to the CollisionPolygon node. **Remember to use snap!**
-Using snap will make sure collision polygons are aligned properly, allowing
-a character to walk seamlessly from tile to tile. Also **do not scale or move**
-the collision and/or collision polygon nodes. Leave them at offset 0,0, with
-scale 1,1 and rotation 0 with respect to the parent sprite.
+When you do this, the "TileSet" panel will open at the bottom of the editor
+window:
 
-.. image:: img/tile_example4.png
+.. image:: img/tilemap_tool.png
 
-Keep adding collisions to the tiles until we are done. Note that BG is just
-a background, so it should not have a collision.
+First, you need to add the texture(s) that you'll use for the tiles. Click the
+"Add Texture(s) to TileSet" button and select the ``tilesheet.png`` image.
 
-.. image:: img/tile_example5.png
+Next, click "New Single Tile" and drag in the image to select the tile you want.
+Click the "Enable Snap" button to make it easier to select the entire tile. A
+yellow rectangle appears around the selected tile.
 
-OK! We're done! Remember to save this scene for future edit. Name it
-"tileset_edit.scn" or something like that.
+.. image:: img/tilemap_add_tile.png
 
-Exporting a TileSet
--------------------
+Click on the TileMap in the scene tree, and you'll see that the newly created
+tile now appears on the right side. Click in the viewport and you can place
+tiles. Right-click to remove them.
 
-With the scene created and opened in the editor, the next step will be to
-create a tileset. Use Scene > Convert To > Tile Set from the Scene Menu:
+.. image:: img/tilemap_draw.png
 
-.. image:: img/tileset_export.png
+It's easy to accidentally select and move the tilemap node. To avoid this, use
+the node's lock button:
 
-Then choose a filename, like "mytiles.tres". Make sure the "Merge With
-Existing" option is toggled on. This way, every time the tileset
-resource file is overwritten, existing tiles are merged and updated
-(they are referenced by their unique name, so again, **name your tiles
-properly**).
+.. image:: img/tile_lock.png
 
-.. image:: img/tileset_merge.png
+Collision Shapes
+----------------
 
-Using the TileSet in a TileMap
-------------------------------
+If you're making a map that needs collisions - walls, floor, or other obstacles,
+for example - then you'll need to add collision shapes to any tiles that you
+want to be considered "solid".
 
-Create a new scene, using any node or node2d as root, and then create a
-:ref:`TileMap <class_TileMap>` as
-a child.
+Click "TileSet" at the bottom of the editor window to return to the tileset
+tool. Click the tile you previously defined (outlined in yellow). Select the
+"Collision" tab and click the "Create a new rectangle" button. Make sure you
+still have grid snap enabled, then click and drag in the tile. A square
+collision shape appears in light blue:
 
-.. image:: img/tilemap_scene.png
+.. image:: img/tileset_add_collision.png
 
-Go to the TileSet property of this node and assign the one created in
-previous steps:
+You can add occlusion and navigation shapes to the tile in the same way.
 
-.. image:: img/tileset_property.png
+Atlas tiles
+-----------
 
-Also set the cell size to '50', since that is the size used by the
-tiles. Quadrant size is a tuning value, which means that the engine will
-draw and cull the tilemap in blocks of 16x16 tiles. This value is
-usually fine and does not need to be changed, but can be used to fine tune
-performance in specific cases (if you know what you are doing).
+Rather than adding individual tiles one at a time, you can define a group of
+tiles all at once using an atlas. Click "New Atlas" and drag to select the
+entire tile sheet.
 
-Painting your world
--------------------
+.. image:: img/tileset_atlas.png
 
-With all set, make sure the TileMap node is selected. A red grid will
-appear on the screen, allowing you to paint on it with the selected tile on the
-left palette.
+If you haven't already, make sure to change the "Step" in the snap settings to
+`(64, 64)`, or your tiles may be chopped into smaller pieces. You can find
+this in the Inspector:
 
-.. image:: img/tile_example6.png
+.. image:: img/tileset_snap.png
 
-To avoid accidentally moving and selecting the tilemap node (something
-common, given it's a huge node), it is recommended that you lock it,
-using the lock button:
+Once you've defined the atlas you can add collision shapes to the individual
+tiles as before. You can also click "Icon" to select one of the tiles to represent
+the atlas.
 
-.. image:: img/tile_lock.png
+Back in the TileMap, you can select the atlas tile and you'll see all of the
+tiles it contains:
 
-If you accidentally place a tile somewhere you don't want it to be, you
-can delete it with ``RMB`` (the right mouse button) while in the tilemap editor.
+.. image:: img/tileset_draw_atlas.png
 
-You can also flip and rotate sprites in the TileMap editor (note:
-flipping the sprite in the TileSet will have no effect). Icons at the
-top right of the editor allow flipping and rotating of the currently
-selected sprite - you can also use the A and S keys to flip the sprite
-horizontally and vertically. With a brick pattern like this tutorial uses,
-flipping the sprites would create unpleasant discontinuities unless you're
-flipping an entire region of bricks. But for some kinds of tiles, flipping
-can be a convenient and space-saving feature.
+In addition to saving time when defining the tiles, this can help by grouping
+similar tiles together when you're working with a large number of tiles.
 
-Offset and scaling artifacts
-----------------------------
+Tips and tricks
+---------------
 
-When using a single texture for all the tiles, scaling the tileset (or
-even moving to a non pixel-aligned location) will most likely result in
-filtering artifacts like so:
+- If you're using a :ref:`Camera2D <class_Camera2D>` to scroll your level, you
+  may notice lines appearing between your tiles. To fix this, open Project
+  Settings and enable "Use Pixel Snap" in the "Rendering/Quality" section.
 
-.. image:: img/tileset_filter.png
+- You can flip and rotate tiles using the icons at the top right of the editor.
 
-This is unavoidable, as it is the way the hardware bilinear filter
-works. To avoid this situation, there are a few workarounds. Try the
-one that looks better for you:
+- To draw straight lines, hold <Shift> while clicking and dragging a tile.
 
+- Tools such as copy, paste, and bucket fill, can be found in the "TileMap"
+  menu in the upper-right.
 
--  Disable filtering and mipmaps for either the tileset texture or all tile textures if using separate images (see the :ref:`doc_import_images` asset pipeline tutorial).
--  Enable pixel snap (Set ``Project > Project Settings >
-   Rendering > Quality > 2d > Use Pixel Snap`` to true; you can also search for ``Pixel Snap``).
--  Viewport Scaling can often help with shrinking the map (see the
-   :ref:`doc_viewports` tutorial). Simply adding a camera, setting it to ``Current`` and playing around with its ``Zoom`` may be a good starting point.
--  You can use a single, separate image for each tile. This will remove all artifacts, but
-   can be more cumbersome to implement and is less optimized.
+.. image:: img/tilemap_menu.png

BIN=BIN
tutorials/3d/files/gridmap_demo.zip


BIN=BIN
tutorials/3d/fps_tutorial/img/AnimationPlayerAddPoint.png


BIN=BIN
tutorials/3d/fps_tutorial/img/AnimationPlayerAddTrack.png


BIN=BIN
tutorials/3d/fps_tutorial/img/AnimationPlayerCallFuncTrack.png


BIN=BIN
tutorials/3d/fps_tutorial/img/AnimationPlayerEditPoints.png


BIN=BIN
tutorials/3d/fps_tutorial/img/AnimationPlayerInsertKey.png


+ 214 - 8
tutorials/3d/fps_tutorial/part_one.rst

@@ -138,7 +138,8 @@ Attach a new script to the ``Player`` node and call it ``Player.gd``.
 Let's program our player by adding the ability to move around, look around with the mouse, and jump.
 Add the following code to ``Player.gd``:
 
-::
+.. tabs::
+ .. code-tab:: gdscript GDScript
 
     extends KinematicBody
 
@@ -240,6 +241,135 @@ Add the following code to ``Player.gd``:
             camera_rot.x = clamp(camera_rot.x, -70, 70)
             rotation_helper.rotation_degrees = camera_rot
 
+ .. code-tab:: csharp
+
+    using Godot;
+    using System;
+
+    public class Player : KinematicBody
+    {
+        [Export]
+        public float Gravity = -24.8f;
+        [Export]
+        public float MaxSpeed = 20.0f;
+        [Export]
+        public float JumpSpeed = 18.0f;
+        [Export]
+        public float Accel = 4.5f;
+        [Export]
+        public float Deaccel = 16.0f;
+        [Export]
+        public float MaxSlopeAngle = 40.0f;
+        [Export]
+        public float MouseSensitivity = 0.05f;
+
+        private Vector3 _vel = new Vector3();
+        private Vector3 _dir = new Vector3();
+
+        private Camera _camera;
+        private Spatial _rotationHelper;
+
+        // Called when the node enters the scene tree for the first time.
+        public override void _Ready()
+        {
+            _camera = GetNode<Camera>("Rotation_Helper/Camera");
+            _rotationHelper = GetNode<Spatial>("Rotation_Helper");
+
+            Input.SetMouseMode(Input.MouseMode.Captured);
+        }
+
+        public override void _PhysicsProcess(float delta)
+        {
+            ProcessInput(delta);
+            ProcessMovement(delta);
+        }
+
+        private void ProcessInput(float delta)
+        {
+            //  -------------------------------------------------------------------
+            //  Walking
+            _dir = new Vector3();
+            Transform camXform = _camera.GetGlobalTransform();
+
+            Vector2 inputMovementVector = new Vector2();
+
+            if (Input.IsActionPressed("movement_forward"))
+                inputMovementVector.y += 1;
+            if (Input.IsActionPressed("movement_backward"))
+                inputMovementVector.y -= 1;
+            if (Input.IsActionPressed("movement_left"))
+                inputMovementVector.x -= 1;
+            if (Input.IsActionPressed("movement_right"))
+                inputMovementVector.x += 1;
+
+            inputMovementVector = inputMovementVector.Normalized();
+
+            _dir += -camXform.basis.z.Normalized() * inputMovementVector.y;
+            _dir += camXform.basis.x.Normalized() * inputMovementVector.x;
+            //  -------------------------------------------------------------------
+
+            //  -------------------------------------------------------------------
+            //  Jumping
+            if (IsOnFloor())
+            {
+                if (Input.IsActionJustPressed("movement_jump"))
+                    _vel.y = JumpSpeed;
+            }
+            //  -------------------------------------------------------------------
+
+            //  -------------------------------------------------------------------
+            //  Capturing/Freeing the cursor
+            if (Input.IsActionJustPressed("ui_cancel"))
+            {
+                if (Input.GetMouseMode() == Input.MouseMode.Visible)
+                    Input.SetMouseMode(Input.MouseMode.Captured);
+                else
+                    Input.SetMouseMode(Input.MouseMode.Visible);
+            }
+            //  -------------------------------------------------------------------
+        }
+
+        private void ProcessMovement(float delta)
+        {
+            _dir.y = 0;
+            _dir = _dir.Normalized();
+
+            _vel.y += delta * Gravity;
+
+            Vector3 hvel = _vel;
+            hvel.y = 0;
+
+            Vector3 target = _dir;
+
+            target *= MaxSpeed;
+
+            float accel;
+            if (_dir.Dot(hvel) > 0)
+                accel = Accel;
+            else
+                accel = Deaccel;
+
+            hvel = hvel.LinearInterpolate(target, accel * delta);
+            _vel.x = hvel.x;
+            _vel.z = hvel.z;
+            _vel = MoveAndSlide(_vel, new Vector3(0, 1, 0), false, 4, Mathf.Deg2Rad(MaxSlopeAngle));
+        }
+
+        public override void _Input(InputEvent @event)
+        {
+            if (@event is InputEventMouseMotion && Input.GetMouseMode() == Input.MouseMode.Captured)
+            {
+                InputEventMouseMotion mouseEvent = @event as InputEventMouseMotion;
+                _rotationHelper.RotateX(Mathf.Deg2Rad(mouseEvent.Relative.y * MouseSensitivity));
+                RotateY(Mathf.Deg2Rad(-mouseEvent.Relative.x * MouseSensitivity));
+
+                Vector3 cameraRot = _rotationHelper.RotationDegrees;
+                cameraRot.x = Mathf.Clamp(cameraRot.x, -70, 70);
+                _rotationHelper.RotationDegrees = cameraRot;
+            }
+        }
+    }
+
 This is a lot of code, so let's break it down function by function:
 
 .. tip:: While copy and pasting code is ill advised, as you can learn a lot from manually typing the code in, you can
@@ -339,7 +469,8 @@ In Godot, the origin is at position ``(0, 0, 0)`` with a rotation of ``(0, 0, 0)
 
 If you want to move using the world space directional vectors, you'd do something like this:
 
-::
+.. tabs::
+ .. code-tab:: gdscript GDScript
 
     if Input.is_action_pressed("movement_forward"):
         node.translate(Vector3(0, 0, 1))
@@ -349,6 +480,17 @@ If you want to move using the world space directional vectors, you'd do somethin
         node.translate(Vector3(1, 0, 0))
     if Input.is_action_pressed("movement_right"):
         node.translate(Vector3(-1, 0, 0))
+        
+ .. code-tab:: csharp
+ 
+    if (Input.IsActionPressed("movement_forward"))
+        node.Translate(new Vector3(0, 0, 1));
+    if (Input.IsActionPressed("movement_backward"))
+        node.Translate(new Vector3(0, 0, -1));
+    if (Input.IsActionPressed("movement_left"))
+        node.Translate(new Vector3(1, 0, 0));
+    if (Input.IsActionPressed("movement_right"))
+        node.Translate(new Vector3(-1, 0, 0));
 
 .. note:: Notice how we do not need to do any calculations to get world space directional vectors.
           We can define a few :ref:`Vector3 <class_Vector3>` variables and input the values pointing in each direction.
@@ -387,7 +529,8 @@ Each of those vectors point towards each of the local space vectors coming from
 
 To use the :ref:`Spatial <class_Spatial>` node's local directional vectors, we use this code:
 
-::
+.. tabs::
+ .. code-tab:: gdscript GDScript
 
     if Input.is_action_pressed("movement_forward"):
         node.translate(node.global_transform.basis.z.normalized())
@@ -397,6 +540,17 @@ To use the :ref:`Spatial <class_Spatial>` node's local directional vectors, we u
         node.translate(node.global_transform.basis.x.normalized())
     if Input.is_action_pressed("movement_right"):
         node.translate(-node.global_transform.basis.x.normalized())
+        
+ .. code-tab:: csharp
+        
+    if (Input.IsActionPressed("movement_forward"))
+        node.Translate(node.GlobalTransform.basis.z.Normalized());
+    if (Input.IsActionPressed("movement_backward"))
+        node.Translate(-node.GlobalTransform.basis.z.Normalized());
+    if (Input.IsActionPressed("movement_left"))
+        node.Translate(node.GlobalTransform.basis.x.Normalized());
+    if (Input.IsActionPressed("movement_right"))
+        node.Translate(-node.GlobalTransform.basis.x.Normalized());
 
 Here is what local space looks like in 2D:
 
@@ -539,7 +693,8 @@ so let's do that!
 
 First we need a few more class variables in our player script:
 
-::
+.. tabs::
+ .. code-tab:: gdscript GDScript
 
     const MAX_SPRINT_SPEED = 30
     const SPRINT_ACCEL = 18
@@ -547,6 +702,16 @@ First we need a few more class variables in our player script:
 
     var flashlight
 
+ .. code-tab:: csharp
+
+    [Export]
+    public float MaxSprintSpeed = 30.0f;
+    [Export]
+    public float SprintAccel = 18.0f;
+    private bool _isSprinting = false;
+    
+    private SpotLight _flashlight;
+
 All the sprinting variables work exactly the same as the non sprinting variables with
 similar names.
 
@@ -555,17 +720,23 @@ we will be using to hold the player's flash light node.
 
 Now we need to add a few lines of code, starting in ``_ready``. Add the following to ``_ready``:
 
-::
+.. tabs::
+ .. code-tab:: gdscript GDScript
 
     flashlight = $Rotation_Helper/Flashlight
 
+ .. code-tab:: csharp
+ 
+    _flashlight = GetNode<SpotLight>("Rotation_Helper/Flashlight");
+
 This gets the ``Flashlight`` node and assigns it to the ``flashlight`` variable.
 
 _________
 
 Now we need to change some of the code in ``process_input``. Add the following somewhere in ``process_input``:
 
-::
+.. tabs::
+ .. code-tab:: gdscript GDScript
 
     # ----------------------------------
     # Sprinting
@@ -584,6 +755,26 @@ Now we need to change some of the code in ``process_input``. Add the following s
             flashlight.show()
     # ----------------------------------
 
+ .. code-tab:: csharp
+ 
+    //  -------------------------------------------------------------------
+    //  Sprinting
+    if (Input.IsActionPressed("movement_sprint"))
+        _isSprinting = true;
+    else
+        _isSprinting = false;
+    //  -------------------------------------------------------------------
+
+    //  -------------------------------------------------------------------
+    //  Turning the flashlight on/off
+    if (Input.IsActionJustPressed("flashlight"))
+    {
+        if (_flashlight.IsVisibleInTree())
+            _flashlight.Hide();
+        else
+            _flashlight.Show();
+    }
+
 Let's go over the additions:
 
 We set ``is_sprinting`` to true when the player is holding down the ``movement_sprint`` action, and false
@@ -597,25 +788,40 @@ _________
 
 Now we need to change a couple things in ``process_movement``. First, replace ``target *= MAX_SPEED`` with the following:
 
-::
+.. tabs::
+ .. code-tab:: gdscript GDScript
 
     if is_sprinting:
         target *= MAX_SPRINT_SPEED
     else:
         target *= MAX_SPEED
 
+ .. code-tab:: csharp
+ 
+    if (_isSprinting)
+        target *= MaxSprintSpeed;    
+    else
+        target *= MaxSpeed;
+            
 Now instead of always multiplying ``target`` by ``MAX_SPEED``, we first check to see if the player is sprinting or not.
 If the player is sprinting, we instead multiply ``target`` by ``MAX_SPRINT_SPEED``.
 
 Now all that's left is to change the acceleration when sprinting. Change ``accel = ACCEL`` to the following:
 
-::
+.. tabs::
+ .. code-tab:: gdscript GDScript
 
     if is_sprinting:
         accel = SPRINT_ACCEL
     else:
         accel = ACCEL
 
+ .. code-tab:: csharp
+ 
+    if (_isSprinting)
+        accel = SprintAccel;
+    else
+        accel = Accel;
 
 Now, when the player is sprinting, we'll use ``SPRINT_ACCEL`` instead of ``ACCEL``, which will accelerate the player faster.
 

+ 17 - 37
tutorials/3d/fps_tutorial/part_two.rst

@@ -255,7 +255,7 @@ check for every possible animation state. If we need to, we will transition into
 
 _________
 
-Finally, there is ``animation_callback``. This function will be called by a function track in our animations.
+Finally, there is ``animation_callback``. This function will be called by a call method track in our animations.
 If we have a :ref:`FuncRef <class_FuncRef>` assigned to ``callback_function``, then we call that passed in function. If we do not
 have a :ref:`FuncRef <class_FuncRef>` assigned to ``callback_function``, we print out a warning to the console.
 
@@ -271,17 +271,16 @@ Before that, though, we need to set some animation callback tracks in our firing
 Open up ``Player.tscn`` if you don't have it open and navigate to the :ref:`AnimationPlayer <class_AnimationPlayer>` node
 (``Player`` -> ``Rotation_Helper`` -> ``Model`` -> ``Animation_Player``).
 
-We need to attach a function track to three of our animations: The firing animation for the pistol, rifle, and knife.
+We need to attach a call method track to three of our animations: The firing animation for the pistol, rifle, and knife.
 Let's start with the pistol. Click the animation drop down list and select "Pistol_fire".
 
 Now scroll down to the bottom of the list of animation tracks. The final item in the list should read
-``Armature/Skeleton:Left_UpperPointer``. Now at the bottom of the list, click the plus icon on the bottom
-bar of animation window, right next to the loop button and the up arrow.
+``Armature/Skeleton:Left_UpperPointer``. Now above the list, click the "Add track" button, to the left of the time line
 
 .. image:: img/AnimationPlayerAddTrack.png
 
-This will bring up a window with three choices. We want to add a function callback track, so click the
-option that reads "Add Call Func Track". This will open a window showing the entire node tree. Navigate to the
+This will bring up a window with a few choices. We want to add a call method track, so click the
+option that reads "Call Method Track". This will open a window showing the entire node tree. Navigate to the
 :ref:`AnimationPlayer <class_AnimationPlayer>` node, select it, and press OK.
 
 .. image:: img/AnimationPlayerCallFuncTrack.png
@@ -306,25 +305,13 @@ reach the point where the muzzle starts to flash.
 
          You can also change how the timeline scrubbing snaps by changing the value in ``Step (s)`` to a lower/higher value.
 
-Once you get to a point you like, press the little green plus symbol on the far right side of the
-``AnimationPlayer`` track. This will place a little green point at the position you are currently
-at in the animation on your ``AnimationPlayer`` track.
+Once you get to a point you like, right click on the row for "Animation Player" and press insert key.
+In the empty name field, enter ``animation_callback`` and press ``enter``.
 
-.. image:: img/AnimationPlayerAddPoint.png
+.. image:: img/AnimationPlayerInsertKey.png
 
-Now we have one more step before we are done with the pistol. Select the "enable editing of individual keys"
-button on the far right corner of the animation window. It looks like a pencil with a little point beside it.
 
-.. image:: img/AnimationPlayerEditPoints.png
-
-Once you've clicked that, a new window will open on the right side. Now click the green point on the ``AnimationPlayer``
-track. This will bring up the information associated with that point in the timeline. In the empty name field, enter
-``animation_callback`` and press ``enter``.
-
-Now when we are playing this animation the callback function will be triggered at that specific point of the animation.
-
-.. warning:: Be sure to press the "enable editing of individual keys" button again to turn off the ability to edit individual keys
-              so you cannot change one of the transform tracks by accident!
+Now when we are playing this animation the call method track will be triggered at that specific point of the animation.
 
 _________
 
@@ -333,28 +320,21 @@ Let's repeat the process for the rifle and knife firing animations!
 .. note:: Because the process is exactly the same as the pistol, the process is going to explained in a little less depth.
           Follow the steps from above if you get lost! It is exactly the same, just on a different animation.
 
-Go to the "Rifle_fire" animation from the animation drop down. Add the function callback track once you reach the bottom of the
-animation track list by clicking the little plus icon at the bottom of the screen. Find the point where the muzzle starts
-to flash and click the little green plus symbol to add a function callback point at that position on the track.
+Go to the "Rifle_fire" animation from the animation drop down. Add the call method track once you reach the bottom of the
+animation track list by clicking the "Add Track" button above the list. Find the point where the muzzle starts
+to flash and right click and press ``Insert Key`` to add a call method track point at that position on the track.
 
-Next, click the "enable editing of individual keys" button.
-Select the newly created function callback point, put "animation_callback" into the name field and press ``enter``.
-Click the "enable editing of individual keys" button again to turn off individual key editing.
-so we cannot change one of the transform tracks by accident.
+Type "animation_callback" into the name field of the pop up which opened and press ``enter``.
 
-Now we need to apply the callback function track to the knife animation. Select the "Knife_fire" animation and scroll to the bottom of the
-animation tracks. Click the plus symbol at the bottom of the animation window and add a function callback track.
-Next find a point around the first third of the animation to place the animation callback function point at.
+Now we need to apply the callback method track to the knife animation. Select the "Knife_fire" animation and scroll to the bottom of the
+animation tracks. Click the "Add Track" button above the list and add a method track.
+Next find a point around the first third of the animation to place the animation callback method point at.
 
 .. note:: We will not actually be firing the knife, and the animation is a stabbing animation rather than a firing one.
          For this tutorial we are reusing the gun firing logic for our knife, so the animation has been named in a style that
          is consistent with the other animations.
 
-From there click the little green plus to add a function callback point at the current position. Then click the "enable editing of individual keys"
-button, the button with a plus at the bottom right side of the animation window.
-Select the newly created function callback point, put "animation_callback" into the name field and press ``enter``.
-Click the "enable editing of individual keys" button again to turn off individual key editing,
-so we cannot change one of the transform tracks by accident.
+From there right click on the timeline and click "Insert Key". Put "animation_callback" into the name field and press ``enter``.
 
 .. tip:: Be sure to save your work!
 

BIN=BIN
tutorials/3d/img/multimesh_scene_tree.png


BIN=BIN
tutorials/3d/img/multimesh_toolbar.png


+ 2 - 2
tutorials/3d/using_multi_mesh_instance.rst

@@ -31,8 +31,8 @@ on. In the tree example, this would be the landscape.
 The other node is used as the source, the mesh that you want to have duplicated.
 In the tree case, this would be the tree itself.
 
-In our example, we would use a :ref:`Node <class_Node>` as the root node of the
-scene. Your scene tree would look like this:
+In our example, we would use a :ref:`Spatial <class_Spatial>` node as the root node of
+the scene. Your scene tree would look like this:
 
 .. image:: img/multimesh_scene_tree.png
 

+ 2 - 2
tutorials/3d/using_transforms.rst

@@ -334,7 +334,7 @@ Example of looking around, FPS style:
 
     public override void _Input(InputEvent @event)
     {
-        if (mouseMotion is InputEventMouseMotion mouseMotion)
+        if (@event is InputEventMouseMotion mouseMotion)
         {
             // modify accumulated mouse rotation
             _rotationX += mouseMotion.Relative.x * LookAroundSpeed;
@@ -374,7 +374,7 @@ Converting a rotation to quaternion is straightforward.
 
     // Convert basis to quaternion, keep in mind scale is lost
     var a = transform.basis.Quat();
-    var b = transform.basis.Quat();
+    var b = transform2.basis.Quat();
     // Interpolate using spherical-linear interpolation (SLERP).
     var c = a.Slerp(b, 0.5f); // find halfway point between a and b
     // Apply back

+ 9 - 9
tutorials/3d/vertex_animation/animating_thousands_of_fish.rst

@@ -80,13 +80,13 @@ We construct a rotation matrix like so:
   //angle is scaled by 0.1 so that the fish only pivots and doesn't rotate all the way around
   //pivot is a uniform float
   float pivot_angle = cos(time) * 0.1 * pivot;
-	mat2 rotation_matrix = mat2(vec2(cos(pivot_angle), -sin(pivot_angle)), vec2(sin(pivot_angle), cos(pivot_angle)));
+  mat2 rotation_matrix = mat2(vec2(cos(pivot_angle), -sin(pivot_angle)), vec2(sin(pivot_angle), cos(pivot_angle)));
 
 And then we apply it in the ``x`` and ``z`` axes by multiplying it by ``VERTEX.xz``.
 
 .. code-block:: glsl
 
-	VERTEX.xz = rotation_matrix * VERTEX.xz;
+  VERTEX.xz = rotation_matrix * VERTEX.xz;
 
 With only the pivot applied you should see something like this:
 
@@ -121,14 +121,14 @@ we first  construct a rotation matrix.
 
   //twist is a uniform float
   float twist_angle = cos(time + body) * 0.3 * twist;
-	mat2 twist_matrix = mat2(vec2(cos(twist_angle), -sin(twist_angle)), vec2(sin(twist_angle), cos(twist_angle)));
+  mat2 twist_matrix = mat2(vec2(cos(twist_angle), -sin(twist_angle)), vec2(sin(twist_angle), cos(twist_angle)));
 
 We apply the rotation in the ``xy`` axes so that the fish appears to roll around its spine. For 
 this to work, the fishes spine needs to be centered on the ``z`` axis.
 
 .. code-block:: glsl
 
-	VERTEX.xy = twist_matrix * VERTEX.xy;
+  VERTEX.xy = twist_matrix * VERTEX.xy;
 
 Here is the fish with twist applied:
 
@@ -219,10 +219,10 @@ to loop over all the instances and set their transform to a random position.
 
 ::
   
-	for i in range($School.multimesh.instance_count):
-		var position = Transform()
-		position = position.translated(Vector3(randf() * 100 - 50, randf() * 50 - 25, randf() * 50 - 25))
-		$School.multimesh.set_instance_transform(i, position)
+  for i in range($School.multimesh.instance_count):
+    var position = Transform()
+    position = position.translated(Vector3(randf() * 100 - 50, randf() * 50 - 25, randf() * 50 - 25))
+    $School.multimesh.set_instance_transform(i, position)
 
 Running this script will place the fish in random positions in a box around the position of the
 MultiMeshInstance.
@@ -244,7 +244,7 @@ We do that by adding the per-instance custom value ``INSTANCE_CUSTOM`` to ``time
 
 .. code-block:: glsl
 
- 	float time = (TIME * time_scale) + (6.28318 * INSTANCE_CUSTOM.x);
+  float time = (TIME * time_scale) + (6.28318 * INSTANCE_CUSTOM.x);
 
 Next, we need to pass a value into ``INSTANCE_CUSTOM``. We do that by adding one line into 
 the ``for`` loop from above. In the ``for`` loop we assign each instance a set of four 

+ 4 - 4
tutorials/3d/vertex_animation/controlling_thousands_of_fish.rst

@@ -92,16 +92,16 @@ Then, use those seeds to generate random numbers using ``rand_from_seed``:
 .. code-block:: glsl
 
   CUSTOM.x = rand_from_seed(alt_seed1);
-  vec3 position = vec3(rand_from_seed(alt_seed2)*2.0-1.0, 
-                       rand_from_seed(alt_seed3)*2.0-1.0, 
-                       rand_from_seed(alt_seed4)*2.0-1.0);
+  vec3 position = vec3(rand_from_seed(alt_seed2) * 2.0 - 1.0, 
+                       rand_from_seed(alt_seed3) * 2.0 - 1.0, 
+                       rand_from_seed(alt_seed4) * 2.0 - 1.0);
 
 Finally, assign ``position`` to ``TRANSFORM[3].xyz``, which is the part of the transform that holds
 the position information.
 
 .. code-block:: glsl
 
-  TRANSFORM[3].xyz = CUSTOM.xyz*20.0;
+  TRANSFORM[3].xyz = position * 20.0;
 
 Remember, all this code so far goes inside the ``RESTART`` block.
 

+ 166 - 165
tutorials/animation/cutout_animation.rst

@@ -6,47 +6,46 @@ Cutout animation
 What is it?
 ~~~~~~~~~~~
 
-Cut-out is a technique of animating in 2D where pieces of paper (or
-similar material) are cut in special shapes and laid one over the other.
-The papers are animated and photographed, frame by frame using a stop
-motion technique (more info
-`here <https://en.wikipedia.org/wiki/Cutout_animation>`__).
-
-With the advent of the digital age, this technique became possible using
-computers, which resulted in an increased amount of animation TV shows
-using digital Cut-out. Notable examples are `South
-Park <https://en.wikipedia.org/wiki/South_Park>`__ or `Jake and the Never
-Land
-Pirates <https://en.wikipedia.org/wiki/Jake_and_the_Never_Land_Pirates>`__
-.
+Traditionally, `cutout animation <https://en.wikipedia.org/wiki/Cutout_animation>`__
+is a type of `stop motion animation <https://en.wikipedia.org/wiki/Stop_motion>`__
+in which pieces of paper (or other thin material) are cut into special shapes
+and arranged in two-dimensional representations of characters and objects.
+Characters' bodies are usually made out of several pieces. The pieces are
+arranged and photographed once for each frame of the film. The animator moves
+and rotates the parts in small increments between each shot to create the
+illusion of movement when the images are played back quickly in sequence.
+
+Simulations of cutout animation can now be created using software as seen in
+`South Park <https://en.wikipedia.org/wiki/South_Park>`__ and `Jake and the Never
+Land Pirates <https://en.wikipedia.org/wiki/Jake_and_the_Never_Land_Pirates>`__.
 
 In video games, this technique has also become popular. Examples of
-this are `Paper
-Mario <https://en.wikipedia.org/wiki/Super_Paper_Mario>`__ or `Rayman
-Origins <https://en.wikipedia.org/wiki/Rayman_Origins>`__ .
+this are `Paper Mario <https://en.wikipedia.org/wiki/Super_Paper_Mario>`__ or
+`Rayman Origins <https://en.wikipedia.org/wiki/Rayman_Origins>`__ .
 
-Cutout in Godot
-~~~~~~~~~~~~~~~
+Cutout animation in Godot
+~~~~~~~~~~~~~~~~~~~~~~~~~
 
-Godot provides a few tools for working with these kind of assets, but
-its overall design makes it ideal for the workflow. The reason is that,
-unlike other tools meant for this, Godot has the following advantages:
+Godot provides tools for working with cutout rigs, and is ideal for the workflow:
 
 -  **The animation system is fully integrated with the engine**: This
-   means, animations can control much more than just motion of objects,
-   such as textures, sprite sizes, pivots, opacity, color modulation,
-   etc. Everything can be animated and blended.
--  **Mix with Traditional**: AnimatedSprite allows traditional animation
-   to be mixed, useful for complex objects, such as shape of hands
-   and foot, changing facial expression, etc.
--  **Custom Shaped Elements**: Can be created with
+   means animations can control much more than just motion of objects. Textures,
+   sprite sizes, pivots, opacity, color modulation, and more, can all be animated
+   and blended.
+-  **Combine animation styles**: AnimatedSprite allows traditional cel animation 
+   to be used alongside cutout animation. In cel animation different animation
+   frames use entirely different drawings rather than the same pieces positioned
+   differently. In an otherwise cutout-based animation, cel animation can be used
+   selectively for complex parts such as hands, feet, changing facial expressions,
+   etc.
+-  **Custom Shaped Elements**: Custom shapes can be created with
    :ref:`Polygon2D <class_Polygon2D>`
-   allowing the mixing of UV animation, deformations, etc.
--  **Particle Systems**: Can also be mixed with the traditional
-   animation hierarchy, useful for magic effects, jetpacks, etc.
+   allowing UV animation, deformations, etc.
+-  **Particle Systems**: A cutout animation rig can be combined with particle
+   systems. This can useful for magic effects, jetpacks, etc.
 -  **Custom Colliders**: Set colliders and influence areas in different
-   parts of the skeletons, great for bosses, fighting games, etc.
--  **Animation Tree**: Allows complex combinations and blendings of
+   parts of the skeletons, great for bosses and fighting games.
+-  **Animation Tree**: Allows complex combinations and blending between
    several animations, the same way it works in 3D.
 
 And much more!
@@ -69,14 +68,14 @@ Create an empty Node2D as root of the scene, we will work under it:
 
 .. image:: img/tuto_cutout1.png
 
-OK, the first node of the model that we will create will be the hip.
+The first node of the model is the hip.
 Generally, both in 2D and 3D, the hip is the root of the skeleton. This
 makes it easier to animate:
 
 .. image:: img/tuto_cutout2.png
 
 Next will be the torso. The torso needs to be a child of the hip, so
-create a child sprite and load the torso, later accommodate it properly:
+create a child sprite and load the torso texture, later accommodate it properly:
 
 .. image:: img/tuto_cutout3.png
 
@@ -86,11 +85,9 @@ and dragging with the left mouse button. To exit rotate mode hit ``ESC``.
 
 .. image:: img/tutovec_torso1.gif
 
-Ouch, that doesn't look good! The rotation pivot is wrong, this means
-it needs to be adjusted.
+The rotation pivot is wrong and needs to be adjusted.
 
-This small little cross in the middle of the
-:ref:`Sprite <class_Sprite>` is
+This small cross in the middle of the :ref:`Sprite <class_Sprite>` is
 the rotation pivot:
 
 .. image:: img/tuto_cutout4.png
@@ -103,52 +100,52 @@ Sprite:
 
 .. image:: img/tuto_cutout5.png
 
-However, there is a way to do it more *visually*. While hovering over the
-desired pivot point, simply press the "v" key to move the pivot there for the
-selected Sprite. Alternately, there is a tool in the tool bar that has a
+The pivot can also be adjusted *visually*. While hovering over the
+desired pivot point,  press the "v" key to move the pivot there for the
+selected Sprite. There is also a tool in the tool bar that has a
 similar function.
 
 .. image:: img/tutovec_torso2.gif
 
-Now it looks good! Let's continue adding body pieces, starting by the
-right arm. Make sure to put the sprites in hierarchy, so their rotations
-and translations are relative to the parent:
+Continue adding body pieces, starting with the
+right arm. Make sure to put each sprite in its correct place in the hierarchy,
+so its rotations and translations are relative to its parent:
 
 .. image:: img/tuto_cutout6.png
 
-This seems easy, so continue with the left arm. The rest should be
-simple! Or maybe not:
+With the left arm there's a problem. In 2D, child nodes appear in front of
+their parents:
 
 .. image:: img/tuto_cutout7.png
 
-Right. In 2D, parent nodes appear below children nodes. Well, this sucks.
-But how can this problem be solved? We want the left arm to appear behind
-the hip and the torso. For this, we can move the nodes behind the hip
-(note that you can bypass this by setting the Node2D Z property, but then you
-won't learn about all this!):
+We want the left arm to appear *behind*
+the hip and the torso. We could move the left arm nodes behind the hip (above
+the hip node in the scene hierarchy), but then the left arm is no longer in its
+proper place in the hierarchy. This means it wouldn't be affected the movement
+of the torso. We'll fix this problem with ``RemoteTransform2D`` nodes.
 
-.. image:: img/tuto_cutout8.png
-
-But then, we lose the hierarchy layout, which allows to control the
-skeleton like.. a skeleton. Is there any hope?.. Of Course!
+.. note:: You can also fix depth ordering problems by adjusting the Z property
+   of any node inheriting from Node2D.
 
 RemoteTransform2D node
 ~~~~~~~~~~~~~~~~~~~~~~
 
-Godot provides a special node, :ref:`RemoteTransform2D <class_RemoteTransform2D>`.
-This node will transform nodes that are sitting somewhere else in the
-hierarchy, by applying the transform to the remote nodes.
+The :ref:`RemoteTransform2D <class_RemoteTransform2D>` node transforms nodes
+somewhere else in the hierarchy. This node applies its own transform (including
+any transformation it inherits from its parents) to the remote node it targets.
 
-This enables to have a visibility order independent from the
-hierarchy.
+This allows us to correct the visibility order of our elements independent from
+the locations of those parts in the cutout hierarchy.
 
-Simply create two more nodes as children from torso, remote_arm_l and
-remote_hand_l and link them to the actual sprites:
+Create a ``RemoteTransform2D`` node as a child of the torso. Call it ``remote_arm_l``.
+Create another RemoteTransform2D node inside the first and call it ``remote_hand_l``.
+Use the ``Remote Path`` property of the two new nodes to target the ``arm_l`` and
+``hand_l`` sprites respectively:
 
 .. image:: img/tuto_cutout9.png
 
-Moving the remote transform nodes will move the sprites, allowing you to
-easily animate and pose the character:
+Moving the ``RemoteTransform2D`` nodes now moves the sprites. So we can create
+animations by adjusting the ``RemoteTransform2D`` transforms:
 
 .. image:: img/tutovec_torso4.gif
 
@@ -163,27 +160,23 @@ parts. The resulting scene should look similar to this:
 The resulting rig will be easy to animate. By selecting the nodes and
 rotating them you can animate forward kinematics (FK) efficiently.
 
-For simple objects and rigs this is fine, however the following problems
-are common:
+For simple objects and rigs this is fine, but there are limitations:
 
--  Selecting sprites can become difficult for complex rigs, and the
-   scene tree ends being used due to the difficulty of clicking over the
-   proper sprite.
--  Inverse Kinematics is often desired for extremities.
+-  Selecting sprites in the main viewport can become difficult in complex rigs.
+   The scene tree ends up being used to select parts instead, which can be slower.
+-  Inverse Kinematics (IK) is useful for animating extremities like hands and
+   feet, and can't be used with our rig in its current state.
 
-To solve these problems, Godot supports a simple method of skeletons.
+To solve these problems we'll use Godot's skeletons.
 
 Skeletons
 ~~~~~~~~~
 
-Godot doesn't actually support *true* Skeletons, but it does feature a
-helper to create "bones" between nodes. This is enough for most cases,
-but the way it works is not completely obvious.
-
-
+In Godot there is a helper to create "bones" between nodes. The bone-linked
+nodes are called skeletons.
 
 As an example, let's turn the right arm into a skeleton. To create
-skeletons, a chain of nodes must be selected from top to bottom:
+a skeleton, a chain of nodes must be selected from top to bottom:
 
 .. image:: img/tuto_cutout11.png
 
@@ -191,25 +184,13 @@ Then, click on the Skeleton menu and select ``Make Bones``.
 
 .. image:: img/tuto_cutout12.png
 
-This will add bones covering the arm, but the result is not quite what
-is expected.
+This will add bones covering the arm, but the result may be surprising.
 
 .. image:: img/tuto_cutout13.png
 
-It looks like the bones are shifted up in the hierarchy. The hand
-connects to the arm, and the arm to the body. So the question is:
-
--  Why does the hand lack a bone?
--  Why does the arm connect to the body?
-
-This might seem strange at first, but will make sense later on. In
-traditional skeleton systems, bones have a position, an orientation and
-a length. In Godot, bones are mostly helpers so they connect the current
-node with the parent. Because of this, **toggling a node as a bone will
-just connect it to the parent**.
-
-So, with this knowledge. Let's do the same again so we have an actual,
-useful skeleton.
+Why does the hand lack a bone? In Godot, a bone connects a
+node with its parent. And there's currently no child of the hand node.
+With this knowledge let's try again.
 
 The first step is creating an endpoint node. Any kind of node will do,
 but :ref:`Position2D <class_Position2D>` is preferred because it's
@@ -226,36 +207,40 @@ bones:
 The result resembles a skeleton a lot more, and now the arm and forearm
 can be selected and animated.
 
-Finally, create endpoints in all meaningful extremities and connect the
-whole skeleton with bones up to the hip.
+Create endpoints for all important extremities. Generate bones for all
+articulable parts of the cutout, with the hip as the ultimate connection
+between all of them.
 
-You may notice when connecting the hip and torso, that an extra bone is created.
-To fix this, select the root and hip node, open the Skeleton menu, click ``clear bones``.
+You may notice that an extra bone is created when connecting the hip and torso.
+Godot has connected the hip node to the scene root with a bone, and we don't
+want that. To fix this, select the root and hip node, open the Skeleton menu,
+click ``clear bones``.
 
 .. image:: img/tuto_cutout15_2.png
 
-
-After fixing that your final skeleton should look something like this:
+Your final skeleton should look something like this:
 
 .. image:: img/tuto_cutout16.png
 
-Finally! the whole skeleton is rigged! On close look, it is noticeable
-that there is a second set of endpoints in the hands. This will make
+You might have noticed a second set of endpoints in the hands. This will make
 sense soon.
 
-Now that a whole skeleton is rigged, the next step is setting up the IK
+Now that the whole figure is rigged, the next step is setting up the IK
 chains. IK chains allow for more natural control of extremities.
 
 IK chains
 ~~~~~~~~~
 
-IK chains are a powerful animation tool. Imagine you want to pose a character's foot in a specific position on the ground. Without IK chains, each motion of the foot would require rotating and positioning several other bones. This would be quite complex and lead to imprecise results.
-
-What if we could move the foot and let the rest of the leg self-adjust?
+IK stands for inverse kinematics. It's a convenient technique for animating the
+position of hands, feet and other extremities of rigs like the one we've made.
+Imagine you want to pose a character's foot in a specific position on the ground.
+Without IK chains, each motion of the foot would require rotating and positioning
+several other bones (the shin and the thigh at least). This would be quite
+complex and lead to imprecise results.
 
-This type of posing is called IK (Inverse Kinematic).
+IK allows us to move directly the foot while the shin and thigh self-adjust.
 
-To create an IK chain, simply select a chain of bones from endpoint to
+To create an IK chain, select a chain of bones from endpoint to
 the base for the chain. For example, to create an IK chain for the right
 leg, select the following:
 
@@ -269,103 +254,119 @@ As a result, the base of the chain will turn *Yellow*.
 
 .. image:: img/tuto_cutout19.png
 
-Once the IK chain is set-up, simply grab any of the bones in the
-extremity, any child or grand-child of the base of the chain and try to
-grab it and move it. Result will be pleasant, satisfaction warranted!
+Once the IK chain is set-up grab any child or grand-child of the base of the
+chain (e.g. a foot) and move it. You'll see the rest of the chain adjust as you
+adjust its position.
 
 .. image:: img/tutovec_torso5.gif
 
-Animation
-~~~~~~~~~
+Animation tips
+~~~~~~~~~~~~~~
 
-The following section will be a collection of tips for creating
-animation for your rigs. If unsure about how the animation system in
-Godot works, refresh it by checking again the :ref:`doc_animations`.
+The following section will be a collection of tips for creating animation for
+your cutout rigs. For more information on how the animation system in Godot
+works, see :ref:`doc_animations`.
 
-2D animation
-------------
+Setting keyframes and excluding properties
+------------------------------------------
 
-When doing animation in 2D, a helper will be present in the top menu.
-This helper only appears when the animation editor window is opened:
+Special contextual elements appear in the top toolbar when the animation editor
+window is open:
 
 .. image:: img/tuto_cutout20.png
 
-The key button will insert location/rotation/scale keyframes to the
-selected objects or bones. This depends on the mask enabled. Green items
-will insert keys while red ones will not, so modify the key insertion
-mask to your preference.
+The key button inserts location, rotation, and scale keyframes for the
+selected objects or bones at the current playhead position.
 
-Rest pose
-~~~~~~~~~
+The "loc", "rot", and "scl" toggle buttons to the left of the key button modify
+its function, allowing you to specify which of the three properties keyframes
+will be created for.
+
+Here's an illustration of how this can be useful: Imagine you have a node which
+already has two keyframes animating its scale only. You want to add an
+overlapping rotation movement to the same node. The rotation movement should
+begin and end at different times from the scale change that's already set up.
+You can use the toggle buttons to have only rotation information added when you
+add a new keyframe. This way, you can avoid adding unwanted scale keyframes
+which would disrupt the existing scale animation.
 
-These kind of rigs do not have a "rest" pose, so it's recommended to
-create a reference rest pose in one of the animations.
+Creating a rest pose
+~~~~~~~~~~~~~~~~~~~~
 
-Simply do the following steps:
+Think of a rest pose as a default pose that your cutout rig should be set to
+when no other pose is active in your game. Create a rest pose as follows:
 
-1. Make sure the rig is in "rest" (not doing any specific pose).
+1. Make sure the rig parts are positioned in what looks like a "resting"
+arrangement.
 
-2. Create a new animation, rename it to "rest".
+2. Create a new animation, rename it "rest".
 
-3. Select all nodes (box selection should work fine).
+3. Select all nodes in your rig (box selection should work fine).
 
-4. Select "loc" and "rot" on the top menu.
+4. Make sure the "loc", "rot", and "scl" toggle buttons are all active in the
+toolbar.
 
-5. Push the key button. Keys will be inserted for everything, creating
-   a default pose.
+5. Press the key button. Keys will be inserted for all selected parts storing
+their current arrangement. This pose can now be recalled when necessary in
+your game by playing the "rest" animation you've created.
 
 .. image:: img/tuto_cutout21.png
 
-Rotation
-~~~~~~~~
+Modifying rotation only
+~~~~~~~~~~~~~~~~~~~~~~~
 
-Animating these models means only modifying the rotation of the nodes.
-Location and scale are rarely used, with the only exception of moving
-the entire rig from the hip (which is the root node).
+When animating a cutout rig, often it's only the rotation of the nodes that
+needs to change.
+Location and scale are rarely used.
 
-As a result, when inserting keys, only the "rot" button needs to be
-pressed most of the time:
+So when inserting keys, you might find it convenient to have only the "rot"
+toggle active most of the time:
 
 .. image:: img/tuto_cutout22.png
 
-This will avoid the creation of extra animation tracks for the position
-that will remain unused.
+This will avoid the creation of unwanted animation tracks for position
+and scale.
 
-Keyframing IK
-~~~~~~~~~~~~~
+Keyframing IK chains
+~~~~~~~~~~~~~~~~~~~~
 
-When editing IK chains, it is not necessary to select the whole chain to
+When editing IK chains, it's not necessary to select the whole chain to
 add keyframes. Selecting the endpoint of the chain and inserting a
-keyframe will automatically insert keyframes until the chain base too.
-This makes the task of animating extremities much simpler.
+keyframe will automatically insert keyframes for all other parts of the chain too.
+
+Visually move a sprite behind its parent
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-Moving sprites above and behind others
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Sometimes it is necessary to have a node change its visual depth relative to
+its parent node during an animation. Think of a character facing the camera,
+who pulls something out from behind his back and holds it out in front of him.
+During this animation the whole arm and the object in his hand would need to
+change their visual depth relative to the body of the character.
 
-RemoteTransform2D works in most cases, but sometimes it is
-necessary to have a node above and below others during an animation. To
-aid on this the "Behind Parent" property exists on any Node2D:
+To help with this there's a keyframable "Behind Parent" property on all
+Node2D-inheriting nodes. When planning your rig, think about the movements it
+will need to perform and give some thought to how you'll use "Behind Parent"
+and/or RemoteTransform2D nodes. They provide overlapping functionality.
 
 .. image:: img/tuto_cutout23.png
 
-Batch setting transition curves
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Setting easing curves for multiple keys
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+To apply the same the easing curve to multiple keyframes at once:
 
-When creating complex animations and inserting many keyframes,
-editing the individual keyframe curves for each can become an endless
-task. For this, the Animation Editor has a small menu where changing
-animation curves is easy. First select the appropriate keys. Next click on the
-pencil icon in the bottom right of the animation panel, this will open the
-transition editor. Now click on one of the curve options most appropriate for
-your animation.
+1. Select the relevant keys.
+2. Click on the pencil icon in the bottom right of the animation panel, this
+   will open the transition editor.
+3. In the transition editor click on the desired curve to apply it.
 
 .. image:: img/tuto_cutout24.png
 
 2D Skeletal deform
 ~~~~~~~~~~~~~~~~~~
 
-Starting with Godot 3.1, 2D skeletal deform is supported, which can be used to enhance this workflow and add more flexibility 
-(single pieces can deform more organically instead of having to use many separate ones). 
+Skeletal deform can be used to augment a cutout rig, allowing single pieces to
+deform organically (e.g. antennae that wobble as an insect character walks).
 
 This process is described in a :ref:`separate tutorial <doc_2d_skeletons>`.
 

+ 53 - 57
tutorials/audio/audio_buses.rst

@@ -6,34 +6,23 @@ Audio buses
 Introduction
 ------------
 
-Beginning with Godot 3.0, the audio engine has been rewritten from scratch.
-The aim now is to present an interface much friendlier to sound design
-professionals. To achieve this, the audio engine contains a virtual rack
-where unlimited audio buses can be created and, on each of it, unlimited
-amount of effect processors can be added (or more like, as long as your
-CPU holds up!)
+Godot's audio processing code has been written with games in mind, with the aim of achieving an optimal balance between performance and sound quality.
 
-The implementation in Godot is pretty efficient and has been written
-entirely from the ground up, without relying on any existing audio libraries.
-
-Even the effect processors were written exclusively for Godot (save for
-the pitch shifting library), with games in mind. This allows
-an efficient tradeoff between performance and sound quality.
+Godot's audio engine allows any number of audio buses to be created and any number of effect processors can be added to each bus. Only the hardware of the device running your game will limit the number of buses and effects that can be used before performance starts to suffer.
 
 Decibel scale
 -------------
 
-The new audio engine works primarily using the decibel scale. We have
-chosen this over linear representation of amplitude because it's
-more intuitive for audio professionals.
+Godot's sound interface is designed to meet the expectations of sound design
+professionals. To this end it primarily uses the decibel scale.
 
 For those unfamiliar with it, it can be explained with a few facts:
 
 * The decibel (dB) scale is a relative scale. It represents the ratio of sound power by using 10 times the base 10 logarithm of the ratio (10×log\ :sub:`10`\ (P/P\ :sub:`0`\ )).
-* For every 3dB, sound doubles or halves. 6dB represents a factor 4, 9dB a factor 8, 10dB a factor 10, 20dB a factor 100, etc.
+* For every 3dB, sound amplitude doubles or halves. 6dB represents a factor of 4, 9dB a factor of 8, 10dB a factor of 10, 20dB a factor of 100, etc.
 * Since the scale is logarithmic, true zero (no audio) can't be represented.
-* 0dB is considered the maximum audible volume without *clipping*. This limit is not the human limit, but a limit from the sound hardware. Your sound output simply can't output any sound louder than 0dB without distorting it (clipping it).
-* Because of the above, your sound mix should work in a way where the sound output of the *Master Bus* (more on that later), should never be above 0dB.
+* 0dB is the maximum amplitude possible in a digital audio system. This limit is not the human limit, but a limit from the sound hardware. Audio with amplitudes that are too high to be represented properly below 0dB create a kind of distortion called clipping.
+* To avoid clipping, your sound mix be arranged so that the output of the *Master Bus* (more on that later) never exceeds 0dB.
 * Every 3dB below the 0dB limit, sound energy is *halved*. It means the sound volume at -3dB is half as loud as 0dB. -6dB is half as loud as -3dB and so on.
 * When working with decibels, sound is considered no longer audible between -60dB and -80dB. This makes your working range generally between -60dB and 0dB.
 
@@ -46,20 +35,20 @@ Audio buses can be found in the bottom panel of the Godot Editor:
 
 .. image:: img/audio_buses1.png
 
-An *Audio Bus* bus (often called *Audio Channel* too) is a device where audio is channeled. Audio data passes through it and can be *modified* and *re-routed*. A VU meter (the bars that go up and down when sound is played) can measure the loudness of the sound in Decibel scale.
+An *Audio Bus* (also called an *Audio Channel*) can be considered a place that audio is channeled through on the way to playback through a device's speakers. Audio data can be *modified* and *re-routed* by an *Audio Bus*. An *Audio Bus* has a VU meter (the bars that light up when sound is played) which indicates the amplitude of the signal passing through.
 
-The leftmost bus is the *Master Bus*. This bus outputs the mix to your speakers so, as mentioned in the item above (Decibel Scale), make sure that your mix rarely or never goes above 0dB in this bus.
-The rest of the audio buses are used for *routing*. This means that, after modifying the sound, they must send it to another bus to the left. Routing is always from right to left without exception as this
-avoids creating infinite routing loops!
+The leftmost bus is the *Master Bus*. This bus outputs the mix to your speakers so, as mentioned in the item above (Decibel Scale), make sure that your mix level doesn't reach 0dB in this bus.
+The rest of the audio buses can be flexibly routed. After modifying the sound, they send it to another bus to the left. The destination bus can be specified for each of the non-master audio buses. Routing always passes audio from buses on the right to buses further to the left. This
+avoids infinite routing loops.
 
 .. image:: img/audio_buses2.png
 
-In the above image, *Bus 2* is routing its output to the *Master* bus.
+In the above image, the output of *Bus 2* has been routed to the *Master* bus.
 
-Playback of audio to a bus
---------------------------
+Playback of audio through a bus
+-------------------------------
 
-To test playback to a bus, create an AudioStreamPlayer node, load an AudioStream and select a target bus for playback:
+To test passing audio to a bus, create an AudioStreamPlayer node, load an AudioStream and select a target bus for playback:
 
 .. image:: img/audio_buses3.png
 
@@ -74,37 +63,40 @@ Audio buses can contain all sorts of effects. These effects modify the sound in
 
 .. image:: img/audio_buses4.png
 
-Following is a short description of available effects:
+Try them all out to get a sense of how they alter sound. Here follows a short description of available effects:
 
 Amplify
 ~~~~~~~
 
-It's the most basic effect. It changes the sound volume. Amplifying too much can make the sound clip, so be wary of that.
+Amplify changes the amplitude of the signal. Some care needs to be taken. Setting the level too high can make the sound clip, which is usually undesirable.
 
 BandLimit and BandPass
 ~~~~~~~~~~~~~~~~~~~~~~
 
-These are resonant filters which block frequencies around the *Cutoff* point. BandPass is resonant, while BandLimit stretches to the sides.
+These are resonant filters which block frequencies around the *Cutoff* point. BandPass can be used to simulate sound passing through an old telephone line or megaphone. Modulating the BandPass frequency can simulate the sound of a wah-wah guitar pedal, think of the guitar in Jimi Hendrix's *Voodoo Child (Slight Return)*.
 
 Chorus
 ~~~~~~
 
-This effect adds extra voices, detuned by LFO and with a small delay, to add more richness to the sound harmonics and stereo width.
+The Chorus effect duplicates the incoming audio, delays the duplicate slightly and uses an LFO to continuously modulate the pitch of the duplicated signal before mixing the duplicatated signal(s) and the original together again. This creates a shimmering effect and adds stereo width to the sound.
 
 Compressor
 ~~~~~~~~~~
 
-The aim of a dynamic range compressor is to reduce the level of the sound when the amplitude goes over a certain threshold in Decibels.
-One of the main uses of a compressor is to increase the dynamic range while clipping the least possible (when sound goes over 0dB).
+A dynamic range compressor automatically attenuates the level of the incoming signal when its amplitude exceeds a certain threshold. The level of attenuation applied is proportional to how far the incoming audio exceeds the threshold. The compressor's Ratio parameter controls the degree of attenuation.
+One of the main uses of a compressor is to reduce the dynamic range of signals with very loud and quiet parts. Reducing the dynamic range of a signal can make it easier to mix.
 
-The compressor has many uses in the mix, for example:
+The compressor has many uses. For example:
 
-* It can be used in the Master bus to compress the whole output (Although a Limiter would probably be better)
+* It can be used in the Master bus to compress the whole output.
 * It can be used in voice channels to ensure they sound as even as possible.
-* It can be *Sidechained*. This means it can reduce the sound level using another audio bus for threshold detection. This technique is very common in video game mixing to download the level of Music/SFX while voices are being heard.
-* It can accentuate transients by using a bit wider attack, meaning it can make sound effects sound more punchy.
+* It can be *Sidechained*. This means it can reduce the sound level of one signal using the level of another audio bus for threshold detection. This technique is very common in video game mixing to 'duck' the level of music or sound effects when voices need to be heard.
+* It can accentuate transients by using a slower attack. This can make sound effects more punchy.
+
+.. note::
+
+    If your goal is to prevent a signal from exceeding a given amplitude altogether, rather that to reduce the dynamic range       of the signal, a limiter is likely a better choice than a compressor. See below.
 
-There is a lot of bibliography written about compressors, and the Godot implementation is rather standard.
 
 Delay
 ~~~~~
@@ -114,53 +106,58 @@ Adds an "Echo" effect with a feedback loop. It can be used, together with Reverb
 Distortion
 ~~~~~~~~~~
 
-Adds classical effects to modify the sound and make it dirty. Godot supports effects like overdrive, tan, or bit crushing.
-For games, it can simulate sound coming from some saturated device or speaker efficiently.
+Distortion effects make the sound 'dirty'. Godot offers several types of distortion: Overdrive, tan and bit crushing.
+Distortion can be used simulate sound coming through a low-quality speaker or device.
 
-EQ6, EQ10, EQ21
-~~~~~~~~~~~~~~~
+EQ, EQ6, EQ10, EQ21
+~~~~~~~~~~~~~~~~~~~
 
-Godot provides three models of equalizers with different band counts. Equalizers are useful on the Master Bus to completely master a mix and give it character. They are
-also useful when a game is run on a mobile device, to adjust the mix to that kind of speakers (it can be added but disabled when headphones are plugged).
+Godot provides four equalizers with different numbers of bands. An equalizer on the master bus can be useful to cut frequencies that the device's speakers can't reproduce well (e.g. a mobile phone's speakers won't reproduce bass content well). The equalizer effect can be disabled when headphones are plugged in.
+
+Filter
+~~~~~~
+
+Filter is what all other effects processors inherit from and should not be used directly.
 
 HighPassFilter, HighShelfFilter
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-These are filters that cut frequencies below a specific *Cutoff*. A common use of high pass filters is to add it to effects (or voice) that were recorded too close to a mic and need
-to sound more realistic. It is commonly used for some types of environment, like space.
+These are filters that cut frequencies below a specific *Cutoff* frequency. HighPassFilter and HighShelfFilter are used to reduce the bass content of a signal.
 
 Limiter
 ~~~~~~~
 
-A limiter is similar to a compressor, but it's less flexible and designed to disallow sound going over a given dB threshold. Adding one in the *Master Bus* is always recommended
-to reduce the effects of clipping.
+A limiter is similar to a compressor, but it's less flexible and designed to prevent a signal's amplitude exceeding a given dB threshold. Adding a limiter to the *Master Bus* is a safeguard against clipping.
 
 LowPassFilter, LowShelfFilter
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-These are the most common filters, they cut frequencies above a specific *Cutoff* and can also resonate. They can be used for a wide amount of effects, from underwater sound to simulating
-a sound coming from far away.
+These are the most common filters, they cut frequencies above a specific *Cutoff* frequency and can also resonate (boost frequencies close to the *Cutoff* frequency). Low pass filters can be used to simulate 'muffled' sound. For instance underwater sound, sound blocked by walls, or distant sound.
 
 NotchFilter
 ~~~~~~~~~~~
 
-The opposite to the BandPassFilter, it removes a band of sound from the frequency spectrum at a given *Cutoff*.
+The opposite to the BandPassFilter, it removes a band of sound from the frequency spectrum at a given *Cutoff* frequency.
 
 Panner
 ~~~~~~
 
-This is a simple helper to pan sound left or right.
+The Panner allows the stereo balance of a signal to be adjusted between left and right channels (wear headphones to audition this effect).
 
 Phaser
 ~~~~~~
 
-It probably does not make much sense to explain that this effect is formed by two signals being dephased and cancelling each other out.
-It will be sufficient to note that you can make a Darth Vader voice with it, or jet-like sounds.
+It probably does not make much sense to explain that this effect is formed by two signals being dephased and cancelling each other out. You can make a Darth Vader voice with it, or jet-like sounds.
 
 PitchShift
 ~~~~~~~~~~
 
-This effect allows for modulating pitch independently of tempo. All frequencies can be increased/decreased with minimal effect on transients. Can be used for effects such as voice modulation.
+This effect allows the adjustment of the signal's pitch independently of its speed. All frequencies can be increased/decreased with minimal effect on transients. PitchShift can be useful to create unusually high or deep voices.
+
+Record
+~~~~~~
+
+The Record effect allows audio passing through the bus to be written to a file.
 
 Reverb
 ~~~~~~
@@ -171,7 +168,7 @@ to apply chamber feel to all sounds.
 StereoEnhance
 ~~~~~~~~~~~~~
 
-This effect has a few algorithms available to enhance the stereo spectrum, in case this is needed.
+This effect has a few algorithms for enhancing a signal's stereo spectrum.
 
 Automatic bus disabling
 -----------------------
@@ -191,5 +188,4 @@ If a bus is renamed, however, the reference will be lost and the Stream Player w
 Default bus layout
 ------------------
 
-The default bus layout is automatically saved to the ``res://default_bus_layout.tres`` file. Other bus layouts can be saved to/retrieved from files in case of having
-to change snapshots, but in most cases, this is not necessary.
+The default bus layout is automatically saved to the ``res://default_bus_layout.tres`` file. Custom bus arrangements can saved and loaded from disk.

+ 15 - 17
tutorials/audio/audio_streams.rst

@@ -6,43 +6,41 @@ Audio streams
 Introduction
 ------------
 
-As you might have already read in the :ref:`Audio Buses Tutorial<doc_audio-buses>` ,
+As you might have already read in the :ref:`Audio Buses Tutorial<doc_audio-buses>`,
 sound is sent to each bus via an AudioStreamPlayer.
 
-There are many types of AudioStreamPlayer, which will be explained in detail. Each one loads
+There are different kinds of AudioStreamPlayer. Each one loads
 an AudioStream and plays it back.
 
 AudioStream
 -----------
 
-An audio stream is an abstract object that emits sound. It can come from many places, but most commonly
+An audio stream is an abstract object that emits sound. The sound can come from many places, but most commonly
 from the filesystem. Audio files, such as .wav or .ogg, can be loaded as AudioStreams and placed
 inside an AudioStreamPlayer.
 
-Here is a comparison of the two, to help you choose which one fits your specific use case best:
+Here is a comparison of the two types of file to help you choose the one that fits your use case best:
 
-* Audio files of type *.wav* are quite large, but use little CPU power to play back. Hundreds of them can be played simultaneously with little impact to performance. This format is usually best for short sound effects, as the importer will trim and convert them to IMA-ADPCM.
-* Audio files of type *.ogg* are much smaller, but use considerably more CPU power to play back, so only a few can be played back (especially on mobile!). This format is usually best for music or long sound effect sequences. It also works well for voice at relatively low bitrates.
+* Audio files of type *.wav* are quite large, but use little CPU power to play back. Hundreds of them can be played simultaneously with little impact to performance. This format is usually best for short sound effects.
+* Audio files of type *.ogg* are much smaller, but use considerably more CPU power to play back, so only a few can be played back (especially on mobile!). This format works well for music, long sound effect sequences, and voice at relatively low bitrates.
 
-Keep in mind neither .wav nor .ogg usually contains looping information, so this information must be set on the import options of each:
+Keep in mind neither .wav nor .ogg usually contains looping information. If looping is desired it must be set up using the import options of each file type:
 
 .. image:: img/audio_stream_import.png
 
-There are other types of AudioStream, such as AudioStreamRandomPitch, which takes an existing AudioStream and modulates the pitch every time it's played back randomly (great for some sound effects),
-and more will keep appearing in the future.
+There are other types of AudioStreamPlayer, such as AudioStreamRandomPitch. This one makes a random adjustment to the sound's pitch every time it's played back. This can be helpful for adding interest to sounds that are played back often.
 
 AudioStreamPlayer
 -----------------
 
-This is the standard stream player; it can play to any given bus. In 5.1 sound, it can send to stereo mix or front speakers.
+This is the standard stream player; it can play to any bus. In 5.1 sound, it can send to stereo mix or front speakers.
 
 AudioStreamPlayer2D
 -------------------
 
 This is a variant of AudioStreamPlayer, but emits sound in a 2D positional environment. When close to the left of the screen, the panning will go left. When close to the right side, it will go right.
 
-While it's possible to send these effects to specific audio buses, one of the best strategies is to use an Area2D to divert sound to a specific bus. This allows you to create buses with different
-reverb or sound qualities and make it so the emitter will automatically send to them when entering the Area2D shapes.
+.. note:: Area2Ds can be used to divert sound from any AudioStreamPlayer2Ds they contain to specific buses. This makes it possible to create buses with different reverb or sound qualities to handle action happening in a particular parts of your game world.
 
 .. image:: img/audio_stream_2d_area.png
 
@@ -66,19 +64,19 @@ This is done by enabling this type of reverb in the *Reverb Bus* section of *Are
 
 .. image:: img/audio_stream_reverb_bus.png
 
-At the same time, a special bus layout is created where each area receives the reverb info from each area. Of course, an actual Reverb effect must be created in that bus for anything to happen:
+At the same time, a special bus layout is created where each area receives the reverb info from each area. A Reverb effect needs to be created and configured in each reverb bus to complete the setup for the desired effect:
 
 .. image:: img/audio_stream_reverb_bus2.png
 
-The Area Reverb Bus section also has a specific parameter named "Uniformity". Some types of rooms bounce sounds more than others (like for example, a typical warehouse), so reverberation can be heard
-almost uniformly across the room even though the source is far away. Playing around with this parameter can simulate that effect.
+The Area Reverb Bus section also has a parameter named "Uniformity". Some types of rooms bounce sounds more than others (like a warehouse), so reverberation can be heard
+almost uniformly across the room even though the source may be far away. Playing around with this parameter can simulate that effect.
 
 Doppler
 ~~~~~~~
 
-When the relative velocity between an emitter and listener changes, this is perceived as an increase or decrease of the pitch shift. Godot can track changes in velocities of *AudioStreamPlayer3D* or *Camera*.
+When the relative velocity between an emitter and listener changes, this is perceived as an increase or decrease in the pitch of the emitted sound. Godot can track changes in velocities of *AudioStreamPlayer3D* or *Camera*.
 Both have this property, which must be enabled manually:
 
 .. image:: img/audio_stream_doppler.png
 
-Simply enable it by setting it depending on how objects will be moved (whether on regular *process* or *physics_process* step) and the tracking will happen automatically!
+Enable it by setting it depending on how objects will be moved (whether on regular *process* or *physics_process* step) and the tracking will happen automatically.

BIN=BIN
tutorials/audio/img/audio_buses1.png


BIN=BIN
tutorials/audio/img/audio_buses2.png


BIN=BIN
tutorials/audio/img/audio_buses3.png


BIN=BIN
tutorials/audio/img/audio_buses4.png


BIN=BIN
tutorials/audio/img/audio_buses5.png


+ 2 - 0
tutorials/content/index.rst

@@ -5,4 +5,6 @@ Creating content
    :maxdepth: 1
    :name: toc-tutorials-content
 
+   procedural_geometry
    making_trees
+

+ 144 - 0
tutorials/content/procedural_geometry.rst

@@ -0,0 +1,144 @@
+.. _doc_procedural_geometry:
+
+Procedural geometry generation
+==============================
+
+Users often ask how to generate geometry from code. This is not very complicated, but it's not obvious.
+Godot provides a few classes entirely dedicated to make it this easy. Still, the best tool for the job depends
+entirely on the use case.
+
+SurfaceTool
+-----------
+
+This is the most common helper. :ref:`SurfaceTool<class_SurfaceTool>` is a class you can instantiate to generate :ref:`Meshes<class_Mesh>`, specifically *Mesh Surfaces*.
+
+It has a similar API to OpenGL 1.x, and it's meant for static content. This means, the mesh is generated once and then used.
+
+Here is a simple example of how to use it to add a single triangle.
+
+.. tabs::
+ .. code-tab:: gdscript GDScript
+
+    var st = SurfaceTool.new()
+
+    st.begin(Mesh.PRIMITIVE_TRIANGLES)
+
+    # Prepare attributes for add_vertex.
+    st.add_normal(Vector3(0, 0, 1))
+    st.add_uv(Vector2(0, 0))
+    # Call last for each vertex, adds the above attributes.
+    st.add_vertex(Vector3(-1, -1, 0))
+
+    st.add_normal(Vector3(0, 0, 1))
+    st.add_uv(Vector2(0, 1))
+    st.add_vertex(Vector3(-1, 1, 0))
+
+    st.add_normal(Vector3(0, 0, 1))
+    st.add_uv(Vector2(1, 1))
+    st.add_vertex(Vector3(1, 1, 0))
+
+    # Create indices, indices are optional.
+    st.index()
+
+    # Commit to a mesh.
+    var mesh = st.commit()
+
+Just explore the APIs and the possibilities.
+
+ImmediateGeometry
+-----------------
+
+Unlike *SurfaceTool*, :ref:`ImmediateGeometry<class_ImmediateGeometry>` is an actual node. It's similar in the "OpenGL 1.x" style API,
+but it's actually designed to create content on the fly and modify it every frame efficiently.
+
+Generating complex geometry (several thousand vertices) with this node is inefficient, even if it's done only once. Instead, *ImmediateGeometry* is designed to generate simple geometry that changes every frame.
+
+It's used similar to *SurfaceTool*.
+
+.. tabs::
+ .. code-tab:: gdscript GDScript
+
+    extends ImmediateGeometry
+
+    void _process(delta):
+        # Clean up before drawing.
+        clear()
+
+        # Begin draw.
+        begin(Mesh.PRIMITIVE_TRIANGLES)
+
+        # Prepare attributes for add_vertex.
+        set_normal( Vector3(0, 0, 1))
+        set_uv(Vector2(0, 0))
+        # Call last for each vertex, adds the above attributes.
+        add_vertex(Vector3(-1, -1, 0))
+
+        set_normal(Vector3(0, 0, 1))
+        set_uv(Vector2(0, 1))
+        add_vertex(Vector3(-1, 1, 0))
+
+        set_normal(Vector3(0, 0, 1))
+        set_uv(Vector2(1, 1))
+        add_vertex(Vector3(1, 1, 0))
+
+        # End drawing.
+        end()
+
+Arrays
+------
+
+Lastly, the final way to do this is to create arrays themselves. This is the most efficient way to create static geometry, and is only
+recommended when SurfaceTool is not fast enough.
+
+Similar code as before, but draw a square using indices:
+
+
+.. tabs::
+ .. code-tab:: gdscript GDScript
+
+    var arrays = []
+    arrays.resize(Mesh.ARRAY_MAX)
+
+    var normal_array = []
+    var uv_array = []
+    var vertex_array = []
+    var index_array = []
+
+    normal_array.resize(4)
+    uv_array.resize(4)
+    vertex_array.resize(4)
+    index_array.resize(6)
+
+    normal_array[0] = Vector3(0, 0, 1)
+    uv_array[0] = Vector2(0, 0)
+    vertex_array[0] = Vector3(-1, -1)
+
+    normal_array[1] = Vector3(0, 0, 1)
+    uv_array[1] = Vector2(0,1)
+    vertex_array[1] = Vector3(-1, 1)
+
+    normal_array[2] = Vector3(0, 0, 1)
+    uv_array[2] = Vector2(1, 1)
+    vertex_array[2] = Vector3(1, 1)
+
+    normal_array[3] = Vector3(0, 0, 1)
+    uv_array[3] = Vector2(1, 0)
+    vertex_array[3] = Vector3(1, -1)
+
+    # Indices are optional in Godot, but if they exist they are used.
+    index_array[0] = 0
+    index_array[1] = 1
+    index_array[2] = 2
+
+    index_array[3] = 2
+    index_array[4] = 3
+    index_array[5] = 0
+
+    arrays[Mesh.ARRAY_VERTEX] = vertex_array
+    arrays[Mesh.ARRAY_NORMAL] = normal_array
+    arrays[Mesh.ARRAY_TEX_UV] = uv_array
+    arrays[Mesh.ARRAY_INDEX] = index_array
+
+    var mesh = ArrayMesh.new()
+
+    mesh.add_surface_from_arrays(Mesh.PRIMITIVE_TRIANGLES,arrays)

+ 181 - 0
tutorials/gui/gui_containers.rst

@@ -0,0 +1,181 @@
+.. _doc_gui_containers:
+
+Containers
+==========
+
+:ref:`Anchors <doc_size_and_anchors>` are an efficient way to handle 
+different aspect ratios for basic multiple resolution handling in GUIs,  
+
+For more complex user interfaces, they can become difficult to use. 
+
+This is often the case of games, such as RPGs, online chats, tycoons or simulations. Another
+common case where more advanced layout features may be required is in-game tools (or simply just tools). 
+
+All these situations require a more capable OS-like user interface, with advanced layout and formatting.
+For that, :ref:`Containers <class_container>` are more useful.
+
+Container layout
+----------------
+
+Containers provide a huge amount of layout power (as an example, the Godot editor user interface is entirely done using them):
+
+   .. image:: img/godot_containers.png
+
+When a :ref:`Container <class_Container>`-derived node is used, all children :ref:`Control <class_Control>` nodes give up their
+own positioning ability. This means the *Container* will control their positioning and any attempt to manually alter these
+nodes will be either ignored or invalidated the next time their parent is resized.
+
+Likewise, when a *Container* derived node is resized, all it's children will be re-positioned according to it, 
+with a behavior based on the type of container used:
+
+   .. image:: img/container_example.gif
+
+Example of *HBoxContainer* resizing children buttons.
+
+The real strength of containers is that they can be nested (as nodes), allowing the creation of very complex layouts that resize effortlessly.
+
+Size flags
+----------
+
+When adding a node to a container, the way the container treats each child depends mainly on their *size flags*. These flags
+can be found by inspecting any control that is a child of a *Container*.
+
+   .. image:: img/container_size_flags.png
+
+Size flags are independent for vertical and horizontal sizing and not all containers make use of them (but most do):
+
+* **Fill**: Ensures the control *fills* the designated area within the container. No matter if 
+  a control *expands* or not (see below), it will only *fill* the designated area when this is toggled on (it is by default).
+* **Expand**: Attempts to use as most space as possible in the parent container (in this each axis). 
+  Controls that don't expand will be pushed away by those that do. Between those expanding, the 
+  amount of space they take from each other is determined by the *Ratio* (see below).
+* **Shrink Center** When expanding (and if not filling), try to remain at the center of the expanded 
+  area (by default it remains at the left or top).
+* **Ratio** Simple ratio of how much expanded controls take up the available space in relation to each 
+  other. A control with "2", will take up twice as much available space as one with "1".
+
+Experimenting with these flags and different containers is recommended to get a better grasp on how they work.
+
+Container types
+---------------
+
+Godot provides several container types out of the box as they serve different purposes:
+
+Box Containers
+^^^^^^^^^^^^^^
+
+Arrange child controls vertically or horizontally (via :ref:`HBoxContainer <class_HBoxContainer>` and
+:ref:`VBoxContainer <class_VBoxContainer>`). In the opposite of the designated direction
+(as in, vertical for an horizontal container), it just expands the children.
+
+   .. image:: img/containers_box.png
+
+These containers make use of the *Ratio* property for children with the *Expand* flag set.
+
+Grid Container
+^^^^^^^^^^^^^^
+
+Arranges child controls in a grid layout (via :ref:`GridContainer <class_GridContainer>`, amount 
+of columns must be specified). Uses both the vertical and horizontal expand flags.
+
+   .. image:: img/containers_grid.png
+
+Margin Container
+^^^^^^^^^^^^^^^^
+
+Child controls are expanded towards the bounds of this control (via 
+:ref:`MarginContainer <class_MarginContainer>`). Padding will be added on the margins 
+depending on the theme configuration.
+
+   .. image:: img/containers_margin.png
+
+Again, keep in mind that the margins are a *Theme* value, so they need to be edited at the
+constants overrides section if desired for a single control:
+
+   .. image:: img/containers_margin_constants.png
+
+Tab Container
+^^^^^^^^^^^^^
+
+Allows you to place several child controls stacked on top of each other (via 
+:ref:`TabContainer <class_TabContainer>`), with only the *current* one visible. 
+
+   .. image:: img/containers_tab.png
+
+Changing the *current* one is done via tabs located at the top of the container, via clicking:
+
+   .. image:: img/containers_tab_click.gif
+
+The titles are generated from the node names by default (although they can be overriden via *TabContainer* API).
+
+Settings such as tab placement and *StyleBox* can be modified in the *TabContainer* theme overrides.
+
+Split Container
+^^^^^^^^^^^^^^^
+
+Accepts only one or two children controls, then places them side to side with a divisor 
+(via :ref:`HSplitContainer <class_HSplitContainer>` and :ref:`VSplitContainer <class_VSplitContainer>`). 
+Respects both horizontal and vertical flags, as well as *Ratio*.
+
+   .. image:: img/containers_split.png
+
+The divisor can be dragged around to change the size relation between both children:
+
+   .. image:: img/containers_split_drag.gif
+
+
+PanelContainer
+^^^^^^^^^^^^^^
+
+Simple container that draws a *StyleBox*, then expands children to cover its whole area 
+(via :ref:`PanelContainer <class_PanelContainer>`, respecting the *StyleBox* margins). 
+It respects both the horizontal and vertical size flags.
+
+   .. image:: img/containers_panel.png
+
+This container is useful as top-level, or just to add custom backgrounds to sections of a layout.
+
+ScrollContainer
+^^^^^^^^^^^^^^^
+
+Accepts a single child node. If this node is bigger than the container, scrollbars will be added 
+to allow panning the node around (via :ref:`ScrollContainer <class_ScrollContainer>`). Both 
+vertical and horizontal size flags are respected, and the behavior can be turned on or off 
+per axis in the properties.
+
+   .. image:: img/containers_scroll.png
+
+Mouse wheel and touch drag (when touch is available) are also valid ways to pan the child control around.
+
+   .. image:: img/containers_center_pan.gif
+
+As in the example above, one of the most common ways to use this container is together with a *VBoxContainer* as child.
+
+
+ViewportContainer
+^^^^^^^^^^^^^^^^^
+
+This is a special control that will only accept a single *Viewport* node as child, and it will display 
+it as if it was an image (via :ref:`ViewportContainer <class_ViewportContainer>`).
+
+Creating custom Containers
+--------------------------
+
+It is possible to easily create a custom container using script. Here is an example of a simple container that fits children
+to its rect size:
+
+.. tabs::
+ .. code-tab:: gdscript GDScript
+
+    extends Container
+
+    func _notification(what):
+        if (what==NOTIFICATION_SORT_CHILDREN):
+            # Must re-sort the children
+            for c in get_children():
+                # Fit to own size
+                fit_child_in_rect( c, Rect2( Vector2(), rect_size ) )
+	
+    func set_some_setting():
+        # Some setting changed, ask for childre re-sort
+        queue_sort()

BIN=BIN
tutorials/gui/img/container_example.gif


BIN=BIN
tutorials/gui/img/container_size_flags.png


BIN=BIN
tutorials/gui/img/containers_box.png


BIN=BIN
tutorials/gui/img/containers_center.png


BIN=BIN
tutorials/gui/img/containers_center_pan.gif


BIN=BIN
tutorials/gui/img/containers_grid.png


BIN=BIN
tutorials/gui/img/containers_margin.png


BIN=BIN
tutorials/gui/img/containers_margin_constants.png


Algúns arquivos non se mostraron porque demasiados arquivos cambiaron neste cambio