From f4aeaac2e24879273957c4cad2ce1ab01e2b9652 Mon Sep 17 00:00:00 2001 From: Meriipu Date: Mon, 22 Jun 2020 16:47:26 +0200 Subject: [PATCH 01/21] high-level networking: remove bad practice; bomber demo more explicit Removed an instance of a bad practice (letting the clients pass their own rpc caller id to the server and having the server trust it), as well as making the server the only one able to unpause the game. The first of the two is a fairly harmful habit to teach, especially in a first introduction. Also made the bomber demo way more explicit (and verbose) by avoiding as many ambiguous pronouns as possible, instead being quite explicit about which nodes or methods are being referred to at any time, and also some intermingled motivations/reminders for why these steps are being taken. --- .../networking/high_level_multiplayer.rst | 61 +++++++++++++++---- 1 file changed, 49 insertions(+), 12 deletions(-) diff --git a/tutorials/networking/high_level_multiplayer.rst b/tutorials/networking/high_level_multiplayer.rst index 45c92230e..7f56d7167 100644 --- a/tutorials/networking/high_level_multiplayer.rst +++ b/tutorials/networking/high_level_multiplayer.rst @@ -291,7 +291,8 @@ every peer and RPC will work great! Here is an example: get_node("/root/world/players").add_child(player) # Tell server (remember, server is always ID=1) that this peer is done pre-configuring. - rpc_id(1, "done_preconfiguring", selfPeerID) + # The server can call get_tree().get_rpc_sender_id() to find out who said they were done. + rpc_id(1, "done_preconfiguring") .. note:: Depending on when you execute pre_configure_game(), you may need to change any calls to ``add_child()`` @@ -314,7 +315,8 @@ When the server gets the OK from all the peers, it can tell them to start, as fo :: var players_done = [] - remote func done_preconfiguring(who): + remote func done_preconfiguring(): + var who = get_tree().get_rpc_sender_id() # Here are some checks you can do, for example assert(get_tree().is_network_server()) assert(who in player_info) # Exists @@ -326,8 +328,10 @@ When the server gets the OK from all the peers, it can tell them to start, as fo rpc("post_configure_game") remote func post_configure_game(): - get_tree().set_pause(false) - # Game starts now! + # Only the server is allowed to tell a client to unpause + if 1 == get_tree().get_rpc_sender_id(): + get_tree().set_pause(false) + # Game starts now! Synchronizing the game ---------------------- @@ -403,19 +407,43 @@ Example player code: return # Already stunned rpc("stun") - stun() # Stun myself, could have used remotesync keyword too. + + # Stun this player instance for myself as well; could instead have used + # the remotesync keyword above (in place of puppet) to achieve this. + stun() -In the above example, a bomb explodes somewhere (likely managed by whoever is master). The bomb knows the bodies in the area, so it checks them -and checks that they contain an ``exploded`` function. +In the above example, a bomb explodes somewhere (likely managed by whoever is the master of this bomb-node, e.g. the host). +The bomb knows the bodies (player nodes) in the area, so it checks that they contain an ``exploded`` method before calling it. -If they do, the bomb calls ``exploded`` on it. However, the ``exploded`` method in the player has a ``master`` keyword. This means that only the player -who is master for that instance will actually get the function. +Recall that each peer has a complete set of instances of player nodes, one instance for each peer (including itself and the host). +Each peer has set itself as the master of the instance corresponding to itself, and it has set a different peer as the master for +each of the other instances. -This instance, then, calls the ``stun`` method in the same instances of that same player (but in different peers), and only those which are set as puppet, -making the player look stunned in all the peers (as well as the current, master one). +Now, going back to the call to the ``exploded`` method, the bomb on the host has called it remotely on all bodies in the area +that have the method. However, this method is in a player node and has a ``master`` keyword. + +The ``master`` keyword on the ``exploded`` method in the player node means two things for how this call is made. +Firstly, from the perspective of the calling peer (the host), the calling peer will only attempt to remotely call the +method on the peer that it has set as the network master of the player node in question. +Secondly, from the perspective of the peer the host is sending the call to, the peer will only accept the call if it +set itself as the network master of the player node with the method being called (which has the ``master`` keyword). +This works well as long as all peers agree on who is the master of what. + +The above setup means that only the peer who owns the affected body will be responsible for telling all the other peers that its body +was stunned, after being remotely instructed to do so by the host's bomb. +The owning peer therefore (still in the ``exploded`` method) tells all the other peers that its player node was stunned. +The peer does this by remotely calling the ``stun`` method on all instances of that player node (on the other peers). +Because the ``stun`` method has the ``puppet`` keyword, only peers who did not set themselves as the network master of the node will +call it (in other words, those peers are set as puppets for that node by virtue of not being the network master of it). + +The result of this call to ``stun`` is to make the player look stunned on the screen of all the peers, including the current +network master peer (due to the local call to ``stun`` after ``rpc("stun")``). + +The master of the bomb (the host) repeats the above steps for each of the bodies in the area, such that all the instances of +any player in the bomb area get stunned on the screens of all the peers. Note that you could also send the ``stun()`` message only to a specific player by using ``rpc_id(, "exploded", bomb_owner)``. -This may not make much sense for an area-of-effect case like the bomb, but in other cases, like single target damage. +This may not make much sense for an area-of-effect case like the bomb, but might in other cases, like single target damage. :: @@ -434,3 +462,12 @@ a dedicated server with no GPU available. See server. You'll have to modify them so the server isn't considered to be a player. You'll also have to modify the game starting mechanism so that the first player who joins can start the game. + +.. note:: + + The bomberman example here is largely for illustrational purposes, and does not + do anything on the host-side to handle the case where a peer uses a custom client + to cheat by for example refusing to to stun itself. In the current implementation + such cheating is perfectly possible because each client is the network master of + its own player, and the network master of a player is the one which decides whether + to call the I-was-stunned method (``stun``) on all of the other peers and itself. From 8e924d5739fd96a29ae489a5daa7321bd79e24c4 Mon Sep 17 00:00:00 2001 From: Hugo Locurcio Date: Thu, 30 Jul 2020 19:55:03 +0200 Subject: [PATCH 02/21] Mention the Godot build options generator in Optimizing for size --- development/compiling/optimizing_for_size.rst | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/development/compiling/optimizing_for_size.rst b/development/compiling/optimizing_for_size.rst index 8443ba77b..cc1b418ef 100644 --- a/development/compiling/optimizing_for_size.rst +++ b/development/compiling/optimizing_for_size.rst @@ -17,6 +17,13 @@ This tutorial aims to give an overview on different methods to create a smaller binary. Before continuing, it is recommended to read the previous tutorials on compiling Godot for each platform. +.. seealso:: + + You can use the online + `Godot build options generator `__ + to generate a ``custom.py`` file containing SCons options. + You can then save this file and place it at the root of your Godot source directory. + Disabling 3D ------------ @@ -70,7 +77,7 @@ following: .. code-block:: python # custom.py - + module_arkit_enabled = "no" module_assimp_enabled = "no" module_bmp_enabled = "no" @@ -104,7 +111,7 @@ following: module_webrtc_enabled = "no" module_websocket_enabled = "no" module_xatlas_unwrap_enabled = "no" - + .. seealso:: :ref:`doc_overriding_build_options`. From 43d4dedb9081bc8ef43b94ce9daa1012c4fef258 Mon Sep 17 00:00:00 2001 From: Bobby Youstra Date: Fri, 31 Jul 2020 14:27:47 -0700 Subject: [PATCH 03/21] Changed TextEditor reference to TextEdit Optimizing Builds For Size referenced a node type called TextEditor when talking about advanced GUI nodes when it most likely means the TextEdit node instead. --- development/compiling/optimizing_for_size.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/development/compiling/optimizing_for_size.rst b/development/compiling/optimizing_for_size.rst index cc1b418ef..b30d658fa 100644 --- a/development/compiling/optimizing_for_size.rst +++ b/development/compiling/optimizing_for_size.rst @@ -41,7 +41,7 @@ Disabling advanced GUI nodes ---------------------------- Most small games don't require complex GUI controls such as Tree, ItemList, -TextEditor or GraphEdit. They can be disabled using a build flag: +TextEdit or GraphEdit. They can be disabled using a build flag: :: From f7ebb1b5c0814159f2f42956ddf79a93dc4cab29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tania=20R=2E=20Z=C3=BA=C3=B1iga?= Date: Sun, 2 Aug 2020 05:25:18 -0500 Subject: [PATCH 04/21] Specify more options to `python -m http.server` to avoid errors (#3855) better use python -m http.server 8000 --bind 127.0.0.1 to avoid UnicodeDecodeError --- getting_started/workflow/export/exporting_for_web.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/getting_started/workflow/export/exporting_for_web.rst b/getting_started/workflow/export/exporting_for_web.rst index 7879abe78..9c2516c05 100644 --- a/getting_started/workflow/export/exporting_for_web.rst +++ b/getting_started/workflow/export/exporting_for_web.rst @@ -17,7 +17,7 @@ in the user's browser. ``file://`` protocol. To get around this, use a local server. .. tip:: Python offers an easy method to start a local server. - Use ``python -m http.server`` with Python 3 to serve the + Use ``python -m http.server 8000 --bind 127.0.0.1`` with Python 3 to serve the current working directory at ``http://localhost:8000``. .. attention:: `There are significant bugs when running HTML5 projects on iOS `__ From 367f09ddc5e9ae47e7a84c989225097c978237e9 Mon Sep 17 00:00:00 2001 From: Hugo Locurcio Date: Mon, 13 Jul 2020 15:00:59 +0200 Subject: [PATCH 05/21] Style external links differently to distinguish them from internal ones --- _static/css/custom.css | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/_static/css/custom.css b/_static/css/custom.css index 713d9a11c..f3dfb263a 100644 --- a/_static/css/custom.css +++ b/_static/css/custom.css @@ -30,6 +30,7 @@ --link-color-hover: #3091d1; --link-color-active: #105078; --link-color-visited: #9b59b6; + --external-reference-icon: url("data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjEyIiB3aWR0aD0iMTIiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGcgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjMjk4MGI5Ij48cGF0aCBkPSJtNy41IDcuMXYzLjRoLTZ2LTZoMy40Ii8+PHBhdGggZD0ibTUuNzY1IDFoNS4yMzV2NS4zOWwtMS41NzMgMS41NDctMS4zMS0xLjMxLTIuNzI0IDIuNzIzLTIuNjktMi42ODggMi44MS0yLjgwOC0xLjMxMy0xLjMxeiIvPjwvZz48L3N2Zz4K"); --hr-color: #e1e4e5; --table-row-odd-background-color: #f3f6f6; @@ -115,6 +116,7 @@ --link-color-hover: #9df; --link-color-active: #6ad; --link-color-visited: #cb99f6; + --external-reference-icon: url("data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjEyIiB3aWR0aD0iMTIiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGcgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjOGNmIj48cGF0aCBkPSJtNy41IDcuMXYzLjRoLTZ2LTZoMy40Ii8+PHBhdGggZD0ibTUuNzY1IDFoNS4yMzV2NS4zOWwtMS41NzMgMS41NDctMS4zMS0xLjMxLTIuNzI0IDIuNzIzLTIuNjktMi42ODggMi44MS0yLjgwOC0xLjMxMy0xLjMxeiIvPjwvZz48L3N2Zz4K"); --hr-color: #555; --table-row-odd-background-color: #3b3e41; @@ -267,6 +269,14 @@ a.btn:hover { text-decoration: none; } +/* Style external links differently to make them easier to distinguish from internal links. */ +.reference.external { + background-position: center right; + background-repeat: no-repeat; + background-image: var(--external-reference-icon); + padding-right: 13px; +} + hr, #search-results .search li:first-child, #search-results .search li { From 428106f91061366fff610d06048e8ae5bfd159df Mon Sep 17 00:00:00 2001 From: Leonardo Jeanteur Date: Sun, 2 Aug 2020 22:02:32 +0200 Subject: [PATCH 06/21] Correct grammar, formatting and add download link (#3860) Add a link to Godot Engine's download page. --- getting_started/scripting/gdscript/gdscript_exports.rst | 2 +- getting_started/scripting/gdscript/gdscript_styleguide.rst | 2 +- getting_started/scripting/gdscript/static_typing.rst | 2 +- getting_started/step_by_step/intro_to_the_editor_interface.rst | 2 ++ 4 files changed, 5 insertions(+), 3 deletions(-) diff --git a/getting_started/scripting/gdscript/gdscript_exports.rst b/getting_started/scripting/gdscript/gdscript_exports.rst index 5b98ba3af..d36b8cfd4 100644 --- a/getting_started/scripting/gdscript/gdscript_exports.rst +++ b/getting_started/scripting/gdscript/gdscript_exports.rst @@ -179,7 +179,7 @@ from the FileSystem dock at once. # Exported arrays can specify type (using the same hints as before). - export(Array, int) var ints = [1,2,3] + export(Array, int) var ints = [1, 2, 3] export(Array, int, "Red", "Green", "Blue") var enums = [2, 1, 0] export(Array, Array, float) var two_dimensional = [[1.0, 2.0], [3.0, 4.0]] diff --git a/getting_started/scripting/gdscript/gdscript_styleguide.rst b/getting_started/scripting/gdscript/gdscript_styleguide.rst index 787236d5a..cc75401da 100644 --- a/getting_started/scripting/gdscript/gdscript_styleguide.rst +++ b/getting_started/scripting/gdscript/gdscript_styleguide.rst @@ -640,7 +640,7 @@ Start with the ``_init()`` callback method, that the engine will call upon creating the object in memory. Follow with the ``_ready()`` callback, that Godot calls when it adds a node to the scene tree. -These function should come first because they show how the object is +These functions should come first because they show how the object is initialized. Other built-in virtual callbacks, like ``_unhandled_input()`` and diff --git a/getting_started/scripting/gdscript/static_typing.rst b/getting_started/scripting/gdscript/static_typing.rst index 64271c127..665b74004 100644 --- a/getting_started/scripting/gdscript/static_typing.rst +++ b/getting_started/scripting/gdscript/static_typing.rst @@ -248,7 +248,7 @@ Typed or dynamic: stick to one style ------------------------------------ Typed GDScript and dynamic GDScript can coexist in the same project. But -I recommended to stick to either style for consistency in your codebase, +I recommend to stick to either style for consistency in your codebase, and for your peers. It's easier for everyone to work together if you follow the same guidelines, and faster to read and understand other people's code. diff --git a/getting_started/step_by_step/intro_to_the_editor_interface.rst b/getting_started/step_by_step/intro_to_the_editor_interface.rst index 1f61019bf..a3148bea0 100644 --- a/getting_started/step_by_step/intro_to_the_editor_interface.rst +++ b/getting_started/step_by_step/intro_to_the_editor_interface.rst @@ -7,6 +7,8 @@ This tutorial will run you through Godot's interface. We're going to look at the **Project Manager, docks, workspaces** and everything you need to know to get started with the engine. +You can `download Godot Engine here `_. + Project manager --------------- From 0140ed06516d8708517e1ae0177cc02c73a610e8 Mon Sep 17 00:00:00 2001 From: Hugo Locurcio Date: Mon, 3 Aug 2020 11:26:37 +0200 Subject: [PATCH 07/21] Use transparent instead of white to separate editor screenshots This partially addresses #3861. --- .../step_by_step/img/script_added.png | Bin 6354 -> 5714 bytes getting_started/step_by_step/img/signals.png | Bin 7944 -> 7292 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/getting_started/step_by_step/img/script_added.png b/getting_started/step_by_step/img/script_added.png index 43995a6d3d3e9f61d8bcc548940cdcecd3dd53a5..86ae7f3451d00c0d5d2d38249ced50b7e607695b 100644 GIT binary patch literal 5714 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 j`=3Tt>iDnWf`^Akrl=sJg@=a^;L7Va z32^7R+~{Q7h0sn)RSFNUA@SC^#dX~MH4iO$X}nq#WE&5U08c|jNA?l7$d!zY?F;|X zy*GR!>Y93%boA_utWWs>`Kzm|_4W1D)m2d`by!lmkeKoqYTD#)M_zuYw||tKlb6E_ zFAZJGrluxqd(Ss@@7Ny$o<3nU^(`Z#;{hRY^>5n%ah2q>yuN`Et|yYl=1vACc9yno zV`HdiLUJ6u;xF9%ef-13p&DUPi6WA!8QDcj>c(Z|mAUZOaS0jhJYrIES}GbQ0-{Pq z#br@(sd7sC((*bk?g5CANpHU}BQpmVci(}5VF3}v$4|u`KaFpo( z3yjRmFU-z;J%kvyck+ylPgm76D=w{`ot>MQoI)T+;RWSddKUbEytaW2pCD91MssX@ zYG7!z>0N7TMuCd9jhAl-KcKL>glYe?BtyK|;k>yp&;?DVYHo<70v zdk4DT51CuJdisRx8d^KL_=ZO(&CJX^;ud`(Afuq7XKn8;r=%O7m{wd;UQ$|7QT(u#UmQf6QO zV0U*fa%9ZX#)XYb=yh>*K~Z&A&tOzs#=_#qqMfRY#nxw-je;LE_c_>}m>tjB^< zu;lEzhStXB&X)G~z5(Hy`u62kFC@e@mc9J0A|h&P8=YMJbc~#2Rm^N1z}Qzw8Ch^o z-{^qgNG8^2rR8tV&dv{yzJLFIY-sLgWbPCP%h}!C7nag(YiqZ24zNq|P_#61dl`{1 zl9@Q3rDSFN^tqI!y|=KqQfq6goT_8+paZ^c` z`o}+hh(h%_c}1)pebE>!AD|H3n`~s}WM=I-H@}ptTi=6+cgIapMoPzL>Dvmi3ANo4 z-oCff6DWQx?J|OF#PBAgJR@aMNN7wcrOfqEe9o8{qpGl?1i?(58X}*ytj*b#s&`&B zMv1GA^WQ8coLg3$y<0jyx+d-(1g`CN^QBthU!y`M;Y}P>dvqexlFoyV#3wqBZVb?G zY`k#zOhG%|`}AJI``5u97iS@ol(?XrD0z+`=-UF=b0q3xcN=7^|^q!!kdagvan|j-0Cb; zx}oq5R_uOrfZx{i$1Ahb>(NJA7gK9AD#IYY_@_?sEh{VN9{7x=39F)AGAwKXp$>Qa zc-@jiTJvQky=Hcvy`^b@v+zjNs^hO?y?+;2cdI8YQ3fmhqH)`hOWk`0>SWJUzg(tm8(jZ*H=n1t?cVH)EHbU zN1%n4Z(Ekwr;(LmOO6Xj-xcgu>6MFLWPkR{v#nC|^Sq;}QrF<%pEPnn)Qwx1nEvT4 znM$3goeWu9L>l~;`qZ=(YComXvqq`*^7|eHg>BT~>zs2V@9|XZ{=yms2@F5s3gudE z|Ebqr)hVW|pRNr~-Pv@XH17QjeINx5b>~Xr`;L)xz7D=_!N;v`IApkI6#xJFPIM-p z-y{KACD0T!*BbuoE?OuG{(Oe$t-opkI0S1v)UQ9pvw3o7WEBGu?K;a$gP1)*xRU}j zzD|29_a{0Qv{6m8kdq1^KPsv8Z&fw3{d1E_e(xYRvpO(nZ0jN`qn`k{i)0G^cpp7P zHniug46uo3`F30~>_yN4BBfdmocFNu(5#_+I9YESnp4n+0MSqixAd#dq6bFp?jFu% zXEF;gzQ027P14`)2-F{F@?1_z%cfP3Fv)1wvV>B%` z;r`iqWI3TSGM(Q?sQ^TTkS>w{nbU}brqLaQVPm?!&=F-_rv$*BEsCA-Rf}y$?mt z7sZd~YsAgx8Ne>vf?|U%e(LFOuU5Tt1w4APC_wIXkGR|)X-5zqZ`hHxgU@gV=%#zz zt3rxB5;)R5X%fK?WgL)!@!RUl4AjzIyXW)^Cg{ke68hlbgp_4+h!NK?T|viFce{6y zbcb2un6bdT#v5n@P2*DMN13_PFHDU$sz~~?pEb5{h1&XYNyV2C$a6Cjlr`5wB&dPb z*?p7SZ=bps%j){>Yqp4^#{w_*@4I%N3|S;u?Nyx+Y)QVZM8mPJF^*m6G0hN}}*EqUw6OI#KalZ?MjsSio<21CYOWup{JWw4{ydtwB%r zGfx^D>ZbFaC3bUOO+34AKCunVIb1ayl2>N0#xd-|{b`AGan)=eqq4wkU30Dx&`&42#&$7QB9Mpd^OK6itObFL(5?K`@If0Tr^L@9Rg_o zI@kG*kD%iR3{+_^U8U>j4x>>877$a`tJC>#Ujvlva%;sZ$KuH~a;)uea%27k&2(3K z)`U3)xG>=%+@Cg5k1{)g?9~f*Qe8a}`?x(RYKo1(@QakkxbM&g0N;Od9j8rij|YdM zlFZlrp;4l=bYOW$MdKdnB9i0atWikQ7D0S|*`DXfm6`$vPAP*8&C|_c(N)V&9l6-b zO|S!Zl*KI(?(HXrl@(4^%t)yN?ay4H+M63nulo`1!avueL$u1^^kxNtzZO+R5Q@Jl zgFg3moWH+verU`*cO zAu0tc1y$CwMk;HmBhEOV-qy`CFFO~K&YgRt$eHo+e<5zLqujOctHvCP?DGe5xe{My z2DYe^C&y9XLf#fJI5x6P7l@3Fd(mE+2g9H@^J<~&Y8A7Nx_zV~zo%AStS1G_Wa2xr z(gwnEKHV*0!T4-;HAHKqJQ<;ougJsHiwskv4f2_;+Gzk1RS{`r1we4$jAggR_Jwy$ z6?_)RXS9>lJvoHK;Vju2e?8Po1|6Gk4OmAlS6s?a-Lbvm3Vne(AOz-2h|ha=_3xKZZ}jH|WTpH((0blq$w^pSaNiq1pN!yK051zU7xeH}B0QjfG41vBO|#q;K| zAuRk(`To(W|Jxo9RJUwvxuZdvl`>$wtIc*l@yu9~Tp66=qQ+1D`l53h42jsdHv_(o z4|rn(rIMcgu)RT4v8vD_Ek@3q_j@!AP@25`HHu900$Hh(JQ~udkxsz`5K+kR_CIL+ zO47+3OWr$b$51-&({fY3=@zKIz}kGl4D4rOPZ!4MA(Nk83?)$rBPvcZ2@NmCw1#J5@g`p=Y!HB)?ezBjs#n$*BWg?X079Q)GE2dKozp{zZ+qmVfX}*Nu%ng*d(d z8iS>7`g(D??DcS7xdfoPbLR^=AG`%ES6)#E!KOD+)w0BAA{rI`2cb4>$!H@dE}qtx z)n@45hMF-`_8}{*_{?|LWTH*up2krp(flXRb*1%5`ari=sD_W9p&vE}Wt-^(C)cw1 zWWol4{2lop>0Tl*AD4!M80=(9|0jrgb8$bWyD!KJ(_A~!bN;nLGx%bvb&vOU?dn}* zzz?qn7k$^laIx`X_}v`xTfZD?O|DCnNB4qhNc%kS`>nI#diWN=kBPX9 zOgp04VuZXT^4B1f{-V<9zH9j9#}sA;Uv=S~^H3XmM5oNO(~Q-(gGUsjKtA+1|Gh-; z#c@Hl9W8fsjEQAhcv))seaFAtzxwzTa}xSi!dgc8w|4gbp!?A-TEV^va;>5(aJU-a zJCQQqh~TAXk$uou@O(SApl*Tr2$v?xBH((&;IJLF&$BGsDUer1qsDYdLF^gnrm32Wo`c6PK3Bs5T)R)b48HNfNK zWO%2Zqq~{~J9gNkS8(}am;@-J7F7hCgMtpGXI&6Ij9s!E10dDc>so$)xmT-fQcEsq zlUM&vfrFr55Ysi?2&c?pCbWKGd)ntjjKZ8_#^fuF0$skjA?A(|3lA6@f-VN0EV@Yy z$}Q25G;pwKvA=0sBn2hauE6Eg>neb@jqk{;H;(eR_0_-#ws18xRj0uviKeaw?UUI^ zM!jzXXVGbd9|DZKISUv|o>uiC9C5k+rgTzY2^8tzpB$5ukve-6s5tSLe>%8#fbiDhAr8Xz^X|&cTLHy5nH{@s$}67*IKxLIE9n3L1-JYU&%C+6XAc2qzP}4bW%OMH6I=Ffh zCo`Wy@A3=gzGn*Ke-~68-agt(f9JsR{$(Zw&Uq3M+BY(4_Vbh|1zlX@sUrC>GdpP* z9uk(AuV!?LIHP#>Q2MB`>Swl7Mp)|=4prxH43|rG$1SJMIz7ahvq308EVhvTKdeV* z2nO*N{n>Jdco z)0AP)bT|JfF!0OP$~gabdqN=D(m>Rg2C-06n11 zfgXda)4@nORtlArIvo`3p=Gju;38q8B4ov869P)Bf4!=#?o)VpNJQmf3cu6W<8@E_9x-ZNsEbMnAX$JDGn-Yj(xjzwoxbJ`RiVlQ{hIUj@+~qmP^EOaVayWE- zuIT^_9|-T~mUp$cCZ23Iv(C3|>2lrOO&a!S`#PZrQ%T?-F0q&$>(aURf z3i1^gNxFAmg>#KkK-7A|JOh0zd?nyo7t{KlEus)5aI0-OQYSd_eiddmDzTj_BD)p2 z;RjG{2>uGqGPFfQxDwmkn99y+5f&Ys621@GK4apaBACvyyotEWuhZyBY?lZO2L9Be zO@1qbG&MLfAZWQYYS;ktXV%Ol)ds=4oA#5VmAj^};mgCUtiuZi#%O2YfcRS;(N@QA zCl}5LyK1BOd?$LZo4Z(G*=!w~V~rR*C2d=nyv^#mQ0QAQdOQq@Ds7T%C4l$%Nm7@- zNFxn9w`^)#9&SI`2!Y&1M-)sX$+UGxPtHCz3`%!V0cz}=?hx@&3ggHbA!&BFiqz4c zb=BpeYkcxpKVgE^ZW>ix57~VqaC|0*vxeVrGQ?XhD!^$X8MyX|&pOexLzEF}s|#E6 zmL=L%AL0P9vqcdX^eTYA9b1wvP}P;Ozx3W*$d}bE6q){>aSL~VS1nFXjwEjBc^x%F z61i!qZ18a#go8#E#_@riuDE;+&_YoKM&A#7O}5BA7B5b?E&m{FEO_;ba`*T5p(9G> zeC&J|F4kebK%k7#uWxLBzk#3)c$oqTBuIx>&oVNB>9TGTcuIJVjYGnOf<;!~O?OSyNj8 diff --git a/getting_started/step_by_step/img/signals.png b/getting_started/step_by_step/img/signals.png index 3d6675e51bbf980526e2eed6ac7ebe06c92dcc2c..313276c928b1cd2a9dd506cc6f8bff93c591c3b5 100644 GIT binary patch literal 7292 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 Id-~#k00I0#7XSbN literal 7944 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 Date: Mon, 3 Aug 2020 12:06:22 +0200 Subject: [PATCH 08/21] Improve the Singletons (AutoLoad) documentation This closes #3864. --- .../step_by_step/singletons_autoload.rst | 66 ++++++++++++------- 1 file changed, 41 insertions(+), 25 deletions(-) diff --git a/getting_started/step_by_step/singletons_autoload.rst b/getting_started/step_by_step/singletons_autoload.rst index 5cda37226..c1ce98632 100644 --- a/getting_started/step_by_step/singletons_autoload.rst +++ b/getting_started/step_by_step/singletons_autoload.rst @@ -20,33 +20,42 @@ own limitations: that require it, but frequently saving and loading data is cumbersome and may be slow. -The `Singleton Pattern `_ is +The `Singleton pattern `_ is a useful tool for solving the common use case where you need to store -persistent information between scenes. In our case it is possible re-use the -same scene or class for multiple singletons, so long as they have different +persistent information between scenes. In our case, it's possible to reuse the +same scene or class for multiple singletons as long as they have different names. Using this concept, you can create objects that: -- Are always loaded, no matter which scene is currently running -- Can store global variables, such as player information -- Can handle switching scenes and between-scene transitions -- Act like a singleton, since GDScript does not support global variables by design +- Are always loaded, no matter which scene is currently running. +- Can store global variables such as player information. +- Can handle switching scenes and between-scene transitions. +- *Act* like a singleton, since GDScript does not support global variables by design. Autoloading nodes and scripts can give us these characteristics. +.. note:: + + Godot won't make an AutoLoad a "true" singleton as per the singleton design + pattern. It may still be instanced more than once by the user if desired. + AutoLoad -------- -You can use AutoLoad to load a scene or a script that inherits from -:ref:`Node `. Note: when autoloading a script, a Node will be -created and the script will be attached to it. This node will be added to the -root viewport before any other scenes are loaded. +You can create an AutoLoad to load a scene or a script that inherits from +:ref:`class_Node`. + +.. note:: + + When autoloading a script, a :ref:`class_Node` will be created and the script will be + attached to it. This node will be added to the root viewport before any + other scenes are loaded. .. image:: img/singleton.png -To autoload a scene or script, select ``Project -> Project Settings`` from the -menu and switch to the "AutoLoad" tab. +To autoload a scene or script, select **Project > Project Settings** from the +menu and switch to the **AutoLoad** tab. .. image:: img/autoload_tab.png @@ -70,8 +79,8 @@ This means that any node can access a singleton named "PlayerVariables" with: var playerVariables = (PlayerVariables)GetNode("/root/PlayerVariables"); playerVariables.Health -= 10; // Instance field. -If the "Enable" column is checked (default ``true``) then the singleton can simply -be accessed directly: +If the **Enable** column is checked (which is the default), then the singleton can +be accessed directly without requiring ``get_node()``: .. tabs:: .. code-tab:: gdscript GDScript @@ -92,8 +101,8 @@ you'll see the autoloaded nodes appear: Custom scene switcher --------------------- -This tutorial will demonstrate building a scene switcher using autoload. For -basic scene switching, you can use the +This tutorial will demonstrate building a scene switcher using autoloads. +For basic scene switching, you can use the :ref:`SceneTree.change_scene() ` method (see :ref:`doc_scene_tree` for details). However, if you need more complex behavior when changing scenes, this method provides more functionality. @@ -109,15 +118,15 @@ scene contains a label displaying the scene name and a button with its Global.gd ~~~~~~~~~ -Switch to the "Script" tab and create a new script called Global.gd. Make sure -it inherits from ``Node``: +Switch to the **Script** tab and create a new script called ``Global.gd``. +Make sure it inherits from ``Node``: .. image:: img/autoload_script.png The next step is to add this script to the autoLoad list. Open -``Project > Project Settings`` from the menu, switch to the "AutoLoad" tab and +**Project > Project Settings** from the menu, switch to the **AutoLoad** tab and select the script by clicking the browse button or typing its path: -``res://Global.gd``. Press "Add" to add it to the autoload list: +``res://Global.gd``. Press **Add** to add it to the autoload list: .. image:: img/autoload_tutorial1.png @@ -125,7 +134,7 @@ Now whenever we run any scene in the project, this script will always be loaded. Returning to the script, it needs to fetch the current scene in the `_ready()` function. Both the current scene (the one with the button) and -``global.gd`` are children of root, but autoloaded nodes are always first. This +``Global.gd`` are children of root, but autoloaded nodes are always first. This means that the last child of root is always the loaded scene. .. tabs:: @@ -272,6 +281,13 @@ and Run the project and test that you can switch between scenes by pressing the button. -Note: When scenes are small, the transition is instantaneous. However, if your -scenes are more complex, they may take a noticeable amount of time to appear. To -learn how to handle this, see the next tutorial: :ref:`doc_background_loading` +.. note:: + + When scenes are small, the transition is instantaneous. However, if your + scenes are more complex, they may take a noticeable amount of time to appear. + To learn how to handle this, see the next tutorial: :ref:`doc_background_loading`. + + Alternatively, if the loading time is relatively short (less than 3 seconds or so), + you can display a "loading plaque" by showing some kind of 2D element just before + changing the scene. You can then hide it just after the scene is changed. This can + be used to indicate to the player that a scene is being loaded. From c40d74e19b4495dc365e3daa2bca59eb53774a06 Mon Sep 17 00:00:00 2001 From: balloonpopper <5151242+balloonpopper@users.noreply.github.com> Date: Mon, 3 Aug 2020 21:47:40 +1000 Subject: [PATCH 09/21] Added examples for collision layer masks (#3863) Co-authored-by: Hugo Locurcio Co-authored-by: Balloonpopper --- tutorials/3d/fps_tutorial/part_five.rst | 4 ++- tutorials/physics/physics_introduction.rst | 32 +++++++++++++++++++++- tutorials/physics/ragdoll_system.rst | 2 +- tutorials/physics/ray-casting.rst | 1 + 4 files changed, 36 insertions(+), 3 deletions(-) diff --git a/tutorials/3d/fps_tutorial/part_five.rst b/tutorials/3d/fps_tutorial/part_five.rst index 0736be8ed..f6cabdbca 100644 --- a/tutorials/3d/fps_tutorial/part_five.rst +++ b/tutorials/3d/fps_tutorial/part_five.rst @@ -521,7 +521,7 @@ If ``grabbed_object`` is ``null``, we want to see if we can pick up a :ref:`Rigi We first get the direct space state from the current :ref:`World `. This is so we can cast a ray entirely from code, instead of having to use a :ref:`Raycast ` node. -.. note:: see :ref:`Ray-casting ` for more information on raycasting in Godot. +.. note:: See :ref:`Ray-casting ` for more information on raycasting in Godot. Then we get the center of the screen by dividing the current :ref:`Viewport ` size in half. We then get the ray's origin point and end point using ``project_ray_origin`` and ``project_ray_normal`` from the camera. If you want to know more about how these functions work, see :ref:`Ray-casting `. @@ -537,6 +537,8 @@ the :ref:`RigidBody ` we collided with to ``MODE_STATIC`` so it Finally, we set the grabbed :ref:`RigidBody `'s collision layer and collision mask to ``0``. This will make the grabbed :ref:`RigidBody ` have no collision layer or mask, which means it will not be able to collide with anything as long as we are holding it. +.. note:: See :ref:`doc_physics_introduction_collision_layer_code_example` for more information on Godot collision masks. + ______ If ``grabbed_object`` is not ``null``, then we need to throw the :ref:`RigidBody ` the player is holding. diff --git a/tutorials/physics/physics_introduction.rst b/tutorials/physics/physics_introduction.rst index 9dde1a62e..dd09c472f 100644 --- a/tutorials/physics/physics_introduction.rst +++ b/tutorials/physics/physics_introduction.rst @@ -95,6 +95,8 @@ it will typically be equal to ``0.01666...`` (but not always, see below). physics calculations, so that the game behaves correctly if you change the physics update rate or if the player's device can't keep up. +.. _doc_physics_introduction_collision_layers_and_masks: + Collision layers and masks ~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -123,7 +125,7 @@ be assigned in Project Settings -> Layer Names. .. image:: img/physics_layer_names.png -**Example:** +**GUI example:** You have four node types in your game: Walls, Player, Enemy, and Coin. Both Player and Enemy should collide with Walls. The Player node should detect @@ -138,6 +140,34 @@ interact with. For example, the Player's settings would look like this: .. image:: img/player_collision_layers.png .. image:: img/player_collision_mask.png +**Code example:** + +In function calls, layers are specified as a bitmask. Where a function enables +all layers by default, the layer mask will be given as ``0x7fffffff``. Your code +can use binary, hexadecimal, or decimal notation for layer masks, depending +on your preference. + +The code equivalent of the above example where layers 1, 3 and 4 were enabled +would be as follows: + +.. _doc_physics_introduction_collision_layer_code_example: + + # Example: Setting mask value for enabling layers 1, 3 and 4 + + # Binary - set the bit corresponding to the layers you want to enable (1, 3, and 4) to 1, set all other bits to 0. + # Note: Layer 20 is the first bit, layer 1 is the last. The mask for layers 4,3 and 1 is therefore + 0b00000000000000001101 + # (This can be shortened to 0b1101) + + # Hexadecimal equivalent (1101 binary converted to hexadecimal) + 0x000d + # (This value can be shortened to 0xd) + + # Decimal - Add the results of 2 to the power of (layer be enabled-1). + # (2^(1-1)) + (2^(3-1)) + (2^(4-1)) = 1 + 4 + 8 = 13 + pow(2, 1) + pow(2, 3) + pow(2, 4) + + Area2D ------ diff --git a/tutorials/physics/ragdoll_system.rst b/tutorials/physics/ragdoll_system.rst index 5ef3120e1..f74afae3f 100644 --- a/tutorials/physics/ragdoll_system.rst +++ b/tutorials/physics/ragdoll_system.rst @@ -83,4 +83,4 @@ Make sure to set up your collision layers and masks properly so the ``KinematicB .. image:: img/ragdoll_layer.png -For more information, read :ref:`doc_physics_introduction` +For more information, read :ref:`doc_physics_introduction_collision_layers_and_masks`. diff --git a/tutorials/physics/ray-casting.rst b/tutorials/physics/ray-casting.rst index 263d58957..7ce1e24c0 100644 --- a/tutorials/physics/ray-casting.rst +++ b/tutorials/physics/ray-casting.rst @@ -221,6 +221,7 @@ member variable: } } +See :ref:`doc_physics_introduction_collision_layer_code_example` for details on how to set the collision mask. 3D ray casting from screen -------------------------- From f3e24e46b7f9a2c57e46210909cf5795028590b9 Mon Sep 17 00:00:00 2001 From: Hugo Locurcio Date: Mon, 3 Aug 2020 13:54:08 +0200 Subject: [PATCH 10/21] Fix code block formatting and reference in Physics introduction --- tutorials/3d/fps_tutorial/part_five.rst | 5 ++++- tutorials/physics/physics_introduction.rst | 12 +++++++----- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/tutorials/3d/fps_tutorial/part_five.rst b/tutorials/3d/fps_tutorial/part_five.rst index f6cabdbca..e1fb9d776 100644 --- a/tutorials/3d/fps_tutorial/part_five.rst +++ b/tutorials/3d/fps_tutorial/part_five.rst @@ -537,7 +537,10 @@ the :ref:`RigidBody ` we collided with to ``MODE_STATIC`` so it Finally, we set the grabbed :ref:`RigidBody `'s collision layer and collision mask to ``0``. This will make the grabbed :ref:`RigidBody ` have no collision layer or mask, which means it will not be able to collide with anything as long as we are holding it. -.. note:: See :ref:`doc_physics_introduction_collision_layer_code_example` for more information on Godot collision masks. +.. note:: + + See :ref:`Physics introduction ` + for more information on Godot collision masks. ______ diff --git a/tutorials/physics/physics_introduction.rst b/tutorials/physics/physics_introduction.rst index dd09c472f..537451050 100644 --- a/tutorials/physics/physics_introduction.rst +++ b/tutorials/physics/physics_introduction.rst @@ -125,7 +125,8 @@ be assigned in Project Settings -> Layer Names. .. image:: img/physics_layer_names.png -**GUI example:** +GUI example +^^^^^^^^^^^ You have four node types in your game: Walls, Player, Enemy, and Coin. Both Player and Enemy should collide with Walls. The Player node should detect @@ -140,7 +141,10 @@ interact with. For example, the Player's settings would look like this: .. image:: img/player_collision_layers.png .. image:: img/player_collision_mask.png -**Code example:** +.. _doc_physics_introduction_collision_layer_code_example: + +Code example +^^^^^^^^^^^^ In function calls, layers are specified as a bitmask. Where a function enables all layers by default, the layer mask will be given as ``0x7fffffff``. Your code @@ -148,9 +152,7 @@ can use binary, hexadecimal, or decimal notation for layer masks, depending on your preference. The code equivalent of the above example where layers 1, 3 and 4 were enabled -would be as follows: - -.. _doc_physics_introduction_collision_layer_code_example: +would be as follows:: # Example: Setting mask value for enabling layers 1, 3 and 4 From 8230b9c996d7c88cd464ce1abea8a954c40af61c Mon Sep 17 00:00:00 2001 From: Hugo Locurcio Date: Tue, 4 Aug 2020 21:42:01 +0200 Subject: [PATCH 11/21] Improve suffix documentation in Importing 3D scenes This closes #2232. --- .../workflow/assets/importing_scenes.rst | 95 ++++++++++++------- 1 file changed, 61 insertions(+), 34 deletions(-) diff --git a/getting_started/workflow/assets/importing_scenes.rst b/getting_started/workflow/assets/importing_scenes.rst index 550375147..c6c804f66 100644 --- a/getting_started/workflow/assets/importing_scenes.rst +++ b/getting_started/workflow/assets/importing_scenes.rst @@ -52,7 +52,10 @@ text based format and the binary data in a separate binary file. This can be use changes in a text based format. The second is you need the texture files separate from the material file. If you don't need either of those glTF binary files are fine. -.. note:: Blender does not export emissive textures with the glTF file. If your model uses one it must be brought in separately. +.. note:: + + Blender does not export emissive textures with the glTF file. If your model + uses one, it must be brought in separately. Exporting DAE files from Blender ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -352,79 +355,103 @@ Import hints Many times, when editing a scene, there are common tasks that need to be done after exporting: -* Adding collision detection to objects -* Setting objects as navigation meshes -* Deleting nodes that are not used in the game engine (like specific lights used for modelling) +- Adding collision detection to objects. +- Setting objects as navigation meshes. +- Deleting nodes that are not used in the game engine (like specific lights used for modelling). -To simplify this workflow, Godot offers a few suffixes that can be added to the names of the -objects in your 3D modelling software. When imported, Godot will detect them and perform -actions automatically: +To simplify this workflow, Godot offers several suffixes that can be added to +the names of the objects in your 3D modelling software. When imported, Godot +will detect suffixes in object names and will perform actions automatically. + +.. note:: + + All the suffixes described below are *case-sensitive*. Remove nodes (-noimp) ~~~~~~~~~~~~~~~~~~~~~ -Node names that have this suffix will be removed at import time, no -matter what their type is. They will not appear in the imported scene. +Objects that have the ``-noimp`` suffix will be removed at import-time no matter +what their type is. They will not appear in the imported scene. Create collisions (-col, -convcol, -colonly, -convcolonly) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Option "-col" will work only for Mesh nodes. If it is detected, a child -static collision node will be added, using the same geometry as the mesh. +The option ``-col`` will work only for Mesh objects. If it is detected, a child +static collision node will be added, using the same geometry as the mesh. This +will create a triangle mesh collision shape, which is a slow, but accurate +option for collision detection. This option is usually what you want for level +geometry (but see also ``-colonly`` below). -Option "-convcol" will create a :ref:`class_convexpolygonshape` instead of a :ref:`class_concavepolygonshape`. +The option ``-convcol`` will create a :ref:`class_convexpolygonshape` instead of +a :ref:`class_concavepolygonshape`. Unlike triangle meshes which can be concave, +a convex shape can only accurately represent a shape that doesn't have any +concave angles (a pyramid is convex, but a hollow box is concave). Due to this, +convex collision shapes are generally not suited for level geometry. When +representing simple enough meshes, convex collision shapes can result in better +performance compared to a triangle collision shape. This option is ideal for +simple or dynamic objects that require mostly-accurate collision detection. -However, it is often the case that the visual geometry is too complex or -too un-smooth for collisions, which ends up not working well. +However, in both cases, the visual geometry may be too complex or not smooth +enough for collisions. This can create physics glitches and slow down the engine +unneccesarily. -To solve this, the "-colonly" modifier exists, which will remove the mesh upon -import and create a :ref:`class_staticbody` collision instead. +To solve this, the ``-colonly`` modifier exists. It will remove the mesh upon +importing and will create a :ref:`class_staticbody` collision instead. This helps the visual mesh and actual collision to be separated. -Option "-convcolonly" works in a similar way but will create a :ref:`class_convexpolygonshape` instead. +The option ``-convcolonly`` works in a similar way, but will create a :ref:`class_convexpolygonshape` instead. -Option "-colonly" can also be used with Blender's empty objects. +The option ``-colonly`` can also be used with Blender's empty objects. On import, it will create a :ref:`class_staticbody` with a collision node as a child. The collision node will have one of a number of predefined shapes, depending on Blender's empty draw type: .. image:: img/3dimp_BlenderEmptyDrawTypes.png -- Single arrow will create a :ref:`class_rayshape` -- Cube will create a :ref:`class_boxshape` -- Image will create a :ref:`class_worldmarginshape` -- Sphere (and the others not listed) will create a :ref:`class_sphereshape` +- Single arrow will create a :ref:`class_rayshape`. +- Cube will create a :ref:`class_boxshape`. +- Image will create a :ref:`class_worldmarginshape`. +- Sphere (and the others not listed) will create a :ref:`class_sphereshape`. -For better visibility in Blender's editor, the user can set "X-Ray" option on collision -empties and set some distinct color for them in User Preferences / Themes / 3D View / Empty. +When possible, **try to use a few primitive collision shapes** instead of triangle +mesh or convex shapes. Primitive shapes often have the best performance and +reliability. + +.. note:: + + For better visibility in Blender's editor, you can set the "X-Ray" option + on collision empties and set some distinct color for them in Blender's + **User Preferences > Themes > 3D View > Empty**. Create navigation (-navmesh) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -A mesh node with this suffix will be converted to a navigation mesh. Original Mesh node will be -removed. +A mesh node with the ``-navmesh`` suffix will be converted to a navigation mesh. +The original Mesh object will be removed at import-time. Create a VehicleBody (-vehicle) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -A mesh node with this suffix will be imported as a child to a :ref:`VehicleBody ` node. +A mesh node with the ``-vehicle`` suffix will be imported as a child to a +:ref:`class_VehicleBody` node. Create a VehicleWheel (-wheel) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -A mesh node with this suffix will be imported as a child to a :ref:`VehicleWheel ` node. +A mesh node with the ``-wheel`` suffix will be imported as a child to a +:ref:`class_VehicleWheel` node. Rigid Body (-rigid) ~~~~~~~~~~~~~~~~~~~ -Creates a rigid body from this mesh. +A mesh node with the ``-rigid`` suffix will be imported as a :ref:`class_RigidBody`. Animation loop (-loop, -cycle) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Animation clips in the COLLADA document that start or end with the token "loop" or "cycle" -will be imported as a Godot Animation with the loop flag set. This is case-sensitive and -does not require a hyphen. +Animation clips in the COLLADA document that start or end with the token ``loop`` or ``cycle`` +will be imported as a Godot Animation with the loop flag set. +**Unlike the other suffixes described above, this does not require a hyphen.** -In Blender, this requires using the NLA Editor and naming the Action with the "loop" or -"cycle" prefix or suffix. +In Blender, this requires using the NLA Editor and naming the Action with the ``loop`` or +``cycle`` prefix or suffix. From 24f26c744fc274554e659024b19a894b9ee448bf Mon Sep 17 00:00:00 2001 From: Hugo Locurcio Date: Wed, 5 Aug 2020 11:52:04 +0200 Subject: [PATCH 12/21] Mention the need to rebuild C# solutions for the editor in C# basics This closes #3740. --- .../scripting/c_sharp/c_sharp_basics.rst | 36 +++++++++++++------ .../scripting/c_sharp/c_sharp_differences.rst | 2 +- .../scripting/c_sharp/c_sharp_features.rst | 2 +- 3 files changed, 28 insertions(+), 12 deletions(-) diff --git a/getting_started/scripting/c_sharp/c_sharp_basics.rst b/getting_started/scripting/c_sharp/c_sharp_basics.rst index 9a72a389a..16fd8f970 100644 --- a/getting_started/scripting/c_sharp/c_sharp_basics.rst +++ b/getting_started/scripting/c_sharp/c_sharp_basics.rst @@ -56,15 +56,15 @@ Windows (JetBrains Rider) JetBrains Rider comes with bundled MSBuild, so nothing extra is required. Make sure to set the following preferences: -- In Godot: +- In Godot's Editor Settings: - - Mono External Editor to JetBrains Rider - - Mono Build Tool to JetBrains Mono. + - Set **Mono External Editor** to **JetBrains Rider**. + - set **Mono Build Tool** to **JetBrains Mono**. - In Rider: - - Set ``MSBuild version`` to either bundled with Rider or .NET Core. - - Install **Godot support** plugin. + - Set **MSBuild version** to either **Bundled with Rider** or **.NET Core**. + - Install the **Godot support** plugin. macOS and Linux ~~~~~~~~~~~~~~~ @@ -110,19 +110,23 @@ external editors: - Visual Studio for Mac - JetBrains Rider -.. note:: If you are using Visual Studio Code, ensure you download and install - the `C# extension `_ - to enable features like syntax highlighting and IntelliSense. +.. note:: + If you are using Visual Studio Code, ensure you download and install the + `C# extension `_ + to enable features like syntax highlighting and IntelliSense. -.. note:: If you are using Visual Studio 2019, you must follow the instructions found in the "Configure VS2019 for Debugging" section below. +.. note:: + + If you are using Visual Studio 2019, you must follow the instructions found + in the `:ref:doc_c_sharp_configuring_vs_2019_for_debugging` section below. Creating a C# script -------------------- After you successfully set up C# for Godot, you should see the following option -when selecting ``Attach script`` in the context menu of a node in your scene: +when selecting **Attach Script** in the context menu of a node in your scene: .. image:: img/attachcsharpscript.png @@ -195,6 +199,16 @@ In general, the C# Godot API strives to be as idiomatic as is reasonably possibl For more information, see the :ref:`doc_c_sharp_differences` page. +.. warning:: + + You need to (re)build the project assemblies whenever you want to see new + exported variables or signals in the editor. This build can be manually + triggered by clicking the word **Mono** at the bottom of the editor window + to reveal the Mono panel, then clicking the **Build Project** button. + + You will also need to rebuild the project assemblies to apply changes in + "tool" scripts. + Current gotchas and known issues -------------------------------- @@ -267,6 +281,8 @@ Profiling your C# code - `Mono log profiler `_ is available for Linux and macOS. Due to a Mono change, it does not work on Windows currently. - External Mono profiler like `JetBrains dotTrace `_ can be used as described `here `_. +.. _doc_c_sharp_configuring_vs_2019_for_debugging: + Configuring VS 2019 for debugging --------------------------------- diff --git a/getting_started/scripting/c_sharp/c_sharp_differences.rst b/getting_started/scripting/c_sharp/c_sharp_differences.rst index bef9df062..7aa186162 100644 --- a/getting_started/scripting/c_sharp/c_sharp_differences.rst +++ b/getting_started/scripting/c_sharp/c_sharp_differences.rst @@ -121,7 +121,7 @@ This attribute should be used on a `delegate`, whose name signature will be used [Signal] delegate void MySignal(string willSendsAString); -See also: :ref:`c_sharp_signals` +See also: :ref:`doc_c_sharp_signals`. Singletons ---------- diff --git a/getting_started/scripting/c_sharp/c_sharp_features.rst b/getting_started/scripting/c_sharp/c_sharp_features.rst index 50f9ce86a..adf90a8f0 100644 --- a/getting_started/scripting/c_sharp/c_sharp_features.rst +++ b/getting_started/scripting/c_sharp/c_sharp_features.rst @@ -78,7 +78,7 @@ otherwise it returns true. For more advanced type checking, you can look into `Pattern Matching `_. -.. _c_sharp_signals: +.. _doc_c_sharp_signals: C# signals ---------- From b879bfb8724aeb003b1bd30916a39f88f1dbeaa2 Mon Sep 17 00:00:00 2001 From: Hugo Locurcio Date: Thu, 6 Aug 2020 01:55:15 +0200 Subject: [PATCH 13/21] Rename the Lights and shadows page to 3D lights and shadows (#3875) This distinguishes it better from its 2D counterpart. The filename has been left unchanged as to avoid breaking URLs. --- tutorials/3d/lights_and_shadows.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tutorials/3d/lights_and_shadows.rst b/tutorials/3d/lights_and_shadows.rst index f3f94c958..f555ec22e 100644 --- a/tutorials/3d/lights_and_shadows.rst +++ b/tutorials/3d/lights_and_shadows.rst @@ -1,7 +1,7 @@ .. _doc_lights_and_shadows: -Lights and shadows -================== +3D lights and shadows +===================== Introduction ------------ From 424f81ca85bf86ec061213e20a64a47ad2858136 Mon Sep 17 00:00:00 2001 From: Hugo Locurcio Date: Thu, 6 Aug 2020 18:54:18 +0200 Subject: [PATCH 14/21] Document theming customizations in the README This is a relatively important caveat in the documentation, so it's worth mentioning in the README. --- README.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/README.md b/README.md index b4a63268b..9f8471295 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,17 @@ This repository contains the source files of [Godot Engine](https://godotengine. They are meant to be parsed with the [Sphinx](https://www.sphinx-doc.org/) documentation builder to build the HTML documentation on [Godot's website](https://docs.godotengine.org). +## Theming + +The Godot documentation uses the default ``sphinx_rtd_theme`` with many +[customizations](_static/) applied on top. It will automatically switch between +the light and dark theme depending on your browser/OS' theming preference. + +If you use Firefox and wish to use the dark theme regardless of your OS +configuration, you can install the +[Dark Website Forcer](https://addons.mozilla.org/en-US/firefox/addon/dark-mode-website-switcher/) +add-on. + ## Contributing changes **Pull Requests should use the `master` branch by default. Only make Pull Requests against other branches (e.g. `2.1` or `3.0`) if your changes only apply to that specific version of Godot.** From 1e8c25b247a22a1927dab41c6713467544e9f846 Mon Sep 17 00:00:00 2001 From: Hugo Locurcio Date: Thu, 6 Aug 2020 20:56:10 +0200 Subject: [PATCH 15/21] Add issue template configuration to replace the dummy support template (#3859) --- .github/ISSUE_TEMPLATE/config.yml | 6 ++++++ .github/ISSUE_TEMPLATE/support_question.md | 18 ------------------ 2 files changed, 6 insertions(+), 18 deletions(-) create mode 100644 .github/ISSUE_TEMPLATE/config.yml delete mode 100644 .github/ISSUE_TEMPLATE/support_question.md diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 000000000..cefdbcb19 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,6 @@ +blank_issues_enabled: false + +contact_links: + - name: Godot community channels + url: https://godotengine.org/community + about: Please ask for technical support on one of the other community channels, not here. diff --git a/.github/ISSUE_TEMPLATE/support_question.md b/.github/ISSUE_TEMPLATE/support_question.md deleted file mode 100644 index c57bc0609..000000000 --- a/.github/ISSUE_TEMPLATE/support_question.md +++ /dev/null @@ -1,18 +0,0 @@ ---- -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** From fe674e3b30e2cfef488f7bf1d1322ed69c41e4e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcin=20S=C4=99d=C5=82ak-Jakubowski?= Date: Fri, 7 Aug 2020 00:52:04 +0200 Subject: [PATCH 16/21] Change "Custom Node" to "Other Node" in Scenes and nodes (#3877) --- .../step_by_step/img/newnode_button.png | Bin 4576 -> 11302 bytes .../step_by_step/scenes_and_nodes.rst | 4 ++-- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/getting_started/step_by_step/img/newnode_button.png b/getting_started/step_by_step/img/newnode_button.png index 7bdbed79a477afd4a8160241348e6977a50de20c..bde2dba8efd4a7ddfbdd5a35fe87c8efb6f0eefd 100644 GIT binary patch literal 11302 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 I6EX1rKQyL5UH||9 literal 4576 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 diff --git a/getting_started/step_by_step/scenes_and_nodes.rst b/getting_started/step_by_step/scenes_and_nodes.rst index 58a0bbecf..538994baa 100644 --- a/getting_started/step_by_step/scenes_and_nodes.rst +++ b/getting_started/step_by_step/scenes_and_nodes.rst @@ -97,7 +97,7 @@ empty scene, as the "root" node). In an empty scene (without root node), the scene dock shows several options to quickly add a root node to the scene. "2D Scene" adds a Node2D node, "3D Scene" adds a Spatial node, "User Interface" adds a - Control node, and "Custom Node" which lets you select any node (so it + Control node, and "Other Node" which lets you select any node (so it is equivalent to pressing the "Add Child Node" button). You can also press the star-shaped icon to toggle the display of your favorited nodes. @@ -107,7 +107,7 @@ empty scene, as the "root" node). node as its root node, likewise not every GUI or 2D scene needs a Control node or Node2D as their root node. -Now, to add a label node to this scene you can click on the Custom Node +Now, to add a label node to this scene you can click on the Other Node button or the Add Node button at the top. In scenes that aren't empty you use the add node button to create every child node. From 9252df6dfda7addf9307a3fff0fda8cf210006ed Mon Sep 17 00:00:00 2001 From: Anilforextra Date: Fri, 7 Aug 2020 16:11:50 +0545 Subject: [PATCH 17/21] Fix missing indentation in State design pattern (#3878) Added missing indent for Input Code in persistance_state.gd --- tutorials/misc/state_design_pattern.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tutorials/misc/state_design_pattern.rst b/tutorials/misc/state_design_pattern.rst index da6f72f78..f11e6a4a1 100644 --- a/tutorials/misc/state_design_pattern.rst +++ b/tutorials/misc/state_design_pattern.rst @@ -207,10 +207,10 @@ will not change it makes sense to call this new script ``persistent_state.gd``. # Input code was placed here for tutorial purposes. func _process(_delta): - if Input.is_action_pressed("ui_left"): - move_left() - elif Input.is_action_pressed("ui_right"): - move_right() + if Input.is_action_pressed("ui_left"): + move_left() + elif Input.is_action_pressed("ui_right"): + move_right() func move_left(): state.move_left() From 57e98914a2b2b4c4666d6c815259c05cbc1cf6e0 Mon Sep 17 00:00:00 2001 From: Hugo Locurcio Date: Fri, 7 Aug 2020 15:41:55 +0200 Subject: [PATCH 18/21] Mention the OpenGL requirement when using the `--no-window` CLI argument --- .../workflow/export/exporting_for_dedicated_servers.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/getting_started/workflow/export/exporting_for_dedicated_servers.rst b/getting_started/workflow/export/exporting_for_dedicated_servers.rst index a81a0b962..da536c5ab 100644 --- a/getting_started/workflow/export/exporting_for_dedicated_servers.rst +++ b/getting_started/workflow/export/exporting_for_dedicated_servers.rst @@ -15,7 +15,8 @@ Platform support - **macOS:** :ref:`Compile a server binary from source for macOS `. - **Windows:** There is no dedicated server build for Windows yet. As an alternative, you can use the ``--no-window`` command-line argument to prevent Godot from - spawning a window. + spawning a window. Note that even with the ``--no-window`` command-line argument, + you'll need to have OpenGL support available on the Windows machine. If your project uses C#, you'll have to use a Mono-enabled server binary. From 89d3c1db3a88360263ff79583cf0110b326e1ff6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcin=20S=C4=99d=C5=82ak-Jakubowski?= Date: Sun, 9 Aug 2020 20:17:39 +0200 Subject: [PATCH 19/21] Clarify misleading sentence (#3886) This is a section for beginners, and until this point, the writing has been easy and accessible, but the GDScript Reference is over 6.2k words long and difficult to grok in a few minutes by a beginner. This commit changes this sentence to instead suggest skimming and bookmarking the page for later, because I think this was the original intent. --- getting_started/step_by_step/scripting.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/getting_started/step_by_step/scripting.rst b/getting_started/step_by_step/scripting.rst index ecb7b5705..c2466d25d 100644 --- a/getting_started/step_by_step/scripting.rst +++ b/getting_started/step_by_step/scripting.rst @@ -97,9 +97,9 @@ demonstrate: - Hooking up UI elements via signals. - Writing a script that can access other nodes in the scene. -Before continuing, please make sure to read the :ref:`GDScript` reference. -It's a language designed to be simple, and the reference is short, so it will not take more -than a few minutes to get an overview of the concepts. +Before continuing, make sure to skim and bookmark the :ref:`GDScript` reference. +It's a language designed to be simple, and the reference is structured into sections to make it +easier to get an overview of the concepts. Scene setup ~~~~~~~~~~~ From 8197cfa051e90fefd921e3685c785f27aa2c3d55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcin=20S=C4=99d=C5=82ak-Jakubowski?= Date: Sun, 9 Aug 2020 20:20:35 +0200 Subject: [PATCH 20/21] Add missing code formatting to function name in GDScript basics (#3885) --- getting_started/scripting/gdscript/gdscript_basics.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/getting_started/scripting/gdscript/gdscript_basics.rst b/getting_started/scripting/gdscript/gdscript_basics.rst index 7aa6817f8..04ebb9a0d 100644 --- a/getting_started/scripting/gdscript/gdscript_basics.rst +++ b/getting_started/scripting/gdscript/gdscript_basics.rst @@ -1317,7 +1317,7 @@ If a class inherits from :ref:`class_Reference`, then instances will be freed when no longer in use. No garbage collector exists, just reference counting. By default, all classes that don't define inheritance extend **Reference**. If this is not desired, then a class -must inherit :ref:`class_Object` manually and must call instance.free(). To +must inherit :ref:`class_Object` manually and must call ``instance.free()``. To avoid reference cycles that can't be freed, a ``weakref`` function is provided for creating weak references. From ed3d3492ba022678cf0df87e9bb3b241bca677b6 Mon Sep 17 00:00:00 2001 From: Tooniis <36982494+Tooniis@users.noreply.github.com> Date: Mon, 10 Aug 2020 08:14:19 +0400 Subject: [PATCH 21/21] Update jitter_stutter.rst The human eye can see more than 60F/s. It's monitors that are usually 60 Hz. --- tutorials/misc/jitter_stutter.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tutorials/misc/jitter_stutter.rst b/tutorials/misc/jitter_stutter.rst index 5c7d4edea..8dcc67c76 100644 --- a/tutorials/misc/jitter_stutter.rst +++ b/tutorials/misc/jitter_stutter.rst @@ -32,7 +32,7 @@ Jitter There can be many causes of jitter, the most typical one happens when the game *physics frequency* (usually 60 Hz) runs at a different resolution than the monitor refresh rate. Check whether your monitor refresh rate is different from 60 Hz. -This is generally not a problem, given that refresh rates higher than 60 Hz are barely visible to the human eye, and +This is generally not a problem, given that most monitors are 60 Hz, and starting with Godot 3.1, a frame timer was introduced that tries to synchronize with refresh as well as possible. Sometimes only some objects appear to jitter (character or background). This happens when they are processed in different