Przeglądaj źródła

Simplify best practices intro

- Add structure to the article, and a few sections
- Use simpler computer science or programming terms
- Use more accessible english
- Favor direct voice, present tense

I also removed a few sentences that either only asked rethorical questions that
I felt weren't necessary with the following explanations, and one or two
technical details that felt unecessary for users.
Nathan Lovato 6 lat temu
rodzic
commit
9f7b8e81d2

+ 24 - 19
getting_started/workflow/best_practices/introduction_best_practices.rst

@@ -3,22 +3,27 @@
 Introduction
 ============
 
-This tutorial series aims to illustrate intended Godot workflows, i.e. the
-"best practices" of defining one's game API. Godot allows for a great 
-amount of flexibility in how one designs a project's code and scene
-structure. Each method will have its own advantages and disadvantages,
-so outlining the best practices should help users feel less confused
-as they further explore Godot's depth.
-
-This series is also designed to help get users thinking about the best way
-to reason about best practices. It would be impossible to give a comprehensive
-overview of what one should do for any arbitrary design decision. As such,
-each article breaks problems down into the fundamental questions they pose,
-suggests the available solutions, analyzes the advantages and disadvantages
-of each option, and then highlights the best course of action depending on the
-circumstances.
-
-While the articles in this series are largely topic-directed, it is
-recommended that users begin with the :ref:`doc_what_are_godot_classes` article.
-It is from there that the "best practices" for the rest of the engine
-become more clear, based on established OOP practices.
+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
+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
+problems. It would be impossible to cover them all here.
+
+That is why each article starts from a real-world problem. We will break down
+each problem in fundamental questions, suggest solutions, analyze the pros and
+cons of each option, and highlight the best course of action for the problem at hand.
+
+You should start by reading :ref:`doc_what_are_godot_classes`. It explains how
+Godot's nodes and scenes relate to classes and objects in another
+Object-Oriented programming language. It will help you make sense of the rest of the series.
+
+.. note::
+
+   The best practices in Godot rely on Object-Oriented design principles. We
+   use tools like the `single responsibility
+   <https://en.wikipedia.org/wiki/Single_responsibility_principle>`_ principle and
+   `encapsulation <https://en.wikipedia.org/wiki/Encapsulation_(computer_programming)>`_.

+ 95 - 94
getting_started/workflow/best_practices/what_are_godot_classes.rst

@@ -1,80 +1,91 @@
 .. _doc_what_are_godot_classes:
 
-What are Godot classes really?
-==============================
+Godot scenes and scripts are classes
+====================================
 
-Godot offers two main means of creating types: scripts and scenes.
-Both of these represent a "class" since Godot revolves around
-Object-Oriented design. *How* they do this may not be clear to beginner
-or intermediate users though.
+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>`_.
 
-Godot Engine provides classes out-of-the-box (like
-:ref:`Node <class_Node>`), but user-created types are not actually classes.
-Instead they are resources that tell the engine a sequence of initializations
-to perform on an engine class.
+As a result, many best practices in Godot boil down to applying Object-Oriented
+design principles to the scenes, nodes, or script that make up your game.
 
-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 (also called "reflection"). Things stored in the ClassDB
-include, among other things...
+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.
 
-- properties
+Making sense of classes in Godot
+--------------------------------
 
-- methods
+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.
 
-- constants
+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
 
-Furthermore, this ClassDB is what Objects actually check against when
-performing any operation. Access a property? Call a method? Emit a signal?
-It will check the database's records (and the records of the Object's base
-types) to see if the Object supports the operation. Every C++ Object defines
-a static `_bind_methods()` function that describes what C++ content it
-registers to the database and how.
-
-So, if the engine provides all of this data at startup, then how does
-a user define their own data? It'd be nice if users could define a custom
-set of data to be appended to an object's data. That way, users could inject
-their own properties and methods into the engine's Object query requests.
-
-*This* is what a :ref:`Script <class_Script>` is. Objects check their attached
-script before the database, so scripts can even override methods.
-If a script defines a `_get_property_list()` method, that data is appended to
-the list of properties the Object fetches from the ClassDB. The same holds
-true for other declarative code.
-
-This can lead to some users' confusion when they see a script as being
-a class unto itself. In reality, the engine just auto-instantiates the
-base engine class and then adds the script to that object. This then allows
-the Object to defer to the Script's content where the engine logic deems
-appropriate.
-
-A problem does present itself though. 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.
-
-let's see a simple example of creating a single Node as a child.
+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, 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>`
+
+
+Scripting performances and PackedScene
+--------------------------------------
+
+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.
+
+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:
 
 .. tabs::
   .. code-tab:: gdscript GDScript
 
-    # main.gd
+    # Main.gd
     extends Node
 
-    var child # define a variable to store a reference to the child
-
     func _init():
-        child = Node.new() # Construct the child.
-        child.name = "Child" # Change its name.
-        child.script = preload("child.gd") # Give it custom features.
-        child.owner = self # Serialize this node if self is saved.
-        add_child(child) # Add "Child" as a child of self.
+        var child = Node.new()
+        child.name = "Child"
+        child.script = preload("Child.gd")
+        child.owner = self
+        add_child(child)
 
   .. code-tab:: csharp
 
-    // Main.cs
     using System;
     using Godot;
 
@@ -86,53 +97,43 @@ let's see a simple example of creating a single Node as a child.
 
             public Main()
             {
-                Child = new Node(); // Construct the child.
-                Child.Name = "Child"; // Change its name.
-                Child.Script = (Script)ResourceLoader.Load("child.gd"); // Give it custom features.
-                Child.Owner = this; // Serialize this node if this is saved.
-                AddChild(Child); // Add "Child" as a child of this.
+                Child = new Node();
+                Child.Name = "Child";
+                Child.Script = (Script)ResourceLoader.Load("child.gd");
+                Child.Owner = this;
+                AddChild(Child);
             }
         }
     }
 
-Notice that only two pieces of declarative code are involved in
-the creation of this child node: the variable declaration and
-the constructor declaration. Everything else about the child
-must be setup using imperative code. However, script code is
-much slower than engine C++ code. Each change must make a separate
-call to the scripting API which means a lot of C++ "lookups" within
-data structures to find the corresponding logic to execute.
-
-To help offload the work, it would be convenient if one could batch up
-all operations involved in creating and setting up node hierarchies. The
-engine could then handle the construction using its fast C++ code, and the
-script code would be free from the perils of imperative code.
-
-*This* is what a scene (:ref:`PackedScene <class_PackedScene>`) is: a
-resource that provides an advanced "constructor" serialization which is
-offloaded to the engine for batch processing.
+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.
 
-Now, why is any of this important to scene organization? Because one must
-understand that 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.
+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 performances than scripts.
 
-It helps to define...
+Scenes and scripts are objects
+------------------------------
 
-- what objects are available to the script?
+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.
 
-- how are they organized?
+The content of a scene helps to define:
 
-- how are they initialized?
+- What nodes are available to the script
+- How they are organized
+- How are they initialized
+- What signal connections they have with each other
 
-- what connections to each other do they have, if any?
+Many Object-Oriented principles which apply to written code *also* apply to
+scenes.
 
-As such, many Object-Oriented principles which apply to "programming", i.e.
-scripts, *also* apply to scenes. Some scripts are designed to only work
-in one scene (which are often bundled into the scene itself). Other scripts
-are meant to be re-used between scenes.
+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.
 
-**Regardless, the scene is always an extension of the root script, and can
-therefore be interpreted as a part of the class.**
-Most of the points covered in this series will build on this point, so
-keep it in mind.
+Most of the tips and techniques explained in this series will build on his.