Browse Source

Merge pull request #429 from d9n/docpolish+scripting

Polish text in the "Scripting" section
Rémi Verschelde 8 years ago
parent
commit
1032ab3a5d
1 changed files with 112 additions and 106 deletions
  1. 112 106
      learning/step_by_step/scripting.rst

+ 112 - 106
learning/step_by_step/scripting.rst

@@ -7,75 +7,84 @@ Introduction
 ------------
 
 Much has been said about tools that allow users to create video games
-without programming. It's been a dream for many independent developers
-to create games without learning how to code. This need has been around
-for a long time, even inside companies, where game designers wish to
-have more control of the game flow.
-
-Many products have been shipped promising a no-programming environment,
-but the result is often incomplete, too complex or inefficient compared
-to traditional code. As a result, programming is here to stay for a long
-time. In fact, the general direction in game engines has been to add
-tools that try to reduce the amount of code that needs to be written for
-specific tasks, to speed up development.
-
-In that sense, Godot has taken some useful design decisions towards that
-goal. The first, and most important, is the scene system. The aim of it is
-not obvious at first, but is understandable later on. That is, it relieves
-programmers from the responsibility of designing and structuring code.
-
-When designing games using the scene system, the whole project is
-fragmented into *complementary* scenes (not individual ones). Scenes
-complement (i.e. help) each other, instead of being separate. There will be
-plenty of examples of this later on, but it's very important to remember it.
-
-For those with a good amount of programming expertise, this means a
-different design pattern to MVC. Godot promises efficiency at the
-expense of dropping the MVC habits, which are replaced by the *scenes as
-a complement* pattern.
-
-Godot also uses the `extend <http://c2.com/cgi/wiki?EmbedVsExtend>`__
-pattern for scripting, meaning that scripts extend from all the
-available engine classes.
+without programming. This appeals to many people who would love to be able to
+make a game without having to learn how to code. This need has been around for
+a long time, even inside game companies, where game designers would like to
+have more control of their game's flow.
+
+Many products have been shipped promising such a no-programming environment,
+but the results often fall short of expectations. The projects they produce end
+up being too complex or require solutions that are too inefficient compared to
+what could have been accomplished with traditional code.
+
+As a result, we think that programming is here to stay. In fact, game engines
+have been moving in this direction, adding tools that try to reduce the amount
+of code that needs to be written rather than eliminating it. The engine can
+provide many general solutions, while the developer can use code to accomplish
+specific tasks.
+
+Godot has embraced this goal from the beginning, and it has influenced many of
+its design decisions. First and foremost is the scene system. This system has
+many benefits, but fundamentally its goal is to relieve programmers from the
+responsibility of having to implement an overall architecture.
+
+When designing games using the scene system, the whole project is fragmented
+into *complementary* scenes (not individual ones). Scenes complement
+(i.e. help) each other, instead of being separate. There will be plenty of
+examples of this later on, but it's very important to remember it.
 
 GDScript
 --------
 
-:ref:`doc_gdscript` is a dynamically-typed scripting language designed to
-fit inside Godot. It was designed with the following goals:
+:ref:`doc_gdscript` is a dynamically typed scripting language which was
+designed with the following goals:
 
--  First and most importantly, making it simple, familiar and as easy to
-   learn as possible.
--  Making the code readable and error safe. The syntax is mostly
-   borrowed from Python.
+- Most importantly, it should feel simple, familiar, and as easy to learn as
+  possible.
+- It should have a syntax that's very readable. The syntax is mostly borrowed
+  from Python.
+- It should integrate tightly with Godot itself, for example sharing its memory
+  model, taking advantage of the scene/node system, and exposing useful
+  game-related classes already part of the Godot engine.
 
-Programmers generally take a few days to learn it, and within two weeks
-feel comfortable with it.
+Programmers generally take a few days to learn GDScript and feel comfortable
+with it within two weeks.
 
