Browse Source

Merge pull request #3958 from NathanLovato/edit/what-are-godot-classes

Edit "What are Godot classes"
Nathan Lovato 4 years ago
parent
commit
a53ad083b0

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

@@ -7,7 +7,7 @@ This series is a collection of best practices to help you work efficiently with
 Godot.
 
 Godot allows for a great amount of flexibility in how you structure a project's
-codebase and break it down into scenes. Each approach has its own pros and
+codebase and break it down into scenes. Each approach has its pros and
 cons, and they can be hard to weigh until you've worked with the engine for long enough.
 
 There are always many ways to structure your code and solve specific programming

+ 54 - 0
getting_started/workflow/best_practices/scenes_versus_scripts.rst

@@ -147,6 +147,60 @@ this way.
 
 On the downside, it also means having to use largely imperative programming.
 
+Performance of Script vs PackedScene
+------------------------------------
+
+One last aspect to consider when choosing scenes and scripts is execution speed.
+
+As the size of objects increases, the scripts' necessary size to create and
+initialize them grows much larger. Creating node hierarchies demonstrates this.
+Each Node's logic could be several hundred lines of code in length.
+
+The code example below creates a new ``Node``, changes its name, assigns a
+script to it, sets its future parent as its owner so it gets saved to disk along
+with it, and finally adds it as a child of the ``Main`` node:
+
+.. tabs::
+  .. code-tab:: gdscript GDScript
+
+    # Main.gd
+    extends Node
+
+    func _init():
+        var child = Node.new()
+        child.name = "Child"
+        child.script = preload("Child.gd")
+        child.owner = self
+        add_child(child)
+
+  .. code-tab:: csharp
+
+    using System;
+    using Godot;
+
+    public class Main : Resource
+    {
+        public Node Child { get; set; }
+
+        public Main()
+        {
+            Child = new Node();
+            Child.Name = "Child";
+            Child.Script = ResourceLoader.Load<Script>("child.gd");
+            Child.Owner = this;
+            AddChild(Child);
+        }
+    }
+
+Script code like this is much slower than engine-side C++ code. Each instruction
+makes a call to the scripting API which leads to many "lookups" on the back-end
+to find the logic to execute.
+
+Scenes help to avoid this performance issue. :ref:`PackedScene
+<class_PackedScene>`, the base type that scenes inherit from, defines resources
+that use serialized data to create objects. The engine can process scenes in
+batches on the back-end and provide much better performance than scripts.
+
 Conclusion
 ----------
 

+ 45 - 112
getting_started/workflow/best_practices/what_are_godot_classes.rst

@@ -1,127 +1,59 @@
 .. _doc_what_are_godot_classes:
 
-Godot scenes and scripts are classes
-====================================
-
-In Godot, scripts and scenes can both be the equivalent of classes in an
-Object-Oriented programming language. The main difference is that scenes are
-`declarative code <https://en.wikipedia.org/wiki/Declarative_programming>`_,
-while scripts can contain `imperative code
-<https://en.wikipedia.org/wiki/Imperative_programming>`_.
-
-As a result, many best practices in Godot boil down to applying Object-Oriented
-design principles to the scenes, nodes, or scripts that make up your game.
-
-This guide explains how scripts and scenes work in the engine's core, to help
-you get a sense of how Godot works under the hood, and to help you better
-understand where some of this series' best practices come from.
-
-Making sense of classes in Godot
---------------------------------
-
-Godot Engine provides built-in classes like :ref:`Node <class_Node>`.
-User-created types are not technically classes. Instead, they are resources that
-tell the engine a sequence of initializations to perform on one of the engine's
-built-in classes.
-
-Godot's internal classes have methods that register a class's data with a
-:ref:`ClassDB <class_ClassDB>`. This database provides runtime access to class
-information. ``ClassDB`` contains information about classes like:
-
-- properties
-- methods
-- constants
-- signals
-
-This ``ClassDB`` is what Objects check against when performing an operation like
-accessing a property or calling a method. ``ClassDB`` checks the database's
-records and the records of the Object's base types to see if the Object supports
-the operation.
-
-On the engine's side, every class defines a static ``_bind_methods()`` function
-that describes what C++ content it registers to the database and how. When you
-use the engine, you can extend the methods, properties, and signals available from
-the ``ClassDB`` by attaching a :ref:`Script <class_Script>` to your node.
-
-Objects check their attached script before the database. This is why scripts can
-override built-in methods. If a script defines a ``_get_property_list()`` method,
-Godot appends that data to the list of properties the Object fetches from the
-ClassDB. The same is true for other declarative code.
-
-Even scripts that don't inherit from a built-in type, i.e. scripts that don't
-start with the ``extends`` keyword, implicitly inherit from the engine's base
-:ref:`Reference <class_Reference>` class. This allows the Object to defer
-to the script's content where the engine logic deems appropriate.
-
-.. note::
-
-   As a result, you can instance scripts without the ``extends`` keyword
-   from code, but you cannot attach them to a :ref:`Node <class_Node>`
+Applying object-oriented principles in Godot
+============================================
 
