Browse Source

Merge branch 'master' into 3.2

Rémi Verschelde 5 years ago
parent
commit
48faee9f73
100 changed files with 2453 additions and 1425 deletions
  1. 13 0
      .github/ISSUE_TEMPLATE/bug_report.md
  2. 13 0
      .github/ISSUE_TEMPLATE/enhancement_request.md
  3. 18 0
      .github/ISSUE_TEMPLATE/support_question.md
  4. 18 0
      .travis.yml
  5. 3 3
      README.md
  6. 0 0
      _extensions/gdscript.py
  7. 310 32
      _static/css/custom.css
  8. 196 40
      _static/js/custom.js
  9. 15 7
      about/faq.rst
  10. 143 0
      community/contributing/bisecting_regressions.rst
  11. 1 1
      community/contributing/bug_triage_guidelines.rst
  12. 1 1
      community/contributing/docs_writing_guidelines.rst
  13. 1 0
      community/contributing/index.rst
  14. 4 2
      community/contributing/updating_the_class_reference.rst
  15. 1 0
      community/tutorials.rst
  16. 10 9
      conf.py
  17. 21 9
      development/compiling/compiling_for_android.rst
  18. 2 2
      development/compiling/compiling_for_ios.rst
  19. 2 2
      development/compiling/compiling_for_osx.rst
  20. 5 5
      development/compiling/compiling_for_uwp.rst
  21. 3 5
      development/compiling/compiling_for_web.rst
  22. 6 6
      development/compiling/compiling_for_windows.rst
  23. 14 10
      development/compiling/compiling_for_x11.rst
  24. 144 26
      development/compiling/compiling_with_mono.rst
  25. 2 0
      development/compiling/getting_source.rst
  26. 5 3
      development/compiling/introduction_to_the_buildsystem.rst
  27. 6 6
      development/cpp/binding_to_external_libraries.rst
  28. 1 1
      development/cpp/configuring_an_ide.rst
  29. 6 6
      development/cpp/custom_modules_in_cpp.rst
  30. 0 21
      extensions/sphinx_tabs/LICENSE
  31. 0 1
      extensions/sphinx_tabs/__init__.py
  32. 0 7
      extensions/sphinx_tabs/semantic-ui-2.2.10/LICENSE.md
  33. 0 0
      extensions/sphinx_tabs/semantic-ui-2.2.10/menu.min.css
  34. 0 8
      extensions/sphinx_tabs/semantic-ui-2.2.10/segment.min.css
  35. 0 9
      extensions/sphinx_tabs/semantic-ui-2.2.10/tab.min.css
  36. 0 9
      extensions/sphinx_tabs/semantic-ui-2.2.10/tab.min.js
  37. 0 43
      extensions/sphinx_tabs/tabs.css
  38. 0 85
      extensions/sphinx_tabs/tabs.js
  39. 0 348
      extensions/sphinx_tabs/tabs.py
  40. 39 0
      format.sh
  41. 538 0
      getting_started/editor/default_key_mapping.rst
  42. 1 0
      getting_started/editor/index.rst
  43. 2 3
      getting_started/editor/unity_to_godot.rst
  44. 3 6
      getting_started/scripting/c_sharp/c_sharp_basics.rst
  45. 14 0
      getting_started/scripting/c_sharp/c_sharp_style_guide.rst
  46. 2 2
      getting_started/scripting/cross_language_scripting.rst
  47. 5 29
      getting_started/scripting/gdscript/gdscript_basics.rst
  48. 15 2
      getting_started/scripting/gdscript/gdscript_styleguide.rst
  49. 102 0
      getting_started/scripting/visual_script/custom_visualscript_nodes.rst
  50. BIN
      getting_started/scripting/visual_script/img/visual_script_custom_node_result.png
  51. BIN
      getting_started/scripting/visual_script/img/visual_script_custom_node_set_script.png
  52. 1 1
      getting_started/scripting/visual_script/index.rst
  53. 2 2
      getting_started/step_by_step/exporting.rst
  54. 1 1
      getting_started/step_by_step/filesystem.rst
  55. BIN
      getting_started/step_by_step/img/editor_ui_intro_script_class_documentation.png
  56. BIN
      getting_started/step_by_step/img/editor_ui_intro_script_search_documentation.png
  57. BIN
      getting_started/step_by_step/img/editor_ui_intro_script_search_help_window.png
  58. BIN
      getting_started/step_by_step/img/tree.png
  59. 1 1
      getting_started/step_by_step/instancing.rst
  60. 18 2
      getting_started/step_by_step/intro_to_the_editor_interface.rst
  61. 17 4
      getting_started/step_by_step/signals.rst
  62. 9 5
      getting_started/step_by_step/your_first_game.rst
  63. 7 2
      getting_started/workflow/assets/importing_scenes.rst
  64. 1 1
      getting_started/workflow/best_practices/data_preferences.rst
  65. 8 8
      getting_started/workflow/best_practices/godot_interfaces.rst
  66. 6 6
      getting_started/workflow/export/android_custom_build.rst
  67. 1 1
      getting_started/workflow/export/exporting_for_android.rst
  68. 1 1
      getting_started/workflow/export/exporting_for_ios.rst
  69. 1 2
      getting_started/workflow/export/exporting_for_web.rst
  70. 2 2
      getting_started/workflow/export/exporting_projects.rst
  71. 1 1
      getting_started/workflow/index.rst
  72. 1 1
      getting_started/workflow/project_setup/project_organization.rst
  73. BIN
      img/docs_logo.png
  74. 13 0
      requirements.txt
  75. 1 1
      tutorials/2d/custom_drawing_in_2d.rst
  76. 1 1
      tutorials/2d/using_tilemaps.rst
  77. 2 2
      tutorials/3d/fps_tutorial/part_four.rst
  78. 1 1
      tutorials/audio/sync_with_audio.rst
  79. 1 1
      tutorials/i18n/internationalizing_games.rst
  80. 6 6
      tutorials/i18n/localization_using_gettext.rst
  81. 5 5
      tutorials/io/background_loading.rst
  82. 2 2
      tutorials/math/matrices_and_transforms.rst
  83. 8 24
      tutorials/math/vector_math.rst
  84. 11 0
      tutorials/math/vectors_advanced.rst
  85. 70 67
      tutorials/misc/binary_serialization_api.rst
  86. 3 0
      tutorials/misc/instancing_with_signals.rst
  87. 3 3
      tutorials/networking/high_level_multiplayer.rst
  88. 1 1
      tutorials/networking/http_client_class.rst
  89. 1 1
      tutorials/networking/ssl_certificates.rst
  90. 1 1
      tutorials/physics/using_area_2d.rst
  91. 28 0
      tutorials/physics/using_kinematic_body_2d.rst
  92. 1 3
      tutorials/platform/android_in_app_purchases.rst
  93. 157 311
      tutorials/platform/customizing_html5_shell.rst
  94. 266 0
      tutorials/platform/html5_shell_classref.rst
  95. BIN
      tutorials/platform/img/html5_export_options.png
  96. 1 1
      tutorials/platform/index.rst
  97. 11 0
      tutorials/platform/platform_html5.rst
  98. 2 2
      tutorials/platform/services_for_ios.rst
  99. 93 201
      tutorials/plugins/editor/making_main_screen_plugins.rst
  100. 1 1
      tutorials/plugins/editor/spatial_gizmos.rst

+ 13 - 0
.github/ISSUE_TEMPLATE/bug_report.md

@@ -0,0 +1,13 @@
+---
+name: Bug report
+about: Report incorrect or outdated documentation
+title: ''
+labels: bug
+assignees: ''
+---
+
+**Your Godot version:**
+
+**Issue description:**
+
+**URL to the documentation page:**

+ 13 - 0
.github/ISSUE_TEMPLATE/enhancement_request.md

@@ -0,0 +1,13 @@
+---
+name: Enhancement request
+about: Suggest new documentation or improving existing documentation
+title: ''
+labels: enhancement
+assignees: ''
+---
+
+**Your Godot version:**
+
+**Issue description:**
+
+**URL to the documentation page (if already existing):**

+ 18 - 0
.github/ISSUE_TEMPLATE/support_question.md

@@ -0,0 +1,18 @@
+---
+name: Support question
+about: Asking a question about the engine or something not working
+title: 'IMPORTANT: This repository does not accept support questions.'
+labels: archived
+assignees: ''
+---
+
+**IMPORTANT, PLEASE READ**
+
+Support questions are not accepted on this repository.
+Please use one of the other community channels instead, such as Discord:
+
+https://godotengine.org/community
+
+Do not submit to this repository or your issue will be closed.
+
+**IMPORTANT, PLEASE READ**

+ 18 - 0
.travis.yml

@@ -0,0 +1,18 @@
+dist: bionic
+
+stages:
+  - build
+
+matrix:
+  include:
+    - name: Static checks (format.sh)
+      stage: build
+      os: linux
+      addons:
+        apt:
+          packages:
+            - dos2unix
+            - recode
+
+script:
+  - bash ./format.sh

+ 3 - 3
README.md

@@ -42,13 +42,13 @@ Similarly, you can include attachments (like assets as support material for a tu
 
 
 ## Building with Sphinx
 ## Building with Sphinx
 
 
-To build the HTML website (or any other format supported by Sphinx, like PDF, EPUB or LaTeX), you need to install [Sphinx](https://www.sphinx-doc.org/) >= 1.3 as well as (for the HTML) the [readthedocs.org theme](https://github.com/snide/sphinx_rtd_theme). Only the Python 3 flavor was tested, though the Python 2 versions might work too.
+To build the HTML website (or any other format supported by Sphinx, like PDF, EPUB or LaTeX), you need to install [Sphinx](https://www.sphinx-doc.org/) >= 1.3 as well as (for the HTML) the [readthedocs.org theme](https://github.com/snide/sphinx_rtd_theme).
+You also need to install the Sphinx extensions defined in `requirements.txt`.
 
 
 Those tools are best installed using [pip](https://pip.pypa.io), Python's module installer. The Python 3 version might be provided (on Linux distros) as `pip3` or `python3-pip`. You can then run:
 Those tools are best installed using [pip](https://pip.pypa.io), Python's module installer. The Python 3 version might be provided (on Linux distros) as `pip3` or `python3-pip`. You can then run:
 
 
 ```sh
 ```sh
-pip3 install sphinx
-pip3 install sphinx_rtd_theme
+pip install -r requirements.txt
 ```
 ```
 
 
 You can then build the HTML documentation from the root folder of this repository with:
 You can then build the HTML documentation from the root folder of this repository with:

+ 0 - 0
extensions/gdscript.py → _extensions/gdscript.py


+ 310 - 32
_static/css/custom.css

@@ -21,6 +21,10 @@
     --navbar-level-2-color: #b8d6f0;
     --navbar-level-2-color: #b8d6f0;
     --navbar-level-3-color: #a3c4e1;
     --navbar-level-3-color: #a3c4e1;
     --navbar-heading-color: #ff7381;
     --navbar-heading-color: #ff7381;
+    --navbar-scrollbar-color: #d45a66;
+    --navbar-scrollbar-hover-color: #b14550;
+    --navbar-scrollbar-active-color: #72383e;
+    --navbar-scrollbar-background: #131e2b;
 
 
     --link-color: #2980b9;
     --link-color: #2980b9;
     --link-color-hover: #3091d1;
     --link-color-hover: #3091d1;
@@ -35,7 +39,16 @@
     --input-background-color: #fcfcfc;
     --input-background-color: #fcfcfc;
     --input-focus-border-color: #5f8cff;
     --input-focus-border-color: #5f8cff;
 
 
+    --search-input-background-color: #e6eef3; /* derived from --input-background-color */
+    --search-match-color: #2c6b96; /* derived from --link-color */
+    --search-match-background-color: #e3f2fd; /* derived from --link-color */
+    --search-active-color: #efefef;
+    --search-credits-background-color: #333f67; /* derived from --navbar-background-color */
+    --search-credits-color: #b3b3b3; /* derived from --footer-color */
+    --search-credits-link-color: #4392c5; /* derived from --link-color */
+
     --highlight-background-color: #f5ffe1;
     --highlight-background-color: #f5ffe1;
+    --highlight-default-color: #404040;
     --highlight-comment-color: #408090;
     --highlight-comment-color: #408090;
     --highlight-keyword-color: #007020;
     --highlight-keyword-color: #007020;
     --highlight-keyword2-color: #902000;
     --highlight-keyword2-color: #902000;
@@ -92,6 +105,10 @@
         --navbar-level-2-color: #ccc;
         --navbar-level-2-color: #ccc;
         --navbar-level-3-color: #bbb;
         --navbar-level-3-color: #bbb;
         --navbar-heading-color: #ee7381;
         --navbar-heading-color: #ee7381;
+        --navbar-scrollbar-color: #be5460;
+        --navbar-scrollbar-hover-color: #963e48;
+        --navbar-scrollbar-active-color: #5f3034;
+        --navbar-scrollbar-background: #1c1e21;
 
 
         --link-color: #8cf;
         --link-color: #8cf;
         --link-color-hover: #9df;
         --link-color-hover: #9df;
@@ -106,8 +123,17 @@
         --input-background-color: #333537;
         --input-background-color: #333537;
         --input-focus-border-color: #5f8cff;
         --input-focus-border-color: #5f8cff;
 
 
+        --search-input-background-color: #43464a; /* derived from --input-background-color */
+        --search-match-color: #52b4ff; /* derived from --link-color */
+        --search-match-background-color: #414c56; /* derived from --link-color */
+        --search-active-color: #202326;
+        --search-credits-background-color: #202123; /* derived from --navbar-background-color */
+        --search-credits-color: #6b6b6b; /* derived from --footer-color */
+        --search-credits-link-color: #628fb1; /* derived from --link-color */
+
         /* Colors taken from the Godot script editor with the Adaptive theme */
         /* Colors taken from the Godot script editor with the Adaptive theme */
         --highlight-background-color: #202531;
         --highlight-background-color: #202531;
+        --highlight-default-color: rgba(255, 255, 255, 0.85);
         --highlight-comment-color: rgba(204, 206, 211, 0.5);
         --highlight-comment-color: rgba(204, 206, 211, 0.5);
         --highlight-keyword-color: #ff7085;
         --highlight-keyword-color: #ff7085;
         --highlight-keyword2-color: #42ffc2;
         --highlight-keyword2-color: #42ffc2;
@@ -230,18 +256,174 @@ hr,
     border-color: var(--hr-color);
     border-color: var(--hr-color);
 }
 }
 
 
-/* Doesn't seem to be used on Read the Docs online builds, but is present when building locally */
+/* JavaScript documentation directives */
 .rst-content dl:not(.docutils) dt {
 .rst-content dl:not(.docutils) dt {
     background-color: var(--admonition-note-background-color);
     background-color: var(--admonition-note-background-color);
     border-color: var(--admonition-note-title-background-color);
     border-color: var(--admonition-note-title-background-color);
     color: var(--admonition-note-color);
     color: var(--admonition-note-color);
 }
 }
+.rst-content dl:not(.docutils) dl dt {
+    background-color: var(--admonition-attention-background-color);
+    border-color: var(--admonition-attention-title-background-color);
+    color: var(--admonition-attention-color);
+}
+.rst-content dl:not(.docutils).class dt,
+.rst-content dl:not(.docutils).function dt,
+.rst-content dl:not(.docutils).method dt,
+.rst-content dl:not(.docutils).attribute dt {
+    width: 100%;
+}
+.rst-content dl:not(.docutils).class > dt,
+.rst-content dl:not(.docutils).function > dt,
+.rst-content dl:not(.docutils).method > dt,
+.rst-content dl:not(.docutils).attribute > dt {
+    font-size: 100%;
+    font-weight: normal;
+    margin-bottom: 16px;
+    padding: 6px 8px;
+}
+.rst-content dl:not(.docutils) tt.descclassname,
+.rst-content dl:not(.docutils) code.descclassname {
+    color: var(--highlight-type2-color);
+    font-weight: normal;
+}
+.rst-content dl:not(.docutils) tt.descname,
+.rst-content dl:not(.docutils) code.descname {
+    color: var(--highlight-function-color);
+    font-weight: normal;
+}
+.rst-content dl:not(.docutils) .sig-paren,
+.rst-content dl:not(.docutils) .optional {
+    color: var(--highlight-operator-color);
+    font-weight: normal;
+    padding: 0 2px;
+}
+.rst-content dl:not(.docutils) .optional {
+    font-style: italic;
+}
+.rst-content dl:not(.docutils) .sig-param,
+.rst-content dl:not(.docutils).class dt > em,
+.rst-content dl:not(.docutils).function dt > em,
+.rst-content dl:not(.docutils).method dt > em {
+    color: var(--code-literal-color);
+    font-style: normal;
+    padding: 0 4px;
+}
+.rst-content dl:not(.docutils) .sig-param,
+.rst-content dl:not(.docutils).class dt > .optional ~ em,
+.rst-content dl:not(.docutils).function dt > .optional ~ em,
+.rst-content dl:not(.docutils).method dt > .optional ~ em {
+    color: var(--highlight-number-color);
+    font-style: italic;
+}
+.rst-content dl:not(.docutils).class dt > em.property {
+    color: var(--highlight-keyword-color);
+}
+.rst-content dl:not(.docutils) dt a.headerlink {
+    color: var(--link-color);
+}
+.rst-content dl:not(.docutils) dt a.headerlink:visited {
+    color: var(--link-color-visited);
+}
 
 
 footer,
 footer,
 #search-results .context {
 #search-results .context {
     color: var(--footer-color);
     color: var(--footer-color);
 }
 }
 
 
+/* Sphinx Search extension */
+/* .wy-body-for-nav is used for higher rule specificity */
+
+/* search popup body */
+.wy-body-for-nav .search__outer {
+    background-color: var(--content-background-color);
+    border: 2px solid var(--content-background-color);
+}
+.wy-body-for-nav .search__cross svg {
+    fill: var(--body-color);
+}
+
+.wy-body-for-nav .search__outer::-webkit-scrollbar-track {
+    border-radius: 10px;
+    background-color: var(--content-background-color);
+}
+.wy-body-for-nav .search__outer::-webkit-scrollbar {
+    width: 7px;
+    height: 7px;
+    background-color: var(--content-background-color);
+}
+.wy-body-for-nav .search__outer::-webkit-scrollbar-thumb {
+    border-radius: 10px;
+    background-color: var(--hr-color);
+}
+
+/* search input */
+.wy-body-for-nav .search__outer__input {
+    background-color: var(--search-input-background-color);
+    background-image: none;
+    border-radius: 50px;
+    border: 2px solid transparent;
+    color: var(--body-color);
+    height: 36px;
+    padding: 6px 12px;
+}
+.wy-body-for-nav .search__outer__input:focus {
+    border-color: var(--input-focus-border-color);
+}
+.wy-body-for-nav .search__outer .bar:after,
+.wy-body-for-nav .search__outer .bar:before {
+    display: none;
+}
+
+/* search item */
+.wy-body-for-nav .search__result__single {
+    border-bottom-color: var(--hr-color);
+}
+/* search item title */
+.wy-body-for-nav .search__result__title {
+    color: var(--link-color);
+    border-bottom: none;
+    font-size: 120%;
+    font-weight: 400;
+}
+
+/* search item section */
+.wy-body-for-nav .outer_div_page_results:hover,
+.wy-body-for-nav .search__result__box .active {
+    background-color: var(--search-active-color);
+}
+.wy-body-for-nav .search__result__subheading{
+    color: var(--body-color);
+    font-size: 100%;
+    font-weight: 400;
+}
+.wy-body-for-nav .search__result__content {
+    color: var(--footer-color);
+}
+
+/* search item matching substring */
+.wy-body-for-nav .search__outer .search__result__title span,
+.wy-body-for-nav .search__outer .search__result__content span {
+    color: var(--search-match-color);
+    border-bottom: 1px solid var(--search-match-color);
+    background-color: var(--search-match-background-color);
+    padding: 0 2px;
+}
+.wy-body-for-nav .search__result__subheading span {
+    border-bottom-color: var(--body-color);
+}
+
+/* search credits */
+.wy-body-for-nav .rtd__search__credits {
+    background-color: var(--search-credits-background-color);
+    border-color: var(--search-credits-background-color);
+    color: var(--search-credits-color);
+    padding: 4px 8px;
+}
+.wy-body-for-nav .rtd__search__credits a {
+    color: var(--search-credits-link-color);
+}
+
 /* Main sections */
 /* Main sections */
 
 
 .wy-nav-content-wrap {
 .wy-nav-content-wrap {
@@ -321,58 +503,95 @@ code,
     background-color: var(--highlight-background-color);
     background-color: var(--highlight-background-color);
 }
 }
 
 
-.highlight .c1,
-.highlight .cm {
+.highlight .gh /* Generic.Heading */,
+.highlight .gu /* Generic.Subheading */,
+.highlight .go /* Generic.Output */,
+.highlight .gt /* Generic.Traceback */ {
+    color: var(--highlight-default-color);
+}
+
+.highlight .c  /* Comment */,
+.highlight .c1 /* Comment.Single */,
+.highlight .cm /* Comment.Multiline */,
+.highlight .cs /* Comment.Special */ {
     color: var(--highlight-comment-color);
     color: var(--highlight-comment-color);
 }
 }
 
 
-.highlight .bp,
-.highlight .k,
-.highlight .kd,
-.highlight .kn,
-.highlight .kt,
-.highlight .ow {
+.highlight .bp /* Name.Builtin.Pseudo */,
+.highlight .k  /* Keyword */,
+.highlight .kc /* Keyword.Constant */,
+.highlight .kd /* Keyword.Declaration */,
+.highlight .kn /* Keyword.Namespace */,
+.highlight .kp /* Keyword.Pseudo */,
+.highlight .kr /* Keyword.Reserved */,
+.highlight .kt /* Keyword.Type */,
+.highlight .ow /* Operator.Word */ {
     color: var(--highlight-keyword-color);
     color: var(--highlight-keyword-color);
 }
 }
 
 
-.highlight .cp {
+.highlight .ch /* Comment.Hashbang */,
+.highlight .cp /* Comment.Preproc */ {
     color: var(--highlight-keyword2-color);
     color: var(--highlight-keyword2-color);
 }
 }
 
 
-.highlight .m,
-.highlight .mf,
-.highlight .mi {
+.highlight .m  /* Literal.Number */,
+.highlight .mf /* Literal.Number.Float */,
+.highlight .mi /* Literal.Number.Integer */,
+.highlight .il /* Literal.Number.Integer.Long */,
+.highlight .mb /* Literal.Number.Bin */,
+.highlight .mh /* Literal.Number.Hex */,
+.highlight .mo /* Literal.Number.Oct */ {
     color: var(--highlight-number-color);
     color: var(--highlight-number-color);
 }
 }
 
 
-.highlight .na {
+.highlight .na /* Name.Attribute */,
+.highlight .nd /* Name.Decorator */,
+.highlight .ni /* Name.Entity */,
+.highlight .nl /* Name.Label */ {
     color: var(--highlight-decorator-color);
     color: var(--highlight-decorator-color);
 }
 }
 
 
-.highlight .nb {
+.highlight .nb /* Name.Builtin */,
+.highlight .ne /* Name.Exception */ {
     color: var(--highlight-type-color);
     color: var(--highlight-type-color);
 }
 }
 
 
-.highlight .nc,
-.highlight .nn,
-.highlight .nv {
+.highlight .nc /* Name.Class */,
+.highlight .nn /* Name.Namespace */,
+.highlight .no /* Name.Constant */,
+.highlight .nv /* Name.Variable */,
+.highlight .vc /* Name.Variable.Class */,
+.highlight .vg /* Name.Variable.Global */,
+.highlight .vi /* Name.Variable.Instance */,
+.highlight .vm /* Name.Variable.Magic */ {
     color: var(--highlight-type2-color);
     color: var(--highlight-type2-color);
 }
 }
 
 
-.highlight .nf,
-.highlight .nt {
+.highlight .nf /* Name.Function */,
+.highlight .fm /* Name.Function.Magic */,
+.highlight .nt /* Name.Tag */ {
     color: var(--highlight-function-color);
     color: var(--highlight-function-color);
 }
 }
 
 
-.highlight .o {
+.highlight .o  /* Operator */,
+.highlight .si /* Literal.String.Interpol */,
+.highlight .sx /* Literal.String.Other */,
+.highlight .sr /* Literal.String.Regex */,
+.highlight .ss /* Literal.String.Symbol */ {
     color: var(--highlight-operator-color);
     color: var(--highlight-operator-color);
 }
 }
 
 
-.highlight .cpf,
-.highlight .s,
-.highlight .s1,
-.highlight .s2,
-.highlight .se {
+.highlight .cpf/* Comment.PreprocFile */,
+.highlight .s  /* Literal.String */,
+.highlight .s1 /* Literal.String.Single */,
+.highlight .s2 /* Literal.String.Double */,
+.highlight .sc /* Literal.String.Char */,
+.highlight .se /* Literal.String.Escape */,
+.highlight .sa /* Literal.String.Affix */,
+.highlight .sb /* Literal.String.Backtick */,
+.highlight .dl /* Literal.String.Delimiter */,
+.highlight .sd /* Literal.String.Doc */,
+.highlight .sh /* Literal.String.Heredoc */ {
     color: var(--highlight-string-color);
     color: var(--highlight-string-color);
 }
 }
 
 
@@ -461,6 +680,13 @@ kbd, .kbd {
     opacity: var(--logo-opacity);
     opacity: var(--logo-opacity);
 }
 }
 
 
+.wy-side-nav-search > a img.logo {
+    /* Fixed size to prevent reflows and support hiDPI displays */
+    /* A 5 pixel margin is added on each side. The logo itself displays at 200×200 at 100% scaling. */
+    width: 210px;
+    height: 210px;
+}
+
 .wy-side-nav-search {
 .wy-side-nav-search {
     background-color: var(--navbar-background-color);
     background-color: var(--navbar-background-color);
 }
 }