-As with most dynamically typed languages, the higher productivity
-(code is easier to learn, faster to write, no compilation, etc) is
-balanced with a performance penalty. But most critical code is written
-in C++ already in the engine (vector ops, physics, math, indexing, etc),
-resulting in more than sufficient performance for most types of
-games.
+As with most dynamically typed languages, the higher productivity (code is
+easier to learn, faster to write, no compilation, etc.) is balanced with a
+performance penalty. However, keep in mind that most critical code is already
+written in C++ in the engine (vector ops, physics, math, indexing, etc.), which
+results in more than sufficient performance for most types of games.
 
 In any case, if more performance is required, critical sections can be
-rewritten in C++ and exposed transparently to the script. This allows
-the replacement of a GDScript class with a C++ class without altering
-the rest of the game.
+rewritten in C++ and registered with Godot, which in turn exposes them to all
+scripts. In this way, you can write a class in GDScript first but convert it to
+a C++ class later, and the rest of the game will work the same as before.
+
+Finally, note that GDScript provides the powerful
+`extend <http://c2.com/cgi/wiki?EmbedVsExtend>`__ keyword. Many classes in the
+Godot engine are available as base classes to be extended from.
 
 Scripting a scene
 -----------------
 
+In the rest of this tutorial, we'll set up a simple GUI scene consisting of a
+button and a label, where pressing the button will update the label. This will
+demonstrate:
+
+- how to write a basic script and attach it to a node
+- how to hook up UI elements via *signals*
+- how to write a script that can access other nodes in the scene
+
 Before continuing, please make sure to read the :ref:`doc_gdscript` reference.
-It's a simple language and the reference is short, it will not take
-more than a few minutes to get an overview of the concepts.
+It's a simple language and the reference is short, so it will not take more
+than a few minutes to get an overview of the concepts.
 
 Scene setup
 ~~~~~~~~~~~
 
-This tutorial will begin by scripting a simple GUI scene. Use the add
-node dialog to create the following hierarchy, with the following nodes:
+Use the add node dialog to create the following hierarchy, with the following
+nodes:
 
 - Panel
 
@@ -91,129 +100,126 @@ look like the image below. You can set the text in the Inspector pane.
 
 .. image:: /img/label_button_example.png
 
-Finally, save the scene, a fitting name could be "sayhello.tscn"
+Finally, save the scene, with a name such as "sayhello.tscn"
 
 .. _doc_scripting-adding_a_script:
 
 Adding a script
 ~~~~~~~~~~~~~~~
 
-Right click on the panel node, then select "Add Script" in the context
+Right click on the panel node, and then select "Add Script" in the context
 menu:
 
 .. image:: /img/add_script.png
 
-The script creation dialog will pop up. This dialog allows to select
-the language, class name, etc. GDScript does not use class names in
-script files, so that field is not editable. The script should inherit
-from "Panel" (as it is meant to extend the node, which is of Panel type,
-this is automatically filled).
+The script creation dialog will pop up. This dialog allows you to set the
+language, class name, and other relevant options.
+
+Actually, in GDScript, the file itself represents the class, so in this case,
+the class name field is not editable.
+
+The node we're attaching the script to is a panel, so the "Inherits" field
+should automatically be filled in with "Panel". This is what we want as our
+script's goal is to extend this panel node's functionality.
 
-Enter a path name for the script and then select "Create":
+Finally, enter a path name for the script and select "Create":
 
 .. image:: /img/script_create.png
 
-Once this is done, the script will be created and added to the node. You
-can see this both as an extra icon in the node, as well as in the script
-property:
+Once this is done, the script will be created and added to the node. You can
+see this both as an extra icon in the node as well as in the script property:
 
 .. image:: /img/script_added.png
 
-To edit the script, select either of the highlighted buttons. 
-This will bring you to the script editor where an existing template will
-be included by default:
+To edit the script, select either of the highlighted buttons. This will bring
+you to the script editor where an existing template will be included by default:
 
 .. image:: /img/script_template.png
 
 There is not much in there. The "_ready()" function is called when the
-node (and all its children) entered the active scene. (Remember, it's
-not a constructor, the constructor is "_init()").
+node (and all its children) enter the active scene. (Note: "_ready()" is not
+the a constructor; the constructor is "_init()").
 
 The role of the script
 ~~~~~~~~~~~~~~~~~~~~~~
 