+The engine offers two main ways to create reusable objects: scripts and scenes. Neither of these
+technically define classes under the hood.
 
-Scripting performances and PackedScene
---------------------------------------
+Still, many best practices using Godot involve applying object-oriented programming principles to
+the scripts and scenes that compose your game. That is why it's useful to understand how we can
+think of them as classes.
 
-As the size of Objects increases, the scripts' necessary size to create them
-grows much, much larger. Creating node hierarchies demonstrates this. Each
-individual Node's logic could be several hundred lines of code in length.
+This guide briefly explains how scripts and scenes work in the engine's core to help you understand
+how they work under the hood.
 
-Let's see a simple example of creating a single ``Node`` as a child. The code
-below creates a new ``Node``, changes its name, assigns a script to it, sets its
-future parent as its owner so it gets saved to disk along with it, and finally
-adds it as a child of the ``Main`` node:
+How scripts work in the engine
+------------------------------
 
-.. tabs::
-  .. code-tab:: gdscript GDScript
+The engine provides built-in classes like :ref:`Node <class_Node>`. You can extend those to create
+derived types using a script.
 
-    # Main.gd
-    extends Node
+These scripts are not technically classes. Instead, they are resources that tell the engine a
+sequence of initializations to perform on one of the engine's built-in classes.
 
-    func _init():
-        var child = Node.new()
-        child.name = "Child"
-        child.script = preload("Child.gd")
-        child.owner = self
-        add_child(child)
+Godot's internal classes have methods that register a class's data with a :ref:`ClassDB
+<class_ClassDB>`. This database provides runtime access to class information. ``ClassDB`` contains
+information about classes like:
 
-  .. code-tab:: csharp
+- Properties.
+- Methods.
+- Constants.
+- Signals.
 
-    using System;
-    using Godot;
+This ``ClassDB`` is what objects check against when performing an operation like accessing a
+property or calling a method. It checks the database's records and the object's base types' records
+to see if the object supports the operation.
 
-    namespace ExampleProject
-    {
-        public class Main : Resource
-        {
-            public Node Child { get; set; }
+Attaching a :ref:`Script <class_Script>` to your object extends the methods, properties, and signals
+available from the ``ClassDB``.
 
-            public Main()
-            {
-                Child = new Node();
-                Child.Name = "Child";
-                Child.Script = (Script)ResourceLoader.Load("child.gd");
-                Child.Owner = this;
-                AddChild(Child);
-            }
-        }
-    }
+.. note::
 
-Script code like this is much slower than engine-side C++ code. Each change
-makes a separate call to the scripting API which leads to many "look-ups" on the
-back-end to find the logic to execute.
+    Even scripts that don't use the ``extends`` keyword implicitly inherit from the engine's base
+    :ref:`Reference <class_Reference>` class. As a result, you can instantiate scripts without the
+    ``extends`` keyword from code. Since they extend ``Reference`` though, you cannot attach them to
+    a :ref:`Node <class_Node>`.
 
-Scenes help to avoid this performance issue. :ref:`PackedScene
-<class_PackedScene>`, the base type that scenes inherit from, are resources that
-use serialized data to create objects. The engine can process scenes in batches
-on the back-end and provide much better performance than scripts.
+Scenes
+------
 
-Scenes and scripts are objects
-------------------------------
+The behavior of scenes has many similarities to classes, so it can make sense to think of a scene as
+a class. Scenes are reusable, instantiable, and inheritable groups of nodes. Creating a scene is
+similar to having a script that creates nodes and adds them as children using ``add_child()``.
 
-Why is any of this important to scene organization? Because scenes *are*
-objects. One often pairs a scene with a scripted root node that makes use of the
-sub-nodes. This means that the scene is often an extension of the script's
-declarative code.
+We often pair a scene with a scripted root node that makes use of the scene's nodes. As such, the
+scene is often an extension of the script's declarative code.
 
 The content of a scene helps to define:
 
@@ -130,10 +62,11 @@ The content of a scene helps to define:
 - How they are initialized
 - What signal connections they have with each other
 
-Many Object-Oriented principles which apply to written code *also* apply to
-scenes.
+Why is any of this important to scene organization? Because instances of scenes *are* objects. As a
+result, many object-oriented principles that apply to written code also apply to scenes: single
+responsibility, encapsulation, and others.
 
-The scene is *always an extension of the script attached to its root node*. You
-can see all the nodes it contains as part of a single class.
+The scene is *always an extension of the script attached to its root node*, so you can interpret it
+as part of a class.
 
-Most of the tips and techniques explained in this series will build on this.
+Most of the techniques explained in this best practices series build on this point.