@@ -472,7 +698,7 @@ kbd, .kbd {
 @media only screen and (min-width: 769px) {
 @media only screen and (min-width: 769px) {
     /* Simulate a drop shadow that only affects the bottom edge */
     /* Simulate a drop shadow that only affects the bottom edge */
     /* This is used to indicate the search bar is fixed */
     /* This is used to indicate the search bar is fixed */
-    .wy-side-nav-search.fixed::after {
+    .wy-side-nav-search.fixed-and-scrolled::after {
         content: '';
         content: '';
         position: absolute;
         position: absolute;
         left: 0;
         left: 0;
@@ -551,11 +777,6 @@ kbd, .kbd {
 
 
 /* First level of navigation items */
 /* First level of navigation items */
 
 
-.wy-menu-vertical {
-    /* Account for the increased `toctree-expand` button margins */
-    width: 308px;
-}
-
 .wy-menu-vertical a {
 .wy-menu-vertical a {
     color: var(--navbar-level-1-color);
     color: var(--navbar-level-1-color);
 }
 }
@@ -623,6 +844,16 @@ kbd, .kbd {
     background-color: var(--navbar-current-background-color-active);
     background-color: var(--navbar-current-background-color-active);
 }
 }
 
 
+.wy-menu-vertical a {
+    /* This overrides 8px margin added in other multi-selector rules */
+    margin-right: 0;
+}
+
+/* Banner panel in sidebar */
+.wy-nav-side .ethical-rtd.fixed {
+    position: fixed;
+}
+
 /* Version selector (only visible on Read the Docs) */
 /* Version selector (only visible on Read the Docs) */
 
 
 .rst-versions {
 .rst-versions {
@@ -673,3 +904,50 @@ kbd, .kbd {
     font-weight: inherit;
     font-weight: inherit;
     padding: 0;
     padding: 0;
 }
 }
+
+/* Allows the scrollbar to be shown in the sidebar */
+@media only screen and (min-width: 769px) {
+    .wy-side-scroll {
+        overflow: hidden;
+    }
+
+    .wy-nav-side .wy-side-scroll .ethical-rtd {
+        width: calc(300px - 1.25em);
+        padding: 0 0 0 1em;
+    }
+}
+.wy-menu.wy-menu-vertical {
+    overflow-y: auto;
+    overflow-x: hidden;
+    max-height: calc(100% - 348px);
+}
+@media screen and (max-width: 768px) {
+    .wy-nav-side {
+        padding-bottom: 44px;
+    }
+    .wy-menu.wy-menu-vertical {
+        overflow-y: initial;
+        max-height: initial;
+    }
+}
+
+/* Scrollbar styling */
+.wy-menu.wy-menu-vertical {
+    scrollbar-color: var(--navbar-scrollbar-color) var(--navbar-scrollbar-background);
+}
+.wy-menu.wy-menu-vertical::-webkit-scrollbar {
+    width: .75rem;
+}
+.wy-menu.wy-menu-vertical::-webkit-scrollbar-track {
+    background-color: var(--navbar-scrollbar-background);
+}
+.wy-menu.wy-menu-vertical::-webkit-scrollbar-thumb {
+    background-color: var(--navbar-scrollbar-color);
+}
+/* Firefox does the dimming on hover automatically. We emulate it for Webkit-based browsers. */
+.wy-menu.wy-menu-vertical::-webkit-scrollbar-thumb:hover {
+    background-color: var(--navbar-scrollbar-hover-color);
+}
+.wy-menu.wy-menu-vertical::-webkit-scrollbar-thumb:active {
+    background-color: var(--navbar-scrollbar-active-color);
+}

+ 196 - 40
_static/js/custom.js

@@ -1,48 +1,204 @@
-// The number of pixels the user must scroll by before the logo is hidden.
-const scrollTopPixels = 234;
-
-// The margin to apply to the menu when the search bar is made fixed.
-// Should roughly match the logo's height as to not hide the top menu items
-// behind it.
-const menuTopMargin = '330px';
-
-// Hide the navigation bar logo when scrolling down on desktop platforms.
-// The logo is quite tall, so this helps make the rest of the navigation bar
-// more readable.
-function registerOnScrollEvent(mediaQuery) {
-  // The navigation bar that contains the logo.
-  const $navbar = $('.wy-side-scroll');
-  const $menu = $('.wy-menu-vertical');
-  const $search = $('.wy-side-nav-search');
-
-  // The anchor that contains the logo. This element will be hidden
-  // (instead of hiding just the logo), otherwise, a small clickable area
-  // would remain visible.
-  const $logo = $('.wy-side-nav-search > a');
-
-  if (mediaQuery.matches) {
-    // We're on desktop; register the scroll event.
-    $navbar.scroll(function() {
-      if ($(this).scrollTop() >= scrollTopPixels) {
-        $logo.hide();
-        $search.addClass('fixed');
-        $menu.css('margin-top', menuTopMargin);
+// Handle page scroll and adjust sidebar accordingly.
+
+// Each page has two scrolls: the main scroll, which is moving the content of the page;
+// and the sidebar scroll, which is moving the navigation in the sidebar.
+// We want the logo to gradually disappear as the main content is scrolled, giving
+// more room to the navigation on the left. This means adjusting the height
+// available to the navigation on the fly. There is also a banner below the navigation
+// that must be dealt with simultaneously.
+const registerOnScrollEvent = (function(){
+  // Configuration.
+
+  // The number of pixels the user must scroll by before the logo is completely hidden.
+  const scrollTopPixels = 234;
+  // The target margin to be applied to the navigation bar when the logo is hidden.
+  const menuTopMargin = 90;
+  // The max-height offset when the logo is completely visible.
+  const menuHeightOffset_default = 338;
+  // The max-height offset when the logo is completely hidden.
+  const menuHeightOffset_fixed = 102;
+  // The distance between the two max-height offset values above; used for intermediate values.
+  const menuHeightOffset_diff = (menuHeightOffset_default - menuHeightOffset_fixed);
+
+  // Media query handler.
+  return function(mediaQuery) {
+    // We only apply this logic to the "desktop" resolution (defined by a media query at the bottom).
+    // This handler is executed when the result of the query evaluation changes, which means that 
+    // the page has moved between "desktop" and "mobile" states.
+
+    // When entering the "desktop" state, we register scroll events and adjust elements on the page.
+    // When entering the "mobile" state, we clean up any registered events and restore elements on the page
+    // to their initial state.
+
+    const $window = $(window);
+    const $sidebar = $('.wy-side-scroll');
+    const $search = $sidebar.children('.wy-side-nav-search');
+    const $menu = $sidebar.children('.wy-menu-vertical');
+    const $ethical = $sidebar.children('.ethical-rtd');
+
+    // This padding is needed to correctly adjust the height of the scrollable area in the sidebar.
+    // It has to have the same height as the ethical block, if there is one.
+    let $menuPadding = $menu.children('.wy-menu-ethical-padding');
+    if ($menuPadding.length == 0) {
+      $menuPadding = $('<div class="wy-menu-ethical-padding"></div>');
+      $menu.append($menuPadding);
+    }
+
+    if (mediaQuery.matches) {
+      // Entering the "desktop" state.
+
+      // The main scroll event handler.
+      // Executed as the page is scrolled and once immediatelly as the page enters this state.
+      const handleMainScroll = (currentScroll) => {
+        if (currentScroll >= scrollTopPixels) {
+          // After the page is scrolled below the threshold, we fix everything in place.
+          $search.css('margin-top', `-${scrollTopPixels}px`);
+          $menu.css('margin-top', `${menuTopMargin}px`);
+          $menu.css('max-height', `calc(100% - ${menuHeightOffset_fixed}px)`);
+        }
+        else {
+          // Between the top of the page and the threshold we calculate intermediate values 
+          // to guarantee a smooth transition.
+          $search.css('margin-top', `-${currentScroll}px`);
+          $menu.css('margin-top', `${menuTopMargin + (scrollTopPixels - currentScroll)}px`);
+
+          if (currentScroll > 0) {
+            const scrolledPercent = (scrollTopPixels - currentScroll) / scrollTopPixels;
+            const offsetValue = menuHeightOffset_fixed + menuHeightOffset_diff * scrolledPercent;
+            $menu.css('max-height', `calc(100% - ${offsetValue}px)`);
+          } else {
+            $menu.css('max-height', `calc(100% - ${menuHeightOffset_default}px)`);
+          }
+        }
+      };
+
+      // The sidebar scroll event handler.
+      // Executed as the sidebar is scrolled as well as after the main scroll. This is needed
+      // because the main scroll can affect the scrollable area of the sidebar.
+      const handleSidebarScroll = () => {
+        const menuElement = $menu.get(0);
+        const menuScrollTop = $menu.scrollTop();
+        const menuScrollBottom = menuElement.scrollHeight - (menuScrollTop + menuElement.offsetHeight);
+
+        // As the navigation is scrolled we add a shadow to the top bar hanging over it.
+        if (menuScrollTop > 0) {
+          $search.addClass('fixed-and-scrolled');
+        } else {
+          $search.removeClass('fixed-and-scrolled');
+        }
+
+        // Near the bottom we start moving the sidebar banner into view.
+        if (menuScrollBottom < ethicalOffsetBottom) {
+          $ethical.css('display', 'block');
+          $ethical.css('margin-top', `-${ethicalOffsetBottom - menuScrollBottom}px`);
+        } else {
+          $ethical.css('display', 'none');
+          $ethical.css('margin-top', '0px');
+        }
+      };
+
+      $search.addClass('fixed');
+      $ethical.addClass('fixed');
+
+      // Adjust the inner height of navigation so that the banner can be overlaid there later.
+      const ethicalOffsetBottom = $ethical.height() || 0;
+      if (ethicalOffsetBottom) {
+        $menuPadding.css('height', `${ethicalOffsetBottom}px`);
       } else {
       } else {
-        $logo.show();
-        $search.removeClass('fixed');
-        $menu.css('margin-top', 0);
+        $menuPadding.css('height', `0px`);
       }
       }
-    });
-  } else {
-    // We're on mobile; unregister the scroll event so the logo isn't hidden
-    // when scrolling.
-    $logo.show();
-    $navbar.unbind('scroll');
-  }
-}
+
+      $window.scroll(function() {
+        handleMainScroll(window.scrollY);
+        handleSidebarScroll();
+      });
+
+      $menu.scroll(function() {
+        handleSidebarScroll();
+      })
+
+      handleMainScroll(window.scrollY);
+      handleSidebarScroll();
+    } else {
+      // Entering the "mobile" state.
+
+      $window.unbind('scroll');
+      $menu.unbind('scroll');
+
+      $search.removeClass('fixed');
+      $ethical.removeClass('fixed');
+
+      $search.css('margin-top', `0px`);
+      $menu.css('margin-top', `0px`);
+      $menu.css('max-height', 'initial');
+      $menuPadding.css('height', `0px`);
+      $ethical.css('margin-top', '0px');
+      $ethical.css('display', 'block');
+    }
+  };
+})();
+
+// Subscribe to DOM changes in the sidebar container, because there is a 
+// banner that gets added at a later point, that we might not catch otherwise.
+const registerSidebarObserver = (function(){
+  return function(callback) {
+    const sidebarContainer = document.querySelector('.wy-side-scroll');
+    
+    let sidebarEthical = null;
+    const registerEthicalObserver = () => {
+      if (sidebarEthical) {
+        // Do it only once.
+        return;
+      }
+
+      sidebarEthical = sidebarContainer.querySelector('.ethical-rtd');
+      if (!sidebarEthical) {
+        // Do it only after we have the element there.
+        return;
+      }
+
+      // This observer watches over the ethical block in sidebar, and all of its subtree.
+      const ethicalObserverConfig = { childList: true, subtree: true };
+      const ethicalObserverCallback = (mutationsList, observer) => {
+        for (let mutation of mutationsList) {
+          if (mutation.type !== 'childList') {
+            continue;
+          }
+    
+          callback();
+        }
+      };
+    
+      const ethicalObserver = new MutationObserver(ethicalObserverCallback);
+      ethicalObserver.observe(sidebarEthical, ethicalObserverConfig);
+    };
+    registerEthicalObserver();
+  
+    // This observer watches over direct children of the main sidebar container.
+    const observerConfig = { childList: true };
+    const observerCallback = (mutationsList, observer) => {
+      for (let mutation of mutationsList) {
+        if (mutation.type !== 'childList') {
+          continue;
+        }
+  
+        callback();
+        registerEthicalObserver();
+      }
+    };
+  
+    const observer = new MutationObserver(observerCallback);
+    observer.observe(sidebarContainer, observerConfig);
+  };
+})();
 
 
 $(document).ready(() => {
 $(document).ready(() => {
   const mediaQuery = window.matchMedia('only screen and (min-width: 769px)');
   const mediaQuery = window.matchMedia('only screen and (min-width: 769px)');
+  
   registerOnScrollEvent(mediaQuery);
   registerOnScrollEvent(mediaQuery);
   mediaQuery.addListener(registerOnScrollEvent);
   mediaQuery.addListener(registerOnScrollEvent);
+
+  registerSidebarObserver(() => {
+    registerOnScrollEvent(mediaQuery);
+  });
 });
 });

+ 15 - 7
about/faq.rst

@@ -87,6 +87,8 @@ NativeScript / PluginScript facilities. (See the question about plugins below.)
 Work is currently underway, for example, on unofficial bindings for Godot
 Work is currently underway, for example, on unofficial bindings for Godot
 to `Python <https://github.com/touilleMan/godot-python>`_ and `Nim <https://github.com/pragmagic/godot-nim>`_.
 to `Python <https://github.com/touilleMan/godot-python>`_ and `Nim <https://github.com/pragmagic/godot-nim>`_.
 
 
+.. _doc_faq_what_is_gdscript:
+
 What is GDScript and why should I use it?
 What is GDScript and why should I use it?
 -----------------------------------------
 -----------------------------------------
 
 
@@ -124,25 +126,31 @@ languages can be found in the :ref:`doc_gdscript_more_efficiently` tutorial.
 What were the motivations behind creating GDScript?
 What were the motivations behind creating GDScript?
 ---------------------------------------------------
 ---------------------------------------------------
 
 
+In the early days, the engine used the `Lua <https://www.lua.org>`__
+scripting language. Lua is fast, but creating bindings to an object
+oriented system (by using fallbacks) was complex and slow and took an
+enormous amount of code. After some experiments with
+`Python <https://www.python.org>`__, it also proved difficult to embed.
+
 The main reasons for creating a custom scripting language for Godot were:
 The main reasons for creating a custom scripting language for Godot were:
 
 
-1. Poor thread support in most script VMs, and Godot uses threads
-   (Lua, Python, Squirrel, JS, AS, etc.).
+1. Poor threading support in most script VMs, and Godot uses threads
+   (Lua, Python, Squirrel, JavaScript, ActionScript, etc.).
 2. Poor class-extending support in most script VMs, and adapting to
 2. Poor class-extending support in most script VMs, and adapting to
-   the way Godot works is highly inefficient (Lua, Python, JS).
+   the way Godot works is highly inefficient (Lua, Python, JavaScript).
 3. Many existing languages have horrible interfaces for binding to C++, resulting in large amount of
 3. Many existing languages have horrible interfaces for binding to C++, resulting in large amount of
    code, bugs, bottlenecks, and general inefficiency (Lua, Python,
    code, bugs, bottlenecks, and general inefficiency (Lua, Python,
-   Squirrel, JS, etc.) We wanted to focus on a great engine, not a great amount of integrations.
+   Squirrel, JavaScript, etc.) We wanted to focus on a great engine, not a great amount of integrations.
 4. No native vector types (vector3, matrix4, etc.), resulting in highly
 4. No native vector types (vector3, matrix4, etc.), resulting in highly
    reduced performance when using custom types (Lua, Python, Squirrel,
    reduced performance when using custom types (Lua, Python, Squirrel,
-   JS, AS, etc.).
+   JavaScript, ActionScript, etc.).
 5. Garbage collector results in stalls or unnecessarily large memory
 5. Garbage collector results in stalls or unnecessarily large memory
-   usage (Lua, Python, JS, AS, etc.).
+   usage (Lua, Python, JavaScript, ActionScript, etc.).
 6. Difficulty to integrate with the code editor for providing code
 6. Difficulty to integrate with the code editor for providing code
    completion, live editing, etc. (all of them). This is well
    completion, live editing, etc. (all of them). This is well
    supported by GDScript.
    supported by GDScript.
 
 
-GDScript was designed to curtail the issues above and more.
+GDScript was designed to curtail the issues above, and more.
 
 
 What type of 3D model formats does Godot support?
 What type of 3D model formats does Godot support?
 -------------------------------------------------
 -------------------------------------------------

+ 143 - 0
community/contributing/bisecting_regressions.rst

@@ -0,0 +1,143 @@
+.. _doc_bisecting_regressions:
+
+Bisecting regressions
+=====================
+
+.. highlight:: shell
+
+Bisecting is a way to find regressions in software. After reporting a bug on the
+`Godot repository on GitHub <https://github.com/godotengine/godot>`__, you may
+be asked by a contributor to *bisect* the issue. Bisecting makes it possible for
+contributors to fix bugs faster, as they can know in advance which commit caused
+the regression. Your effort will be widely appreciated :)
+
+The guide below explains how to find a regression by bisecting.
+
+What is bisecting?
+------------------
+
+Godot developers use the `Git <https://git-scm.com/>`__ version control system.
+In the context of Git, bisecting is the process of performing a manual
+`binary search <https://en.wikipedia.org/wiki/Binary_search_algorithm>`__
+to determine when a regression appeared. While it's typically used for bugs,
+it can also be used to find other kinds of unexpected changes such as
+performance regressions.
+
+Using official builds to speed up bisecting
+-------------------------------------------
+
+Before using Git's ``bisect`` command, we strongly recommend trying to reproduce
+the bug with an older (or newer) official release. This greatly reduces the
+range of commits that potentially need to be built from source and tested.
+You can find binaries of official releases, as well as alphas, betas,
+and release candidates `here <https://downloads.tuxfamily.org/godotengine/>`__.
+
+For example, if you've reported a bug against Godot 3.2, you should first try to
+reproduce the bug in Godot 3.1 (not a patch release, see below for the reason).
+If the bug doesn't occur there, try to reproduce it in Godot 3.2 *beta 1* (which
+is roughly in the middle of all test builds available). If you can't reproduce
+the bug with Godot 3.2 beta 1, then try newer betas and RC builds. If you do
+manage to reproduce the bug with Godot 3.2 beta 1, then try older alpha builds.
+
+.. warning::
+
+    For bisecting regressions, don't use patch releases such as Godot 3.1.2.
+    Instead, use the minor version's first release like Godot 3.1. This is
+    because patch releases are built from a separate *stable branch*. This kind
+    of branch doesn't follow the rest of Godot's development, which is done in
+    the ``master`` branch.
+
+The Git bisect command
+----------------------
+
+If you've found a build that didn't exhibit the bug in the above testing
+process, you can now start bisecting the regression. The Git version control
+system offers a built-in command for this: ``git bisect``. This makes the
+process semi-automated as you only have to build the engine, run it and try to
+reproduce the bug.
+
+.. note::
+
+    Before bisecting a regression, you need to set up a build environment to
+    compile Godot from source. To do so, read the
+    :ref:`Compiling <toc-devel-compiling>` page for your target platform.
+    (Compiling Godot from source doesn't require C++ programming knowledge.)
+
+    Note that compiling Godot can take a while on slow hardware (up an hour for
+    each full rebuild on a slow dual-core CPU). This means the full process can
+    take up to several hours. If your hardware is too slow, you may want to stop
+    there and report the results of your "pre-bisecting" on the GitHub issue so
+    another contributor can continue bisecting from there.
+
+To start bisecting, you must first determine the commit hashes (identifiers) of
+the "bad" and "good" build. "bad" refers to the build that exhibits the bug,
+whereas "good" refers to the version that doesn't exhibit the bug. If you're
+using a pre-release build as the "good" or "bad" build, browse the `download
+mirror <https://downloads.tuxfamily.org/godotengine/>`__, go to the folder that
+contains the pre-release you downloaded and look for the ``README.txt`` file.
+The commit hash is written inside that file.
+
+If you're using a stable release as the "good" or "bad" build, use one of the
+following commit hashes depending on the version:
+
+.. code-block:: none
+
+    3.2-stable
+    3.1-stable
+    3.0-stable
+
+To refer to the latest state of the master branch, you can use ``master``
+instead of a commit hash.
+
+:ref:`Get Godot's source code using Git <doc_getting_source>`. Once this
+is done, in the terminal window, use ``cd`` to reach the Godot repository
+folder and enter the following command:
+
+.. code-block:: shell
+
+    # <good> is the commit hash of the build that works as expected.
+    # <bad> is the commit hash of the build exhibiting the bug.
+    $ git bisect start <good> <bad>
+
+Compile Godot. This assumes you've set up a build environment:
+
+.. code-block:: shell
+
+    # <platform> is the platform you're targeting for regression testing,
+    # like "windows", "x11" or "osx".
+    $ scons platform=<platform> -j4
+
+Since building Godot takes a while, you want to dedicate as many CPU threads as
+possible to the task. This is what the ``-j`` parameter does. Here, the command
+assigns 4 CPU threads to compiling Godot.
+
+Run the binary located in the ``bin/`` folder and try to reproduce the bug.
+
+If the build **still** exhibits the bug, run the following command:
+
+.. code-block:: shell
+
+    $ git bisect bad
+
+If the build **does not** exhibit the bug, run the following command:
+
+.. code-block:: shell
+
+    $ git bisect good
+
+After entering one of the commands above, Git will switch to a different commit.
+You should now build Godot again, try to reproduce the bug, then enter ``git
+bisect good`` or ``git bisect bad`` depending on the result. You'll have to
+repeat this several times. The longer the commit range, the more steps will be
+required. 5 to 10 steps are usually sufficient to find most regressions; Git
+will remind you of the number of steps remaining (in the worst case scenario).
+
+Once you've completed enough steps, Git will display the commit hash where the
+regression appeared. Write this commit hash as a comment to the GitHub issue
+you've bisected. This will help in solving the issue. Thanks again for
+contributing to Godot :)
+
+.. note::
+
+    You can read the full documentation on ``git bisect``
+    `here <https://git-scm.com/docs/git-bisect>`__.

+ 1 - 1
community/contributing/bug_triage_guidelines.rst

@@ -123,7 +123,7 @@ be filed under the corresponding milestone; if they don't correspond to
 any current roadmap, they should be left without milestone. As a rule of
 any current roadmap, they should be left without milestone. As a rule of
 thumb, an issue corresponds to a given milestone if it concerns a feature
 thumb, an issue corresponds to a given milestone if it concerns a feature
 that is new in the milestone, or a critical bug that can't be accepted in any
 that is new in the milestone, or a critical bug that can't be accepted in any
-future stable release, or anything that Juan wants to work on right now
+future stable release, or anything that Juan wants to work on right now.
 :)
 :)
 
 
 Contributors are free to pick issues regardless of their assigned milestone;
 Contributors are free to pick issues regardless of their assigned milestone;

+ 1 - 1
community/contributing/docs_writing_guidelines.rst

@@ -506,7 +506,7 @@ important guidelines to follow.
 First, you should always be using the default editor theme and text when taking
 First, you should always be using the default editor theme and text when taking
 screenshots.
 screenshots.
 
 
-To improve the apperance of 3D screenshots, use 4× MSAA, enable anisotropic
+To improve the appearance of 3D screenshots, use 4× MSAA, enable anisotropic
 filtering on the project's textures, and set the anisotropic filter quality to
 filtering on the project's textures, and set the anisotropic filter quality to
 16× in Project Settings.
 16× in Project Settings.
 
 

+ 1 - 0
community/contributing/index.rst

@@ -8,6 +8,7 @@ Contributing
    ways_to_contribute
    ways_to_contribute
    best_practices_for_engine_contributors
    best_practices_for_engine_contributors
    pr_workflow
    pr_workflow
+   bisecting_regressions
    code_style_guidelines
    code_style_guidelines
    bug_triage_guidelines
    bug_triage_guidelines
    documentation_guidelines
    documentation_guidelines

+ 4 - 2
community/contributing/updating_the_class_reference.rst

@@ -3,6 +3,8 @@
 Contribute to the Class Reference
 Contribute to the Class Reference
 =================================
 =================================
 
 
+.. highlight:: shell
+
 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>`.
 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.
 This reference is essential for anyone learning the engine: it is available both online and in the engine.
 
 
@@ -255,7 +257,7 @@ Godot's class reference supports BBcode-like tags. They add nice formatting to t
 
 
 Use ``[codeblock]`` for pre-formatted code blocks. Inside ``[codeblock]``, always use **four spaces** for indentation (the parser will delete tabs). Example:
 Use ``[codeblock]`` for pre-formatted code blocks. Inside ``[codeblock]``, always use **four spaces** for indentation (the parser will delete tabs). Example:
 
 
-.. code-block:: xml
+.. code-block:: none
 
 
     [codeblock]
     [codeblock]
     func _ready():
     func _ready():
@@ -265,7 +267,7 @@ Use ``[codeblock]`` for pre-formatted code blocks. Inside ``[codeblock]``, alway
 
 
 Will display as:
 Will display as:
 
 
-::
+.. code-block:: gdscript
 
 
     func _ready():
     func _ready():
         var sprite = get_node("Sprite")
         var sprite = get_node("Sprite")

+ 1 - 0
community/tutorials.rst

@@ -21,6 +21,7 @@ Video tutorials
 
 
 - `Emilio <https://www.youtube.com/channel/UC9DR22-qohBDtZ74R3FxOZg>`_ (2D, GDScript and VisualScript).
 - `Emilio <https://www.youtube.com/channel/UC9DR22-qohBDtZ74R3FxOZg>`_ (2D, GDScript and VisualScript).
 - `GDQuest <https://www.youtube.com/channel/UCxboW7x0jZqFdvMdCFKTMsQ/playlists>`_ (2D and 3D, GDScript, VisualScript and C#).
 - `GDQuest <https://www.youtube.com/channel/UCxboW7x0jZqFdvMdCFKTMsQ/playlists>`_ (2D and 3D, GDScript, VisualScript and C#).
+- `Game Development Channel <https://www.youtube.com/channel/UClseGZiVmeHamsjYmpbiAmQ/playlists>`_ (2D, GDScript).
 - `Game Endeavor <https://www.youtube.com/channel/UCLweX1UtQjRjj7rs_0XQ2Eg/videos>`_ (2D, GDScript).
 - `Game Endeavor <https://www.youtube.com/channel/UCLweX1UtQjRjj7rs_0XQ2Eg/videos>`_ (2D, GDScript).
 - `Game from Scratch <https://www.youtube.com/watch?v=iDEcP8Mc-7s&list=PLS9MbmO_ssyDk79j9ewONxV88fD5e_o5d>`_ (2D and 3D, GDScript and C#).
 - `Game from Scratch <https://www.youtube.com/watch?v=iDEcP8Mc-7s&list=PLS9MbmO_ssyDk79j9ewONxV88fD5e_o5d>`_ (2D and 3D, GDScript and C#).
 - `HeartBeast <https://www.youtube.com/watch?v=wETY5_9kFtA&list=PL9FzW-m48fn2jlBu_0DRh7PvAt-GULEmd>`_ (2D, GDScript).
 - `HeartBeast <https://www.youtube.com/watch?v=wETY5_9kFtA&list=PL9FzW-m48fn2jlBu_0DRh7PvAt-GULEmd>`_ (2D, GDScript).

+ 10 - 9
conf.py

@@ -11,8 +11,13 @@ import os
 needs_sphinx = "1.3"
 needs_sphinx = "1.3"
 
 
 # Sphinx extension module names and templates location
 # Sphinx extension module names and templates location
-sys.path.append(os.path.abspath("extensions"))
-extensions = ["gdscript", "sphinx_tabs.tabs", "sphinx.ext.imgmath"]
+sys.path.append(os.path.abspath("_extensions"))
+extensions = [
+    "gdscript",
+    "sphinx_search.extension",
+    "sphinx_tabs.tabs",
+    "sphinx.ext.imgmath",
+]
 
 
 templates_path = ["_templates"]
 templates_path = ["_templates"]
 
 
@@ -32,9 +37,9 @@ author = "Juan Linietsky, Ariel Manzur and the Godot community"
 
 
 # Version info for the project, acts as replacement for |version| and |release|
 # Version info for the project, acts as replacement for |version| and |release|
 # The short X.Y version
 # The short X.Y version
-version = "latest"
+version = os.getenv("READTHEDOCS_VERSION", "latest")
 # The full version, including alpha/beta/rc tags
 # The full version, including alpha/beta/rc tags
-release = "latest"
+release = version
 
 
 # Parse Sphinx tags passed from RTD via environment
 # Parse Sphinx tags passed from RTD via environment
 env_tags = os.getenv("SPHINX_TAGS")
 env_tags = os.getenv("SPHINX_TAGS")
@@ -51,7 +56,7 @@ exclude_patterns = ["_build"]
 
 
 # fmt: off
 # fmt: off
 # These imports should *not* be moved to the start of the file,
 # These imports should *not* be moved to the start of the file,
-# they depend on the sys.path.append call registering "extensions".
+# they depend on the sys.path.append call registering "_extensions".
 # GDScript syntax highlighting
 # GDScript syntax highlighting
 from gdscript import GDScriptLexer
 from gdscript import GDScriptLexer
 from sphinx.highlighting import lexers
 from sphinx.highlighting import lexers
@@ -155,7 +160,3 @@ rst_epilog = """
     image_locale="-" if language == "en" else language,
     image_locale="-" if language == "en" else language,
     target_locale="" if language == "en" else "/" + language,
     target_locale="" if language == "en" else "/" + language,
 )
 )
-
-# Exclude class reference when marked with tag i18n.
-if is_i18n:
-    exclude_patterns = ["classes"]

+ 21 - 9
development/compiling/compiling_for_android.rst

@@ -21,22 +21,25 @@ Requirements
 
 
 For compiling under Windows, Linux or macOS, the following is required:
 For compiling under Windows, Linux or macOS, the following is required:
 
 
--  `Python 3.5+ <https://www.python.org/downloads/>`_
--  `SCons <https://scons.org/pages/download.html>`_ build system
--  `Android SDK <https://developer.android.com/studio/#command-tools>`_ (command-line tools are sufficient)
+-  `Python 3.5+ <https://www.python.org/downloads/>`_.
+-  `SCons 3.0+ <https://scons.org/pages/download.html>`_ build system.
+-  `Android SDK <https://developer.android.com/studio/#command-tools>`_
+   (command-line tools are sufficient).
 
 
-   -  Required SDK components will be automatically installed by Gradle (except the NDK)
+   -  Required SDK components will be automatically installed by Gradle (except the NDK).
 
 
--  `Android NDK <https://developer.android.com/ndk/downloads/>`_ r17 or later
--  Gradle (will be downloaded and installed automatically if missing)
--  JDK 8 (either OpenJDK or Oracle JDK)
+-  `Android NDK <https://developer.android.com/ndk/downloads/>`_ r17 or later.
+-  Gradle (will be downloaded and installed automatically if missing).
+-  JDK 8 (either OpenJDK or Oracle JDK).
 
 
-   -  JDK 9 or later are not currently supported
-   -  You can download a build from `ojdkbuild <https://github.com/ojdkbuild/ojdkbuild>`_
+   -  JDK 9 or later are not currently supported.
+   -  You can download a build from `ojdkbuild <https://github.com/ojdkbuild/ojdkbuild>`_.
 
 
 .. seealso:: For a general overview of SCons usage for Godot, see
 .. seealso:: For a general overview of SCons usage for Godot, see
              :ref:`doc_introduction_to_the_buildsystem`.
              :ref:`doc_introduction_to_the_buildsystem`.
 
 
+.. _doc_android_setting_up_the_buildsystem:
+
 Setting up the buildsystem
 Setting up the buildsystem
 --------------------------
 --------------------------
 
 
@@ -196,6 +199,15 @@ referenced.
 Troubleshooting
 Troubleshooting
 ---------------
 ---------------
 
 
+Platform doesn't appear in SCons
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Double-check that you've set both the ``ANDROID_HOME`` and ``ANDROID_NDK_ROOT``
+environment variables. This is required for the platform to appear in SCons'
+list of detected platforms.
+See :ref:`Setting up the buildsystem <doc_android_setting_up_the_buildsystem>`
+for more information.
+
 Application not installed
 Application not installed
 ~~~~~~~~~~~~~~~~~~~~~~~~~
 ~~~~~~~~~~~~~~~~~~~~~~~~~
 
 

+ 2 - 2
development/compiling/compiling_for_ios.rst

@@ -8,8 +8,8 @@ Compiling for iOS
 Requirements
 Requirements
 ------------
 ------------
 
 
--  SCons (you can get it from macports, you should be able to run
-   ``scons`` in a terminal when installed)
+-  SCons 3.0+ (you can install it via Homebrew or Macports, you should be able
+   to run ``scons`` in a terminal when installed).
 -  Xcode 10.0 (or later) with the iOS (10.0) SDK and the command line tools.
 -  Xcode 10.0 (or later) with the iOS (10.0) SDK and the command line tools.
 
 
 .. seealso:: For a general overview of SCons usage for Godot, see
 .. seealso:: For a general overview of SCons usage for Godot, see

+ 2 - 2
development/compiling/compiling_for_osx.rst

@@ -10,8 +10,8 @@ Requirements
 
 
 For compiling under macOS, the following is required:
 For compiling under macOS, the following is required:
 
 
-- `Python 3.5+ <https://www.python.org>`_
-- `SCons <https://www.scons.org>`_ build system.
+- `Python 3.5+ <https://www.python.org>`_.
+- `SCons 3.0+ <https://www.scons.org>`_ build system.
 - `Xcode <https://apps.apple.com/us/app/xcode/id497799835>`_
 - `Xcode <https://apps.apple.com/us/app/xcode/id497799835>`_
   (or the more lightweight Command Line Tools for Xcode).
   (or the more lightweight Command Line Tools for Xcode).
 - *Optional* - `yasm <https://yasm.tortall.net/>`_ (for WebM SIMD optimizations).
 - *Optional* - `yasm <https://yasm.tortall.net/>`_ (for WebM SIMD optimizations).

+ 5 - 5
development/compiling/compiling_for_uwp.rst

@@ -8,10 +8,9 @@ Compiling for Universal Windows Platform
 Requirements
 Requirements
 ------------
 ------------
 
 
--  SCons (see :ref:`doc_compiling_for_windows` for more details).
--  Visual Studio 2015 Update 2. It may work with earlier versions. See
-   :ref:`doc_compiling_for_windows` about the caveats of installing it
-   and the various prompts.
+-  SCons 3.0+ (see :ref:`doc_compiling_for_windows` for more details).
+-  Visual Studio 2017 or later. See :ref:`doc_compiling_for_windows` about the
+   caveats of installing it and the various prompts.
 -  Windows 10 SDK (can be selected in Visual Studio installation).
 -  Windows 10 SDK (can be selected in Visual Studio installation).
 -  `ANGLE source <https://github.com/Microsoft/angle>`__. Use the
 -  `ANGLE source <https://github.com/Microsoft/angle>`__. Use the
    ``ms_master`` (default) branch. Keep it in a path without spaces to
    ``ms_master`` (default) branch. Keep it in a path without spaces to
@@ -21,7 +20,8 @@ Requirements
           ``ms_master`` branch has been cleared out.
           ``ms_master`` branch has been cleared out.
           
           
           As a temporary workaround however, it is still possible to
           As a temporary workaround however, it is still possible to
-          download an older state of the source code via commit `c61d048 <https://github.com/microsoft/angle/tree/c61d0488abd9663e0d4d2450db7345baa2c0dfb6>`__.
+          download an older state of the source code via commit
+          `c61d048 <https://github.com/microsoft/angle/tree/c61d0488abd9663e0d4d2450db7345baa2c0dfb6>`__.
           
           
           This page will eventually be updated in the future to reflect
           This page will eventually be updated in the future to reflect
           the new build instructions.
           the new build instructions.

+ 3 - 5
development/compiling/compiling_for_web.rst

@@ -10,11 +10,9 @@ Requirements
 
 
 To compile export templates for the Web, the following is required:
 To compile export templates for the Web, the following is required:
 
 
--  `Emscripten 1.38.27+ <http://kripken.github.io/emscripten-site>`__: If the version available
-   per package manager is not recent enough, the best alternative is to install
-   using the `Emscripten SDK <http://kripken.github.io/emscripten-site/docs/getting_started/downloads.html>`__
--  `Python 3.5+ <https://www.python.org/>`__
--  `SCons <https://www.scons.org>`__ build system
+-  `Emscripten 1.39.0+ <https://emscripten.org>`__.
+-  `Python 3.5+ <https://www.python.org/>`__.
+-  `SCons 3.0+ <https://www.scons.org>`__ build system.
 
 
 .. seealso:: For a general overview of SCons usage for Godot, see
 .. seealso:: For a general overview of SCons usage for Godot, see
              :ref:`doc_introduction_to_the_buildsystem`.
              :ref:`doc_introduction_to_the_buildsystem`.

+ 6 - 6
development/compiling/compiling_for_windows.rst

@@ -11,14 +11,14 @@ Requirements
 For compiling under Windows, the following is required:
 For compiling under Windows, the following is required:
 
 
 - `Visual Studio Community <https://www.visualstudio.com/vs/community/>`_,
 - `Visual Studio Community <https://www.visualstudio.com/vs/community/>`_,
-  version 2015 (14.0) or later. VS 2019 is recommended.
+  version 2017 or later. VS 2019 is recommended.
   **Make sure to read "Installing Visual Studio caveats" below or you
   **Make sure to read "Installing Visual Studio caveats" below or you
   will have to run/download the installer again.**
   will have to run/download the installer again.**
-- MinGW-w64 with GCC can be used as an alternative to Visual Studio.
-  Be sure to install/configure it to use the ``posix`` thread model.
-- `Python 3.5+ <https://www.python.org/downloads/windows/>`_
-- `SCons <https://www.scons.org>`_ build system. If using Visual Studio 2019,
-  you *must* have SCons 3.1.1 or later.
+- `MinGW-w64 <http://mingw-w64.org/>`_ with GCC can be used as an alternative to
+  Visual Studio. Be sure to install/configure it to use the ``posix`` thread model.
+- `Python 3.5+ <https://www.python.org/downloads/windows/>`_.
+- `SCons 3.0 <https://www.scons.org>`_ build system. If using Visual Studio 2019,
+  you need at least SCons 3.1.1.
 - *Optional* - `yasm <https://yasm.tortall.net/>`_ (for WebM SIMD optimizations)
 - *Optional* - `yasm <https://yasm.tortall.net/>`_ (for WebM SIMD optimizations)
 
 
 .. note:: If you have `Scoop <https://scoop.sh/>`_ installed, you can easily
 .. note:: If you have `Scoop <https://scoop.sh/>`_ installed, you can easily

+ 14 - 10
development/compiling/compiling_for_x11.rst

@@ -11,16 +11,20 @@ Requirements
 For compiling under Linux or other Unix variants, the following is
 For compiling under Linux or other Unix variants, the following is
 required:
 required:
 
 
--  GCC or Clang
--  Python 3.5+
--  SCons build system (3.0 or later for Python 3)
--  pkg-config (used to detect the dependencies below)
--  X11, Xcursor, Xinerama, Xi and XRandR development libraries
--  MesaGL development libraries
--  ALSA development libraries
--  PulseAudio development libraries
--  *Optional* - libudev (build with ``udev=yes``)
--  *Optional* - yasm (for WebM SIMD optimizations)
+-  GCC 7+ or Clang 6+.
+-  Python 3.5+.
+-  SCons 3.0+ build system. If your distribution uses Python 2 by default,
+   or you are using a version of SCons prior to 3.1.2, you will need to change
+   the version of Python that SCons uses by changing the shebang (the first line)
+   of the SCons script file to ``#! /usr/bin/python3``.
+   Use the command ``which scons`` to find the location of the SCons script file.
+-  pkg-config (used to detect the dependencies below).
+-  X11, Xcursor, Xinerama, Xi and XRandR development libraries.
+-  MesaGL development libraries.
+-  ALSA development libraries.
+-  PulseAudio development libraries.
+-  *Optional* - libudev (build with ``udev=yes``).
+-  *Optional* - yasm (for WebM SIMD optimizations).
 
 
 .. seealso:: For a general overview of SCons usage for Godot, see
 .. seealso:: For a general overview of SCons usage for Godot, see
              :ref:`doc_introduction_to_the_buildsystem`.
              :ref:`doc_introduction_to_the_buildsystem`.

+ 144 - 26
development/compiling/compiling_with_mono.rst

@@ -69,7 +69,7 @@ without having to repeat this process.
 module enabled. Its exact name will differ based on your system and
 module enabled. Its exact name will differ based on your system and
 configuration, but should be of the form
 configuration, but should be of the form
 ``bin/godot.<platform>.tools.<bits>.mono``, e.g. ``bin/godot.x11.tools.64.mono``
 ``bin/godot.<platform>.tools.<bits>.mono``, e.g. ``bin/godot.x11.tools.64.mono``
-or ``bin/godot.windows.tools.64.exe``. Be especially aware of the **.mono**
+or ``bin/godot.windows.tools.64.mono.exe``. Be especially aware of the **.mono**
 suffix! If you've previously compiled Godot without Mono support, you might have
 suffix! If you've previously compiled Godot without Mono support, you might have
 similarly named binaries without this suffix. These binaries can't be used to
 similarly named binaries without this suffix. These binaries can't be used to
 generate the Mono glue.
 generate the Mono glue.
@@ -160,8 +160,8 @@ The data directory is a dependency for Godot binaries built with the Mono module
 enabled. It contains important files for the correct functioning of Godot. It
 enabled. It contains important files for the correct functioning of Godot. It
 must be distributed together with the Godot executable.
 must be distributed together with the Godot executable.
 
 
-.. note:: The information below doesn't apply to Android, as there is
-          no data directory for that platform.
+.. note:: The information below doesn't apply for Android, iOS and WASM,
+          as there is no data directory for these platforms.
 
 
 Export templates
 Export templates
 ^^^^^^^^^^^^^^^^
 ^^^^^^^^^^^^^^^^
@@ -219,6 +219,19 @@ when building the editor in order to create this folder and its contents.
 The ``Tools`` subdirectory contains tools required by the editor, like the
 The ``Tools`` subdirectory contains tools required by the editor, like the
 ``GodotTools`` assemblies and its dependencies.
 ``GodotTools`` assemblies and its dependencies.
 
 
+Building the Mono runtime
+-------------------------
+
+When building Godot for the desktop, you will likely use the pre-built Mono runtime
+that is installed on your system. This likely won't be the case when targeting other
+platforms like Android, iOS and WebAssembly. You will have to build the Mono runtime
+yourself for those platforms.
+
+We recommend using these `build scripts <https://github.com/godotengine/godot-mono-builds>`_.
+They simplify this process but also include some patches needed
+for proper functioning with Godot. See the README on the link above
+for instructions on how to use the scripts.
+
 Targeting Android
 Targeting Android
 -----------------
 -----------------
 
 
@@ -228,20 +241,116 @@ There is no need to worry about run-time dependencies like a data directory or
 the shared library (when dynamically linking) as those are automatically added
 the shared library (when dynamically linking) as those are automatically added
 to the Gradle project.
 to the Gradle project.
 
 
-Before building Godot, you need to cross compile the Mono runtime for the target
-architectures. We recommend using these
-`build scripts <https://github.com/godotengine/godot-mono-builds>`_.
-They simplify this process but also include some patches needed
-for proper functioning with Godot. See the README on the link above
-for instructions on how to use the scripts.
-
 Once you've built Mono, you can proceed to build Godot with the instructions
 Once you've built Mono, you can proceed to build Godot with the instructions
 described in this page and the
 described in this page and the
-:ref:`Compiling for Android<doc_compiling_for_android>` page. Make sure
-to let SCons know about the location of the Mono runtime you've just built:
+:ref:`Compiling for Android<doc_compiling_for_android>` page.
+Make sure to let SCons know about the location of the Mono runtime you've just built, e.g.:
 ``scons [...] mono_prefix="$HOME/mono-installs/android-armeabi-v7a-release"``
 ``scons [...] mono_prefix="$HOME/mono-installs/android-armeabi-v7a-release"``
-(This path may be different on your system, depending on the options you used
-to build Mono).
+(This path may be different on your system).
+
+Targeting iOS
+-------------
+
+Once you've built Mono, you can proceed to build Godot with the instructions
+described in this page and the
+:ref:`Compiling for iOS<doc_compiling_for_ios>` page.
+Make sure to let SCons know about the location of the Mono runtime you've just built, e.g.:
+``scons [...] mono_prefix="$HOME/mono-installs/ios-arm64-release"``
+(This path may be different on your system).
+
+After building Godot for each architecture, you will notice SCons has
+copied the Mono libraries for each of them to the output directory:
+
+::
+
+    #bin/libmono-native.iphone.<arch>.a
+    #bin/libmonosgen-2.0.iphone.<arch>.a
+    #bin/libmonoprofiler-log.iphone.<arch>.a
+
+    #bin/libmono-ilgen.iphone.<arch>.a
+    #bin/libmono-ee-interp.iphone.<arch>.a
+    #bin/libmono-icall-table.iphone.<arch>.a
+
+The last three are only for iOS devices and are not available for the iOS simulator.
+
+These libraries must be put in universal (multi-architecture) "fat"
+files to be distributed with the export templates.
+
+The following bash script will create the "fat" libraries in the directory ``#bin/ios/iphone-mono-libs``:
+
+::
+
+    mkdir -p bin/ios
+    mkdir -p bin/ios/iphone-mono-libs
+
+    lipo -create bin/libmonosgen-2.0.iphone.arm64.a bin/libmonosgen-2.0.iphone.x86_64.a -output bin/ios/iphone-mono-libs/libmonosgen-2.0.iphone.fat.a
+    lipo -create bin/libmono-native.iphone.arm64.a bin/libmono-native.iphone.x86_64.a -output bin/ios/iphone-mono-libs/libmono-native.iphone.fat.a
+    lipo -create bin/libmono-profiler-log.iphone.arm64.a bin/libmono-profiler-log.iphone.x86_64.a -output bin/ios/iphone-mono-libs/libmono-profiler-log.iphone.fat.a
+
+    # The Mono libraries for the interpreter are not available for simulator builds
+    lipo -create bin/libmono-ee-interp.iphone.arm64.a -output bin/ios/iphone-mono-libs/libmono-ee-interp.iphone.fat.a
+    lipo -create bin/libmono-icall-table.iphone.arm64.a -output bin/ios/iphone-mono-libs/libmono-icall-table.iphone.fat.a
+    lipo -create bin/libmono-ilgen.iphone.arm64.a -output bin/ios/iphone-mono-libs/libmono-ilgen.iphone.fat.a
+
+The ``iphone-mono-libs`` folder must be distributed with the export templates.
+The Godot editor will look for the libraries in ``<templates>/iphone-mono-libs/lib<name>.iphone.fat.a``.
+
+Targeting WebAssembly
+---------------------
+
+Building for WebAssembly currently involves the same process regardless of whether the Mono module is enabled.
+
+Once you've built Mono, you can proceed to build Godot with the instructions
+described in this page and the
+:ref:`Compiling for the Web<doc_compiling_for_web>` page.
+Make sure to let SCons know about the location of the Mono runtime you've just built, e.g.:
+``scons [...] mono_prefix="$HOME/mono-installs/wasm-runtime-release"``
+(This path may be different on your system).
+
+Base Class Library
+------------------
+
+The export templates must also include the BCL (Base Class Library) for each target platform.
+Godot looks for the BCL folder at ``<templates>/bcl/<target_platform>``,
+where ``<target_platform>`` is the same name passed to the SCons ``platform`` option,
+e.g.: ``<templates>/bcl/windows``, ``<templates>/bcl/javascript``.
+
+Alternatively, Godot will look for them in the following locations:
+
++-------------------+---------------------------------+
+|      Android      |  ``<templates>/bcl/monodroid``  |
++-------------------+---------------------------------+
+|        iOS        |  ``<templates>/bcl/monotouch``  |
++-------------------+---------------------------------+
+|    WebAssembly    |    ``<templates>/bcl/wasm``     |
++-------------------+---------------------------------+
+|  Linux and macOS  |   ``<templates>/bcl/net_4_x``   |
++-------------------+---------------------------------+
+|      Windows      | ``<templates>/bcl/net_4_x_win`` |
++-------------------+---------------------------------+
+
+As of now, we're assuming the same BCL profile can be used for both Linux and macOS,
+but this may change in the future as they're not guaranteed to be the same
+(as is the case with the Windows BCL).
+
+If the target platform is the same as the platform of the Godot editor,
+then the editor will use the BCL it's running on (``<data_folder>/Mono/lib/mono/4.5``)
+if it cannot find the BCL in the export templates.
+
+AOT cross-compilers
+-------------------
+
+To perform ahead-of-time (AOT) compilation for other platforms, Godot needs to have
+access to the Mono cross-compilers for that platform and architecture.
+
+Godot will look for the cross-compiler executable in the AOT compilers folder.
+The location of this folder is ``<data_folder>/Tools/aot-compilers/``.
+
+In order to build the cross-compilers we recommend using these
+`build scripts <https://github.com/godotengine/godot-mono-builds>`_.
+
+After building them, copy the executable to the Godot AOT compilers directory. The
+executable name is ``<triple>-mono-sgen``, e.g.: ``aarch64-apple-darwin-mono-sgen``.
 
 
 Command-line options
 Command-line options
 --------------------
 --------------------
@@ -249,20 +358,29 @@ Command-line options
 The following is the list of command-line options available when building with
 The following is the list of command-line options available when building with
 the Mono module:
 the Mono module:
 
 
-- **module_mono_enabled**: Build Godot with the Mono module enabled
-  (yes | **no**)
+- **module_mono_enabled**\ =yes | **no**
+
+  - Build Godot with the Mono module enabled.
+
+- **mono_glue**\ =\ **yes** | no
+
+  - Whether to include the glue source files in the build
+    and define ``MONO_GLUE_DISABLED`` as a preprocessor macro.
+
+- **mono_prefix**\ =path
+
+  - Path to the Mono installation directory for the target platform and architecture.
+
+- **xbuild_fallback**\ =yes | **no**
 
 
-- **mono_glue**: Whether to include the glue source files in the build
-  and define ``MONO_GLUE_DISABLED`` as a preprocessor macro (**yes** | no)
+  - Whether to fallback to xbuild if MSBuild is not available.
 
 
-- **mono_prefix**: Path to the Mono installation directory
-  for the target platform and architecture
+- **mono_static**\ =yes | no
 
 
-- **xbuild_fallback**: Whether to fallback to xbuild if MSBuild is not available
-  (yes | **no**)
+  - Whether to link the Mono runtime statically.
+  - The default is **yes** for iOS and WASM, and **no** for other platforms.
 
 
-- **mono_static**: Whether to link the Mono runtime statically
-  (yes | **no**)
+- **copy_mono_root**\ =yes | **no**
 
 
-- **copy_mono_root**: Whether to copy the Mono framework assemblies
-  and configuration files required by the Godot editor (yes | **no**)
+  - Whether to copy the Mono framework assemblies
+    and configuration files required by the Godot editor.

+ 2 - 0
development/compiling/getting_source.rst

@@ -3,6 +3,8 @@
 Getting the source
 Getting the source
 ==================
 ==================
 
 
+.. highlight:: shell
+
 Downloading the Godot source code
 Downloading the Godot source code
 ---------------------------------
 ---------------------------------
 
 

+ 5 - 3
development/compiling/introduction_to_the_buildsystem.rst

@@ -3,7 +3,7 @@
 Introduction to the buildsystem
 Introduction to the buildsystem
 ===============================
 ===============================
 
 
-.. highlight:: none
+.. highlight:: shell
 
 
 SCons
 SCons
 -----
 -----
@@ -108,7 +108,9 @@ For the previous build attempt, the result would look like this::
 This means that the binary is for X11, is not optimized, has tools (the
 This means that the binary is for X11, is not optimized, has tools (the
 whole editor) compiled in, and is meant for 64 bits.
 whole editor) compiled in, and is meant for 64 bits.
 
 
-A Windows binary with the same configuration will look like this::
+A Windows binary with the same configuration will look like this:
+
+.. code-block:: console
 
 
     C:\godot> dir bin/
     C:\godot> dir bin/
     godot.windows.tools.64.exe
     godot.windows.tools.64.exe
@@ -202,7 +204,7 @@ If you download the official export templates package and unzip it, you
 will notice that most files are optimized binaries or packages for each
 will notice that most files are optimized binaries or packages for each
 platform:
 platform:
 
 
-::
+.. code-block:: none
 
 
     android_debug.apk
     android_debug.apk
     android_release.apk
     android_release.apk

+ 6 - 6
development/cpp/binding_to_external_libraries.rst

@@ -13,7 +13,7 @@ library written in C++.
 
 
 To bind to an external library, set up a module directory similar to the Summator example:
 To bind to an external library, set up a module directory similar to the Summator example:
 
 
-::
+.. code-block:: none
 
 
     godot/modules/tts/
     godot/modules/tts/
 
 
@@ -70,7 +70,7 @@ And then you'll add the cpp file.
 Just as before, the new class needs to be registered somehow, so two more files
 Just as before, the new class needs to be registered somehow, so two more files
 need to be created:
 need to be created:
 
 
-::
+.. code-block:: none
 
 
     register_types.h
     register_types.h
     register_types.cpp
     register_types.cpp
@@ -118,7 +118,7 @@ You'll need to install the external library on your machine to get the .a librar
 documentation for specific instructions on how to do this for your operation system.  We've included the
 documentation for specific instructions on how to do this for your operation system.  We've included the
 installation commands for Linux below, for reference.
 installation commands for Linux below, for reference.
 
 
-::
+.. code-block:: shell
 
 
     sudo apt-get install festival festival-dev <-- Installs festival and speech_tools libraries
     sudo apt-get install festival festival-dev <-- Installs festival and speech_tools libraries
     apt-cache search festvox-* <-- Displays list of voice packages
     apt-cache search festvox-* <-- Displays list of voice packages
@@ -135,7 +135,7 @@ files accessible to the compiler, while also keeping the module code self-contai
 festival and speech_tools libraries can be installed from the modules/tts/ directory via
 festival and speech_tools libraries can be installed from the modules/tts/ directory via
 git using the following commands:
 git using the following commands:
 
 
-::
+.. code-block:: shell
 
 
     git clone https://github.com/festvox/festival
     git clone https://github.com/festvox/festival
     git clone https://github.com/festvox/speech_tools
     git clone https://github.com/festvox/speech_tools
@@ -143,7 +143,7 @@ git using the following commands:
 If you don't want the external repository source files committed to your repository, you
 If you don't want the external repository source files committed to your repository, you
 can link to them instead by adding them as submodules (from within the modules/tts/ directory), as seen below:
 can link to them instead by adding them as submodules (from within the modules/tts/ directory), as seen below:
 
 
-::
+.. code-block:: shell
 
 
     git submodule add https://github.com/festvox/festival
     git submodule add https://github.com/festvox/festival
     git submodule add https://github.com/festvox/speech_tools
     git submodule add https://github.com/festvox/speech_tools
@@ -182,7 +182,7 @@ Example `SCsub` with custom flags:
 
 
 The final module should look like this:
 The final module should look like this:
 
 
-::
+.. code-block:: none
 
 
     godot/modules/tts/festival/
     godot/modules/tts/festival/
     godot/modules/tts/libpath/libestbase.a
     godot/modules/tts/libpath/libestbase.a

+ 1 - 1
development/cpp/configuring_an_ide.rst

@@ -139,7 +139,7 @@ Now that the project has been imported, open the project configuration.
 
 
 Add the following includes/imports:
 Add the following includes/imports:
 
 
-::
+.. code-block:: none
 
 
     .  // a dot to indicate the root of the Godot project
     .  // a dot to indicate the root of the Godot project
     core/
     core/

+ 6 - 6
development/cpp/custom_modules_in_cpp.rst

@@ -45,7 +45,7 @@ The example module will be called "summator", and is placed inside the
 Godot source tree (``C:\godot`` refers to wherever the Godot sources are
 Godot source tree (``C:\godot`` refers to wherever the Godot sources are
 located):
 located):
 
 
-::
+.. code-block:: console
 
 
     C:\godot> cd modules
     C:\godot> cd modules
     C:\godot\modules> mkdir summator
     C:\godot\modules> mkdir summator
@@ -114,7 +114,7 @@ And then the cpp file.
 Then, the new class needs to be registered somehow, so two more files
 Then, the new class needs to be registered somehow, so two more files
 need to be created:
 need to be created:
 
 
-::
+.. code-block:: none
 
 
     register_types.h
     register_types.h
     register_types.cpp
     register_types.cpp
@@ -211,7 +211,7 @@ this case, ``True`` means it will build for every platform).
 And that's it. Hope it was not too complex! Your module should look like
 And that's it. Hope it was not too complex! Your module should look like
 this:
 this:
 
 
-::
+.. code-block:: none
 
 
     godot/modules/summator/config.py
     godot/modules/summator/config.py
     godot/modules/summator/summator.h
     godot/modules/summator/summator.h
@@ -309,7 +309,7 @@ Once compiled, we should end up with a ``bin`` directory containing both the
 a standard directory (like ``/usr/lib``), we have to help our binary find it
 a standard directory (like ``/usr/lib``), we have to help our binary find it
 during runtime with the ``LD_LIBRARY_PATH`` environ variable:
 during runtime with the ``LD_LIBRARY_PATH`` environ variable:
 
 
-::
+.. code-block:: shell
 
 
     user@host:~/godot$ export LD_LIBRARY_PATH=`pwd`/bin/
     user@host:~/godot$ export LD_LIBRARY_PATH=`pwd`/bin/
     user@host:~/godot$ ./bin/godot*
     user@host:~/godot$ ./bin/godot*
@@ -355,7 +355,7 @@ and as a shared library when passing ``summator_shared=yes``.
 Finally you can even speedup build further by explicitly specifying your
 Finally you can even speedup build further by explicitly specifying your
 shared module as target in the scons command:
 shared module as target in the scons command:
 
 
-::
+.. code-block:: shell
 
 
     user@host:~/godot$ scons summator_shared=yes platform=x11 bin/libsummator.x11.tools.64.so
     user@host:~/godot$ scons summator_shared=yes platform=x11 bin/libsummator.x11.tools.64.so
 
 
@@ -397,7 +397,7 @@ directory.
 
 
 3. Run command:
 3. Run command:
 
 
-   ::
+   .. code-block:: shell
 
 
       godot --doctool <path>
       godot --doctool <path>
 
 

+ 0 - 21
extensions/sphinx_tabs/LICENSE

@@ -1,21 +0,0 @@
-The MIT License (MIT)
-
-Copyright (c) 2017 djungelorm
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.

+ 0 - 1
extensions/sphinx_tabs/__init__.py

@@ -1 +0,0 @@
-__import__('pkg_resources').declare_namespace(__name__)

+ 0 - 7
extensions/sphinx_tabs/semantic-ui-2.2.10/LICENSE.md

@@ -1,7 +0,0 @@
-# The MIT License
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

File diff suppressed because it is too large
+ 0 - 0
extensions/sphinx_tabs/semantic-ui-2.2.10/menu.min.css


File diff suppressed because it is too large
+ 0 - 8
extensions/sphinx_tabs/semantic-ui-2.2.10/segment.min.css


+ 0 - 9
extensions/sphinx_tabs/semantic-ui-2.2.10/tab.min.css

@@ -1,9 +0,0 @@
-/*!
- * # Semantic UI 2.2.10 - Tab
- * http://github.com/semantic-org/semantic-ui/
- *
- *
- * Released under the MIT license
- * http://opensource.org/licenses/MIT
- *
- */.ui.tab{display:none}.ui.tab.active,.ui.tab.open{display:block}.ui.tab.loading{position:relative;overflow:hidden;display:block;min-height:250px}.ui.tab.loading *{position:relative!important;left:-10000px!important}.ui.tab.loading.segment:before,.ui.tab.loading:before{position:absolute;content:'';top:100px;left:50%;margin:-1.25em 0 0 -1.25em;width:2.5em;height:2.5em;border-radius:500rem;border:.2em solid rgba(0,0,0,.1)}.ui.tab.loading.segment:after,.ui.tab.loading:after{position:absolute;content:'';top:100px;left:50%;margin:-1.25em 0 0 -1.25em;width:2.5em;height:2.5em;-webkit-animation:button-spin .6s linear;animation:button-spin .6s linear;-webkit-animation-iteration-count:infinite;animation-iteration-count:infinite;border-radius:500rem;border-color:#767676 transparent transparent;border-style:solid;border-width:.2em;box-shadow:0 0 0 1px transparent}

File diff suppressed because it is too large
+ 0 - 9
extensions/sphinx_tabs/semantic-ui-2.2.10/tab.min.js


+ 0 - 43
extensions/sphinx_tabs/tabs.css

@@ -1,43 +0,0 @@
-.sphinx-tabs {
-    margin-bottom: 2em;
-}
-
-.sphinx-tabs .sphinx-menu a.item {
-    color: #2980b9 !important;
-}
-
-.sphinx-tabs .sphinx-menu {
-    border-bottom-color: #a0b3bf !important;
-    display: flex;
-    flex-direction: row;
-    flex-wrap: wrap;
-}
-
-.sphinx-tabs .sphinx-menu a.active.item {
-    border-color: #a0b3bf !important;
-}
-
-.sphinx-tab {
-    border-color: #a0b3bf !important;
-    box-sizing: border-box;
-}
-
-.tab div[class^='highlight']:last-child {
-    margin-bottom: 0;
-}
-
-.tab .wy-plain-list-disc:last-child,
-.rst-content .section ul:last-child,
-.rst-content .toctree-wrapper ul:last-child,
-article ul:last-child {
-    margin-bottom: 0;
-}
-
-/* Code tabs don't need the code-block border */
-.code-tab.tab {
-    padding: 0.4em !important;
-}
-
-.code-tab.tab div[class^='highlight'] {
-    border: none;
-}

+ 0 - 85
extensions/sphinx_tabs/tabs.js

@@ -1,85 +0,0 @@
-// From http://stackoverflow.com/questions/123999/how-to-tell-if-a-dom-element-is-visible-in-the-current-viewport
-function elementIsInView (el) {
-  if (typeof jQuery === "function" && el instanceof jQuery) {
-    el = el[0];
-  }
-
-  const  rect = el.getBoundingClientRect();
-
-  return (
-    rect.top >= 0 &&
-    rect.left >= 0 &&
-    rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
-    rect.right <= (window.innerWidth || document.documentElement.clientWidth)
-  );
-}
-
-$(function() {
-  // Change container tags <div> -> <a>
-  $('.sphinx-menu.menu .item').each(function() {
-    var this_ = $(this);
-    var a_this = $('<a>');
-
-    a_this.html(this_.html());
-    $.each(this_.prop('attributes'), function() {
-      a_this.attr(this.name, this.value);
-    });
-
-    this_.replaceWith(a_this);
-  });
-
-  // We store the data-tab values as sphinx-data-<data-tab value>
-  // Add data-tab attribute with the extracted value
-  $('.sphinx-menu.menu .item, .sphinx-tab.tab').each(function() {
-    var this_ = $(this);
-    const prefix = 'sphinx-data-';
-    const classes = this_.attr('class').split(/\s+/);
-    $.each(classes, function(idx, clazz) {
-      if (clazz.startsWith(prefix)) {
-        this_.attr('data-tab',
-                   clazz.substring(prefix.length));
-      }
-    });
-  });
-
-  // Mimic the Semantic UI behaviour
-  $('.sphinx-menu.menu .item').each(function() {
-    var this1 = $(this);
-    var data_tab = this1.attr('data-tab');
-
-    this1.on('click', function() {
-      // Find offset in view
-      const offset = (this1.offset().top - $(window).scrollTop());
-
-      // Enable all tabs with this id
-
-      // For each tab group
-      $('.sphinx-tabs').each(function() {
-        var this2 = $(this);
-
-        // Check if tab group has a tab matching the clicked tab
-        var has_tab = false;
-        this2.children().eq(0).children().each(function() {
-          has_tab |= $(this).attr('data-tab') === data_tab;
-        });
-
-        if (has_tab) {
-          // Enable just the matching tab
-          var toggle = function() {
-            var this3 = $(this);
-            if (this3.attr('data-tab') === data_tab) {
-              this3.addClass('active');
-            } else {
-              this3.removeClass('active');
-            }
-          };
-          this2.children().eq(0).children('[data-tab]').each(toggle);
-          this2.children('[data-tab]').each(toggle);
-        }
-      });
-
-      // Keep tab with the original view offset
-      $(window).scrollTop(this1.offset().top - offset);
-    });
-  });
-});

+ 0 - 348
extensions/sphinx_tabs/tabs.py

@@ -1,348 +0,0 @@
-""" Tabbed views for Sphinx, with HTML builder """
-
-import base64
-import json
-import posixpath
-import os
-from docutils import nodes
-from docutils.parsers.rst import Directive, directives
-from pkg_resources import resource_filename
-from pygments.lexers import get_all_lexers
-from sphinx.util.osutil import copyfile
-from sphinx.util import logging
-
-
-FILES = [
-    'tabs.js',
-    'tabs.css',
-    'semantic-ui-2.2.10/segment.min.css',
-    'semantic-ui-2.2.10/menu.min.css',
-    'semantic-ui-2.2.10/tab.min.css',
-    'semantic-ui-2.2.10/tab.min.js',
-]
-
-
-LEXER_MAP = {}
-for lexer in get_all_lexers():
-    for short_name in lexer[1]:
-        LEXER_MAP[short_name] = lexer[0]
-
-
-def get_compatible_builders(app):
-    builders = ['html', 'singlehtml', 'dirhtml',
-                'readthedocs', 'readthedocsdirhtml',
-                'readthedocssinglehtml', 'readthedocssinglehtmllocalmedia',
-                'spelling']
-    builders.extend(app.config['sphinx_tabs_valid_builders'])
-    return builders
-
-
-class TabsDirective(Directive):
-    """ Top-level tabs directive """
-
-    has_content = True
-
-    def run(self):
-        """ Parse a tabs directive """
-        self.assert_has_content()
-        env = self.state.document.settings.env
-
-        node = nodes.container()
-        node['classes'] = ['sphinx-tabs']
-
-        if 'next_tabs_id' not in env.temp_data:
-            env.temp_data['next_tabs_id'] = 0
-        if 'tabs_stack' not in env.temp_data:
-            env.temp_data['tabs_stack'] = []
-
-        tabs_id = env.temp_data['next_tabs_id']
-        tabs_key = 'tabs_%d' % tabs_id
-        env.temp_data['next_tabs_id'] += 1
-        env.temp_data['tabs_stack'].append(tabs_id)
-
-        env.temp_data[tabs_key] = {}
-        env.temp_data[tabs_key]['tab_ids'] = []
-        env.temp_data[tabs_key]['tab_titles'] = []
-        env.temp_data[tabs_key]['is_first_tab'] = True
-
-        self.state.nested_parse(self.content, self.content_offset, node)
-
-        if env.app.builder.name in get_compatible_builders(env.app):
-            tabs_node = nodes.container()
-            tabs_node.tagname = 'div'
-
-            classes = 'ui top attached tabular menu sphinx-menu'
-            tabs_node['classes'] = classes.split(' ')
-
-            tab_titles = env.temp_data[tabs_key]['tab_titles']
-            for idx, [data_tab, tab_name] in enumerate(tab_titles):
-                tab = nodes.container()
-                tab.tagname = 'a'
-                tab['classes'] = ['item'] if idx > 0 else ['active', 'item']
-                tab['classes'].append(data_tab)
-                tab += tab_name
-                tabs_node += tab
-
-            node.children.insert(0, tabs_node)
-
-        env.temp_data['tabs_stack'].pop()
-        return [node]
-
-
-class TabDirective(Directive):
-    """ Tab directive, for adding a tab to a collection of tabs """
-
-    has_content = True
-
-    def run(self):
-        """ Parse a tab directive """
-        self.assert_has_content()
-        env = self.state.document.settings.env
-
-        tabs_id = env.temp_data['tabs_stack'][-1]
-        tabs_key = 'tabs_%d' % tabs_id
-
-        args = self.content[0].strip()
-        if args.startswith('{'):
-            try:
-                args = json.loads(args)
-                self.content.trim_start(1)
-            except ValueError:
-                args = {}
-        else:
-            args = {}
-
-        tab_name = nodes.container()
-        self.state.nested_parse(
-            self.content[:1], self.content_offset, tab_name)
-        args['tab_name'] = tab_name
-
-        include_tabs_id_in_data_tab = False
-        if 'tab_id' not in args:
-            args['tab_id'] = env.new_serialno(tabs_key)
-            include_tabs_id_in_data_tab = True
-        i = 1
-        while args['tab_id'] in env.temp_data[tabs_key]['tab_ids']:
-            args['tab_id'] = '%s-%d' % (args['tab_id'], i)
-            i += 1
-        env.temp_data[tabs_key]['tab_ids'].append(args['tab_id'])
-
-        data_tab = str(args['tab_id'])
-        if include_tabs_id_in_data_tab:
-            data_tab = '%d-%s' % (tabs_id, data_tab)
-        data_tab = "sphinx-data-tab-{}".format(data_tab)
-
-        env.temp_data[tabs_key]['tab_titles'].append(
-            (data_tab, args['tab_name']))
-
-        text = '\n'.join(self.content)
-        node = nodes.container(text)
-
-        classes = 'ui bottom attached sphinx-tab tab segment'
-        node['classes'] = classes.split(' ')
-        node['classes'].extend(args.get('classes', []))
-        node['classes'].append(data_tab)
-
-        if env.temp_data[tabs_key]['is_first_tab']:
-            node['classes'].append('active')
-            env.temp_data[tabs_key]['is_first_tab'] = False
-
-        self.state.nested_parse(self.content[2:], self.content_offset, node)
-
-        if env.app.builder.name not in get_compatible_builders(env.app):
-            outer_node = nodes.container()
-            tab = nodes.container()
-            tab.tagname = 'a'
-            tab['classes'] = ['item']
-            tab += tab_name
-
-            outer_node.append(tab)
-            outer_node.append(node)
-            return [outer_node]
-
-        return [node]
-
-
-class GroupTabDirective(Directive):
-    """ Tab directive that toggles with same tab names across page"""
-
-    has_content = True
-
-    def run(self):
-        """ Parse a tab directive """
-        self.assert_has_content()
-
-        group_name = self.content[0]
-        self.content.trim_start(2)
-
-        for idx, line in enumerate(self.content.data):
-            self.content.data[idx] = '   ' + line
-
-        tab_args = {
-            'tab_id': base64.b64encode(
-                group_name.encode('utf-8')).decode('utf-8'),
-            'group_tab': True
-        }
-
-        new_content = [
-            '.. tab:: {}'.format(json.dumps(tab_args)),
-            '   {}'.format(group_name),
-            '',
-        ]
-
-        for idx, line in enumerate(new_content):
-            self.content.data.insert(idx, line)
-            self.content.items.insert(idx, (None, idx))
-
-        node = nodes.container()
-        self.state.nested_parse(self.content, self.content_offset, node)
-        return node.children
-
-
-class CodeTabDirective(Directive):
-    """ Tab directive with a codeblock as its content"""
-
-    has_content = True
-    option_spec = {
-        'linenos': directives.flag
-    }
-
-    def run(self):
-        """ Parse a tab directive """
-        self.assert_has_content()
-
-        args = self.content[0].strip().split()
-        self.content.trim_start(2)
-
-        lang = args[0]
-        tab_name = ' '.join(args[1:]) if len(args) > 1 else LEXER_MAP[lang]
-
-        for idx, line in enumerate(self.content.data):
-            self.content.data[idx] = '      ' + line
-
-        tab_args = {
-            'tab_id': base64.b64encode(
-                tab_name.encode('utf-8')).decode('utf-8'),
-            'classes': ['code-tab'],
-        }
-
-        new_content = [
-            '.. tab:: {}'.format(json.dumps(tab_args)),
-            '   {}'.format(tab_name),
-            '',
-            '   .. code-block:: {}'.format(lang),
-        ]
-
-        if 'linenos' in self.options:
-            new_content.append('      :linenos:')
-
-        new_content.append('')
-
-        for idx, line in enumerate(new_content):
-            self.content.data.insert(idx, line)
-            self.content.items.insert(idx, (None, idx))
-
-        node = nodes.container()
-        self.state.nested_parse(self.content, self.content_offset, node)
-        return node.children
-
-
-class _FindTabsDirectiveVisitor(nodes.NodeVisitor):
-    """ Visitor pattern than looks for a sphinx tabs
-        directive in a document """
-    def __init__(self, document):
-        nodes.NodeVisitor.__init__(self, document)
-        self._found = False
-
-    def unknown_visit(self, node):
-        if not self._found and isinstance(node, nodes.container) and \
-           'classes' in node and isinstance(node['classes'], list):
-            self._found = 'sphinx-tabs' in node['classes']
-
-    @property
-    def found_tabs_directive(self):
-        """ Return whether a sphinx tabs directive was found """
-        return self._found
-
-
-# pylint: disable=unused-argument
-def update_context(app, pagename, templatename, context, doctree):
-    """ Remove sphinx-tabs CSS and JS asset files if not used in a page """
-    if doctree is None:
-        return
-    visitor = _FindTabsDirectiveVisitor(doctree)
-    doctree.walk(visitor)
-    if not visitor.found_tabs_directive:
-        paths = [posixpath.join('_static', 'sphinx_tabs/' + f) for f in FILES]
-        if 'css_files' in context:
-            context['css_files'] = context['css_files'][:]
-            for path in paths:
-                if path.endswith('.css'):
-                    context['css_files'].remove(path)
-        if 'script_files' in context:
-            context['script_files'] = context['script_files'][:]
-            for path in paths:
-                if path.endswith('.js'):
-                    context['script_files'].remove(path)
-# pylint: enable=unused-argument
-
-
-def copy_assets(app, exception):
-    """ Copy asset files to the output """
-    if 'getLogger' in dir(logging):
-        log = logging.getLogger(__name__).info  # pylint: disable=no-member
-        warn = logging.getLogger(__name__).warning  # pylint: disable=no-member
-    else:
-        log = app.info
-        warn = app.warn
-    builders = get_compatible_builders(app)
-    if exception:
-        return
-    if app.builder.name not in builders:
-        if not app.config['sphinx_tabs_nowarn']:
-            warn(
-                'Not copying tabs assets! Not compatible with %s builder' %
-                app.builder.name)
-        return
-
-    log('Copying tabs assets')
-
-    installdir = os.path.join(app.builder.outdir, '_static', 'sphinx_tabs')
-
-    for path in FILES:
-        source = resource_filename('sphinx_tabs', path)
-        dest = os.path.join(installdir, path)
-
-        destdir = os.path.dirname(dest)
-        if not os.path.exists(destdir):
-            os.makedirs(destdir)
-
-        copyfile(source, dest)
-
-
-def setup(app):
-    """ Set up the plugin """
-    app.add_config_value('sphinx_tabs_nowarn', False, '')
-    app.add_config_value('sphinx_tabs_valid_builders', [], '')
-    app.add_directive('tabs', TabsDirective)
-    app.add_directive('tab', TabDirective)
-    app.add_directive('group-tab', GroupTabDirective)
-    app.add_directive('code-tab', CodeTabDirective)
-    for path in ['sphinx_tabs/' + f for f in FILES]:
-        if path.endswith('.css'):
-            if 'add_css_file' in dir(app):
-                app.add_css_file(path)
-            else:
-                app.add_stylesheet(path)
-        if path.endswith('.js'):
-            if 'add_script_file' in dir(app):
-                app.add_script_file(path)
-            else:
-                app.add_javascript(path)
-    app.connect('html-page-context', update_context)
-    app.connect('build-finished', copy_assets)
-
-    return {
-        'parallel_read_safe': True,
-        'parallel_write_safe': True,
-    }

+ 39 - 0
format.sh

@@ -0,0 +1,39 @@
+#!/bin/bash
+
+# Loops through all text files tracked by Git.
+git grep -zIl '' |
+while IFS= read -rd '' f; do
+    # Exclude csproj and hdr files.
+    if [[ $f == *"csproj" ]]; then
+        continue
+    elif [[ $f == *"hdr" ]]; then
+        continue
+    fi
+    # Ensures that files are UTF-8 formatted.
+    recode UTF-8 $f 2> /dev/null
+    # Ensures that files have LF line endings.
+    dos2unix $f 2> /dev/null
+    # Ensures that files do not contain a BOM.
+    sed -i '1s/^\xEF\xBB\xBF//' "$f"
+    # Ensures that files end with newline characters.
+    tail -c1 < "$f" | read -r _ || echo >> "$f";
+done
+
+git diff > patch.patch
+FILESIZE=$(stat -c%s patch.patch)
+MAXSIZE=5
+
+# If no patch has been generated all is OK, clean up, and exit.
+if (( FILESIZE < MAXSIZE )); then
+    printf "Files in this commit comply with the formatting rules.\n"
+    rm -f patch.patch
+    exit 0
+fi
+
+# A patch has been created, notify the user, clean up, and exit.
+printf "\n*** The following differences were found between the code "
+printf "and the formatting rules:\n\n"
+cat patch.patch
+printf "\n*** Aborting, please fix your commit(s) with 'git commit --amend' or 'git rebase -i <hash>'\n"
+rm -f patch.patch
+exit 1

+ 538 - 0
getting_started/editor/default_key_mapping.rst

@@ -0,0 +1,538 @@
+.. _doc_default_key_mapping:
+
+Default editor shortcuts
+========================
+Many of Godot Editor functions can be executed with keyboard shortcuts. This page
+lists functions which have associated shortcuts by default, but many others are 
+available for customization in editor settings as well. To change keys associated 
+with these and other actions navigate to ``Editor -> Editor Settings -> Shortcuts``.
+
+While some actions are universal, a lot of shortcuts are specific to individual 
+tools. For this reason it is possible for some key combinations to be assigned
+to more than one function. The correct action will be performed depending on the
+context.
+
+.. note:: While Windows and Linux builds of the editor share most of the default settings,
+          some shortcuts may differ for macOS version. This is done for better integration
+          of the editor into macOS ecosystem. Users fluent with standard shortcuts on that 
+          OS should find Godot Editor's default key mapping intuitive.
+
+General Editor Actions
+----------------------
+
++-----------------------+-------------------------------+------------------------------+----------------------------------+
+| Action name           | Windows, Linux                | macOS                        | Editor setting                   |
++=======================+===============================+==============================+==================================+
+| Open 2D Editor        | :kbd:`F1`                     | :kbd:`Alt + 1`               | ``editor/editor_2d``             |
++-----------------------+-------------------------------+------------------------------+----------------------------------+
+| Open 3D Editor        | :kbd:`F2`                     | :kbd:`Alt + 2`               | ``editor/editor_3d``             |
++-----------------------+-------------------------------+------------------------------+----------------------------------+
+| Open Script Editor    | :kbd:`F3`                     | :kbd:`Alt + 3`               | ``editor/editor_script``         |
++-----------------------+-------------------------------+------------------------------+----------------------------------+
+| Search Help           | :kbd:`Shift + F1`             | :kbd:`Alt + Space`           | ``editor/editor_help``           |
++-----------------------+-------------------------------+------------------------------+----------------------------------+
+| Distraction Free Mode | :kbd:`Ctrl + Shift + F11`     | :kbd:`Cmd + Ctrl + D`        | ``editor/distraction_free_mode`` |
++-----------------------+-------------------------------+------------------------------+----------------------------------+
+| Next tab              | :kbd:`Ctrl + Tab`             | :kbd:`Cmd + Tab`             | ``editor/next_tab``              |
++-----------------------+-------------------------------+------------------------------+----------------------------------+
+| Previous tab          | :kbd:`Ctrl + Shift + Tab`     | :kbd:`Cmd + Shift + Tab`     | ``editor/prev_tab``              |
++-----------------------+-------------------------------+------------------------------+----------------------------------+
+| Filter Files          | :kbd:`Ctrl + Alt + P`         | :kbd:`Cmd + Alt + P`         | ``editor/filter_files``          |
++-----------------------+-------------------------------+------------------------------+----------------------------------+
+| Open Scene            | :kbd:`Ctrl + O`               | :kbd:`Cmd + O`               | ``editor/open_scene``            |
++-----------------------+-------------------------------+------------------------------+----------------------------------+
+| Close Scene           | :kbd:`Ctrl + Shift + W`       | :kbd:`Cmd + Shift + W`       | ``editor/close_scene``           |
++-----------------------+-------------------------------+------------------------------+----------------------------------+
+| Reopen Closed Scene   | :kbd:`Ctrl + Shift + T`       | :kbd:`Cmd + Shift + T`       | ``editor/reopen_closed_scene``   |
++-----------------------+-------------------------------+------------------------------+----------------------------------+
+| Save Scene            | :kbd:`Ctrl + S`               | :kbd:`Cmd + S`               | ``editor/save_scene``            |
++-----------------------+-------------------------------+------------------------------+----------------------------------+
+| Save Scene As         | :kbd:`Ctrl + Shift + S`       | :kbd:`Cmd + Shift + S`       | ``editor/save_scene_as``         |
++-----------------------+-------------------------------+------------------------------+----------------------------------+
+| Save All Scenes       | :kbd:`Ctrl + Shift + Alt + S` | :kbd:`Cmd + Shift + Alt + S` | ``editor/save_all_scenes``       |
++-----------------------+-------------------------------+------------------------------+----------------------------------+
+| Quick Open            | :kbd:`Shift + Alt + O`        | :kbd:`Shift + Alt + O`       | ``editor/quick_open``            |
++-----------------------+-------------------------------+------------------------------+----------------------------------+
+| Quick Open Scene      | :kbd:`Ctrl + Shift + O`       | :kbd:`Cmd + Shift + O`       | ``editor/quick_open_scene``      |
++-----------------------+-------------------------------+------------------------------+----------------------------------+
+| Quick Open Script     | :kbd:`Ctrl + Alt + O`         | :kbd:`Cmd + Alt + O`         | ``editor/quick_open_script``     |
++-----------------------+-------------------------------+------------------------------+----------------------------------+
+| Undo                  | :kbd:`Ctrl + Z`               | :kbd:`Cmd + Z`               | ``editor/undo``                  |
++-----------------------+-------------------------------+------------------------------+----------------------------------+
+| Redo                  | :kbd:`Ctrl + Shift + Z`       | :kbd:`Cmd + Shift + Z`       | ``editor/redo``                  |
++-----------------------+-------------------------------+------------------------------+----------------------------------+
+| Quit                  | :kbd:`Ctrl + Q`               | :kbd:`Cmd + Q`               | ``editor/file_quit``             |
++-----------------------+-------------------------------+------------------------------+----------------------------------+
+| Quit to Project List  | :kbd:`Ctrl + Shift + Q`       | :kbd:`Shift + Alt + Q`       | ``editor/quit_to_project_list``  |
++-----------------------+-------------------------------+------------------------------+----------------------------------+
+| Take Screenshot       | :kbd:`Ctrl + F12`             | :kbd:`Cmd + F12`             | ``editor/take_screenshot``       |
++-----------------------+-------------------------------+------------------------------+----------------------------------+
+| Toggle Fullscreen     | :kbd:`Shift + F11`            | :kbd:`Cmd + Ctrl + F`        | ``editor/fullscreen_mode``       |
++-----------------------+-------------------------------+------------------------------+----------------------------------+
+| Play                  | :kbd:`F5`                     | :kbd:`Cmd + B`               | ``editor/play``                  |
++-----------------------+-------------------------------+------------------------------+----------------------------------+
+| Pause Scene           | :kbd:`F7`                     | :kbd:`Cmd + Ctrl + Y`        | ``editor/pause_scene``           |
++-----------------------+-------------------------------+------------------------------+----------------------------------+
+| Stop                  | :kbd:`F8`                     | :kbd:`Cmd + .`               | ``editor/stop``                  |
++-----------------------+-------------------------------+------------------------------+----------------------------------+
+| Play Scene            | :kbd:`F6`                     | :kbd:`Cmd + R`               | ``editor/play_scene``            |
++-----------------------+-------------------------------+------------------------------+----------------------------------+
+| Play Custom Scene     | :kbd:`Ctrl + Shift + F5`      | :kbd:`Cmd + Shift + R`       | ``editor/play_custom_scene``     |
++-----------------------+-------------------------------+------------------------------+----------------------------------+
+| Expand Bottom Panel   | :kbd:`Shift + F12`            | :kbd:`Shift + F12`           | ``editor/bottom_panel_expand``   |
++-----------------------+-------------------------------+------------------------------+----------------------------------+
+
+2D / Canvas Item Editor
+-----------------------
+
++------------------------------+-------------------------+------------------------+--------------------------------------------------------+
+| Action name                  | Windows, Linux          | macOS                  | Editor setting                                         |
++==============================+=========================+========================+========================================================+
+| Zoom In                      | :kbd:`Ctrl + =`         | :kbd:`Cmd + =`         | ``canvas_item_editor/zoom_plus``                       |
++------------------------------+-------------------------+------------------------+--------------------------------------------------------+
+| Zoom Out                     | :kbd:`Ctrl + -`         | :kbd:`Cmd + -`         | ``canvas_item_editor/zoom_minus``                      |
++------------------------------+-------------------------+------------------------+--------------------------------------------------------+
+| Zoom Reset                   | :kbd:`Ctrl + 0`         | :kbd:`Cmd + 0`         | ``canvas_item_editor/zoom_reset``                      |
++------------------------------+-------------------------+------------------------+--------------------------------------------------------+
+| Pan View                     | :kbd:`Space`            | :kbd:`Space`           | ``canvas_item_editor/pan_view``                        |
++------------------------------+-------------------------+------------------------+--------------------------------------------------------+
+| Select Mode                  | :kbd:`Q`                | :kbd:`Q`               | ``canvas_item_editor/select_mode``                     |
++------------------------------+-------------------------+------------------------+--------------------------------------------------------+
+| Move Mode                    | :kbd:`W`                | :kbd:`W`               | ``canvas_item_editor/move_mode``                       |
++------------------------------+-------------------------+------------------------+--------------------------------------------------------+
+| Rotate Mode                  | :kbd:`E`                | :kbd:`E`               | ``canvas_item_editor/rotate_mode``                     |
++------------------------------+-------------------------+------------------------+--------------------------------------------------------+
+| Scale Mode                   | :kbd:`S`                | :kbd:`S`               | ``canvas_item_editor/scale_mode``                      |
++------------------------------+-------------------------+------------------------+--------------------------------------------------------+
+| Ruler Mode                   | :kbd:`R`                | :kbd:`R`               | ``canvas_item_editor/ruler_mode``                      |
++------------------------------+-------------------------+------------------------+--------------------------------------------------------+
+| Use Smart Snap               | :kbd:`Shift + S`        | :kbd:`Shift + S`       | ``canvas_item_editor/use_smart_snap``                  |
++------------------------------+-------------------------+------------------------+--------------------------------------------------------+
+| Use Grid Snap                | :kbd:`Shift + G`        | :kbd:`Shift + G`       | ``canvas_item_editor/use_grid_snap``                   |
++------------------------------+-------------------------+------------------------+--------------------------------------------------------+
+| Multiply grid step by 2      | :kbd:`Num *`            | :kbd:`Num *`           | ``canvas_item_editor/multiply_grid_step``              |
++------------------------------+-------------------------+------------------------+--------------------------------------------------------+
+| Divide grid step by 2        | :kbd:`Num /`            | :kbd:`Num /`           | ``canvas_item_editor/divide_grid_step``                |
++------------------------------+-------------------------+------------------------+--------------------------------------------------------+
+| Always Show Grid             | :kbd:`G`                | :kbd:`G`               | ``canvas_item_editor/show_grid``                       |
++------------------------------+-------------------------+------------------------+--------------------------------------------------------+
+| Show Helpers                 | :kbd:`H`                | :kbd:`H`               | ``canvas_item_editor/show_helpers``                    |
++------------------------------+-------------------------+------------------------+--------------------------------------------------------+
+| Show Guides                  | :kbd:`Y`                | :kbd:`Y`               | ``canvas_item_editor/show_guides``                     |
++------------------------------+-------------------------+------------------------+--------------------------------------------------------+
+| Center Selection             | :kbd:`F`                | :kbd:`F`               | ``canvas_item_editor/center_selection``                |
++------------------------------+-------------------------+------------------------+--------------------------------------------------------+
+| Frame Selection              | :kbd:`Shift + F`        | :kbd:`Shift + F`       | ``canvas_item_editor/frame_selection``                 |
++------------------------------+-------------------------+------------------------+--------------------------------------------------------+
+| Preview Canvas Scale         | :kbd:`Ctrl + Shift + P` | :kbd:`Cmd + Shift + P` | ``canvas_item_editor/preview_canvas_scale``            |
++------------------------------+-------------------------+------------------------+--------------------------------------------------------+
+| Insert Key                   | :kbd:`Ins`              | :kbd:`Ins`             | ``canvas_item_editor/anim_insert_key``                 |
++------------------------------+-------------------------+------------------------+--------------------------------------------------------+
+| Insert Key (Existing Tracks) | :kbd:`Ctrl + Ins`       | :kbd:`Cmd + Ins`       | ``canvas_item_editor/anim_insert_key_existing_tracks`` |
++------------------------------+-------------------------+------------------------+--------------------------------------------------------+
+| Make Custom Bones from Nodes | :kbd:`Ctrl + Shift + B` | :kbd:`Cmd + Shift + B` | ``canvas_item_editor/skeleton_make_bones``             |
++------------------------------+-------------------------+------------------------+--------------------------------------------------------+
+| Clear Pose                   | :kbd:`Shift + K`        | :kbd:`Shift + K`       | ``canvas_item_editor/anim_clear_pose``                 |
++------------------------------+-------------------------+------------------------+--------------------------------------------------------+
+
+3D / Spatial Editor
+-------------------
+
++------------------------------------+-----------------------+----------------------+--------------------------------------------------+
+| Action name                        | Windows, Linux        | macOS                | Editor setting                                   |
++====================================+=======================+======================+==================================================+
+| Toggle Freelook                    | :kbd:`Shift + F`      | :kbd:`Shift + F`     | ``spatial_editor/freelook_toggle``               |
++------------------------------------+-----------------------+----------------------+--------------------------------------------------+
+| Freelook Left                      | :kbd:`A`              | :kbd:`A`             | ``spatial_editor/freelook_left``                 |
++------------------------------------+-----------------------+----------------------+--------------------------------------------------+
+| Freelook Right                     | :kbd:`D`              | :kbd:`D`             | ``spatial_editor/freelook_right``                |
++------------------------------------+-----------------------+----------------------+--------------------------------------------------+
+| Freelook Forward                   | :kbd:`W`              | :kbd:`W`             | ``spatial_editor/freelook_forward``              |
++------------------------------------+-----------------------+----------------------+--------------------------------------------------+
+| Freelook Backwards                 | :kbd:`S`              | :kbd:`S`             | ``spatial_editor/freelook_backwards``            |
++------------------------------------+-----------------------+----------------------+--------------------------------------------------+
+| Freelook Up                        | :kbd:`E`              | :kbd:`E`             | ``spatial_editor/freelook_up``                   |
++------------------------------------+-----------------------+----------------------+--------------------------------------------------+
+| Freelook Down                      | :kbd:`Q`              | :kbd:`Q`             | ``spatial_editor/freelook_down``                 |
++------------------------------------+-----------------------+----------------------+--------------------------------------------------+
+| Freelook Speed Modifier            | :kbd:`Shift`          | :kbd:`Shift`         | ``spatial_editor/freelook_speed_modifier``       |
++------------------------------------+-----------------------+----------------------+--------------------------------------------------+
+| Freelook Slow Modifier             | :kbd:`Alt`            | :kbd:`Alt`           | ``spatial_editor/freelook_slow_modifier``        |
++------------------------------------+-----------------------+----------------------+--------------------------------------------------+
+| Select Mode                        | :kbd:`Q`              | :kbd:`Q`             | ``spatial_editor/tool_select``                   |
++------------------------------------+-----------------------+----------------------+--------------------------------------------------+
+| Move Mode                          | :kbd:`W`              | :kbd:`W`             | ``spatial_editor/tool_move``                     |
++------------------------------------+-----------------------+----------------------+--------------------------------------------------+
+| Rotate Mode                        | :kbd:`E`              | :kbd:`E`             | ``spatial_editor/tool_rotate``                   |
++------------------------------------+-----------------------+----------------------+--------------------------------------------------+
+| Scale Mode                         | :kbd:`R`              | :kbd:`R`             | ``spatial_editor/tool_scale``                    |
++------------------------------------+-----------------------+----------------------+--------------------------------------------------+
+| Use Local Space                    | :kbd:`T`              | :kbd:`T`             | ``spatial_editor/local_coords``                  |
++------------------------------------+-----------------------+----------------------+--------------------------------------------------+
+| Use Snap                           | :kbd:`Y`              | :kbd:`Y`             | ``spatial_editor/snap``                          |
++------------------------------------+-----------------------+----------------------+--------------------------------------------------+
+| Snap Object to Floor               | :kbd:`PgDown`         | :kbd:`PgDown`        | ``spatial_editor/snap_to_floor``                 |
++------------------------------------+-----------------------+----------------------+--------------------------------------------------+
+| Top View                           | :kbd:`Num 7`          | :kbd:`Num 7`         | ``spatial_editor/top_view``                      |
++------------------------------------+-----------------------+----------------------+--------------------------------------------------+
+| Bottom View                        | :kbd:`Alt + Num 7`    | :kbd:`Alt + Num 7`   | ``spatial_editor/bottom_view``                   |
++------------------------------------+-----------------------+----------------------+--------------------------------------------------+
+| Front View                         | :kbd:`Num 1`          | :kbd:`Num 1`         | ``spatial_editor/front_view``                    |
++------------------------------------+-----------------------+----------------------+--------------------------------------------------+
+| Rear View                          | :kbd:`Alt + Num 1`    | :kbd:`Alt + Num 1`   | ``spatial_editor/rear_view``                     |
++------------------------------------+-----------------------+----------------------+--------------------------------------------------+
+| Right View                         | :kbd:`Num 3`          | :kbd:`Num 3`         | ``spatial_editor/right_view``                    |
++------------------------------------+-----------------------+----------------------+--------------------------------------------------+
+| Left View                          | :kbd:`Alt + Num 3`    | :kbd:`Alt + Num 3`   | ``spatial_editor/left_view``                     |
++------------------------------------+-----------------------+----------------------+--------------------------------------------------+
+| Switch Perspective/Orthogonal View | :kbd:`Num 5`          | :kbd:`Num 5`         | ``spatial_editor/switch_perspective_orthogonal`` |
++------------------------------------+-----------------------+----------------------+--------------------------------------------------+
+| Insert Animation Key               | :kbd:`K`              | :kbd:`K`             | ``spatial_editor/insert_anim_key``               |
++------------------------------------+-----------------------+----------------------+--------------------------------------------------+
+| Focus Origin                       | :kbd:`O`              | :kbd:`O`             | ``spatial_editor/focus_origin``                  |
++------------------------------------+-----------------------+----------------------+--------------------------------------------------+
+| Focus Selection                    | :kbd:`F`              | :kbd:`F`             | ``spatial_editor/focus_selection``               |
++------------------------------------+-----------------------+----------------------+--------------------------------------------------+
+| Align Transform with View          | :kbd:`Ctrl + Alt + M` | :kbd:`Cmd + Alt + M` | ``spatial_editor/align_transform_with_view``     |
++------------------------------------+-----------------------+----------------------+--------------------------------------------------+
+| Align Rotation with View           | :kbd:`Ctrl + Alt + F` | :kbd:`Cmd + Alt + F` | ``spatial_editor/align_rotation_with_view``      |
++------------------------------------+-----------------------+----------------------+--------------------------------------------------+
+| 1 Viewport                         | :kbd:`Ctrl + 1`       | :kbd:`Cmd + 1`       | ``spatial_editor/1_viewport``                    |
++------------------------------------+-----------------------+----------------------+--------------------------------------------------+
+| 2 Viewports                        | :kbd:`Ctrl + 2`       | :kbd:`Cmd + 2`       | ``spatial_editor/2_viewports``                   |
++------------------------------------+-----------------------+----------------------+--------------------------------------------------+
+| 2 Viewports (Alt)                  | :kbd:`Ctrl + Alt + 2` | :kbd:`Cmd + Alt + 2` | ``spatial_editor/2_viewports_alt``               |
++------------------------------------+-----------------------+----------------------+--------------------------------------------------+
+| 3 Viewports                        | :kbd:`Ctrl + 3`       | :kbd:`Cmd + 3`       | ``spatial_editor/3_viewports``                   |
++------------------------------------+-----------------------+----------------------+--------------------------------------------------+
+| 3 Viewports (Alt)                  | :kbd:`Ctrl + Alt + 3` | :kbd:`Cmd + Alt + 3` | ``spatial_editor/3_viewports_alt``               |
++------------------------------------+-----------------------+----------------------+--------------------------------------------------+
+| 4 Viewports                        | :kbd:`Ctrl + 4`       | :kbd:`Cmd + 4`       | ``spatial_editor/4_viewports``                   |
++------------------------------------+-----------------------+----------------------+--------------------------------------------------+
+
+Text Editor
+-----------
+
++---------------------------+--------------------------+----------------------------+-------------------------------------------------+
+| Action name               | Windows, Linux           | macOS                      | Editor setting                                  |
++===========================+==========================+============================+=================================================+
+| Cut                       | :kbd:`Ctrl + X`          | :kbd:`Cmd + X`             | ``script_text_editor/cut``                      |
++---------------------------+--------------------------+----------------------------+-------------------------------------------------+
+| Copy                      | :kbd:`Ctrl + C`          | :kbd:`Cmd + C`             | ``script_text_editor/copy``                     |
++---------------------------+--------------------------+----------------------------+-------------------------------------------------+
+| Paste                     | :kbd:`Ctrl + V`          | :kbd:`Cmd + V`             | ``script_text_editor/paste``                    |
++---------------------------+--------------------------+----------------------------+-------------------------------------------------+
+| Select All                | :kbd:`Ctrl + A`          | :kbd:`Cmd + A`             | ``script_text_editor/select_all``               |
++---------------------------+--------------------------+----------------------------+-------------------------------------------------+
+| Find                      | :kbd:`Ctrl + F`          | :kbd:`Cmd + F`             | ``script_text_editor/find``                     |
++---------------------------+--------------------------+----------------------------+-------------------------------------------------+
+| Find Next                 | :kbd:`F3`                | :kbd:`Cmd + G`             | ``script_text_editor/find_next``                |
++---------------------------+--------------------------+----------------------------+-------------------------------------------------+
+| Find Previous             | :kbd:`Shift + F3`        | :kbd:`Cmd + Shift + G`     | ``script_text_editor/find_previous``            |
++---------------------------+--------------------------+----------------------------+-------------------------------------------------+
+| Find in Files             | :kbd:`Ctrl + Shift + F`  | :kbd:`Cmd + Shift + F`     | ``script_text_editor/find_in_files``            |
++---------------------------+--------------------------+----------------------------+-------------------------------------------------+
+| Replace                   | :kbd:`Ctrl + R`          | :kbd:`Alt + Cmd + F`       | ``script_text_editor/replace``                  |
++---------------------------+--------------------------+----------------------------+-------------------------------------------------+
+| Replace in Files          | :kbd:`Ctrl + Shift + R`  | :kbd:`Cmd + Shift + R`     | ``script_text_editor/replace_in_files``         |
++---------------------------+--------------------------+----------------------------+-------------------------------------------------+
+| Undo                      | :kbd:`Ctrl + Z`          | :kbd:`Cmd + Z`             | ``script_text_editor/undo``                     |
++---------------------------+--------------------------+----------------------------+-------------------------------------------------+
+| Redo                      | :kbd:`Ctrl + Y`          | :kbd:`Cmd + Y`             | ``script_text_editor/redo``                     |
++---------------------------+--------------------------+----------------------------+-------------------------------------------------+
+| Move Up                   | :kbd:`Alt + Up Arrow`    | :kbd:`Alt + Up Arrow`      | ``script_text_editor/move_up``                  |
++---------------------------+--------------------------+----------------------------+-------------------------------------------------+
+| Move Down                 | :kbd:`Alt + Down Arrow`  | :kbd:`Alt + Down Arrow`    | ``script_text_editor/move_down``                |
++---------------------------+--------------------------+----------------------------+-------------------------------------------------+
+| Delete Line               | :kbd:`Ctrl + Shift + K`  | :kbd:`Cmd + Shift + K`     | ``script_text_editor/delete_line``              |
++---------------------------+--------------------------+----------------------------+-------------------------------------------------+
+| Toggle Comment            | :kbd:`Ctrl + K`          | :kbd:`Cmd + K`             | ``script_text_editor/toggle_comment``           |
++---------------------------+--------------------------+----------------------------+-------------------------------------------------+
+| Fold/Unfold Line          | :kbd:`Alt + F`           | :kbd:`Alt + F`             | ``script_text_editor/toggle_fold_line``         |
++---------------------------+--------------------------+----------------------------+-------------------------------------------------+
+| Clone Down                | :kbd:`Ctrl + Shift + C`  | :kbd:`Cmd + Shift + C`     | ``script_text_editor/clone_down``               |
++---------------------------+--------------------------+----------------------------+-------------------------------------------------+
+| Complete Symbol           | :kbd:`Ctrl + Space`      | :kbd:`Ctrl + Space`        | ``script_text_editor/complete_symbol``          |
++---------------------------+--------------------------+----------------------------+-------------------------------------------------+
+| Clone Down                | :kbd:`Ctrl + D`          | :kbd:`Cmd + D`             | ``script_text_editor/clone_down``               |
++---------------------------+--------------------------+----------------------------+-------------------------------------------------+
+| Complete Symbol           | :kbd:`Ctrl + Space`      | :kbd:`Cmd + Space`         | ``script_text_editor/complete_symbol``          |
++---------------------------+--------------------------+----------------------------+-------------------------------------------------+
+| Evaluate Selection        | :kbd:`Ctrl + Shift + E`  | :kbd:`Cmd + Shift + E`     | ``script_text_editor/evaluate_selection``       |
++---------------------------+--------------------------+----------------------------+-------------------------------------------------+
+| Trim Trailing Whitespace  | :kbd:`Ctrl + Alt + T`    | :kbd:`Cmd + Alt + T`       | ``script_text_editor/trim_trailing_whitespace`` |
++---------------------------+--------------------------+----------------------------+-------------------------------------------------+
+| Uppercase                 | :kbd:`Shift + F4`        | :kbd:`Shift + F4`          | ``script_text_editor/convert_to_uppercase``     |
++---------------------------+--------------------------+----------------------------+-------------------------------------------------+
+| Lowercase                 | :kbd:`Shift + F5`        | :kbd:`Shift + F5`          | ``script_text_editor/convert_to_lowercase``     |
++---------------------------+--------------------------+----------------------------+-------------------------------------------------+
+| Capitalize                | :kbd:`Shift + F6`        | :kbd:`Shift + F6`          | ``script_text_editor/capitalize``               |
++---------------------------+--------------------------+----------------------------+-------------------------------------------------+
+| Convert Indent to Spaces  | :kbd:`Ctrl + Shift + Y`  | :kbd:`Cmd + Shift + Y`     | ``script_text_editor/convert_indent_to_spaces`` |
++---------------------------+--------------------------+----------------------------+-------------------------------------------------+
+| Convert Indent to Tabs    | :kbd:`Ctrl + Shift + I`  | :kbd:`Cmd + Shift + I`     | ``script_text_editor/convert_indent_to_tabs``   |
++---------------------------+--------------------------+----------------------------+-------------------------------------------------+
+| Auto Indent               | :kbd:`Ctrl + I`          | :kbd:`Cmd + I`             | ``script_text_editor/auto_indent``              |
++---------------------------+--------------------------+----------------------------+-------------------------------------------------+
+| Toggle Bookmark           | :kbd:`Ctrl + Alt + B`    | :kbd:`Cmd + Alt + B`       | ``script_text_editor/toggle_bookmark``          |
++---------------------------+--------------------------+----------------------------+-------------------------------------------------+
+| Go to Next Bookmark       | :kbd:`Ctrl + B`          | :kbd:`Cmd + B`             | ``script_text_editor/goto_next_bookmark``       |
++---------------------------+--------------------------+----------------------------+-------------------------------------------------+
+| Go to Previous Bookmark   | :kbd:`Ctrl + Shift + B`  | :kbd:`Cmd + Shift + B`     | ``script_text_editor/goto_previous_bookmark``   |
++---------------------------+--------------------------+----------------------------+-------------------------------------------------+
+| Go to Function            | :kbd:`Ctrl + Alt + F`    | :kbd:`Ctrl + Cmd + J`      | ``script_text_editor/goto_function``            |
++---------------------------+--------------------------+----------------------------+-------------------------------------------------+
+| Go to Line                | :kbd:`Ctrl + L`          | :kbd:`Cmd + L`             | ``script_text_editor/goto_line``                |
++---------------------------+--------------------------+----------------------------+-------------------------------------------------+
+| Toggle Breakpoint         | :kbd:`F9`                | :kbd:`Cmd + Shift + B`     | ``script_text_editor/toggle_breakpoint``        |
++---------------------------+--------------------------+----------------------------+-------------------------------------------------+
+| Remove All Breakpoints    | :kbd:`Ctrl + Shift + F9` | :kbd:`Cmd + Shift + F9`    | ``script_text_editor/remove_all_breakpoints``   |
++---------------------------+--------------------------+----------------------------+-------------------------------------------------+
+| Go to Next Breakpoint     | :kbd:`Ctrl + .`          | :kbd:`Cmd + .`             | ``script_text_editor/goto_next_breakpoint``     |
++---------------------------+--------------------------+----------------------------+-------------------------------------------------+
+| Go to Previous Breakpoint | :kbd:`Ctrl + ,`          | :kbd:`Cmd + ,`             | ``script_text_editor/goto_previous_breakpoint`` |
++---------------------------+--------------------------+----------------------------+-------------------------------------------------+
+| Contextual Help           | :kbd:`Alt + F1`          | :kbd:`Alt + Shift + Space` | ``script_text_editor/contextual_help``          |
++---------------------------+--------------------------+----------------------------+-------------------------------------------------+
+
+Script Editor
+-------------
+
++----------------------+---------------------------------+---------------------------------+----------------------------------------+
+| Action name          | Windows, Linux                  | macOS                           | Editor setting                         |
++======================+=================================+=================================+========================================+
+| Find                 | :kbd:`Ctrl + F`                 | :kbd:`Cmd + F`                  | ``script_editor/find``                 |
++----------------------+---------------------------------+---------------------------------+----------------------------------------+
+| Find Next            | :kbd:`F3`                       | :kbd:`F3`                       | ``script_editor/find_next``            |
++----------------------+---------------------------------+---------------------------------+----------------------------------------+
+| Find Previous        | :kbd:`Shift + F3`               | :kbd:`Shift + F3`               | ``script_editor/find_previous``        |
++----------------------+---------------------------------+---------------------------------+----------------------------------------+
+| Find in Files        | :kbd:`Ctrl + Shift + F`         | :kbd:`Cmd + Shift + F`          | ``script_editor/find_in_files``        |
++----------------------+---------------------------------+---------------------------------+----------------------------------------+
+| Move Up              | :kbd:`Shift + Alt + Up Arrow`   | :kbd:`Shift + Alt + Up Arrow`   | ``script_editor/window_move_up``       |
++----------------------+---------------------------------+---------------------------------+----------------------------------------+
+| Move Down            | :kbd:`Shift + Alt + Down Arrow` | :kbd:`Shift + Alt + Down Arrow` | ``script_editor/window_move_down``     |
++----------------------+---------------------------------+---------------------------------+----------------------------------------+
+| Next Script          | :kbd:`Ctrl + Shift + .`         | :kbd:`Cmd + Shift + .`          | ``script_editor/next_script``          |
++----------------------+---------------------------------+---------------------------------+----------------------------------------+
+| Previous Script      | :kbd:`Ctrl + Shift + ,`         | :kbd:`Cmd + Shift + ,`          | ``script_editor/prev_script``          |
++----------------------+---------------------------------+---------------------------------+----------------------------------------+
+| Reopen Closed Script | :kbd:`Ctrl + Shift + T`         | :kbd:`Cmd + Shift + T`          | ``script_editor/reopen_closed_script`` |
++----------------------+---------------------------------+---------------------------------+----------------------------------------+
+| Save                 | :kbd:`Ctrl + Alt + S`           | :kbd:`Cmd + Alt + S`            | ``script_editor/save``                 |
++----------------------+---------------------------------+---------------------------------+----------------------------------------+
+| Save All             | :kbd:`Ctrl + Shift + Alt + S`   | :kbd:`Cmd + Shift + Alt + S`    | ``script_editor/save_all``             |
++----------------------+---------------------------------+---------------------------------+----------------------------------------+
+| Soft Reload Script   | :kbd:`Ctrl + Shift + R`         | :kbd:`Cmd + Shift + R`          | ``script_editor/reload_script_soft``   |
++----------------------+---------------------------------+---------------------------------+----------------------------------------+
+| History Previous     | :kbd:`Alt + Left Arrow`         | :kbd:`Alt + Left Arrow`         | ``script_editor/history_previous``     |
++----------------------+---------------------------------+---------------------------------+----------------------------------------+
+| History Next         | :kbd:`Alt + Right Arrow`        | :kbd:`Alt + Right Arrow`        | ``script_editor/history_next``         |
++----------------------+---------------------------------+---------------------------------+----------------------------------------+
+| Close                | :kbd:`Ctrl + W`                 | :kbd:`Cmd + W`                  | ``script_editor/close_file``           |
++----------------------+---------------------------------+---------------------------------+----------------------------------------+
+| Run                  | :kbd:`Ctrl + Shift + X`         | :kbd:`Cmd + Shift + X`          | ``script_editor/run_file``             |
++----------------------+---------------------------------+---------------------------------+----------------------------------------+
+| Toggle Scripts Panel | :kbd:`Ctrl + \\`                | :kbd:`Cmd + \\`                 | ``script_editor/toggle_scripts_panel`` |
++----------------------+---------------------------------+---------------------------------+----------------------------------------+
+| Zoom In              | :kbd:`Ctrl + =`                 | :kbd:`Cmd + =`                  | ``script_editor/zoom_in``              |
++----------------------+---------------------------------+---------------------------------+----------------------------------------+
+| Zoom Out             | :kbd:`Ctrl + -`                 | :kbd:`Cmd + -`                  | ``script_editor/zoom_out``             |
++----------------------+---------------------------------+---------------------------------+----------------------------------------+
+| Reset Zoom           | :kbd:`Ctrl + 0`                 | :kbd:`Cmd + 0`                  | ``script_editor/reset_zoom``           |
++----------------------+---------------------------------+---------------------------------+----------------------------------------+
+
+Visual Script Editor
+--------------------
+
++-------------------+-----------------+-------------------+--------------------------------------------+
+| Action name       | Windows, Linux  | macOS             | Editor setting                             |
++===================+=================+===================+============================================+
+| Find Node Type    | :kbd:`Ctrl + F` | :kbd:`Cmd + F`    | ``visual_script_editor/find_node_type``    |
++-------------------+-----------------+-------------------+--------------------------------------------+
+| Copy Nodes        | :kbd:`Ctrl + C` | :kbd:`Cmd + C`    | ``visual_script_editor/copy_nodes``        |
++-------------------+-----------------+-------------------+--------------------------------------------+
+| Cut Nodes         | :kbd:`Ctrl + X` | :kbd:`Cmd + X`    | ``visual_script_editor/cut_nodes``         |
++-------------------+-----------------+-------------------+--------------------------------------------+
+| Paste Nodes       | :kbd:`Ctrl + V` | :kbd:`Cmd + V`    | ``visual_script_editor/paste_nodes``       |
++-------------------+-----------------+-------------------+--------------------------------------------+
+| Delete Selected   | :kbd:`Del`      | :kbd:`Cmd + BkSp` | ``visual_script_editor/delete_selected``   |
++-------------------+-----------------+-------------------+--------------------------------------------+
+| Make Function     | :kbd:`Ctrl + G` | :kbd:`Cmd + G`    | ``visual_script_editor/create_function``   |
++-------------------+-----------------+-------------------+--------------------------------------------+
+| Edit Member       | :kbd:`Ctrl + E` | :kbd:`Cmd + E`    | ``visual_script_editor/edit_member``       |
++-------------------+-----------------+-------------------+--------------------------------------------+
+| Refresh Graph     | :kbd:`Ctrl + R` | :kbd:`Cmd + R`    | ``visual_script_editor/refresh_nodes``     |
++-------------------+-----------------+-------------------+--------------------------------------------+
+| Toggle Breakpoint | :kbd:`F9`       | :kbd:`F9`         | ``visual_script_editor/toggle_breakpoint`` |
++-------------------+-----------------+-------------------+--------------------------------------------+
+
+Editor Output
+-------------
+
++----------------+-------------------------+------------------------+-------------------------+
+| Action name    | Windows, Linux          | macOS                  | Editor setting          |
++================+=========================+========================+=========================+
+| Copy Selection | :kbd:`Ctrl + C`         | :kbd:`Cmd + C`         | ``editor/copy_output``  |
++----------------+-------------------------+------------------------+-------------------------+
+| Clear Output   | :kbd:`Ctrl + Shift + K` | :kbd:`Cmd + Shift + K` | ``editor/clear_output`` |
++----------------+-------------------------+------------------------+-------------------------+
+
+Debugger
+--------
+
++-------------+----------------+------------+------------------------+
+| Action name | Windows, Linux | macOS      | Editor setting         |
++=============+================+============+========================+
+| Step Into   | :kbd:`F11`     | :kbd:`F11` | ``debugger/step_into`` |
++-------------+----------------+------------+------------------------+
+| Step Over   | :kbd:`F10`     | :kbd:`F10` | ``debugger/step_over`` |
++-------------+----------------+------------+------------------------+
+| Continue    | :kbd:`F12`     | :kbd:`F12` | ``debugger/continue``  |
++-------------+----------------+------------+------------------------+
+
+File Dialog
+-----------
+
++---------------------+--------------------------+--------------------------+-------------------------------------+
+| Action name         | Windows, Linux           | macOS                    | Editor setting                      |
++=====================+==========================+==========================+=====================================+
+| Go Back             | :kbd:`Alt + Left Arrow`  | :kbd:`Alt + Left Arrow`  | ``file_dialog/go_back``             |
++---------------------+--------------------------+--------------------------+-------------------------------------+
+| Go Forward          | :kbd:`Alt + Right Arrow` | :kbd:`Alt + Right Arrow` | ``file_dialog/go_forward``          |
++---------------------+--------------------------+--------------------------+-------------------------------------+
+| Go Up               | :kbd:`Alt + Up Arrow`    | :kbd:`Alt + Up Arrow`    | ``file_dialog/go_up``               |
++---------------------+--------------------------+--------------------------+-------------------------------------+
+| Refresh             | :kbd:`F5`                | :kbd:`F5`                | ``file_dialog/refresh``             |
++---------------------+--------------------------+--------------------------+-------------------------------------+
+| Toggle Hidden Files | :kbd:`Ctrl + H`          | :kbd:`Cmd + H`           | ``file_dialog/toggle_hidden_files`` |
++---------------------+--------------------------+--------------------------+-------------------------------------+
+| Toggle Favorite     | :kbd:`Alt + F`           | :kbd:`Alt + F`           | ``file_dialog/toggle_favorite``     |
++---------------------+--------------------------+--------------------------+-------------------------------------+
+| Toggle Mode         | :kbd:`Alt + V`           | :kbd:`Alt + V`           | ``file_dialog/toggle_mode``         |
++---------------------+--------------------------+--------------------------+-------------------------------------+
+| Create Folder       | :kbd:`Ctrl + N`          | :kbd:`Cmd + N`           | ``file_dialog/create_folder``       |
++---------------------+--------------------------+--------------------------+-------------------------------------+
+| Delete              | :kbd:`Del`               | :kbd:`Cmd + BkSp`        | ``file_dialog/delete``              |
++---------------------+--------------------------+--------------------------+-------------------------------------+
+| Focus Path          | :kbd:`Ctrl + D`          | :kbd:`Cmd + D`           | ``file_dialog/focus_path``          |
++---------------------+--------------------------+--------------------------+-------------------------------------+
+| Move Favorite Up    | :kbd:`Ctrl + Up Arrow`   | :kbd:`Cmd + Up Arrow`    | ``file_dialog/move_favorite_up``    |
++---------------------+--------------------------+--------------------------+-------------------------------------+
+| Move Favorite Down  | :kbd:`Ctrl + Down Arrow` | :kbd:`Cmd + Down Arrow`  | ``file_dialog/move_favorite_down``  |
++---------------------+--------------------------+--------------------------+-------------------------------------+
+
+FileSystem Dock
+---------------
+
++-------------+-----------------+-------------------+-------------------------------+
+| Action name | Windows, Linux  | macOS             | Editor setting                |
++=============+=================+===================+===============================+
+| Copy Path   | :kbd:`Ctrl + C` | :kbd:`Cmd + C`    | ``filesystem_dock/copy_path`` |
++-------------+-----------------+-------------------+-------------------------------+
+| Duplicate   | :kbd:`Ctrl + D` | :kbd:`Cmd + D`    | ``filesystem_dock/duplicate`` |
++-------------+-----------------+-------------------+-------------------------------+
+| Delete      | :kbd:`Del`      | :kbd:`Cmd + BkSp` | ``filesystem_dock/delete``    |
++-------------+-----------------+-------------------+-------------------------------+
+
+Scene Tree Dock
+---------------
+
++----------------+--------------------------+-------------------------+----------------------------------+
+| Action name    | Windows, Linux           | macOS                   | Editor setting                   |
++================+==========================+=========================+==================================+
+| Add Child Node | :kbd:`Ctrl + A`          | :kbd:`Cmd + A`          | ``scene_tree/add_child_node``    |
++----------------+--------------------------+-------------------------+----------------------------------+
+| Batch Rename   | :kbd:`Ctrl + F2`         | :kbd:`Cmd + F2`         | ``scene_tree/batch_rename``      |
++----------------+--------------------------+-------------------------+----------------------------------+
+| Copy Node Path | :kbd:`Ctrl + C`          | :kbd:`Cmd + C`          | ``scene_tree/copy_node_path``    |
++----------------+--------------------------+-------------------------+----------------------------------+
+| Delete         | :kbd:`Del`               | :kbd:`Cmd + BkSp`       | ``scene_tree/delete``            |
++----------------+--------------------------+-------------------------+----------------------------------+
+| Force Delete   | :kbd:`Shift + Del`       | :kbd:`Shift + Del`      | ``scene_tree/delete_no_confirm`` |
++----------------+--------------------------+-------------------------+----------------------------------+
+| Duplicate      | :kbd:`Ctrl + D`          | :kbd:`Cmd + D`          | ``scene_tree/duplicate``         |
++----------------+--------------------------+-------------------------+----------------------------------+
+| Move Up        | :kbd:`Ctrl + Up Arrow`   | :kbd:`Cmd + Up Arrow`   | ``scene_tree/move_up``           |
++----------------+--------------------------+-------------------------+----------------------------------+
+| Move Down      | :kbd:`Ctrl + Down Arrow` | :kbd:`Cmd + Down Arrow` | ``scene_tree/move_down``         |
++----------------+--------------------------+-------------------------+----------------------------------+
+
+Animation Track Editor
+----------------------
+
++----------------------+---------------------------+--------------------------+-----------------------------------------------------+
+| Action name          | Windows, Linux            | macOS                    | Editor setting                                      |
++======================+===========================+==========================+=====================================================+
+| Duplicate Selection  | :kbd:`Ctrl + D`           | :kbd:`Cmd + D`           | ``animation_editor/duplicate_selection``            |
++----------------------+---------------------------+--------------------------+-----------------------------------------------------+
+| Duplicate Transposed | :kbd:`Ctrl + Shift + D`   | :kbd:`Cmd + Shift + D`   | ``animation_editor/duplicate_selection_transposed`` |
++----------------------+---------------------------+--------------------------+-----------------------------------------------------+
+| Delete Selection     | :kbd:`Del`                | :kbd:`Cmd + BkSp`        | ``animation_editor/delete_selection``               |
++----------------------+---------------------------+--------------------------+-----------------------------------------------------+
+| Go to Next Step      | :kbd:`Ctrl + Right Arrow` | :kbd:`Cmd + Right Arrow` | ``animation_editor/goto_next_step``                 |
++----------------------+---------------------------+--------------------------+-----------------------------------------------------+
+| Go to Previous Step  | :kbd:`Ctrl + Left Arrow`  | :kbd:`Cmd + Left Arrow`  | ``animation_editor/goto_prev_step``                 |
++----------------------+---------------------------+--------------------------+-----------------------------------------------------+
+
+Tile Map Editor
+---------------
+
++-------------------+-----------------+-------------------+-------------------------------------+
+| Action name       | Windows, Linux  | macOS             | Editor setting                      |
++===================+=================+===================+=====================================+
+| Find Tile         | :kbd:`Ctrl + F` | :kbd:`Cmd + F`    | ``tile_map_editor/find_tile``       |
++-------------------+-----------------+-------------------+-------------------------------------+
+| Pick Tile         | :kbd:`I`        | :kbd:`I`          | ``tile_map_editor/pick_tile``       |
++-------------------+-----------------+-------------------+-------------------------------------+
+| Paint Tile        | :kbd:`P`        | :kbd:`P`          | ``tile_map_editor/paint_tile``      |
++-------------------+-----------------+-------------------+-------------------------------------+
+| Bucket Fill       | :kbd:`G`        | :kbd:`G`          | ``tile_map_editor/bucket_fill``     |
++-------------------+-----------------+-------------------+-------------------------------------+
+| Transpose         | :kbd:`T`        | :kbd:`T`          | ``tile_map_editor/transpose``       |
++-------------------+-----------------+-------------------+-------------------------------------+
+| Flip Horizontally | :kbd:`X`        | :kbd:`X`          | ``tile_map_editor/flip_horizontal`` |
++-------------------+-----------------+-------------------+-------------------------------------+
+| Flip Vertically   | :kbd:`Z`        | :kbd:`Z`          | ``tile_map_editor/flip_vertical``   |
++-------------------+-----------------+-------------------+-------------------------------------+
+| Rotate Left       | :kbd:`A`        | :kbd:`A`          | ``tile_map_editor/rotate_left``     |
++-------------------+-----------------+-------------------+-------------------------------------+
+| Rotate Right      | :kbd:`S`        | :kbd:`S`          | ``tile_map_editor/rotate_right``    |
++-------------------+-----------------+-------------------+-------------------------------------+
+| Clear Transform   | :kbd:`W`        | :kbd:`W`          | ``tile_map_editor/clear_transform`` |
++-------------------+-----------------+-------------------+-------------------------------------+
+| Select            | :kbd:`M`        | :kbd:`M`          | ``tile_map_editor/select``          |
++-------------------+-----------------+-------------------+-------------------------------------+
+| Cut Selection     | :kbd:`Ctrl + X` | :kbd:`Cmd + X`    | ``tile_map_editor/cut_selection``   |
++-------------------+-----------------+-------------------+-------------------------------------+
+| Copy Selection    | :kbd:`Ctrl + C` | :kbd:`Cmd + C`    | ``tile_map_editor/copy_selection``  |
++-------------------+-----------------+-------------------+-------------------------------------+
+| Erase Selection   | :kbd:`Del`      | :kbd:`Cmd + BkSp` | ``tile_map_editor/erase_selection`` |
++-------------------+-----------------+-------------------+-------------------------------------+
+
+Tileset Editor
+--------------
+
++---------------------+----------------+---------------+----------------------------------------+
+| Action name         | Windows, Linux | macOS         | Editor setting                         |
++=====================+================+===============+========================================+
+| Next Coordinate     | :kbd:`PgDown`  | :kbd:`PgDown` | ``tileset_editor/next_shape``          |
++---------------------+----------------+---------------+----------------------------------------+
+| Previous Coordinate | :kbd:`PgUp`    | :kbd:`PgUp`   | ``tileset_editor/previous_shape``      |
++---------------------+----------------+---------------+----------------------------------------+
+| Region Mode         | :kbd:`1`       | :kbd:`1`      | ``tileset_editor/editmode_region``     |
++---------------------+----------------+---------------+----------------------------------------+
+| Collision Mode      | :kbd:`2`       | :kbd:`2`      | ``tileset_editor/editmode_collision``  |
++---------------------+----------------+---------------+----------------------------------------+
+| Occlusion Mode      | :kbd:`3`       | :kbd:`3`      | ``tileset_editor/editmode_occlusion``  |
++---------------------+----------------+---------------+----------------------------------------+
+| Navigation Mode     | :kbd:`4`       | :kbd:`4`      | ``tileset_editor/editmode_navigation`` |
++---------------------+----------------+---------------+----------------------------------------+
+| Bitmask Mode        | :kbd:`5`       | :kbd:`5`      | ``tileset_editor/editmode_bitmask``    |
++---------------------+----------------+---------------+----------------------------------------+
+| Priority Mode       | :kbd:`6`       | :kbd:`6`      | ``tileset_editor/editmode_priority``   |
++---------------------+----------------+---------------+----------------------------------------+
+| Icon Mode           | :kbd:`7`       | :kbd:`7`      | ``tileset_editor/editmode_icon``       |
++---------------------+----------------+---------------+----------------------------------------+
+| Z Index Mode        | :kbd:`8`       | :kbd:`8`      | ``tileset_editor/editmode_z_index``    |
++---------------------+----------------+---------------+----------------------------------------+

+ 1 - 0
getting_started/editor/index.rst

@@ -8,6 +8,7 @@ Editor manual
    unity_to_godot
    unity_to_godot
    command_line_tutorial
    command_line_tutorial
    external_editor
    external_editor
+   default_key_mapping
 
 
 .. ue4_to_godot
 .. ue4_to_godot
 .. debugging
 .. debugging

+ 2 - 3
getting_started/editor/unity_to_godot.rst

@@ -73,13 +73,12 @@ The Toolbar at the top of the screen is similar in both editors, offering contro
 Projects in Godot run in a separate window, rather than inside the editor
 Projects in Godot run in a separate window, rather than inside the editor
 (but the tree and objects can still be explored in the debugger window).
 (but the tree and objects can still be explored in the debugger window).
 
 
-This approach has the disadvantage that in Godot the running game can't be explored from different angles
-(though this may be supported in the future and displaying collision gizmos in the running game is already possible),
-but in exchange has several advantages:
+This approach has several advantages:
 
 
 - Running the project and closing it is fast (Unity has to save, run the project, close the project, and then reload the previous state).
 - Running the project and closing it is fast (Unity has to save, run the project, close the project, and then reload the previous state).
 - Live editing is a lot more useful because changes done to the editor take effect immediately in the game and are not lost (nor have to be synced) when the game is closed. This allows fantastic workflows, like creating levels while you play them.
 - Live editing is a lot more useful because changes done to the editor take effect immediately in the game and are not lost (nor have to be synced) when the game is closed. This allows fantastic workflows, like creating levels while you play them.
 - The editor is more stable because the game runs in a separate process.
 - The editor is more stable because the game runs in a separate process.
+- The running game can be explored from different angles by toggling the "Camera Override" button in the editor viewport, which will switch between using the editor view and the game camera view.
 
 
 Finally, Godot's top toolbar includes a menu for remote debugging.
 Finally, Godot's top toolbar includes a menu for remote debugging.
 These options allow deployment to a device (connected phone, tablet, or browser via HTML5),
 These options allow deployment to a device (connected phone, tablet, or browser via HTML5),

+ 3 - 6
getting_started/scripting/c_sharp/c_sharp_basics.rst

@@ -214,12 +214,9 @@ take a look over the official
 - Writing editor plugins is possible, but it is currently quite convoluted.
 - Writing editor plugins is possible, but it is currently quite convoluted.
 - State is currently not saved and restored when hot-reloading,
 - State is currently not saved and restored when hot-reloading,
   with the exception of exported variables.
   with the exception of exported variables.
-- Exporting Mono projects is only supported for desktop platforms
-  (Linux, Windows and macOS). Android, iOS, HTML5 and UWP are not currently supported
-  (`#20267 <https://github.com/godotengine/godot/issues/20267>`_,
-  `#20268 <https://github.com/godotengine/godot/issues/20268>`_
-  `#20270 <https://github.com/godotengine/godot/issues/20270>`_
-  `#20271 <https://github.com/godotengine/godot/issues/20271>`_).
+- Exporting Mono projects is supported for desktop platforms
+  (Linux, Windows and macOS), Android, HTML5, and iOS. UWP is not currently supported.
+  (`#20271 <https://github.com/godotengine/godot/issues/20271>`_).
 - Attached C# scripts should refer to a class that has a class name
 - Attached C# scripts should refer to a class that has a class name
   that matches the file name.
   that matches the file name.
 - There are some methods such as ``Get()``/``Set()``, ``Call()``/``CallDeferred()``
 - There are some methods such as ``Get()``/``Set()``, ``Call()``/``CallDeferred()``

+ 14 - 0
getting_started/scripting/c_sharp/c_sharp_style_guide.rst

@@ -264,6 +264,20 @@ Rather than:
 
 
     FindNode()?.Change(wpnDmg);
     FindNode()?.Change(wpnDmg);
 
 
+Member variables
+----------------
+
+Don't declare member variables if they are only used locally in a method, as it
+makes the code more difficult to follow. Instead, declare them as local
+variables in the method's body.
+
+Local variables
+---------------
+
+Declare local variables as close as possible to their first use. This makes it
+easier to follow the code, without having to scroll too much to find where the
+variable was declared.
+
 Implicitly typed local variables
 Implicitly typed local variables
 --------------------------------
 --------------------------------
 
 

+ 2 - 2
getting_started/scripting/cross_language_scripting.rst

@@ -5,7 +5,7 @@ Cross-language scripting
 
 
 Godot allows you to mix and match scripting languages to suit your needs.
 Godot allows you to mix and match scripting languages to suit your needs.
 This means a single project can define nodes in both C# and GDScript.
 This means a single project can define nodes in both C# and GDScript.
-This page will go through the possible interactions between two nodes writen
+This page will go through the possible interactions between two nodes written
 in different languages.
 in different languages.
 
 
 The following two scripts will be used as references throughout this page.
 The following two scripts will be used as references throughout this page.
@@ -104,7 +104,7 @@ be instantiated with :ref:`GDScript.New() <class_GDScript_method_new>`.
     GDScript MyGDScript = (GDScript) GD.Load("res://path_to_gd_file.gd");
     GDScript MyGDScript = (GDScript) GD.Load("res://path_to_gd_file.gd");
     Object myGDScriptNode = (Godot.Object) MyGDScript.New(); // This is a Godot.Object
     Object myGDScriptNode = (Godot.Object) MyGDScript.New(); // This is a Godot.Object
 
 
-Here we are using an :ref:`class_Object` but you can use type convertion like
+Here we are using an :ref:`class_Object` but you can use type conversion like
 explained in :ref:`doc_c_sharp_features_type_conversion_and_casting`.
 explained in :ref:`doc_c_sharp_features_type_conversion_and_casting`.
 
 
 Accessing fields
 Accessing fields

+ 5 - 29
getting_started/scripting/gdscript/gdscript_basics.rst

@@ -16,34 +16,10 @@ flexibility for content creation and integration.
 History
 History
 ~~~~~~~
 ~~~~~~~
 
 
-In the early days, the engine used the `Lua <https://www.lua.org>`__
-scripting language. Lua is fast, but creating bindings to an object
-oriented system (by using fallbacks) was complex and slow and took an
-enormous amount of code. After some experiments with
-`Python <https://www.python.org>`__, it also proved difficult to embed.
-
-The last third party scripting language that was used for shipped games
-was `Squirrel <http://squirrel-lang.org>`__, but it was dropped as well.
-At that point, it became evident that a custom scripting language could
-more optimally make use of Godot's particular architecture:
-
--  Godot embeds scripts in nodes. Most languages are not designed with
-   this in mind.
--  Godot uses several built-in data types for 2D and 3D math. Script
-   languages do not provide this, and binding them is inefficient.
--  Godot uses threads heavily for lifting and initializing data from the
-   net or disk. Script interpreters for common languages are not
-   friendly to this.
--  Godot already has a memory management model for resources, most
-   script languages provide their own, which results in duplicate
-   effort and bugs.
--  Binding code is always messy and results in several failure points,
-   unexpected bugs and generally low maintainability.
-
-The result of these considerations is *GDScript*. The language and
-interpreter for GDScript ended up being smaller than the binding code itself
-for Lua and Squirrel, while having equal functionality. With time, having a
-built-in language has proven to be a huge advantage.
+.. note::
+
+    Documentation about GDScript's history has been moved to the
+    :ref:`Frequently Asked Questions <doc_faq_what_is_gdscript>`.
 
 
 Example of GDScript
 Example of GDScript
 ~~~~~~~~~~~~~~~~~~~
 ~~~~~~~~~~~~~~~~~~~
@@ -1434,7 +1410,7 @@ Our ``BattleLog`` node receives each element in the binds array as an extra argu
     func _on_Character_health_changed(old_value, new_value, character_name):
     func _on_Character_health_changed(old_value, new_value, character_name):
         if not new_value <= old_value:
         if not new_value <= old_value:
             return
             return
-            
+
         var damage = old_value - new_value
         var damage = old_value - new_value
         label.text += character_name + " took " + str(damage) + " damage."
         label.text += character_name + " took " + str(damage) + " damage."
 
 

+ 15 - 2
getting_started/scripting/gdscript/gdscript_styleguide.rst

@@ -64,7 +64,7 @@ Here is a complete class example based on these guidelines:
             return
             return
 
 
         var target_state = get_node(target_state_path)
         var target_state = get_node(target_state_path)
-        assert target_state.is_composite == false
+        assert(target_state.is_composite == false)
 
 
         _state.exit()
         _state.exit()
         self._state = target_state
         self._state = target_state
@@ -595,6 +595,19 @@ variables, in that order.
    child nodes in the scene that your class relies on. This is what the example
    child nodes in the scene that your class relies on. This is what the example
    above shows.
    above shows.
 
 
+Member variables
+~~~~~~~~~~~~~~~~
+
+Don't declare member variables if they are only used locally in a method, as it
+makes the code more difficult to follow. Instead, declare them as local
+variables in the method's body.
+
+Local variables
+~~~~~~~~~~~~~~~
+
+Declare local variables as close as possible to their first use. This makes it
+easier to follow the code, without having to scroll too much to find where the
+variable was declared.
 
 
 Methods and static functions
 Methods and static functions
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -635,7 +648,7 @@ in that order.
             return
             return
 
 
         var target_state = get_node(target_state_path)
         var target_state = get_node(target_state_path)
-        assert target_state.is_composite == false
+        assert(target_state.is_composite == false)
 
 
         _state.exit()
         _state.exit()
         self._state = target_state
         self._state = target_state

+ 102 - 0
getting_started/scripting/visual_script/custom_visualscript_nodes.rst

@@ -0,0 +1,102 @@
+.. _doc_custom_visualscript_nodes:
+
+Custom VisualScript Nodes
+=========================
+
+Custom nodes are written in GDScript and can then be used in VisualScript.
+This is useful for offloading complex code to GDScript and reusing it.
+
+Creating a custom node
+----------------------
+
+Create a new script that extends :ref:`class_VisualScriptCustomNode` and put a ``tool`` keyword at the top. This is needed for the script to run in the editor.
+
+There are some functions that can be implemented to set parameters of the custom node.
+Only add functions that are needed, a ``_has_input_sequence_port`` function is not necessary if it should return ``false`` for example.
+
+The most important part of a custom node is the ``_step`` function. The logic of the node is defined there.
+
+The ``inputs`` parameter holds the value of the input ports.
+
+The ``outputs`` parameter is an array where the indices represent the output port ids. It can be modified to set the values of the output ports.
+
+``start_mode`` can be checked to see if it is the first time ``_step`` is called.
+
+``working_mem`` is persistent each ``_step`` call. It can be used to store information.
+
+If you want to throw an error, for example if the input types are incorrect, you can return the error message as a string.
+When everything goes right, return the id of the sequence port which should be called next. If your custom node doesn't have any, just return 0.
+
+
+Example:
+
+::
+
+    tool
+    extends VisualScriptCustomNode
+
+    # the name of the custom node as it appears in the search
+    func _get_caption():
+        return "Get Input Direction 2D"
+
+    func _get_category():
+        return "Input"
+
+    # the text displayed after the input port / sequence arrow
+    func _get_text():
+        return ""
+
+    func _get_input_value_port_count():
+        return 0
+
+    # the types of the inputs per index starting from 0
+    func _get_input_value_port_type(idx):
+        return TYPE_OBJECT
+
+    func _get_output_value_port_count():
+        return 1
+
+    # the types of outputs per index starting from 0
+    func _get_output_value_port_type(idx):
+        return TYPE_VECTOR2
+
+    # the text displayed before each output node per index
+    func _get_output_value_port_name(idx):
+        return "Direction"
+
+    func _has_input_sequence_port():
+        return true
+
+    # the number of output sequence ports to use
+    # (has to be at least one if you have an input sequence port)
+    func _get_output_sequence_port_count():
+        return 1
+
+    func _step(inputs, outputs, start_mode, working_mem):
+        # start_mode can be checked to see if it is the first time _step is called
+        # this is useful if you only want to do an operation once
+
+        # working_memory is persistent between _step calls
+
+        # the inputs array contains the value of the input ports
+
+        var x = int(Input.is_action_pressed("ui_right")) - int(Input.is_action_pressed("ui_left"))
+        var y = int(Input.is_action_pressed("ui_down")) - int(Input.is_action_pressed("ui_up"))
+
+        # the outputs array is used to set the data of the output ports
+
+        outputs[0] = Vector2(x,y)
+
+        # return the error string if an error occurred, else the id of the next sequence port
+        return 0
+
+Using a custom node
+-------------------
+
+To use the script, add a ``CustomNode``, select it and drag your custom node script into the ``script`` property shown in the inspector.
+
+.. image:: img/visual_script_custom_node_set_script.png
+
+Result:
+
+.. image:: img/visual_script_custom_node_result.png

BIN
getting_started/scripting/visual_script/img/visual_script_custom_node_result.png


BIN
getting_started/scripting/visual_script/img/visual_script_custom_node_set_script.png


+ 1 - 1
getting_started/scripting/visual_script/index.rst

@@ -8,4 +8,4 @@ VisualScript
    what_is_visual_scripting
    what_is_visual_scripting
    getting_started
    getting_started
    nodes_purposes
    nodes_purposes
-
+   custom_visualscript_nodes

+ 2 - 2
getting_started/step_by_step/exporting.rst

@@ -334,7 +334,7 @@ tool that Godot uses to communicate with your device.
 Next, create a debug keystore by running the following command on your
 Next, create a debug keystore by running the following command on your
 system's command line:
 system's command line:
 
 
-::
+.. code-block:: shell
 
 
     keytool -keyalg RSA -genkeypair -alias androiddebugkey -keypass android -keystore debug.keystore -storepass android -dname "CN=Android Debug,O=Android,C=US" -validity 9999
     keytool -keyalg RSA -genkeypair -alias androiddebugkey -keypass android -keystore debug.keystore -storepass android -dname "CN=Android Debug,O=Android,C=US" -validity 9999
 
 
@@ -351,7 +351,7 @@ for Android (see above). Select the Android Presets and under *Options* go to
 Click the "Export Project" button and Godot will build an APK you can download
 Click the "Export Project" button and Godot will build an APK you can download
 on your device. To do this on the command line, use the following:
 on your device. To do this on the command line, use the following:
 
 
-::
+.. code-block:: shell
 
 
     adb install dodge.apk
     adb install dodge.apk
 
 

+ 1 - 1
getting_started/step_by_step/filesystem.rst

@@ -27,7 +27,7 @@ Git, Mercurial, Perforce, etc.
 
 
 Example of file system contents:
 Example of file system contents:
 
 
-::
+.. code-block:: none
 
 
     /project.godot
     /project.godot
     /enemy/enemy.tscn
     /enemy/enemy.tscn

BIN
getting_started/step_by_step/img/editor_ui_intro_script_class_documentation.png


BIN
getting_started/step_by_step/img/editor_ui_intro_script_search_documentation.png


BIN
getting_started/step_by_step/img/editor_ui_intro_script_search_help_window.png


BIN
getting_started/step_by_step/img/tree.png


+ 1 - 1
getting_started/step_by_step/instancing.rst

@@ -79,7 +79,7 @@ Multiple instances
 
 
 You can add as many instances as you like to a scene, either by using the
 You can add as many instances as you like to a scene, either by using the
 "Instance" button again, or by clicking on the ball instance and pressing
 "Instance" button again, or by clicking on the ball instance and pressing
-"Duplicate" (:kbd:`Ctrl + D`):
+:kbd:`Ctrl + D` (:kbd:`Cmd + D` on macOS) to duplicate it:
 
 
 .. image:: img/instancing_multiball.png
 .. image:: img/instancing_multiball.png
 
 

+ 18 - 2
getting_started/step_by_step/intro_to_the_editor_interface.rst

@@ -139,8 +139,24 @@ to access it, and :kbd:`F4` to search the reference.
 
 
 .. image:: img/editor_ui_intro_editor_06_script_workspace_expanded.png
 .. image:: img/editor_ui_intro_editor_06_script_workspace_expanded.png
 
 
-Finally the **AssetLib** is a library of Free add-ons, scripts and
-assets to use in your projects.
+To search for information about a class, method, property, constant, or signal
+in the engine while you are writing a script, press the "Search Help" button at
+the top right of the Script workspace.
+
+.. image:: img/editor_ui_intro_script_search_documentation.png
+
+A new window will pop up. Search for the item that you want to find information
+about.
+
+.. image:: img/editor_ui_intro_script_search_help_window.png
+
+Click on the item you are looking for and press open. The documentation for the
+item will be displayed in the script workspace.
+
+.. image:: img/editor_ui_intro_script_class_documentation.png
+
+Finally the **AssetLib** is a library of free and open source add-ons, scripts
+and assets to use in your projects.
 
 
 Modify the interface
 Modify the interface
 --------------------
 --------------------

+ 17 - 4
getting_started/step_by_step/signals.rst

@@ -1,3 +1,6 @@
+.. meta::
+    :keywords: Signal
+
 .. _doc_signals:
 .. _doc_signals:
 
 
 Signals
 Signals
@@ -76,8 +79,9 @@ Click "Connect" and you'll see that the function has been created in the script:
 
 
     extends Node2D
     extends Node2D
 
 
+
     func _on_Timer_timeout():
     func _on_Timer_timeout():
-        pass # replace with function body
+        pass # Replace with function body.
 
 
  .. code-tab:: csharp
  .. code-tab:: csharp
 
 
@@ -97,6 +101,7 @@ the signal is received. Let's make the Sprite blink:
 
 
     extends Node2D
     extends Node2D
 
 
+
     func _on_Timer_timeout():
     func _on_Timer_timeout():
         # Note: the `$` operator is a shorthand for `get_node()`,
         # Note: the `$` operator is a shorthand for `get_node()`,
         # so `$Sprite` is equivalent to `get_node("Sprite")`.
         # so `$Sprite` is equivalent to `get_node("Sprite")`.
@@ -138,9 +143,11 @@ Here is the code for our Timer connection:
 
 
     extends Node2D
     extends Node2D
 
 
+
     func _ready():
     func _ready():
         $Timer.connect("timeout", self, "_on_Timer_timeout")
         $Timer.connect("timeout", self, "_on_Timer_timeout")
 
 
+
     func _on_Timer_timeout():
     func _on_Timer_timeout():
         $Sprite.visible = !$Sprite.visible
         $Sprite.visible = !$Sprite.visible
 
 
@@ -171,6 +178,7 @@ You can also declare your own custom signals in Godot:
 
 
     extends Node2D
     extends Node2D
 
 
+
     signal my_signal
     signal my_signal
 
 
  .. code-tab:: csharp
  .. code-tab:: csharp
@@ -191,8 +199,10 @@ To emit a signal via code, use the ``emit_signal`` function:
 
 
     extends Node2D
     extends Node2D
 
 
+
     signal my_signal
     signal my_signal
 
 
+
     func _ready():
     func _ready():
         emit_signal("my_signal")
         emit_signal("my_signal")
 
 
@@ -208,7 +218,7 @@ To emit a signal via code, use the ``emit_signal`` function:
             EmitSignal(nameof(MySignal));
             EmitSignal(nameof(MySignal));
         }
         }
     }
     }
-    
+
 A signal can also optionally declare one or more arguments. Specify the
 A signal can also optionally declare one or more arguments. Specify the
 argument names between parentheses:
 argument names between parentheses:
 
 
@@ -217,6 +227,7 @@ argument names between parentheses:
 
 
     extends Node
     extends Node
 
 
+
     signal my_signal(value, other_value)
     signal my_signal(value, other_value)
 
 
  .. code-tab:: csharp
  .. code-tab:: csharp
@@ -224,7 +235,7 @@ argument names between parentheses:
     public class Main : Node
     public class Main : Node
     {
     {
         [Signal]
         [Signal]
-        public delegate void MySignal();
+        public delegate void MySignal(bool value, int other_value);
     }
     }
 
 
 .. note::
 .. note::
@@ -241,8 +252,10 @@ To pass values, add them as the second argument to the ``emit_signal`` function:
 
 
     extends Node
     extends Node
 
 
+
     signal my_signal(value, other_value)
     signal my_signal(value, other_value)
 
 
+
     func _ready():
     func _ready():
         emit_signal("my_signal", true, 42)
         emit_signal("my_signal", true, 42)
 
 
@@ -251,7 +264,7 @@ To pass values, add them as the second argument to the ``emit_signal`` function:
     public class Main : Node
     public class Main : Node
     {
     {
         [Signal]
         [Signal]
-        public delegate void MySignal();
+        public delegate void MySignal(bool value, int other_value);
 
 
         public override void _Ready()
         public override void _Ready()
         {
         {

+ 9 - 5
getting_started/step_by_step/your_first_game.rst

@@ -377,7 +377,7 @@ Let's place this code at the end of our ``_process()`` function:
             // See the note below about boolean assignment
             // See the note below about boolean assignment
             animatedSprite.FlipH = velocity.x < 0;
             animatedSprite.FlipH = velocity.x < 0;
         }
         }
-        else if(velocity.y != 0)
+        else if (velocity.y != 0)
         {
         {
             animatedSprite.Animation = "up";
             animatedSprite.Animation = "up";
             animatedSprite.FlipV = velocity.y > 0;
             animatedSprite.FlipV = velocity.y > 0;
@@ -397,10 +397,14 @@ Let's place this code at the end of our ``_process()`` function:
 
 
            .. code-tab:: csharp
            .. code-tab:: csharp
 
 
-             if velocity.x < 0:
-                 animatedSprite.FlipH = true
-             else:
-                 animatedSprite.FlipH = false
+             if (velocity.x < 0)
+             {
+                 animatedSprite.FlipH = true;
+             }
+             else
+             {
+                 animatedSprite.FlipH = false;
+             }
 
 
 Play the scene again and check that the animations are correct in each
 Play the scene again and check that the animations are correct in each
 of the directions. When you're sure the movement is working correctly,
 of the directions. When you're sure the movement is working correctly,

+ 7 - 2
getting_started/workflow/assets/importing_scenes.rst

@@ -318,8 +318,13 @@ In general, this should always be turned on unless you suspect that an animation
 Clips
 Clips
 ~~~~~
 ~~~~~
 
 
-It is possible to specify multiple animations from a single timeline as clips. Specify from which frame to which frame each
-clip must be taken (and, of course, don't forget to specify the FPS option above).
+It is possible to specify multiple animations from a single timeline as clips. For this to work, the model
+must have only one animation that is named ``default``. To create clips, change the clip amount to something
+greater than zero. You can then name a clip, specify which frames it starts and stops on, and choose whether
+the animation loops or not.
+
+.. If this PR (https://github.com/godotengine/godot/pull/36709) is merged for Godot 4.0 this section must
+be updated to reflect that for the 4.0 documentation.
 
 
 Scene inheritance
 Scene inheritance
 -----------------
 -----------------

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

@@ -128,7 +128,7 @@ the expense of memory and some minor operational efficiency.
       minimize hash collisions and maintain the speed of the accesses.
       minimize hash collisions and maintain the speed of the accesses.
 
 
 As one might be able to tell, Dictionaries specialize in tasks that Arrays
 As one might be able to tell, Dictionaries specialize in tasks that Arrays
-aren't. An overview of their operational details is as follows:
+do not. An overview of their operational details is as follows:
 
 
 - **Iterate:** Fast.
 - **Iterate:** Fast.
 
 

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

@@ -70,7 +70,7 @@ access.
 
 
     // Tool script added for the sake of the "const [Export]" example.
     // Tool script added for the sake of the "const [Export]" example.
     [Tool]
     [Tool]
-    public MyType : extends Object
+    public MyType
     {
     {
         // Property initializations load during Script instancing, i.e. .new().
         // Property initializations load during Script instancing, i.e. .new().
         // No "preload" loads during scene load exists in C#.
         // No "preload" loads during scene load exists in C#.
@@ -167,8 +167,8 @@ Nodes likewise have an alternative access point: the SceneTree.
             return
             return
 
 
         # Fail and terminate.
         # Fail and terminate.
-        # Compiled scripts in final binary do not include assert statements
-        assert prop.
+        # Note: Scripts run from a release export template don't run `assert` statements.
+        assert(prop, "'prop' wasn't initialized")
 
 
     # Use an autoload.
     # Use an autoload.
     # Dangerous for typical nodes, but useful for true singleton nodes
     # Dangerous for typical nodes, but useful for true singleton nodes
@@ -342,9 +342,9 @@ accesses:
       # If one does not wish to fail these checks without notifying users, one
       # If one does not wish to fail these checks without notifying users, one
       # can use an assert instead. These will trigger runtime errors
       # can use an assert instead. These will trigger runtime errors
       # immediately if not true.
       # immediately if not true.
-      assert child.has("set_visible")
-      assert child.is_in_group("offer")
-      assert child is CanvasItem
+      assert(child.has("set_visible"))
+      assert(child.is_in_group("offer"))
+      assert(child is CanvasItem)
 
 
       # Can also use object labels to imply an interface, i.e. assume it implements certain methods.
       # Can also use object labels to imply an interface, i.e. assume it implements certain methods.
       # There are two types, both of which only exist for Nodes: Names and Groups
       # There are two types, both of which only exist for Nodes: Names and Groups
@@ -472,7 +472,7 @@ accesses:
   .. code-tab:: csharp
   .. code-tab:: csharp
 
 
     // Child.cs
     // Child.cs
-    public class Child extends Node
+    public class Child : Node
     {
     {
         public FuncRef FN = null;
         public FuncRef FN = null;
 
 
@@ -484,7 +484,7 @@ accesses:
     }
     }
 
 
     // Parent.cs
     // Parent.cs
-    public class Parent extends Node
+    public class Parent : Node
     {
     {
         public Node Child;
         public Node Child;
 
 

+ 6 - 6
getting_started/workflow/export/android_custom_build.rst

@@ -78,7 +78,7 @@ carefully:
 Create a new folder anywhere you want named ``android-sdk`` (it **must** be
 Create a new folder anywhere you want named ``android-sdk`` (it **must** be
 an empty directory). On Windows, the following path is usually good enough:
 an empty directory). On Windows, the following path is usually good enough:
 
 
-::
+.. code-block:: none
 
 
   C:\users\<yourusername>\Documents\android-sdk
   C:\users\<yourusername>\Documents\android-sdk
 
 
@@ -86,7 +86,7 @@ Unzip the Android SDK ZIP file you just downloaded there. The only thing in the
 directory you created in the previous step should be the ``tools`` folder with
 directory you created in the previous step should be the ``tools`` folder with
 its contents inside, like this:
 its contents inside, like this:
 
 
-::
+.. code-block:: none
 
 
   android-sdk/
   android-sdk/
   android-sdk/tools/
   android-sdk/tools/
@@ -128,7 +128,7 @@ Generating the keystore
 Once the *platform tools* are installed, the last step is to generate a debug
 Once the *platform tools* are installed, the last step is to generate a debug
 keystore (this is needed to build). Go up two folders by writing:
 keystore (this is needed to build). Go up two folders by writing:
 
 
-::
+.. code-block:: shell
 
 
     cd ..\..
     cd ..\..
 
 
@@ -137,7 +137,7 @@ keystore (this is needed to build). Go up two folders by writing:
 And you need to input the following line (on Linux and macOS, this should work
 And you need to input the following line (on Linux and macOS, this should work
 out of the box, for Windows there are further instructions below):
 out of the box, for Windows there are further instructions below):
 
 
-::
+.. code-block:: shell
 
 
     keytool -keyalg RSA -genkeypair -alias androiddebugkey -keypass android -keystore debug.keystore -storepass android -dname "CN=Android Debug,O=Android,C=US" -validity 9999
     keytool -keyalg RSA -genkeypair -alias androiddebugkey -keypass android -keystore debug.keystore -storepass android -dname "CN=Android Debug,O=Android,C=US" -validity 9999
 
 
@@ -192,7 +192,7 @@ where the *android-sdk* directory is created.
 In any case, it's better to select a different path inside your user folders.
 In any case, it's better to select a different path inside your user folders.
 The recommended one is usually:
 The recommended one is usually:
 
 
-::
+.. code-block:: none
 
 
   C:\Users\<yourusername>\Documents\android-sdk
   C:\Users\<yourusername>\Documents\android-sdk
 
 
@@ -218,7 +218,7 @@ The actual command line to type is the following. On Linux and macOS, it should
 work out of the box, but on Windows, it needs additional details (keep reading
 work out of the box, but on Windows, it needs additional details (keep reading
 afterwards).
 afterwards).
 
 
-::
+.. code-block:: shell
 
 
     keytool -keyalg RSA -genkeypair -alias androiddebugkey -keypass android -keystore debug.keystore -storepass android -dname "CN=Android Debug,O=Android,C=US" -validity 9999
     keytool -keyalg RSA -genkeypair -alias androiddebugkey -keypass android -keystore debug.keystore -storepass android -dname "CN=Android Debug,O=Android,C=US" -validity 9999
 
 

+ 1 - 1
getting_started/workflow/export/exporting_for_android.rst

@@ -97,7 +97,7 @@ Exporting for Google Play Store
 Uploading an APK to Google's Play Store requires you to sign using a non-debug
 Uploading an APK to Google's Play Store requires you to sign using a non-debug
 keystore file; such file can be generated like this:
 keystore file; such file can be generated like this:
 
 
-::
+.. code-block:: shell
 
 
     keytool -v -genkey -v -keystore mygame.keystore -alias mygame -keyalg RSA -validity 10000
     keytool -v -genkey -v -keystore mygame.keystore -alias mygame -keyalg RSA -validity 10000
 
 

+ 1 - 1
getting_started/workflow/export/exporting_for_ios.rst

@@ -23,7 +23,7 @@ The following export options are required. Leaving any blank will cause the
 exporter to throw an error:
 exporter to throw an error:
 
 
   * In the **Application** category
   * In the **Application** category
-    * **App Store Team ID**
+    * **App Store Team ID** and (Bundle) **Identifier**
   * Everything in the **Required Icons** category
   * Everything in the **Required Icons** category
   * Everything in the **Landscape Launch Screens** category
   * Everything in the **Landscape Launch Screens** category
   * Everything in the **Portrait Launch Screens** category
   * Everything in the **Portrait Launch Screens** category

+ 1 - 2
getting_started/workflow/export/exporting_for_web.rst

@@ -17,8 +17,7 @@ in the user's browser.
                ``file://`` protocol. To get around this, use a local server.
                ``file://`` protocol. To get around this, use a local server.
 
 
                .. tip:: Python offers an easy method to start a local server.
                .. tip:: Python offers an easy method to start a local server.
-                        Use ``python -m SimpleHTTPServer`` with Python 2 or
-                        ``python -m http.server`` with Python 3 to serve the
+                        Use ``python -m http.server`` with Python 3 to serve the
                         current working directory at ``http://localhost:8000``.
                         current working directory at ``http://localhost:8000``.
 
 
 WebGL 2
 WebGL 2

+ 2 - 2
getting_started/workflow/export/exporting_projects.rst

@@ -140,7 +140,7 @@ with the ``--export`` and ``--export-debug`` command line parameters.
 Exporting from the command line still requires an export preset to define
 Exporting from the command line still requires an export preset to define
 the export parameters. A basic invocation of the command would be:
 the export parameters. A basic invocation of the command would be:
 
 
-::
+.. code-block:: shell
 
 
     godot --export "Windows Desktop" some_name
     godot --export "Windows Desktop" some_name
 
 
@@ -156,6 +156,6 @@ This takes place if the target name ends with ``.pck`` or ``.zip``.
 It is often useful to combine the ``--export`` flag with the ``--path``
 It is often useful to combine the ``--export`` flag with the ``--path``
 flag, and to create a dedicated export preset for automated export:
 flag, and to create a dedicated export preset for automated export:
 
 
-::
+.. code-block:: shell
 
 
     godot --path path/to/project --export "pck" game_name.pck
     godot --path path/to/project --export "pck" game_name.pck

+ 1 - 1
getting_started/workflow/index.rst

@@ -8,4 +8,4 @@ Project workflow
    project_setup/index
    project_setup/index
    assets/index
    assets/index
    export/index
    export/index
-   best_practices/index
+   best_practices/index

+ 1 - 1
getting_started/workflow/project_setup/project_organization.rst

@@ -28,7 +28,7 @@ As an example, one can usually place into a single folder their basic assets,
 such as sprite images, 3D model meshes, materials, and music, etc.
 such as sprite images, 3D model meshes, materials, and music, etc.
 They can then use a separate folder to store built levels that use them.
 They can then use a separate folder to store built levels that use them.
 
 
-::
+.. code-block:: none
 
 
     /project.godot
     /project.godot
     /docs/.gdignore  # See "Ignoring specific folders" below
     /docs/.gdignore  # See "Ignoring specific folders" below

BIN
img/docs_logo.png


+ 13 - 0
requirements.txt

@@ -0,0 +1,13 @@
+# Base dependencies
+
+# Sync with readthedocs:
+# https://github.com/readthedocs/readthedocs.org/blob/master/requirements/pip.txt
+# https://github.com/readthedocs/readthedocs.org/blob/master/requirements/local-docs-build.txt
+sphinx==1.8.5  # pyup: <2.0.0
+sphinx_rtd_theme==0.4.3
+
+# Code tabs extension for GDScript/C#
+sphinx-tabs==1.1.13
+
+# Full-page search UI for RTD: https://readthedocs-sphinx-search.readthedocs.io
+git+https://github.com/readthedocs/readthedocs-sphinx-search@master

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

@@ -163,7 +163,7 @@ linked from one to the next. As you can imagine, the more points your shape is m
 the smoother it will appear, but the heavier it will also be in terms of processing cost. In general,
 the smoother it will appear, but the heavier it will also be in terms of processing cost. In general,
 if your shape is huge (or in 3D, close to the camera), it will require more points to be drawn without
 if your shape is huge (or in 3D, close to the camera), it will require more points to be drawn without
 it being angular-looking. On the contrary, if your shape is small (or in 3D, far from the camera),
 it being angular-looking. On the contrary, if your shape is small (or in 3D, far from the camera),
-you may decrease its number of points to save processing costs; this is known as *Level of Detail (LoD)*.
+you may decrease its number of points to save processing costs; this is known as *Level of Detail (LOD)*.
 In our example, we will simply use a fixed number of points, no matter the radius.
 In our example, we will simply use a fixed number of points, no matter the radius.
 
 
 .. tabs::
 .. tabs::

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

@@ -164,4 +164,4 @@ Tips and tricks
 - Tools such as copy, paste, and bucket fill, can be found in the "TileMap"
 - Tools such as copy, paste, and bucket fill, can be found in the "TileMap"
   menu in the upper-right.
   menu in the upper-right.
 
 
-.. image:: img/tilemap_menu.png
+.. image:: img/tilemap_menu.png

+ 2 - 2
tutorials/3d/fps_tutorial/part_four.rst

@@ -125,8 +125,8 @@ the OS.
 Next, we check to see if the joypad vector length is within the ``JOYPAD_DEADZONE`` radius.
 Next, we check to see if the joypad vector length is within the ``JOYPAD_DEADZONE`` radius.
 If it is, we set ``joypad_vec`` to an empty Vector2. If it is not, we use a scaled Radial Dead zone for precise dead zone calculation.
 If it is, we set ``joypad_vec`` to an empty Vector2. If it is not, we use a scaled Radial Dead zone for precise dead zone calculation.
 
 
-.. note:: You can find a great article explaining all about how to handle joypad/controller dead zones here:
-          http://www.third-helix.com/2013/04/12/doing-thumbstick-dead-zones-right.html
+.. note:: You can find a great article explaining all about how to handle joypad/controller dead zones
+          `here <https://web.archive.org/web/20191208161810/http://www.third-helix.com/2013/04/12/doing-thumbstick-dead-zones-right.html>`__.
 
 
           We're using a translated version of the scaled radial dead zone code provided in that article.
           We're using a translated version of the scaled radial dead zone code provided in that article.
           The article is a great read, and I highly suggest giving it a look!
           The article is a great read, and I highly suggest giving it a look!

+ 1 - 1
tutorials/audio/sync_with_audio.rst

@@ -50,7 +50,7 @@ Add these two and it's possible to guess almost exactly when sound or music will
         var time = (OS.get_ticks_usec() - time_begin) / 1000000.0
         var time = (OS.get_ticks_usec() - time_begin) / 1000000.0
         # Compensate for latency.
         # Compensate for latency.
         time -= time_delay
         time -= time_delay
-        # May be below 0 (did not being yet).
+        # May be below 0 (did not begin yet).
         time = max(0, time)
         time = max(0, time)
         print("Time is: ", time)
         print("Time is: ", time)
 
 

+ 1 - 1
tutorials/i18n/internationalizing_games.rst

@@ -89,7 +89,7 @@ Language can be tested when running Godot from the command line.
 For example, to test a game in French, the following argument can be
 For example, to test a game in French, the following argument can be
 supplied:
 supplied:
 
 
-::
+.. code-block:: shell
 
 
    godot --language fr
    godot --language fr
 
 

+ 6 - 6
tutorials/i18n/localization_using_gettext.rst

@@ -93,7 +93,7 @@ create and update the POT file from your scene files and scripts.
 
 
 After installing ``babel`` and ``babel-godot``, for example using pip:
 After installing ``babel`` and ``babel-godot``, for example using pip:
 
 
-::
+.. code-block:: shell
 
 
     pip install babel babel-godot
     pip install babel babel-godot
 
 
@@ -101,7 +101,7 @@ Write a mapping file (for example ``babelrc``) which will indicate which files
 pybabel needs to process (note that we process GDScript as Python, which is
 pybabel needs to process (note that we process GDScript as Python, which is
 generally sufficient):
 generally sufficient):
 
 
-::
+.. code-block:: none
 
 
     [python: **.gd]
     [python: **.gd]
     encoding = utf-8
     encoding = utf-8
@@ -111,7 +111,7 @@ generally sufficient):
 
 
 You can then run pybabel like so:
 You can then run pybabel like so:
 
 
-::
+.. code-block:: shell
 
 
     pybabel extract -F babelrc -k text -k LineEdit/placeholder_text -k tr -o godot-l10n.pot .
     pybabel extract -F babelrc -k text -k LineEdit/placeholder_text -k tr -o godot-l10n.pot .
 
 
@@ -127,7 +127,7 @@ The ``msginit`` command is used to turn a PO template into a messages file.
 For instance, to create a French localization file, use the following command
 For instance, to create a French localization file, use the following command
 while in the ``locale`` directory:
 while in the ``locale`` directory:
 
 
-::
+.. code-block:: shell
 
 
     msginit --no-translator --input=messages.pot --locale=fr
     msginit --no-translator --input=messages.pot --locale=fr
 
 
@@ -157,7 +157,7 @@ that they contain new strings, while removing strings that are no longer
 present in the PO template removed in the PO template. This can be done
 present in the PO template removed in the PO template. This can be done
 automatically using the ``msgmerge`` tool:
 automatically using the ``msgmerge`` tool:
 
 
-::
+.. code-block:: shell
 
 
     # The order matters: specify the message file *then* the PO template!
     # The order matters: specify the message file *then* the PO template!
     msgmerge --update --backup=none fr.po messages.pot
     msgmerge --update --backup=none fr.po messages.pot
@@ -171,7 +171,7 @@ Checking the validity of a PO file or template
 It is possible to check whether a gettext file's syntax is valid by running
 It is possible to check whether a gettext file's syntax is valid by running
 the command below:
 the command below:
 
 
-::
+.. code-block:: shell
 
 
     msgfmt fr.po --check
     msgfmt fr.po --check
 
 

+ 5 - 5
tutorials/io/background_loading.rst

@@ -28,7 +28,7 @@ Usage is generally as follows
 Obtaining a ResourceInteractiveLoader
 Obtaining a ResourceInteractiveLoader
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 
-::
+.. code-block:: cpp
 
 
     Ref<ResourceInteractiveLoader> ResourceLoader::load_interactive(String p_path);
     Ref<ResourceInteractiveLoader> ResourceLoader::load_interactive(String p_path);
 
 
@@ -38,7 +38,7 @@ to manage the load operation.
 Polling
 Polling
 ~~~~~~~
 ~~~~~~~
 
 
-::
+.. code-block:: cpp
 
 
     Error ResourceInteractiveLoader::poll();
     Error ResourceInteractiveLoader::poll();
 
 
@@ -55,7 +55,7 @@ Load progress (optional)
 
 
 To query the progress of the load, use the following methods:
 To query the progress of the load, use the following methods:
 
 
-::
+.. code-block:: cpp
 
 
     int ResourceInteractiveLoader::get_stage_count() const;
     int ResourceInteractiveLoader::get_stage_count() const;
     int ResourceInteractiveLoader::get_stage() const;
     int ResourceInteractiveLoader::get_stage() const;
@@ -66,7 +66,7 @@ To query the progress of the load, use the following methods:
 Forcing completion (optional)
 Forcing completion (optional)
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 
-::
+.. code-block:: cpp
 
 
     Error ResourceInteractiveLoader::wait();
     Error ResourceInteractiveLoader::wait();
 
 
@@ -76,7 +76,7 @@ frame, without any more steps.
 Obtaining the resource
 Obtaining the resource
 ~~~~~~~~~~~~~~~~~~~~~~
 ~~~~~~~~~~~~~~~~~~~~~~
 
 
-::
+.. code-block:: cpp
 
 
     Ref<Resource> ResourceInteractiveLoader::get_resource();
     Ref<Resource> ResourceInteractiveLoader::get_resource();
 
 

+ 2 - 2
tutorials/math/matrices_and_transforms.rst

@@ -124,12 +124,12 @@ When we do this, we get the desired result of rotating the object:
 
 
 .. image:: img/matrices_and_transforms/rotate1.png
 .. image:: img/matrices_and_transforms/rotate1.png
 
 
-If you have trouble understanding the above, try this excercise:
+If you have trouble understanding the above, try this exercise:
 Cut a square of paper, draw X and Y vectors on top of it, place
 Cut a square of paper, draw X and Y vectors on top of it, place
 it on graph paper, then rotate it and note the endpoints.
 it on graph paper, then rotate it and note the endpoints.
 
 
 To perform rotation in code, we need to be able to calculate
 To perform rotation in code, we need to be able to calculate
-the values programatically. This image shows the formulas needed
+the values programmatically. This image shows the formulas needed
 to calculate the transformation matrix from a rotation angle.
 to calculate the transformation matrix from a rotation angle.
 Don't worry if this part seems complicated, I promise it's the
 Don't worry if this part seems complicated, I promise it's the
 hardest thing you need to know.
 hardest thing you need to know.

+ 8 - 24
tutorials/math/vector_math.rst

@@ -188,25 +188,8 @@ Normalization
 
 
 **Normalizing** a vector means reducing its length to ``1`` while
 **Normalizing** a vector means reducing its length to ``1`` while
 preserving its direction. This is done by dividing each of its components
 preserving its direction. This is done by dividing each of its components
-by its magnitude:
-
-.. tabs::
- .. code-tab:: gdscript GDScript
-
-    var a = Vector2(2, 4)
-    var m = sqrt(a.x*a.x + a.y*a.y)  # get magnitude "m" using the Pythagorean theorem
-    a.x /= m
-    a.y /= m
-
- .. code-tab:: csharp
-
-    var a = new Vector2(2, 4);
-    var m = Mathf.Sqrt(a.x*a.x + a.y*a.y);  // get magnitude "m" using the Pythagorean theorem
-    a.x /= m;
-    a.y /= m;
-
-Because this is such a common operation, ``Vector2`` and ``Vector3`` provide
-a method for normalizing:
+by its magnitude. Because this is such a common operation,
+``Vector2`` and ``Vector3`` provide a method for normalizing:
 
 
 .. tabs::
 .. tabs::
  .. code-tab:: gdscript GDScript
  .. code-tab:: gdscript GDScript
@@ -291,12 +274,12 @@ the order of the two vectors does not matter:
  .. code-tab:: gdscript GDScript
  .. code-tab:: gdscript GDScript
 
 
     var c = a.dot(b)
     var c = a.dot(b)
-    var d = b.dot(a)  # these are equivalent
+    var d = b.dot(a) # These are equivalent.
 
 
  .. code-tab:: csharp
  .. code-tab:: csharp
 
 
     float c = a.Dot(b);
     float c = a.Dot(b);
-    float d = b.Dot(a);  // these are equivalent
+    float d = b.Dot(a); // These are equivalent.
 
 
 The dot product is most useful when used with unit vectors, making the
 The dot product is most useful when used with unit vectors, making the
 first formula reduce to just ``cosθ``. This means we can use the dot
 first formula reduce to just ``cosθ``. This means we can use the dot
@@ -319,7 +302,8 @@ zombies ``A`` and ``B``. Assuming a zombie's field of view is **180°**, can the
 The green arrows ``fA`` and ``fB`` are **unit vectors** representing the
 The green arrows ``fA`` and ``fB`` are **unit vectors** representing the
 zombies' facing directions and the blue semicircle represents its field of
 zombies' facing directions and the blue semicircle represents its field of
 view. For zombie ``A``, we find the direction vector ``AP`` pointing to
 view. For zombie ``A``, we find the direction vector ``AP`` pointing to
-the player using ``P - A`` and normalize it. If the angle between this
+the player using ``P - A`` and normalize it, however, Godot has a helper
+method to do this called ``direction_to``. If the angle between this
 vector and the facing vector is less than 90°, then the zombie can see
 vector and the facing vector is less than 90°, then the zombie can see
 the player.
 the player.
 
 
@@ -328,13 +312,13 @@ In code it would look like this:
 .. tabs::
 .. tabs::
  .. code-tab:: gdscript GDScript
  .. code-tab:: gdscript GDScript
 
 
-    var AP = (P - A).normalized()
+    var AP = A.direction_to(P)
     if AP.dot(fA) > 0:
     if AP.dot(fA) > 0:
         print("A sees P!")
         print("A sees P!")
 
 
  .. code-tab:: csharp
  .. code-tab:: csharp
 
 
-    var AP = (P - A).Normalized();
+    var AP = A.DirectionTo(P);
     if (AP.Dot(fA) > 0)
     if (AP.Dot(fA) > 0)
     {
     {
         GD.Print("A sees P!");
         GD.Print("A sees P!");

+ 11 - 0
tutorials/math/vectors_advanced.rst

@@ -586,3 +586,14 @@ So the final algorithm is something like:
     {
     {
         GD.Print("Polygons Collided!");
         GD.Print("Polygons Collided!");
     }
     }
+
+More information
+~~~~~~~~~~~~~~~~
+
+For more information on using vector math in Godot, see the following article:
+
+- :ref:`doc_matrices_and_transforms`
+
+If you would like additional explanation, you should check out
+3Blue1Brown's excellent video series "Essence of Linear Algebra":
+https://www.youtube.com/watch?v=fNk_zzaMoSs&list=PLZHQObOWTQDPD3MizzM2xVFitgF8hE_ab

+ 70 - 67
tutorials/misc/binary_serialization_api.rst

@@ -80,7 +80,10 @@ integer, specifying the type of data:
 +--------+--------------------------+
 +--------+--------------------------+
 
 
 Following this is the actual packet contents, which varies for each type
 Following this is the actual packet contents, which varies for each type
-of packet:
+of packet. Note that this assumes Godot is compiled with single precision
+floats. If instead doubles are used, the length of "Float" fields within
+data structures should be 8, and the offset should be (offset - 4) * 2 + 4.
+The "float" type itself is always double precision.
 
 
 0: null
 0: null
 ~~~~~~~
 ~~~~~~~
@@ -100,10 +103,10 @@ of packet:
 +----------+-------+-----------+--------------------------+
 +----------+-------+-----------+--------------------------+
 | Offset   | Len   | Type      | Description              |
 | Offset   | Len   | Type      | Description              |
 +==========+=======+===========+==========================+
 +==========+=======+===========+==========================+
-| 4        | 4     | Integer   | Signed, 32-Bit Integer   |
+| 4        | 8     | Integer   | Signed, 64-bit Integer   |
 +----------+-------+-----------+--------------------------+
 +----------+-------+-----------+--------------------------+
 
 
-3: :ref:`float<class_float>`/real
+3: :ref:`float<class_float>`
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 
 +----------+-------+---------+-------------------------+
 +----------+-------+---------+-------------------------+
@@ -167,21 +170,21 @@ This field is padded to 4 bytes.
 8: :ref:`Transform2D<class_transform2d>`
 8: :ref:`Transform2D<class_transform2d>`
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 
-+----------+-------+---------+---------------+
-| Offset   | Len   | Type    | Description   |
-+==========+=======+=========+===============+
-| 4        | 4     | Float   | [0][0]        |
-+----------+-------+---------+---------------+
-| 8        | 4     | Float   | [0][1]        |
-+----------+-------+---------+---------------+
-| 12       | 4     | Float   | [1][0]        |
-+----------+-------+---------+---------------+
-| 16       | 4     | Float   | [1][1]        |
-+----------+-------+---------+---------------+
-| 20       | 4     | Float   | [2][0]        |
-+----------+-------+---------+---------------+
-| 24       | 4     | Float   | [2][1]        |
-+----------+-------+---------+---------------+
++----------+-------+---------+---------------------------------------------------------------+
+| Offset   | Len   | Type    | Description                                                   |
++==========+=======+=========+===============================================================+
+| 4        | 4     | Float   | The X component of the X column vector, accessed via [0][0]   |
++----------+-------+---------+---------------------------------------------------------------+
+| 8        | 4     | Float   | The Y component of the X column vector, accessed via [0][1]   |
++----------+-------+---------+---------------------------------------------------------------+
+| 12       | 4     | Float   | The X component of the Y column vector, accessed via [1][0]   |
++----------+-------+---------+---------------------------------------------------------------+
+| 16       | 4     | Float   | The Y component of the Y column vector, accessed via [1][1]   |
++----------+-------+---------+---------------------------------------------------------------+
+| 20       | 4     | Float   | The X component of the origin vector, accessed via [2][0]     |
++----------+-------+---------+---------------------------------------------------------------+
+| 24       | 4     | Float   | The Y component of the origin vector, accessed via [2][1]     |
++----------+-------+---------+---------------------------------------------------------------+
 
 
 9: :ref:`Plane<class_plane>`
 9: :ref:`Plane<class_plane>`
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -235,58 +238,58 @@ This field is padded to 4 bytes.
 12: :ref:`Basis<class_basis>`
 12: :ref:`Basis<class_basis>`
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 
-+----------+-------+---------+---------------+
-| Offset   | Len   | Type    | Description   |
-+==========+=======+=========+===============+
-| 4        | 4     | Float   | [0][0]        |
-+----------+-------+---------+---------------+
-| 8        | 4     | Float   | [0][1]        |
-+----------+-------+---------+---------------+
-| 12       | 4     | Float   | [0][2]        |
-+----------+-------+---------+---------------+
-| 16       | 4     | Float   | [1][0]        |
-+----------+-------+---------+---------------+
-| 20       | 4     | Float   | [1][1]        |
-+----------+-------+---------+---------------+
-| 24       | 4     | Float   | [1][2]        |
-+----------+-------+---------+---------------+
-| 28       | 4     | Float   | [2][0]        |
-+----------+-------+---------+---------------+
-| 32       | 4     | Float   | [2][1]        |
-+----------+-------+---------+---------------+
-| 36       | 4     | Float   | [2][2]        |
-+----------+-------+---------+---------------+
++----------+-------+---------+---------------------------------------------------------------+
+| Offset   | Len   | Type    | Description                                                   |
++==========+=======+=========+===============================================================+
+| 4        | 4     | Float   | The X component of the X column vector, accessed via [0][0]   |
++----------+-------+---------+---------------------------------------------------------------+
+| 8        | 4     | Float   | The Y component of the X column vector, accessed via [0][1]   |
++----------+-------+---------+---------------------------------------------------------------+
+| 12       | 4     | Float   | The Z component of the X column vector, accessed via [0][2]   |
++----------+-------+---------+---------------------------------------------------------------+
+| 16       | 4     | Float   | The X component of the Y column vector, accessed via [1][0]   |
++----------+-------+---------+---------------------------------------------------------------+
+| 20       | 4     | Float   | The Y component of the Y column vector, accessed via [1][1]   |
++----------+-------+---------+---------------------------------------------------------------+
+| 24       | 4     | Float   | The Z component of the Y column vector, accessed via [1][2]   |
++----------+-------+---------+---------------------------------------------------------------+
+| 28       | 4     | Float   | The X component of the Z column vector, accessed via [2][0]   |
++----------+-------+---------+---------------------------------------------------------------+
+| 32       | 4     | Float   | The Y component of the Z column vector, accessed via [2][1]   |
++----------+-------+---------+---------------------------------------------------------------+
+| 36       | 4     | Float   | The Z component of the Z column vector, accessed via [2][2]   |
++----------+-------+---------+---------------------------------------------------------------+
 
 
 13: :ref:`Transform<class_transform>`
 13: :ref:`Transform<class_transform>`
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 
-+----------+-------+---------+---------------+
-| Offset   | Len   | Type    | Description   |
-+==========+=======+=========+===============+
-| 4        | 4     | Float   | [0][0]        |
-+----------+-------+---------+---------------+
-| 8        | 4     | Float   | [0][1]        |
-+----------+-------+---------+---------------+
-| 12       | 4     | Float   | [0][2]        |
-+----------+-------+---------+---------------+
-| 16       | 4     | Float   | [1][0]        |
-+----------+-------+---------+---------------+
-| 20       | 4     | Float   | [1][1]        |
-+----------+-------+---------+---------------+
-| 24       | 4     | Float   | [1][2]        |
-+----------+-------+---------+---------------+
-| 28       | 4     | Float   | [2][0]        |
-+----------+-------+---------+---------------+
-| 32       | 4     | Float   | [2][1]        |
-+----------+-------+---------+---------------+
-| 36       | 4     | Float   | [2][2]        |
-+----------+-------+---------+---------------+
-| 40       | 4     | Float   | [3][0]        |
-+----------+-------+---------+---------------+
-| 44       | 4     | Float   | [3][1]        |
-+----------+-------+---------+---------------+
-| 48       | 4     | Float   | [3][2]        |
-+----------+-------+---------+---------------+
++----------+-------+---------+---------------------------------------------------------------+
+| Offset   | Len   | Type    | Description                                                   |
++==========+=======+=========+===============================================================+
+| 4        | 4     | Float   | The X component of the X column vector, accessed via [0][0]   |
++----------+-------+---------+---------------------------------------------------------------+
+| 8        | 4     | Float   | The Y component of the X column vector, accessed via [0][1]   |
++----------+-------+---------+---------------------------------------------------------------+
+| 12       | 4     | Float   | The Z component of the X column vector, accessed via [0][2]   |
++----------+-------+---------+---------------------------------------------------------------+
+| 16       | 4     | Float   | The X component of the Y column vector, accessed via [1][0]   |
++----------+-------+---------+---------------------------------------------------------------+
+| 20       | 4     | Float   | The Y component of the Y column vector, accessed via [1][1]   |
++----------+-------+---------+---------------------------------------------------------------+
+| 24       | 4     | Float   | The Z component of the Y column vector, accessed via [1][2]   |
++----------+-------+---------+---------------------------------------------------------------+
+| 28       | 4     | Float   | The X component of the Z column vector, accessed via [2][0]   |
++----------+-------+---------+---------------------------------------------------------------+
+| 32       | 4     | Float   | The Y component of the Z column vector, accessed via [2][1]   |
++----------+-------+---------+---------------------------------------------------------------+
+| 36       | 4     | Float   | The Z component of the Z column vector, accessed via [2][2]   |
++----------+-------+---------+---------------------------------------------------------------+
+| 40       | 4     | Float   | The X component of the origin vector, accessed via [3][0]     |
++----------+-------+---------+---------------------------------------------------------------+
+| 44       | 4     | Float   | The Y component of the origin vector, accessed via [3][1]     |
++----------+-------+---------+---------------------------------------------------------------+
+| 48       | 4     | Float   | The Z component of the origin vector, accessed via [3][2]     |
++----------+-------+---------+---------------------------------------------------------------+
 
 
 14: :ref:`Color<class_color>`
 14: :ref:`Color<class_color>`
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -408,7 +411,7 @@ The array data is padded to 4 bytes.
 +==================+=======+===========+===========================+
 +==================+=======+===========+===========================+
 | 4                | 4     |Integer    | Array Length (Floats)     |
 | 4                | 4     |Integer    | Array Length (Floats)     |
 +------------------+-------+-----------+---------------------------+
 +------------------+-------+-----------+---------------------------+
-| 8..8+length\*4   | 4     |Integer    | 32 Bits IEE 754 Float     |
+| 8..8+length\*4   | 4     |Integer    | 32 Bits IEEE 754 Float    |
 +------------------+-------+-----------+---------------------------+
 +------------------+-------+-----------+---------------------------+
 
 
 23: :ref:`PoolStringArray<class_poolstringarray>`
 23: :ref:`PoolStringArray<class_poolstringarray>`

+ 3 - 0
tutorials/misc/instancing_with_signals.rst

@@ -1,3 +1,6 @@
+.. meta::
+    :keywords: Signal
+
 .. _doc_instancing_with_signals:
 .. _doc_instancing_with_signals:
 
 
 Instancing with signals
 Instancing with signals

+ 3 - 3
tutorials/networking/high_level_multiplayer.rst

@@ -32,11 +32,11 @@ In summary, you can use the low-level networking API for maximum control and imp
           well as raw access to low-level protocols like TCP and UDP.
           well as raw access to low-level protocols like TCP and UDP.
 
 
 .. note:: More about TCP/IP, UDP, and networking:
 .. note:: More about TCP/IP, UDP, and networking:
-          https://web.archive.org/web/20190406162102/https://gafferongames.com/post/udp_vs_tcp/
+          https://gafferongames.com/post/udp_vs_tcp/
 
 
           Gaffer On Games has a lot of useful articles about networking in Games
           Gaffer On Games has a lot of useful articles about networking in Games
-          (`here <https://web.archive.org/web/20190405204744/https://gafferongames.com/tags/networking/>`__), including the comprehensive
-          `introduction to networking models in games <http://web.archive.org/web/20190407004521/https://gafferongames.com/post/what_every_programmer_needs_to_know_about_game_networking/>`__.
+          (`here <https://gafferongames.com/categories/game-networking/>`__), including the comprehensive
+          `introduction to networking models in games <https://gafferongames.com/post/what_every_programmer_needs_to_know_about_game_networking/>`__.
 
 
           If you want to use your low-level networking library of choice instead of Godot's built-in networking,
           If you want to use your low-level networking library of choice instead of Godot's built-in networking,
           see here for an example:
           see here for an example:

+ 1 - 1
tutorials/networking/http_client_class.rst

@@ -10,7 +10,7 @@ which has a tutorial available :ref:`here <doc_http_request_class>`.
 Here's an example of using the :ref:`HTTPClient <class_HTTPClient>`
 Here's an example of using the :ref:`HTTPClient <class_HTTPClient>`
 class. It's just a script, so it can be run by executing:
 class. It's just a script, so it can be run by executing:
 
 
-::
+.. code-block:: console
 
 
     c:\godot> godot -s http_test.gd
     c:\godot> godot -s http_test.gd
 
 

+ 1 - 1
tutorials/networking/ssl_certificates.rst

@@ -61,7 +61,7 @@ and it will work.
 If you are using Linux, you can use the supplied certs file, generally
 If you are using Linux, you can use the supplied certs file, generally
 located in:
 located in:
 
 
-::
+.. code-block:: none
 
 
     /etc/ssl/certs/ca-certificates.crt
     /etc/ssl/certs/ca-certificates.crt
 
 

+ 1 - 1
tutorials/physics/using_area_2d.rst

@@ -137,4 +137,4 @@ override.
 .. image:: img/area2d_override.gif
 .. image:: img/area2d_override.gif
 
 
 You can download this project here:
 You can download this project here:
-:download:`using_area_2d.zip <files/using_area_2d.zip>`
+:download:`using_area_2d.zip <files/using_area_2d.zip>`

+ 28 - 0
tutorials/physics/using_kinematic_body_2d.rst

@@ -100,6 +100,34 @@ body will remain attached to the surface. Note that this means you must disable
 snapping when jumping, for example. You can do this either by setting ``snap``
 snapping when jumping, for example. You can do this either by setting ``snap``
 to ``Vector2(0, 0)`` or by using ``move_and_slide()`` instead.
 to ``Vector2(0, 0)`` or by using ``move_and_slide()`` instead.
 
 
+
+Detecting collisions
+--------------------
+
+When using ``move_and_collide()`` the function returns a ``KinematicCollision2D``
+directly, and you can use this in your code.
+
+When using ``move_and_slide()`` it's possible to have multiple collisions occur,
+as the slide response is calculated. To process these collisions, use ``get_slide_count()``
+and ``get_slide_collision()``:
+
+.. tabs::
+ .. code-tab:: gdscript GDScript
+
+    # Using move_and_collide.
+    var collision = move_and_collide(velocity * delta)
+    if collision:
+        print("I collided with ", collision.collider.name)
+
+    # Using move_and_slide.
+    velocity = move_and_slide(velocity)
+    for i in get_slide_count():
+        var collision = get_slide_collision(i)
+        print("I collided with ", collision.collider.name)
+
+See :ref:`KinematicCollision2D <class_KinematicCollision2D>` for details on what
+collision data is returned.
+
 Which movement method to use?
 Which movement method to use?
 -----------------------------
 -----------------------------
 
 

+ 1 - 3
tutorials/platform/android_in_app_purchases.rst

@@ -3,8 +3,6 @@
 Android in-app purchases
 Android in-app purchases
 ========================
 ========================
 
 
-.. highlight:: shell
-
 Godot engine has integrated GooglePaymentsV3 module with which we can implement in-app purchases in our game.
 Godot engine has integrated GooglePaymentsV3 module with which we can implement in-app purchases in our game.
 
 
 The Godot engine demo project repository has an android-iap example project. It includes a gdscript interface for android IAP.
 The Godot engine demo project repository has an android-iap example project. It includes a gdscript interface for android IAP.
@@ -13,7 +11,7 @@ Check the repository here https://github.com/godotengine/godot-demo-projects
 
 
 Find the iap.gd script in
 Find the iap.gd script in
 
 
-::
+.. code-block:: none
 
 
     godot-demo-projects/misc/android_iap
     godot-demo-projects/misc/android_iap
 
 

+ 157 - 311
tutorials/platform/customizing_html5_shell.rst

@@ -1,355 +1,201 @@
 .. _doc_customizing_html5_shell:
 .. _doc_customizing_html5_shell:
 
 
-Customizing the Web export HTML page
+Custom HTML page for Web export
 ====================================
 ====================================
 
 
-Rather than the default HTML page that comes with the export templates, it is
-also possible to use a custom HTML page. This allows drastic customization of
-the final web presentation and behavior. The path to the custom HTML page is
-specified in the export options as ``Html/Custom Html Shell``.
+While Web export templates provide a default HTML page fully capable of launching
+the project without any further customization, it may be beneficial to create a custom
+HTML page. While the game itself cannot be directly controlled from the outside,
+such page allows to customize the initialization process for the engine.
 
 
-The default HTML page is available in the Godot Engine repository at
-`/misc/dist/html/full-size.html <https://github.com/godotengine/godot/blob/master/misc/dist/html/full-size.html>`__.
-Some simple use-cases where customizing the default page is useful include:
-
- - Loading files from a different directory
- - Loading a ``.zip`` file instead of a ``.pck`` file as main pack
- - Loading engine files from a different directory than the main pack file
- - Adding a click-to-play button so games can be started in full-screen mode
- - Loading some extra files before the engine starts, so they are available in
-   the file system later
- - Passing custom "command line" arguments, e.g. ``-s`` to start a MainLoop script
-
-Another sample HTML page is available at `/misc/dist/html/fixed-size.html <https://github.com/godotengine/godot/blob/master/misc/dist/html/fixed-size.html>`__.
-This page uses a fixed size canvas with an output widget below. However, the
-F12 browser console should be preferred as it can display additional
-information, such as WebGL errors.
-
-Placeholder substitution
-------------------------
-
-When exporting the game, several placeholders in the HTML page are replaced
-with values depending on the export:
-
-+------------------------------+-----------------------------------------------+
-| Placeholder                  | Substituted by                                |
-+==============================+===============================================+
-| ``$GODOT_BASENAME``          | Basename of exported files without suffixes,  |
-|                              | e.g. ``game`` when exporting ``game.html``    |
-+------------------------------+-----------------------------------------------+
-| ``$GODOT_DEBUG_ENABLED``     | ``true`` if debugging, ``false`` otherwise    |
-+------------------------------+-----------------------------------------------+
-| ``$GODOT_HEAD_INCLUDE``      | Custom string to include just before the end  |
-|                              | of the HTML ``<head>`` element                |
-+------------------------------+-----------------------------------------------+
-
-The HTML file must evaluate the JavaScript file ``$GODOT_BASENAME.js``. This
-file defines a global ``Engine`` object used to start the engine, :ref:`see
-below <doc_javascript_engine_object>` for details.
-
-The boot splash image is exported as ``$GODOT_BASENAME.png`` and can be used
-e.g. in ``<img />`` elements.
-
-``$GODOT_DEBUG_ENABLED`` can be useful to optionally display e.g. an output
-console or other debug tools.
-
-``$GODOT_HEAD_INCLUDE`` is replaced with the string specified by the export
-option ``Html/Head Include``.
-
-.. _doc_javascript_engine_object:
-
-The ``Engine`` object
----------------------
-
-The JavaScript global object ``Engine`` is defined by ``$GODOT_BASENAME.js``
-and serves as an interface to the engine start-up process.
-
-The API is based on and requires basic understanding of `Promises <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Using_promises>`__.
-
-The object itself has only the following methods:
-
-.. js:function:: Engine.load(basePath)
-
-    Load the engine from the passed base path.
-
-    :param string basePath: Base path of the engine to load.
-    :returns: Promise which resolves once the engine is loaded.
-
-.. js:function:: Engine.unload()
-
-    Unload the engine to free memory.
-
-    This is called automatically once the engine is started unless
-    explicitly disabled using :js:func:`engine.setUnloadAfterInit`.
-
-.. js:function:: Engine.isWebGLAvailable([majorVersion = 1])
-
-    Check whether WebGL is available.
-
-    :param number majorVersion:
-        The major WebGL version to check for. Defaults to 1 for *WebGL 1.0*.
+Some use-cases where customizing the default page is useful include:
 
 
-    :returns:
-        ``true`` if the given major version of WebGL is available, ``false``
-        otherwise.
+- Loading files from a different directory than the page;
+- Loading a ``.zip`` file instead of a ``.pck`` file as the main pack;
+- Loading the engine from a different directory than the main pack file;
+- Adding a click-to-play button so that games can be started in the fullscreen mode;
+- Loading some extra files before the engine starts, making them available in
+  the project file system as soon as possible;
+- Passing custom command line arguments, e.g. ``-s`` to start a ``MainLoop`` script.
 
 
-.. js:function:: Engine.setWebAssemblyFilenameExtension(extension)
-
-    When loading the engine, the filename extension of the WebAssembly module
-    is assumed to be ``wasm``. This function allows usage of an alternate
-    extension.
-
-    .. code-block:: js
-
-        Engine.setWebAssemblyFilenameExtension('dat');
-        // Load 'mygame.dat' as WebAssembly module.
-        Engine.load('mygame');
-
-    This is useful for outdated hosts that only accept uploads of files with
-    certain filename extensions.
-
-    :param string extension:
-        Filename extension without preceding dot.
-
-    .. Note::
-     Depending on the host, using an alternate filename extension can prevent
-     some start-up optimizations. This occurs when the file is delivered with a
-     MIME-type other than :mimetype:`application/wasm`.
-
-Starting an ``Engine`` instance
--------------------------------
-
-:js:class:`Engine` also acts a class:
-
-.. js:class:: Engine
-
-    An instance of the engine that can be started, usually a game.
-
-Instantiate the class using the ``new`` operator:
+The default HTML page is available in the Godot Engine repository at
+`/misc/dist/html/full-size.html <https://github.com/godotengine/godot/blob/master/misc/dist/html/full-size.html>`__
+and can be used as a reference implementation. Another sample HTML page is available at 
+`/misc/dist/html/fixed-size.html <https://github.com/godotengine/godot/blob/master/misc/dist/html/fixed-size.html>`__.
+It differs from the default one by having a fixed size canvas area and an output widget below it.
+
+.. note:: It is recommended to use developer tools provided by browser vendors to debug 
+          exported projects. Output generated by the engine may be limited and does not 
+          include WebGL errors.
+
+Setup
+-----
+As evident by the default HTML page, it is mostly a regular HTML document. To work with 
+Godot projects it needs to be fully realized, to have a control code that calls 
+the :js:class:`Engine` class, and to provide places for several placeholders, which are 
+replaced with their actual values during export.
+
+.. image:: img/html5_export_options.png
+
+- ``$GODOT_BASENAME``:
+  The base name from the *Export Path*, as set up in the export options; suffixes are omitted 
+  (e.g. ``game.html`` becomes ``game``). This variable can be used to generate a path 
+  to the main JavaScript file ``$GODOT_BASENAME.js``, which provides the :js:class:`Engine` 
+  class. A splash image shown during the booting process can be accessed using this variable 
+  as well: ``$GODOT_BASENAME.png``.
+
+- ``$GODOT_HEAD_INCLUDE``:
+  A custom string to include in the HTML document just before the end of the ``<head>`` tag. It 
+  is customized in the export options under the *Html / Head Include* section. While you fully 
+  control the HTML page you create, this variable can be useful for configuring parts of the 
+  HTML ``head`` element from the Godot Editor, e.g. for different Web export presets.
+
+- ``$GODOT_DEBUG_ENABLED``:
+  A flag that tells if this is a debug build, or not. This variable is substituted by strings
+  ``true`` and ``false``, and can be used to disable debug branches within your control code.
+
+When the custom page is ready, it can be selected in the export options under the *Html / Custom Html Shell* 
+section.
+
+Starting the project
+--------------------
+To be able to start the game, you need to write a script that initializes the engine — the control 
+code. This process consists of three steps, though some of them can be skipped and left for 
+a default behavior.
+
+First, the engine must be loaded, then it needs to be initialized, and after this the project 
+can finally be started. You can perform every of these steps manually and with great control. 
+However, in the simplest case all you need to do is to create an instance of the :js:class:`Engine` 
+class and then call the :js:meth:`engine.startGame` method.
 
 
 .. code-block:: js
 .. code-block:: js
 
 
-    var engine = new Engine();
-
-This yields an :js:class:`Engine` instance, referred to as ``engine`` with a
-lower-case ``e`` from here.
-
-To start such an instance, the global ``Engine`` object must be loaded,
-then the ``engine`` instance must be initialized and finally started.
-
-.. js:function:: engine.init([basePath])
-
-    Initialize the instance. The instance can then be started with one of the
-    ``start`` functions, usually :js:func:`engine.startGame`.
-
-    :param string basePath:
-        The base path to the engine, same as in :js:func:`Engine.load`.
-        Must be passed only if the engine hasn't been loaded yet.
-
-    :returns: Promise that resolves once the engine is loaded and initialized.
-
-.. js:function:: engine.preloadFile(file[, path])
-
-    Load a file so it is available in the file system once the instance runs. Must
-    be called **before** starting the instance.
-
-    :param file:
-        If type is string, the file will be loaded from that path.
-
-        If type is ``ArrayBuffer`` or a view on one, the buffer will used as
-        the content of the file.
+    const execName = "path://to/executable"
+    const mainPack = "path://to/main_pack"
 
 
-    :param string path:
-        Path by which the file will be available. Mandatory if ``file`` is not
-        a string. If not passed, the path is derived from the URL of the loaded
-        file.
+    const engine = new Engine();
+    engine.startGame(execName, mainPack)
 
 
-    :returns: Promise that resolves once the file is preloaded.
+This snippet of code automatically loads and initializes the engine before starting the game. 
+It uses the given path to the executable to deduce the path to load the engine. The :js:meth:`engine.startGame` 
+method is asynchronous and returns a ``Promise``. This allows your control code to track if 
+the game was loaded correctly without blocking execution or relying on polling.
 
 
-.. js:function:: engine.start([arg1, arg2, …])
+In case your project needs to have special arguments passed to it by the start-up script, 
+:js:meth:`engine.startGame` can be replaced by :js:meth:`engine.start`. This method takes an 
+arbitrary list of string arguments. As it does not have a defined list of arguments, :js:meth:`engine.start` 
+cannot automatically load the engine.
 
 
-    Starts the instance of the engine, using the passed strings as
-    command line arguments. This allows great control over how the engine is
-    started, but usually the other methods starting with ``engine.start`` are
-    simpler and should be used instead.
+To load the engine manually the :js:meth:`Engine.load` static method must be called. As 
+this method is static, multiple engine instances can be spawned with the exact same ``basePath``. 
+If an instance requires a different ``basePath``, you can call the :js:meth:`engine.init`
+method with that path before starting the game.
 
 
-    If the instance has not yet been initialized with :js:func:`engine.init`,
-    it will be.
+.. note:: Multiple instances cannot be spawned by default, as the engine is immediately unloaded after it is initialized.
+          To prevent this from happening the :js:meth:`engine.setUnloadAfterInit` method can be called. It is still possible 
+          to unload the engine manually afterwards by calling the :js:meth:`Engine.unload` static method. Unloading the engine 
+          frees browser memory by unloading files that are no longer needed once the instance is initialized.
 
 
-    The engine must be loaded beforehand.
+To correctly load the engine on some hosting providers and network configurations you may 
+need to change the default filename extension by using :js:meth:`Engine.setWebAssemblyFilenameExtension`. 
+By default, the extension is assumed to be ``wasm``. If your hosting provider blocks this 
+extension, this static method can be used to change it to something that is supported.
 
 
-    Requires that the engine has been loaded, and that a canvas can be found on
-    the page.
-
-    :param string variadic: Command line arguments.
-
-    :returns: Promise that resolves once the engine started.
-
-.. js:function:: engine.startGame(execName, mainPack)
-
-    Initializes the engine if not yet initialized, loads the executable, 
-    and starts the game with the main pack loaded from the passed URL.
-
-    If the engine isn't loaded yet, the base path of the passed executable name 
-    will be used to load the engine.
-
-    :param string execName:
-        Executable's name (URL) to start. Also used as base path to load the
-        engine if not loaded already. Should not contain the file's extension.
-
-    :param string mainPack:
-        Path (URL) to the main pack to start.
-
-    :returns: Promise that resolves once the game started.
-
-Configuring start-up behaviour
-------------------------------
-
-Beside starting the engine, other methods of the engine instance allow
-configuring the behavior:
-
-.. js:function:: engine.setUnloadAfterInit(enabled)
-
-    Specify whether the Engine will be unloaded automatically after the
-    instance is initialized.
-
-    This frees browser memory by unloading files that are no longer needed once
-    the instance is initialized. However, if more instances of the engine will
-    be started, the Engine will have to be loaded again.
-
-    Enabled by default.
-
-    :param boolean enabled:
-        ``true`` if the engine shall be unloaded after initializing,
-        ``false`` otherwise.
-
-.. js:function:: engine.setCanvas(canvasElem)
-
-    Specify a canvas to use.
-
-    By default, the first canvas element on the page is used for rendering.
-
-    :param HTMLCanvasElement canvasElem: The canvas to use.
-
-.. js:function:: engine.setCanvasResizedOnStart(enabled)
-
-    Specifies whether the canvas will be resized to the width and height
-    specified in the project settings on start.
-
-    Enabled by default.
-
-    :param boolean enabled:
-        ``true`` if the canvas shall be resized on start, ``false`` otherwise.
-
-.. js:function:: engine.setLocale(locale)
-
-    By default, the engine will try to guess the locale to use from the
-    JavaScript environment. It is usually preferable to use a server-side
-    user-specified locale, or at least use the locale requested in the HTTP
-    ``Accept-Language`` header. This method allows specifying such a custom
-    locale string.
-
-    For example, with PHP:
-
-    .. code-block:: php
-
-        engine.setLocale(<?php echo Locale::acceptFromHttp($_SERVER['HTTP_ACCEPT_LANGUAGE']); ?>);
-
-    :param string locale:
-        Locale.
-
-    .. seealso:: List of :ref:`locales <doc_locales>`.
+.. code-block:: js
 
 
-.. js:function:: engine.setExecutableName(execName)
+    Engine.setWebAssemblyFilenameExtension("dat");
+    // Load mygame.dat as WebAssembly module.
+    Engine.load("mygame");
 
 
-    Specify the virtual filename of the executable.
+.. warning:: If a different filename extension is used, some web servers may automatically 
+             set the MIME-type of the file to something other than :mimetype:`application/wasm`. 
+             In that case some start-up optimizations may be skipped.
 
 
-    A real executable file doesn't exist for the HTML5 platform. However,
-    a virtual filename is stored by the engine for compatibility with other
-    platforms.
+Customizing the behavior
+------------------------
+In the Web environment several methods can be used to guarantee that the game will work as intended.
 
 
-    By default, the base name of the loaded engine files is used.
-    This method allows specifying another name.
+If you target a specific version of WebGL, or just want to check if WebGL is available at all, 
+you can call the :js:meth:`Engine.isWebGLAvailable` method. It optionally takes an argument that 
+allows to test for a specific major version of WebGL.
 
 
-    This affects the output of :ref:`OS.get_executable_path() <class_OS_method_get_executable_path>`
-    and the automatically started main pack, :file:`{ExecutableName}.pck`.
+As the real executable file does not exist in the Web environment, the engine only stores a virtual 
+filename formed from the base name of loaded engine files. This value affects the output of the 
+:ref:`OS.get_executable_path() <class_OS_method_get_executable_path>` method and defines the name of 
+the automatically started main pack. The :js:meth:`engine.setExecutableName` method can be used
+to override this value.
 
 
-    :param string execName: Executable name.
+If your project requires some files to be available the moment it is loaded, you can preload
+them by calling the :js:meth:`engine.preloadFile` method with a path to a file or by providing it 
+with an ``ArrayBuffer`` object. In case of the ``ArrayBuffer``, or one of its views, a second argument 
+must be specified to define an internal path for the loaded resource.
 
 
 Customizing the presentation
 Customizing the presentation
 ----------------------------
 ----------------------------
+Several methods can be used to further customize the look and behavior of the game on your page.
 
 
-The following methods are used to implement the presentation:
-
-.. js:function:: engine.setProgressFunc(callback)
+By default, the first canvas element on the page is used for rendering. To use a different canvas 
+element the :js:meth:`engine.setCanvas` method can be used. It requires a reference to the DOM 
+element itself.
 
 
-    Set the callback for displaying download progress.
-
-    :param function callback:
-        Callback called once per frame with two number arguments:
-        bytes loaded so far, and total bytes to load.
-
-    .. code-block:: js
-
-        function printProgress(current, total) {
-            console.log("Loaded " + current + " of " + total + " bytes");
-        }
-        engine.setProgressFunc(printProgress);
-
-    If the total is 0, it couldn't be calculated. Possible reasons
-    include:
-
-     -  Files are delivered with server-side chunked compression
-     -  Files are delivered with server-side compression on Chromium
-     -  Not all file downloads have started yet (usually on servers without
-        multi-threading)
-
-    .. Note::
-     For ease of use, the callback is only called once per frame, so that usage
-     of ``requestAnimationFrame()`` is not necessary.
+.. code-block:: js
 
 
-.. js:function:: engine.setStdoutFunc(callback)
+    const canvasElement = document.querySelector("#my-canvas-element");
+    engine.setCanvas(canvasElement);
 
 
-    Specify the standard output stream callback.
+If the width and height of this canvas element differ from values set in the project settings, it 
+will be resized on the project start. This behavior can be disabled by calling the :js:meth:`engine.setCanvasResizedOnStart` 
+method.
 
 
-    :param function callback:
-        Callback function called with one argument, the string to print.
+If your game takes some time to load, it may be useful to display a custom loading UI which tracks
+the progress. This can be achieved with the :js:meth:`engine.setProgressFunc` method which allows 
+to set up a callback function to be called regularly as the engine loads new bytes.
 
 
-    .. code-block:: js
+.. code-block:: js
 
 
-        function printStdout(text) {
-            console.log(text);
-        }
-        engine.setStdoutFunc(printStdout);
+    function printProgress(current, total) {
+        console.log("Loaded " + current + " of " + total + " bytes");
+    }
+    engine.setProgressFunc(printProgress);
 
 
-    This method should usually only be used in debug pages. The
-    ``$GODOT_DEBUG_ENABLED`` placeholder can be used to check for this.
+Be aware that in some cases ``total`` can be ``0``. This means that it cannot be calculated.
 
 
-    By default, ``console.log()`` is used.
+If your game supports multiple languages, the :js:meth:`engine.setLocale` method can be used to set 
+a specific locale, provided you have a valid language code string. It may be good to use server-side 
+logic to determine which languages a user may prefer. This way the language code can be taken from the 
+``Accept-Language`` HTTP header, or determined by a GeoIP service.
 
 
-.. js:function:: engine.setStderrFunc(callback)
+Debugging
+---------
+To debug exported projects, it may be useful to read the standard output and error streams generated 
+by the engine. This is similar to the output shown in the editor console window. By default, standard 
+``console.log`` and ``console.warn`` are used for the output and error streams respectively. This 
+behavior can be customized by setting your own functions to handle messages.
 
 
-    Specify the standard error stream callback.
+Use the :js:meth:`engine.setStdoutFunc` method to set a callback function for the output stream. Default 
+behavior is similar to this:
 
 
-    :param function callback:
-        Callback function called with one argument, the string to print.
+.. code-block:: js
 
 
-    .. code-block:: js
+    function printStdout(text) {
+        console.log(text);
+    }
+    engine.setStdoutFunc(printStdout);
 
 
-        function printStderr(text) {
-            console.warn("Error: " + text);
-        }
-        engine.setStderrFunc(printStderr);
+Use the :js:meth:`engine.setStderrFunc` method to set a callback function for the error stream. Default 
+behavior is similar to this:
 
 
-    This method should usually only be used in debug pages. The
-    ``$GODOT_DEBUG_ENABLED`` placeholder can be used to check for this.
+.. code-block:: js
 
 
-    By default, ``console.warn()`` is used.
+    function printStderr(text) {
+        console.warn("Error: " + text);
+    }
+    engine.setStderrFunc(printStderr);
 
 
-Accessing the Emscripten ``Module``
------------------------------------
+When handling the engine output keep in mind, that it may not be desirable to print it out in the 
+finished product. To control whether or not the current execution is actually a debug build you can 
+use ``$GODOT_DEBUG_ENABLED`` placeholder.
 
 
-If you know what you're doing, you can access the runtime environment
-(Emscripten's ``Module``) as ``engine.rtenv``. Check the official Emscripten
-documentation for information on how to use it:
-https://kripken.github.io/emscripten-site/docs/api_reference/module.html
+Further debugging options and a low level access to the execution environment are available in a form 
+of Emscripten's ``Module`` object. It can be accessed using the :js:attr:`engine.rtenv` property on the 
+engine instance.

+ 266 - 0
tutorials/platform/html5_shell_classref.rst

@@ -0,0 +1,266 @@
+.. _doc_html5_shell_classref:
+
+HTML5 shell class reference
+===========================
+
+Projects exported for the Web expose the ``Engine`` class to the JavaScript environment, that allows 
+fine control over the engine's start-up process.
+
+This API is built in an asynchronous manner and requires basic understanding 
+of `Promises <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Using_promises>`__.
+
+Engine
+------
+
+The ``Engine`` class provides methods for loading and starting exported projects on the Web. For default export
+settings, this is already part of the exported HTML page. To understand practical use of the ``Engine`` class, 
+see :ref:`Custom HTML page for Web export <doc_customizing_html5_shell>`.
+
+Static Methods
+^^^^^^^^^^^^^^
+
++---------+-------------------------------------------------------------------------------------------------------------------+
+| Promise | `Engine.load <#Engine.load>`__ **(** string basePath **)**                                                        |
++---------+-------------------------------------------------------------------------------------------------------------------+
+| void    | `Engine.unload <#Engine.unload>`__ **(** **)**                                                                    |
++---------+-------------------------------------------------------------------------------------------------------------------+
+| boolean | `Engine.isWebGLAvailable <#Engine.isWebGLAvailable>`__ **(** *[ number majorVersion=1 ]* **)**                    |
++---------+-------------------------------------------------------------------------------------------------------------------+
+| void    | `Engine.setWebAssemblyFilenameExtension <#Engine.setWebAssemblyFilenameExtension>`__ **(** string extension **)** |
++---------+-------------------------------------------------------------------------------------------------------------------+
+
+Instance Properties
+^^^^^^^^^^^^^^^^^^^
+
++-----------------------+----------------------------------+
+| Emscripten ``Module`` | `engine.rtenv <#engine.rtenv>`__ |
++-----------------------+----------------------------------+
+
+Instance Methods
+^^^^^^^^^^^^^^^^
+
++---------+------------------------------------------------------------------------------------------------------+
+| Engine  | `Engine <#Engine>`__ **(** **)**                                                                     |
++---------+------------------------------------------------------------------------------------------------------+
+| Promise | `engine.init <#engine.init>`__ **(** *[ string basePath ]* **)**                                     |
++---------+------------------------------------------------------------------------------------------------------+
+| Promise | `engine.preloadFile <#engine.preloadFile>`__ **(** string\|ArrayBuffer file *[, string path ]* **)** |
++---------+------------------------------------------------------------------------------------------------------+
+| Promise | `engine.start <#engine.start>`__ **(** *[ string arg1, string arg2, … ]* **)**                       |
++---------+------------------------------------------------------------------------------------------------------+
+| Promise | `engine.startGame <#engine.startGame>`__ **(** string execName, string mainPack **)**                |
++---------+------------------------------------------------------------------------------------------------------+
+| void    | `engine.setUnloadAfterInit <#engine.setUnloadAfterInit>`__ **(** boolean enabled **)**               |
++---------+------------------------------------------------------------------------------------------------------+
+| void    | `engine.setCanvas <#engine.setCanvas>`__ **(** HTMLCanvasElement canvasElem **)**                    |
++---------+------------------------------------------------------------------------------------------------------+
+| void    | `engine.setCanvasResizedOnStart <#engine.setCanvasResizedOnStart>`__ **(** boolean enabled **)**     |
++---------+------------------------------------------------------------------------------------------------------+
+| void    | `engine.setLocale <#engine.setLocale>`__ **(** string locale **)**                                   |
++---------+------------------------------------------------------------------------------------------------------+
+| void    | `engine.setExecutableName <#engine.setExecutableName>`__ **(** string execName **)**                 |
++---------+------------------------------------------------------------------------------------------------------+
+| void    | `engine.setProgressFunc <#engine.setProgressFunc>`__ **(** function callback **)**                   |
++---------+------------------------------------------------------------------------------------------------------+
+| void    | `engine.setStdoutFunc <#engine.setStdoutFunc>`__ **(** function callback **)**                       |
++---------+------------------------------------------------------------------------------------------------------+
+| void    | `engine.setStderrFunc <#engine.setStderrFunc>`__ **(** function callback **)**                       |
++---------+------------------------------------------------------------------------------------------------------+
+
+
+Static Method Descriptions
+^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+.. js:method:: Engine.load(basePath)
+
+    Load the engine from the specified base path.
+
+    :param string basePath:
+        Base path of the engine to load.
+    :returns:
+        Promise which resolves once the engine is loaded.
+
+.. js:method:: Engine.unload()
+
+    Unload the engine to free memory.
+
+    This method is called automatically once the engine is started unless
+    explicitly disabled using :js:meth:`engine.setUnloadAfterInit`.
+
+.. js:method:: Engine.isWebGLAvailable([majorVersion = 1])
+
+    Check whether WebGL is available. Optionally, specify a particular version of WebGL to check for.
+
+    :param number majorVersion:
+        The major WebGL version to check for. Defaults to ``1`` for *WebGL 1.0*.
+    :returns:
+        ``true`` if the given major version of WebGL is available, ``false``
+        otherwise.
+
+.. js:method:: Engine.setWebAssemblyFilenameExtension(extension)
+
+    Set an alternative filename extension for the WebAssembly module. By default 
+    it is assumed to be ``wasm``.
+
+    :param string extension:
+        Filename extension without preceding dot.
+
+
+Instance Property Descriptions
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+.. js:attribute:: engine.rtenv
+
+    The runtime environment provided by Emscripten's ``Module``. For more information
+    refer to the `official documentation <https://emscripten.org/docs/api_reference/module.html>`__ on Emscripten.
+    
+Instance Method Descriptions
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+.. js:class:: Engine
+
+    Create a new instance of the ``Engine`` class.
+
+.. js:method:: engine.init([basePath])
+
+    Initialize the engine instance. Optionally, pass the base path to the engine to load it,
+    if it hasn't been loaded yet. See :js:meth:`Engine.load`.
+
+    :param string basePath:
+        Base path of the engine to load.
+
+    :returns:
+        Promise that resolves once the engine is loaded and initialized.
+
+.. js:method:: engine.preloadFile(file[, path])
+
+    Load a file so it is available in the instance's file system once it runs. Must
+    be called **before** starting the instance.
+
+    :param string|ArrayBuffer file:
+        If type is ``string``, the file will be loaded from that path.
+
+        If type is ``ArrayBuffer`` or a view on one, the buffer will used as
+        the content of the file.
+
+    :param string path:
+        Path by which the file will be accessible. Required, if ``file`` is not
+        a string. If not passed, the path is derived from the URL of the loaded
+        file.
+
+    :returns:
+        Promise that resolves once the file is loaded.
+
+.. js:method:: engine.start([arg1, arg2, …])
+
+    Start the instance of the engine, using the passed strings as
+    command line arguments. :js:meth:`engine.startGame` can be used 
+    in typical cases instead.
+    
+    This will initialize the instance if it is not initialized. For manual 
+    initialization, see :js:meth:`engine.init`. The engine must be loaded beforehand.
+
+    Fails if a canvas cannot be found on the page.
+
+    :param string variadic:
+        Command line argument.
+
+    :returns:
+        Promise that resolves once the engine started.
+
+.. js:method:: engine.startGame(execName, mainPack)
+
+    Start the game instance using the given executable URL and main pack URL.
+
+    This will initialize the instance if it is not initialized. For manual 
+    initialization, see :js:meth:`engine.init`.
+
+    This will load the engine if it is not loaded. The base path of the 
+    executable URL will be used as the engine base path.
+
+    :param string execName:
+        Executable name in a form of URL, omitting filename extension.
+
+    :param string mainPack:
+        URL of the main pack to start the game.
+
+    :returns:
+        Promise that resolves once the game started.
+
+.. js:method:: engine.setUnloadAfterInit(enabled)
+
+    Specify whether the engine will be unloaded automatically after the
+    instance is initialized. Enabled by default.
+
+    :param boolean enabled:
+        ``true`` if the engine shall be unloaded after initializing,
+        ``false`` otherwise.
+
+.. js:method:: engine.setCanvas(canvasElem)
+
+    Specify a canvas HTML element to use. By default, the first canvas element
+    on the page is used for rendering.
+
+    :param HTMLCanvasElement canvasElem:
+        The canvas element to use.
+
+.. js:method:: engine.setCanvasResizedOnStart(enabled)
+
+    Specifies whether the canvas will be resized to the width and height
+    specified in the project settings on start. Enabled by default.
+
+    :param boolean enabled:
+        ``true`` if the canvas shall be resized on start, ``false`` otherwise.
+
+.. js:method:: engine.setLocale(locale)
+
+    Specify a language code to select the proper localization for the game.
+    
+    .. seealso:: Complete list of :ref:`supported locales <doc_locales>`.
+
+    :param string locale:
+        Language code.
+
+.. js:method:: engine.setExecutableName(execName)
+
+    Specify the virtual filename of the executable. By default, the base name 
+    of the loaded engine files is used.
+
+    This affects the output of :ref:`OS.get_executable_path() <class_OS_method_get_executable_path>`
+    and sets the automatically started main pack to :file:`{ExecutableName}.pck`.
+
+    :param string execName:
+        Executable name.
+
+.. js:method:: engine.setProgressFunc(callback)
+
+    Specify a callback function for displaying download progress. The callback function is
+    called once per frame, so that the usage of ``requestAnimationFrame()`` is not necessary.
+
+    If the callback function receives a total amount of bytes as 0, this means that
+    it is impossible to calculate. Possible reasons include:
+
+     -  Files are delivered with server-side chunked compression
+     -  Files are delivered with server-side compression on Chromium
+     -  Not all file downloads have started yet (usually on servers without
+        multi-threading)
+
+    :param function callback:
+        The callback function must accept two numeric arguments: the amount of bytes 
+        loaded so far, and the total number of bytes to load.
+
+.. js:method:: engine.setStdoutFunc(callback)
+
+    Specify a callback function for handling the standard output stream. This method 
+    should usually only be used in debug pages. By default, ``console.log()`` is used.
+
+    :param function callback:
+        The callback function must accept one string argument: the message to print.
+
+.. js:method:: engine.setStderrFunc(callback)
+
+    Specify a callback function for handling the standard error stream. This method 
+    should usually only be used in debug pages. By default, ``console.warn()`` is used.
+
+    :param function callback:
+        The callback function must accept one string argument: the message to print.

BIN
tutorials/platform/img/html5_export_options.png


+ 1 - 1
tutorials/platform/index.rst

@@ -7,5 +7,5 @@ Platform-specific
 
 
    android_in_app_purchases
    android_in_app_purchases
    services_for_ios
    services_for_ios
-   customizing_html5_shell
+   platform_html5
    consoles
    consoles

+ 11 - 0
tutorials/platform/platform_html5.rst

@@ -0,0 +1,11 @@
+.. _doc_platform_html5:
+
+HTML5
+=====
+
+.. toctree::
+   :maxdepth: 1
+   :name: toc-learn-features-platform-html5
+
+   html5_shell_classref
+   customizing_html5_shell

+ 2 - 2
tutorials/platform/services_for_ios.rst

@@ -25,7 +25,7 @@ locally (no internet connection, API incorrectly configured, etc). If
 the error value is 'OK', a response event will be produced and added to
 the error value is 'OK', a response event will be produced and added to
 the 'pending events' queue. Example:
 the 'pending events' queue. Example:
 
 
-.. code-block:: python
+::
 
 
     func on_purchase_pressed():
     func on_purchase_pressed():
         var result = InAppStore.purchase( { "product_id": "my_product" } )
         var result = InAppStore.purchase( { "product_id": "my_product" } )
@@ -428,7 +428,7 @@ you need inside a conditional block, you need to also define them as
 valid identifiers (local variable or class member). This is an example
 valid identifiers (local variable or class member). This is an example
 of how to work around this in a class:
 of how to work around this in a class:
 
 
-.. code-block:: python
+::
 
 
     var GameCenter = null # define it as a class member
     var GameCenter = null # define it as a class member
 
 

+ 93 - 201
tutorials/plugins/editor/making_main_screen_plugins.rst

@@ -7,280 +7,172 @@ What this tutorial covers
 -------------------------
 -------------------------
 
 
 As seen in the :ref:`doc_making_plugins` page, making a basic plugin that
 As seen in the :ref:`doc_making_plugins` page, making a basic plugin that
-extends the editor is fairly easy. This plugin mechanism also allows you to
-create new UIs in the central part of the editor, similarly to the basic 2D, 3D,
-Script and AssetLib views. Such editor plugins are referred as "Main screen
-plugins".
+extends the editor is fairly easy. Main screen plugins allow you to create
+new UIs in the central part of the editor, which appear next to the
+"2D", "3D", "Script", and "AssetLib" buttons. Such editor plugins are
+referred as "Main screen plugins".
 
 
-This tutorial leads you through the creation of a basic main screen plugin. With 
-this plugin example, we want to demonstrate:
-
-- Creating a main screen plugin
-- Linking the main screen to another plugin GUI element (such as a Tab panel,
-  similar to the Inspector tab)
-
-For the sake of simplicity, the two GUI elements of our main screen plugin will
-both consist in a Label and a Button. Pressing one element's button will display
-some text on the other's label node.
+This tutorial leads you through the creation of a basic main screen plugin.
+For the sake of simplicity, our main screen plugin will contain a single
+button that prints text to the console.
 
 
 Initializing the plugin
 Initializing the plugin
 -----------------------
 -----------------------
 
 
-The plugin itself is a Godot project. It is best to set its contents in an
-``addons/my_plugin_name/`` structure. The only files that lie in the root folder
-are the project.godot file, and the project icon.
+First create a new plugin from the Plugins menu. For this tutorial, we'll put
+it in a folder called ``main_screen``, but you can use any name you'd like.
 
 
-In the ``addons/my_plugin_name/`` folder, we create the ``plugin.cfg`` file as
-described in the :ref:`doc_making_plugins` page.
-
-::
-
-    [plugin]
-    name="Main screen plugin demo"
-    description="A plugin that adds a main screen panel and a side-panel which communicate with each other."
-    author="Your Name Here"
-    version="1.0.0"
-    script="main_screen_plugin.gd"
-
-We also initialize the file targeted by the ``script=`` property of the ``.cfg``
-file. In our example, ``main_screen_plugin.gd``.
+The plugin script will come with ``_enter_tree()`` and ``_exit_tree()``
+methods, but for a main screen plugin we need to add a few extra methods.
+Add five extra methods such that the script looks like this:
 
 
 ::
 ::
 
 
     tool
     tool
     extends EditorPlugin
     extends EditorPlugin
 
 
+
     func _enter_tree():
     func _enter_tree():
-       pass
+        pass
 
 
 
 
     func _exit_tree():
     func _exit_tree():
-       pass
+        pass
 
 
 
 
     func has_main_screen():
     func has_main_screen():
-       return true
+        return true
 
 
 
 
     func make_visible(visible):
     func make_visible(visible):
-       pass
+        pass
 
 
 
 
     func get_plugin_name():
     func get_plugin_name():
-       return "Main Screen Plugin"
+        return "Main Screen Plugin"
 
 
 
 
     func get_plugin_icon():
     func get_plugin_icon():
-       return get_editor_interface().get_base_control().get_icon("Node", "EditorIcons")
-
-The important part in this script is the ``has_main_screen()`` function, which is
-overloaded so it returns ``true``. This function is automatically called by the
-editor on plugin activation, to tell it that this plugin adds a new center view to
-the editor. For now, we'll leave this script as-is and we'll come back to it
-later.
-
-Scenes
-------
-
-The ``main_screen_plugin.gd`` file will be responsible for each of our plugin's
-UI element instantiation, and it will also manage the communication between them.
-
-As a matter of fact, we wish to design each UI element in their own scene.
-Different scenes are not aware of each other unless they are both children of a
-parent scene, yet they will then require ``get_node("../sibling")`` accessors.
-Such practice is more likely to produce errors at runtime, especially if these
-scenes do not share the same parent node. This is why, they should only be
-allowed to access their children.
-
-So, in order to communicate information to another scene, the best design is to
-define signals. If a user action in a UI scene #1 has to trigger something in
-another UI scene #2, then this user action has to emit a signal from scene #1,
-and scene #2 will be connected to that signal. Since all of our UI scenes will
-be instanced by ``main_screen_plugin.gd`` script, this one script will also
-connect each of them to the required signals.
-
-.. note:: If the ``main_screen_plugin.gd`` instantiates the UI scenes, won't
-          they be sibling nodes then?
-
-Not necessarily: this script may add all UI scenes as children of the same node
-of the editor's scene tree - but maybe it won't. And the ``main_screen_plugin.gd``
-script will *not* be the parent node of any instantiated scene because it is a
-script, not a node! This script will only hold references to instantiated
-scenes.
+        return get_editor_interface().get_base_control().get_icon("Node", "EditorIcons")
+
+The important part in this script is the ``has_main_screen()`` function,
+which is overloaded so it returns ``true``. This function is automatically
+called by the editor on plugin activation, to tell it that this plugin
+adds a new center view to the editor. For now, we'll leave this script
+as-is and we'll come back to it later.
 
 
 Main screen scene
 Main screen scene
 -----------------
 -----------------
 
 
-Create a new scene with a ``Panel`` root node. Select this root node,
-and in the viewport, click the ``Layout`` menu and select ``Full Rect``.
-You also need to enable the ``Expand`` vertical size flag in the inspector.
-The panel now uses all the space available in the viewport.
-Now, let's add a new script on the root node. Name it ``main_panel.gd``.
-
-We then add 2 children to this Panel node: first a ``Button`` node. Place it
-anywhere on the Panel. Then add a ``Label`` node.
-
-Now we need to define a behaviour when this button is pressed. This is covered
-by the :ref:`Handling a signal <doc_scripting_handling_a_signal>` page, so this
-part will not be described in details in this tutorial.
-Select the Button node and click the ``Node`` side dock.
-Select the ``pressed()`` signal and click the ``Connect`` button (you can also
-double-click the ``pressed()`` signal instead). In the window that opened,
-select the Panel node (we will centralize all behaviors in its attached
-script). Keep the default function name, make sure that the ``Make function``
-toggle is ON and hit ``Connect``. This creates an ``_on_Button_pressed()``
-function in the ``main_panel.gd`` script, that will be called every time the
-button is pressed.
-
-As the button gets pressed, we want the side-panel's ``Label`` node to show a
-specific text. As explained above, we cannot directly access the target scene,
-so we'll emit a signal instead. The ``main_screen_plugin.gd`` script will then
-connect this signal to the target scene. Let's continue in the ``main_panel.gd``
-script:
-
-::
-
-    tool
-    extends Panel
-
-    signal main_button_pressed(value)
-
-    func _on_Button_pressed():
-       emit_signal("main_button_pressed", "Hello from main screen!")
-
-In the same way, this main scene's Label node has to show a value when it
-receives a specific signal. Let's create a new
-``_on_side_button_pressed(text_to_show)`` function for this purpose:
-
-::
-
-    func _on_side_button_pressed(text_to_show):
-       $Label.text = text_to_show
-
-We are done for the main screen panel. Save the scene as ``main_panel.tscn``.
-
-Tabbed panel scene
-------------------
+Create a new scene with a root node derived from ``Control`` (for this
+example plugin, we'll make the root node a ``CenterContainer``).
+Select this root node, and in the viewport, click the ``Layout`` menu
+and select ``Full Rect``. You also need to enable the ``Expand``
+vertical size flag in the inspector.
+The panel now uses all the space available in the main viewport.
 
 
-The tabbed panel scene is almost identical to the main panel scene. You can
-either duplicate the ``main_panel.tscn`` file and name the new file
-``side_panel.tscn``, or re-create it from a new scene by following the previous
-section again. However, you will have to create a new script and attach it to
-the Panel root node. Save it as ``side_panel.gd``. Its content is slightly
-different, as the signal emitted and the target function have different names.
-Here is the script's full content:
+Next, let's add a button to our example main screen plugin.
+Add a ``Button`` node, and set the text to "Print Hello" or similar.
+Add a script to the button like this:
 
 
 ::
 ::
 
 
     tool
     tool
-    extends Panel
+    extends Button
 
 
-    signal side_button_pressed(value)
 
 
-    func _on_Button_pressed():
-       emit_signal("side_button_pressed", "Hello from side panel!")
+    func _on_PrintHello_pressed():
+        print("Hello from the main screen plugin!")
 
 
+Then connect the "pressed" signal to itself. If you need help with signals,
+see the :ref:`doc_signals` article.
 
 
-    func _on_main_button_pressed(text_to_show):
-       $Label.text = text_to_show
+We are done with the main screen panel. Save the scene as ``main_panel.tscn``.
 
 
-Connecting the two scenes in the plugin script
-----------------------------------------------
+Update the plugin script
+------------------------
 
 
-We now need to update the ``main_screen_plugin.gd`` script so the plugin
-instances our 2 GUI scenes and places them at the right places in the editor.
-Here is the full ``main.gd``:
+We need to update the ``main_screen_plugin.gd`` script so the plugin
+instances our main panel scene and places it where it needs to be.
+Here is the full plugin script:
 
 
 ::
 ::
 
 
     tool
     tool
     extends EditorPlugin
     extends EditorPlugin
 
 
-    const MainPanel = preload("res://addons/my_plugin_name/main_panel.tscn")
-    const SidePanel = preload("res://addons/my_plugin_name/side_panel.tscn")
 
 
-    var main_panel_instance
-    var side_panel_instance
+    const MainPanel = preload("res://addons/main_screen/main_panel.tscn")
 
 
-    func _enter_tree():
-       main_panel_instance = MainPanel.instance()
-       side_panel_instance = SidePanel.instance()
-
-       # Add the main panel to the editor's main viewport.
-       get_editor_interface().get_editor_viewport().add_child(main_panel_instance)
+    var main_panel_instance
 
 
-       # Add the side panel to the Upper Left (UL) dock slot of the left part of the editor.
-       # The editor has 4 dock slots (UL, UR, BL, BR) on each side (left/right) of the main screen.
-       add_control_to_dock(DOCK_SLOT_LEFT_UL, side_panel_instance)
 
 
-       # Hide the main panel
-       make_visible(false)
+    func _enter_tree():
+        main_panel_instance = MainPanel.instance()
+        # Add the main panel to the editor's main viewport.
+        get_editor_interface().get_editor_viewport().add_child(main_panel_instance)
+        # Hide the main panel. Very much required.
+        make_visible(false)
 
 
 
 
     func _exit_tree():
     func _exit_tree():
-       main_panel_instance.queue_free()
-       side_panel_instance.queue_free()
-
-
-    func _ready():
-       main_panel_instance.connect("main_button_pressed", side_panel_instance, "_on_main_button_pressed")
-       side_panel_instance.connect("side_button_pressed", main_panel_instance, "_on_side_button_pressed")
+        if main_panel_instance:
+            main_panel_instance.queue_free()
 
 
 
 
     func has_main_screen():
     func has_main_screen():
-       return true
+        return true
 
 
 
 
     func make_visible(visible):
     func make_visible(visible):
-       if visible:
-          main_panel_instance.show()
-       else:
-          main_panel_instance.hide()
+        if main_panel_instance:
+            main_panel_instance.visible = visible
 
 
 
 
     func get_plugin_name():
     func get_plugin_name():
-       return "Main Screen Plugin"
+        return "Main Screen Plugin"
 
 
 
 
     func get_plugin_icon():
     func get_plugin_icon():
-       # Must return some kind of Texture for the icon.
-       return get_editor_interface().get_base_control().get_icon("Node", "EditorIcons")
-
-A couple of specific lines were added. First, we defined the constants that
-contain our 2 GUI packed scenes (``MainPanel`` and ``SidePanel``). We will use
-these resources to instance both scenes.
-
-The ``_enter_tree()`` function is called before ``_ready()``. This is where we
-actually instance the 2 GUI scenes, and add them as children of specific parts
-of the editor. The side panel case is similar to the example shown in
-:ref:`doc_making_plugins` page: we add the scene in an editor dock. We specified
-it will be placed in the left-side dock, upper-left tab.
-
-``EditorPlugin`` class does not provide any function to add an element in the
-main viewport. We thus have to use the
-``get_editor_interface().get_editor_viewport()`` to obtain this viewport and add
-our main panel instance as a child to it. We call the ``make_visible(false)``
-function to hide the main panel so it is not directly shown when first
-activating the plugin.
-
-The ``_exit_tree()`` is pretty straightforward. It is automatically called when
-the plugin is deactivated. It is then important to ``queue_free()`` the elements
-previously instanced to preserve memory. If you don't, the elements will
-effectively be invisible in the editor, but they will remain present in the
-memory. Multiple de-activations/re-activations will then increase memory usage
-without any way to free it, which is not good.
-
-Finally the ``make_visible()`` function is overridden to hide or show the main
+        # Must return some kind of Texture for the icon.
+        return get_editor_interface().get_base_control().get_icon("Node", "EditorIcons")
+
+A couple of specific lines were added. ``MainPanel`` is a constant that holds
+a reference to the scene, and we instance it into `main_panel_instance`.
+
+The ``_enter_tree()`` function is called before ``_ready()``. This is where
+we instance the main panel scene, and add them as children of specific parts
+of the editor. We use ``get_editor_interface().get_editor_viewport()`` to
+obtain the viewport and add our main panel instance as a child to it.
+We call the ``make_visible(false)`` function to hide the main panel so
+it doesn't compete for space when first activating the plugin.
+
+The ``_exit_tree()`` function is called when the plugin is deactivated.
+If the main screen still exists, we call ``queue_free()`` to free the
+instance and remove it from memory.
+
+The ``make_visible()`` function is overridden to hide or show the main
 panel as needed. This function is automatically called by the editor when the
 panel as needed. This function is automatically called by the editor when the
-user clicks on another main viewport button such as 2D, 3D or Script.
+user clicks on the main viewport buttons at the top of the editor.
+
+The ``get_plugin_name()`` and ``get_plugin_icon()`` functions control
+the displayed name and icon for the plugin's main viewport button.
+
+Another function you can add is the ``handles()`` function, which
+allows you to handle a node type, automatically focusing the main
+screen when the type is selected. This is similar to how clicking
+on a 3D node will automatically switch to the 3D viewport.
 
 
 Try the plugin
 Try the plugin
 --------------
 --------------
 
 
-Activate the plugin in the Project Settings. You'll observe a new button next to
-2D, 3D, Script above the main viewport. You'll also notice a new tab in the left
-dock. Try to click the buttons in both side and main panels: events are emitted
-and caught by the corresponding target scene to change the Label caption inside it.
+Activate the plugin in the Project Settings. You'll observe a new button next
+to 2D, 3D, Script above the main viewport. Clicking it will take you to your
+new main screen plugin, and the button in the middle will print text.
+
+If you would like to try a finished version of this plugin,
+check out the plugin demos here:
+https://github.com/godotengine/godot-demo-projects/tree/master/plugins
 
 
 If you would like to see a more complete example of what main screen plugins
 If you would like to see a more complete example of what main screen plugins
 are capable of, check out the 2.5D demo projects here:
 are capable of, check out the 2.5D demo projects here:

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

@@ -178,7 +178,7 @@ for the Spatial nodes we want to target.
         else:
         else:
             return null
             return null
 
 
-This way all the gizmo logic and drawing methods can be implemented in a new clas extending
+This way all the gizmo logic and drawing methods can be implemented in a new class extending
 :ref:`EditorSpatialGizmo<class_EditorSpatialGizmo>`, like so:
 :ref:`EditorSpatialGizmo<class_EditorSpatialGizmo>`, like so:
 
 
 ::
 ::

Some files were not shown because too many files changed in this diff