-A script adds behavior to a node. It is used to control the
-node functions as well as other nodes (children, parent, siblings, etc).
-The local scope of the script is the node (just like in regular
-inheritance) and the virtual functions of the node are captured by the
-script.
+A script adds behavior to a node. It is used to control how the node functions
+as well as how it interacts with other nodes (children, parent, siblings,
+etc.). The local scope of the script is the node. In other words, the script
+inherits the functions provided by that node.
 
 .. image:: /img/brainslug.jpg
 
 Handling a signal
 ~~~~~~~~~~~~~~~~~
 
-Signals are used mostly in GUI nodes (although other nodes have them
-too). Signals are "emitted" when some specific kind of action happens,
-and can be connected to any function of any script instance. In this
-step, the "pressed" signal from the button will be connected to a custom
-function.
+Signals are "emitted" when some specific kind of action happens, and they can be
+connected to any function of any script instance. Signals are used mostly in
+GUI nodes (although other nodes have them too, and you can even define custom
+signals in your own scripts).
 
-An interface for connecting signals to your scripts exists in the editor. 
-You can access this by selecting the node in the scene tree and then
-selecting the "Node" tab. Make sure that you have "Signals" selected.
+In this step, we'll connect the "pressed" signal to a custom function.
+
+The editor provides an interface for connecting signals to your scripts. You
+can access this by selecting the node in the scene tree and then selecting the
+"Node" tab. Next, make sure that you have "Signals" selected.
 
 .. image:: /img/signals.png
 
-In any case, at this point it is clear that we are interested in
-the "pressed" signal. Instead of using the visual interface, we will opt
-to code the connection.
+At this point, you could use the visual interface to hook up the "pressed"
+signal by double clicking on it and selecting a target node that already has a
+script attached to it. But for the sake of learning, we're going to code up the
+connection manually.
 
-For this, a function exists that is probably the one most used by Godot
-programmers, namely :ref:`Node.get_node() <class_Node_get_node>`.
-This function uses paths to fetch nodes in the current tree or anywhere
-in the scene, relative to the node holding the script.
+To accomplish this, we will introduce a function that is probably the most used
+by Godot programmers, namely :ref:`Node.get_node() <class_Node_get_node>`.
+This function uses paths to fetch nodes anywhere in the scene, relative to the
+node that owns the script.
 
-To fetch the button, the following must be used:
+In our case, because the button and the label are siblings under the panel
+where the script is attached, you can fetch the button as follows:
 
 ::
 
     get_node("Button")
 
-Next, a callback will be added that will change the label's text when
-the button is pressed:
+Next, write a function which will be called when the button is pressed:
 
 ::
 
     func _on_button_pressed():  
         get_node("Label").set_text("HELLO!")
 
-Finally, the button "pressed" signal will be connected to that callback
-in _ready(), by using :ref:`Object.connect() <class_Object_connect>`.
+Finally, connect the button's "pressed" signal to that callback in _ready(), by
+using :ref:`Object.connect() <class_Object_connect>`.
 
 ::
 
     func _ready():
         get_node("Button").connect("pressed",self,"_on_button_pressed")
 
-The final script should look like this:
+The final script should look basically like this:
 
 ::
 
     extends Panel
 
-    # member variables here, example:
-
-    # var a=2
-    # var b="textvar"
-
     func _on_button_pressed():
         get_node("Label").set_text("HELLO!")
 
     func _ready():
         get_node("Button").connect("pressed",self,"_on_button_pressed")
 
-Running the scene should have the expected result when pressing the
-button:
+Run the scene and press the button. You should get the following result:
 
 .. image:: /img/scripting_hello.png
 
-**Note:** As it is a common misunderstanding in this tutorial, let's clarify
-again that get_node(path) works by returning the *immediate* children of
-the node controlled by the script (in this case, *Panel*), so *Button*
-must be a child of *Panel* for the above code to work. To give this
-clarification more context, if *Button* were a child of *Label*, the code
-to obtain it would be:
+Why hello there! Congratulations on scripting your first scene.
+
+**Note:** A common misunderstanding in this tutorial is how get_node(path)
+works. For some given node, get_node(path) searches its immediate children.
+In the above code, this means that *Button* must be a child of *Panel*. If
+*Button* were instead a child of *Label*, the code to obtain it would be:
 
 ::