Parcourir la source

Merge pull request #2175 from willnationsdev/scene-organization

Add a "best practices" section
Nathan Lovato il y a 6 ans
Parent
commit
baf1374d85

+ 103 - 0
getting_started/workflow/best_practices/autoloads_versus_internal_nodes.rst

@@ -0,0 +1,103 @@
+.. _doc_autoloads_versus_internal_nodes:
+
+Autoloads versus internal nodes
+===============================
+
+Other engines might encourage the use of creating "manager" classes that
+organize lots of functionality into a globally accessible entity. Godot
+thrives by supporting ways to cut down the size of such objects. Instead it
+shifts content into individual nodes as much as possible.
+
+For example, what if a developer is building a platformer and they want to
+collect coins that play a sound effect? Well, there's a node for that:
+the :ref:`AudioStreamPlayer <class_AudioStreamPlayer>`. But they notice during
+their testing that if they "play" an AudioStreamPlayer while it is already playing
+the sound, then the new sound interrupts the first sound, terminating it
+before it can play.
+
+Users tend to think the best solution is to make the whole system smarter by 
+making a SoundManager autoload node. It generates a pool of AudioStreamPlayers
+that cycle through as each new request for sound effects comes in. They then
+make this SoundManager an autoload so that they can access it from anywhere with
+`SFX.play("coin_pickup.ogg")`. Little do they know, they've invited a great
+many complications into their code.
+
+- **global state**: One object is now responsible for all objects' data. If
+  SFX has errors or doesn't have an AudioStreamPlayer available, everything
+  will break.
+
+- **global access**: Now that any object can call `SFX.play(sound_path)`
+  from anywhere, there's no longer an easy way to track where an SFX bug
+  began.
+
+- **global resource allocation**: If all objects' data and processing is
+  centralized from the start, then one must either...
+
+  1. risk under-allocating resources which might lead to faulty behavior.
+
+     - Ex: Have too few AudioStreamPlayers in the object pool. Sound doesn't
+       play or it interrupts another sound.
+
+  2. over-allocate resources and use more memory/processing than it needs.
+
+     - Ex: Have an arbitrarily large number of AudioStreamPlayers, with
+       many of them idling away and not doing anything.
+
+  3. have each object that needs an AudioStreamPlayer register exactly how
+     many it needs and for which sounds. This defeats the purpose of
+     using a 3rd party though; it is now coupled to each object, just
+     as a child node would have been. One has added an unnecessary
+     middleman to the equation.
+
+Contrast this with each scene keeping as many AudioStreamPlayer nodes as it
+needs within itself and all these problems go away.
+
+- Each scene manages its own state information. If there is a problem with the
+  data, it will only cause issues in that one scene.
+
+- Each scene accesses only its own nodes. Now, if there is
+  a bug, tracing which node is responsible (probably the root node of the
+  scene), and where in the code it's making the problematic call (locate
+  where the code references the given node) is going to be much easier.
+
+- Each scene knows exactly how many resources it needs for the task it
+  performs. No waste of memory or processing due to a lack of information.
+
+The typical justifications for the Autoload include, "I have common Xs that
+involve many nodes across many scenes, and I want each scene to have X."
+
+If X is a function, then the solution is to create a new type of
+:ref:`Node <class_Node>` that deals with providing that feature for an
+individual scene or node subtree.
+
+If X is data, then the solution is either 1) to create a new type of
+:ref:`Resource <class_Resource>` to share the data, or 2) to store the data
+in an object to which each node has access (nodes within a scene can use
+`get_owner()` to fetch the scene root for example).
+
+So when *should* one use an autoload?
+
+- **Static Data**: if you need static data, i.e. data that should be
+  associated with a class (so there is only ever one copy of the data), then
+  autoloads are good opportunities for that. Static data doesn't exist in
+  Godot's scripting API, so autoload singletons are the next best thing. If
+  one creates a class as an autoload, and never creates another copy of that
+  class within a scene, then it will function in place of a formal singleton
+  API.
+
+- **Convenience**: autoloaded nodes have a global variable for their name
+  generated in GDScript. This can be very convenient for defining objects
+  that should always exist, but which need object instance information.
+  The alternative is to create a namespace script: a script that's purpose
+  is only to load and create constants to access other Script or PackedScene
+  resources, resulting in something like ``MyAutoload.MyNode.new()``.
+
+  - Note that the introduction of script classes in Godot 3.1 questions
+    the validity of this reason. With them, one can access scripts using an
+    explicit name from GDScript. Using an autoload to get to a namespace
+    script becomes unnecessary, e.g. ``MyScriptClass.MyPreloadedScript.new()``.
+
+If the singleton is managing its own information and not invading the data of
+other objects, then it's a great way to create a "system" class that handles
+a broad-scoped task. For example a targeting system, quest system, or dialogue
+system would be great use cases of singleton implementations.

+ 354 - 0
getting_started/workflow/best_practices/data_preferences.rst

@@ -0,0 +1,354 @@
+.. _doc_data_preferences:
+
+Data preferences
+================
+
+Ever wondered whether one should approach problem X with data structure
+Y or Z? This article covers a variety of topics related to these dilemmas.
+
+.. note::
+
+  This article makes references to "[something]-time" operations. This
+  terminology comes from algorithm analysis'
+  `Big O Notation <https://rob-bell.net/2009/06/a-beginners-guide-to-big-o-notation/>`_.
+
+  Long-story short, it describes the worst-case scenario of runtime length.
+  In laymen's terms:
+
+  "As the size of a problem domain increases, the runtime length of the
+  algorithm..."
+  
+  - Constant-time, O(1): "...does not increase."
+  - Logarithmic-time, O(log n): "...increases at a slow rate."
+  - Linear-time, O(n): "...increases at the same rate."
+  - Etc.
+
+  Imagine if one had to process 3 million data points within a single frame. It
+  would be impossible to craft the feature with a linear-time algorithm since
+  the sheer size of the data would increase the runtime far beyond the time alotted. 
+  In comparison, using a constant-time algorithm could handle the operation without
+  issue.
+
+  By and large, developers want to avoid engaging in linear-time operations as
+  much as possible. But, if one keeps the scale of a linear-time operation
+  small, and if one does not need to perform the operation often, then it may
+  be acceptable. Balancing these requirements and choosing the right
+  algorithm / data structure for the job is part of what makes programmers'
+  skills valuable.
+
+Array vs. Dictionary vs. Object
+-------------------------------
+
+Godot stores all variables in the scripting API in the
+`Variant <https://docs.godotengine.org/en/latest/development/cpp/variant_class.html>`_
+class. Variants can store Variant-compatible data structures such as
+:ref:`Array <class_Array>` and :ref:`Dictionary <class_Dictionary>` as well as
+:ref:`Object <class_Object>` s.
+
+Godot implements Array as a Vector<Variant>. The engine stores the Array
+contents in a contiguous section of memory, i.e. they are in a row adjacent
+to each other.
+
+.. note::
+  For those unfamiliar with C++, a Vector is the name of the
+  array object in traditional C++ libraries. It is a "templated"
+  type, meaning that its records can only contain a particular type (denoted
+  by angled brackets). So, for example, a
+  :ref:`PoolStringArray <class_PoolStringArray>` would be something like
+  a Vector<String>.
+
+Contiguous memory stores imply the following operation performance:
+
+- **Iterate:** Fastest. Great for loops.
+
+    - Op: All it does is increment a counter to get to the next record.
+
+- **Insert, Erase, Move:** Position-dependent. Generally slow.
+
+    - Op: Adding/removing/moving content involves moving the adjacent records
+      over (to make room / fill space).
+
+    - Fast add/remove *from the end*.
+
+    - Slow add/remove *from an arbitrary position*.
+
+    - Slowest add/remove *from the front*.
+
+    - If doing many inserts/removals *from the front*, then...
+
+        1. invert the array.
+
+        2. do a loop which executes the Array changes *at the end*.
+
+        3. re-invert the array.
+
+      This makes only 2 copies of the array (still constant time, but slow)
+      versus copying roughly 1/2 of the array, on average, N times (linear time).
+
+- **Get, Set:** Fastest *by position*. Ex. can request 0th, 2nd, 10th record, etc.
+  but cannot specify which record you want.
+
+    - Op: 1 addition operation from array start position up to desired index.
+
+- **Find:** Slowest. Identifies the index/position of a value.
+
+    - Op: Must iterate through array and compare values until one finds a match.
+
+        - Performance is also dependent on whether one needs an exhaustive
+          search.
+
+    - If kept ordered, custom search operations can bring it to logarithmic
+      time (relatively fast). Laymen users won't be comfortable with this
+      though. Done by re-sorting the Array after every edit and writing an
+      ordered-aware search algorithm.
+
+Godot implements Dictionary as an OrderedHashMap<Variant, Variant>. The engine
+stores a giant array (initialized to 1000 records) of key-value pairs. When
+one attempts to access a value, they provide it a key. It then *hashes* the
+key, i.e. converts it into a number. The "hash" becomes the index into the
+array, giving the OHM a quick lookup for the value within the conceptual
+"table" of keys mapped to values.
+
+Hashes are to reduce the chance of a key collision. If one occurs, the table
+must recalculate another index for the value that takes the previous position
+into account. In all, this results in constant-time access to all records at
+the expense of memory and some minor operational efficiency.
+
+1. Hashing every key an arbitrary number of times.
+
+    - Hash operations are constant-time, so even if an algorithm must do more
+      than one, as long as the number of hash calculations doesn't become
+      too dependent on the density of the table, things will stay fast.
+      Which leads to...
+
+2. Maintaining a huge size for the table.
+
+    - The reason it starts with 1000 records, and the reason it forces
+      large gaps of unused memory interspersed in the table is to
+      minimize hash collisions and maintain the speed of the accesses.
+
+As one might be able to tell, Dictionaries specialize in tasks that Arrays
+aren't. An overview of their operational details is as follows:
+
+- **Iterate:** Fast.
+
+    - Op: Iterate over the map's internal vector of hashes. Return each key.
+      Afterwards, users then use the key to jump to and return the desired
+      value.
+
+- **Insert, Erase, Move:** Fastest.
+
+    - Op: Hash the given key. Do 1 addition operation to look up the
+      appropriate value (array start + offset). Move is two of these
+      (one insert, one erase). The map must do some maintenance to preserve
+      its capabilities:
+
+        - update ordered List of records.
+
+        - determine if table density mandates a need to expand table capacity.
+
+    - The Dictionary remembers in what
+      order users inserted its keys. This enables it to execute reliable iterations.
+
+- **Get, Set:** Fastest. Same as a lookup *by key*.
+
+    - Op: Same as insert/erase/move.
+
+- **Find:** Slowest. Identifies the key of a value.
+
+    - Op: Must iterate through records and compare the value until a match is
+      found.
+
+    - Note that Godot does not provide this feature out-of-the-box (because
+      they aren't meant for this task).
+
+Godot implements Objects as stupid, but dynamic containers of data content.
+Objects query data sources when posed questions. For example, to answer
+the question, "do you have a property called, 'position'?", it might ask
+its :ref:`script <class_Script>` or the :ref:`ClassDB <class_ClassDB>`.
+One can find more information about what objects are and how they work in
+the :ref:`what are godot classes <doc_what_are_godot_classes>` documentation.
+
+The important detail here is the complexity of the Object's task. Every time
+it performs one of these multi-source queries, it runs through *several*
+iteration loops and HashMap lookups. What's more, the queries are linear-time
+operations dependent on the Object's inheritance hierarchy size. If the class
+the Object queries (it's current class) doesn't find anything, the request
+defers to the next base class, all the way up until the original Object class.
+While these are each fast operations in isolation, the fact that it must make
+so many checks is what makes them slower than both of the alternatives for
+looking up data.
+
+.. note::
+
+  When developers mention how slow the scripting API is, it is this chain
+  of queries they refer to. Compared to compiled C++ code where the
+  application knows exactly where to go to find anything, it is inevitable 
+  that scripting API operations will take much longer. They must locate the
+  source of any relevant data before they can attempt to access it.
+
+  The reason GDScript is slow is because every operation it performs passes
+  through this system.
+  
+  C# can process some content at higher speeds via more optimized bytecode.
+  But, if the C# script calls into an engine class'
+  content or if the script tries to access something external to it, it will
+  go through this pipeline.
+  
+  NativeScript C++ goes even further and keeps everything internal by default.
+  Calls into external structures will go through the scripting API. In
+  NativeScript C++, registering methods to expose them to the scripting API is
+  a manual task. It is at this point that external, non-C++ classes will use
+  the API to locate them.
+
+So, assuming one extends from Reference to create a data structure, like
+an Array or Dictionary, why choose an Object over the other two options?
+
+1. **Control:** With objects comes the ability to create more sophisticated
+   structures. One can layer abstractions over the data to ensure the external
+   API doesn't change in response to internal data structure changes. What's
+   more, Objects can have signals, allowing for reactive behavior.
+
+2. **Clarity:** Objects are a reliable data source when it comes to the data
+   that scripts and engine classes define for them. Properties may not hold the
+   values one expects, but one doesn't need to worry about whether the property
+   exists in the first place.
+
+3. **Convenience:** If one already has a similar data structure in mind, then
+   extending from an existing class makes the task of building the data
+   structure much easier. In comparison, Arrays and Dictionaries don't
+   fulfill all use cases one might have.
+
+Objects also give users the opportunity to create even more specialized data
+structures. With it, one can design their own List, Binary Search Tree, Heap,
+Splay Tree, Graph, Disjoint Set, and any host of other options.
+
+"Why not use Node for tree structures?" one might ask. Well, the Node
+class contains things that won't be relevant to one's custom data structure.
+As such, it can be helpful to construct one's own node type when building
+tree structures.
+
+.. tabs::
+  .. code-tab:: gdscript GDScript
+
+    extends Object
+    class_name TreeNode
+
+    var _parent : TreeNode = null
+    var _children : = [] setget
+
+    func _notification(p_what):
+        match p_what:
+            NOTIFICATION_PREDELETE:
+                # destructor
+                for a_child in _children:
+                    a_child.free()
+
+  .. code-tab:: csharp
+
+    // Can decide whether to expose getters/setters for properties later
+    public class TreeNode : public Object {
+
+        private TreeNode _parent = null;
+
+        private object[] _children = new object[0];
+
+        // Not sure if this should be a destructor or a notification
+        public void ~TreeNode() {
+            foreach (object child in _children) {
+                TreeNode node = child as TreeNode;
+                if (node != null) {
+                    node.Free();
+                }
+            }
+        }
+    }
+
+From here, one can then create their own structures with specific features,
+limited only by their imagination.
+
+Enumerations: int vs. string
+----------------------------
+
+Most languages offer an enumeration type option. GDScript is no different,
+but unlike most other languages, it allows one to use either integers or
+strings for the enum values. The question then arises, "which should one
+use?"
+
+The short answer is, "whichever you are more comfortable with." This
+is a feature specific to GDScript and not Godot scripting in general;
+The languages prioritizes usability over performance.
+
+On a technical level, integer comparisons (constant-time) will happen
+faster than string comparisons (linear-time). If one wants to keep
+up other languages' conventions though, then one should use integers.
+
+The primary issue with using integers comes up when one wants to *print*
+an enum value. As integers, attempting to print MY_ENUM will print
+``5`` or what-have-you, rather than something like ``"MyEnum"``. To
+print an integer enum, one would have to write a Dictionary that maps the
+corresponding string value for each enum.
+
+If the primary purpose of using an enum is for printing values and one wishes
+to group them together as related concepts, then it makes sense to use them as
+strings. That way, a separate data structure to execute on the printing is
+unnecessary.
+
+AnimatedTexture vs. AnimatedSprite vs. AnimationPlayer vs. AnimationTree
+------------------------------------------------------------------------
+
+Under what circumstances should one use each of Godot's animation classes?
+The answer may not be immediately clear to new Godot users.
+
+:ref:`AnimatedTexture <class_AnimatedTexture>` is a texture that
+the engine draws as an animated loop rather than a static image.
+Users can manipulate...
+
+1. the rate at which it moves across each section of the texture (fps).
+
+2. the number of regions contained within the texture (frames).
+
+Godot's :ref:`VisualServer <class_VisualServer>` then draws
+the regions in sequence at the prescribed rate. The good news is that this
+involves no extra logic on the part of the engine. The bad news is
+that users have very little control.
+
+Also note that AnimatedTexture is a :ref:`Resource <class_Resource>` unlike
+the other :ref:`Node <class_Node>` objects discussed here. One might create
+a :ref:`Sprite <class_Sprite>` node that uses AnimatedTexture as its texture.
+Or (something the others can't do) one could add AnimatedTextures as tiles
+in a :ref:`TileSet <class_TileSet>` and integrate it with a
+:ref:`TileMap <class_TileMap>` for many auto-animating backgrounds that
+all render in a single batched draw call.
+
+The AnimatedSprite node, in combination with the
+:ref:`SpriteFrames <class_SpriteFrames>` resource, allows one to create a
+variety of animation sequences through spritesheets, flip between animations,
+and control their speed, regional offset, and orientation. This makes them
+well-suited to controlling 2D frame-based animations.
+
+If one needs trigger other effects in relation to animation changes (for
+example, create particle effects, call functions, or manipulate other
+peripheral elements besides the frame-based animation), then will need to use
+an :ref:`AnimationPlayer <class_AnimationPlayer>` node in conjunction with
+the AnimatedSprite.
+
+AnimationPlayers are also the tool one will need to use if they wish to design
+more complex 2D animation systems, such as...
+
+1. **Cut-Out animations:** editing sprites' transforms at runtime.
+
+2. **2D Mesh animations:** defining a region for the sprite's texture and
+   rigging a skeleton to it. Then one animates the bones which
+   stretch and bend the texture in proportion to the bones' relationships to
+   each other.
+
+3. A mix of the above.
+
+While one needs an AnimationPlayer to design each of the individual
+animation sequences for a game, it can also be useful to combine animations
+for blending, i.e. enabling smooth transitions between these animations. There
+may also be a hierarchical structure between animations that one plans out for
+their object. These are the cases where the :ref:`AnimationTree <class_AnimationTree>`
+shines. One can find an in-depth guide on using the AnimationTree
+:ref:`here <doc_animation_tree>`.

+ 503 - 0
getting_started/workflow/best_practices/godot_interfaces.rst

@@ -0,0 +1,503 @@
+.. _doc_godot_interfaces:
+
+Godot Interfaces
+================
+
+Often one needs scripts that rely on other objects for features. There
+are 2 parts to this process:
+
+1. Acquiring a reference to the object that presumably has the features.
+
+2. Accessing the data or logic from the object.
+
+The rest of this tutorial outlines the various ways of doing all this.
+
+Acquiring object references
+---------------------------
+
+For all :ref:`Object <class_Object>`s, the most basic way of referencing them 
+is to get a reference to an existing object from another acquired instance.
+
+.. tabs::
+  .. code-tab:: gdscript GDScript
+
+    var obj = node.object # Property access
+    var obj = node.get_object() # Method access
+
+  .. code-tab:: csharp
+
+    Object obj = node.Object; // Property access
+    Object obj = node.GetObject(); // Method access
+
+The same principle applies for :ref:`Reference <class_Reference>` objects.
+While users often access :ref:`Node <class_Node>` and
+:ref:`Resource <class_Resource>` this way, alternative measures are available.
+
+Instead of property or method access, one can get Resources by load
+access.
+
+.. tabs::
+  .. code-tab:: gdscript GDScript
+
+    var preres = preload(path) # Load resource during scene load
+    var res = load(path) # Load resource when program reaches statement
+
+    # Note that users load scenes and scripts, by convention, with PascalCase
+    # names (like typenames), often into constants.
+    const MyScene : = preload("my_scene.tscn") as PackedScene # Static load
+    const MyScript : = preload("my_script.gd") as Script
+
+    # This type's value varies, i.e. it is a variable, so it uses snake_case
+    export(Script) var script_type: Script
+
+    # If need an "export const var" (which doesn't exist), use a conditional 
+    # setter for a tool script that checks if it's executing in the editor.
+    tool # must place at top of file
+
+    # Must configure from the editor, defaults to null
+    export(Script) var const_script setget set_const_script
+    func set_const_script(value):
+        if Engine.is_editor_hint():
+            const_script = value
+
+    # Warn users if the value hasn't been set
+    func _get_configuration_warning():
+        if not const_script:
+            return "Must initialize property 'const_script'."
+        return ""
+
+  .. code-tab:: csharp
+
+    // Tool script added for the sake of the "const [Export]" example
+    [Tool]
+    public MyType : extends Object
+    {
+        // Property initializations load during Script instancing, i.e. .new().
+        // No "preload" loads during scene load exists in C#.
+
+        // Initialize with a value. Editable at runtime.
+        public Script MyScript = GD.Load("MyScript.cs");
+
+        // Initialize with same value. Value locked.
+        public const Script MyConstScript = GD.Load("MyScript.cs");
+
+        // Like 'const' due to inaccessible setter.
+        // But, value can be set during constructor, i.e. MyType().
+        public Script Library { get; } = GD.Load("res://addons/plugin/library.gd") as Script;
+
+        // If need a "const [Export]" (which doesn't exist), use a 
+        // conditional setter for a tool script that checks if it's executing
+        // in the editor.
+        [Export]
+        public PackedScene EnemyScn
+        {
+            get;
+            
+            set
+            {
+                if (Engine.IsEditorHint())
+                {
+                    EnemyScn = value;
+                }
+            }
+        };
+
+        // Warn users if the value hasn't been set
+        public String _GetConfigurationWarning()
+        {
+            if (EnemyScn == null)
+                return "Must initialize property 'const_script'.";
+            return "";
+        }
+    }
+
+Note the following:
+
+1. There are many ways in which a language can load such resources.
+
+2. When designing how objects will access data, don't forget
+   that one can pass resources around as references as well.
+
+3. Keep in mind that loading a resource fetches the cached resource
+   instance maintained by the engine. To get a new object, one must
+   :ref:`duplicate <class_Resource_method_duplicate>` an existing reference or 
+   instantiate one from scratch with ``new()``.
+
+Nodes likewise have an alternative access point: the SceneTree.
+
+.. tabs::
+  .. code-tab:: gdscript GDScript
+
+    extends Node
+
+    # Slow
+    func dynamic_lookup_with_dynamic_nodepath():
+        print(get_node("Child"))
+
+    # Faster. GDScript only
+    func dynamic_lookup_with_cached_nodepath():
+        print($Child)
+
+    # Fastest. Doesn't break if node moves later.
+    # Note that `onready` keyword is GDScript only.
+    # Other languages must do...
+    #     var child
+    #     func _ready():
+    #         child = get_node("Child")
+    onready var child = $Child
+    func lookup_and_cache_for_future_access():
+        print(child)
+    
+    # Delegate reference assignment to an external source
+    # Con: need to perform a validation check
+    # Pro: node makes no requirements of its external structure.
+    #      'prop' can come from anywhere.
+    var prop
+    func call_me_after_prop_is_initialized_by_parent():
+        # validate prop in one of three ways
+
+        # fail with no notification
+        if not prop:
+            return
+        
+        # fail with an error message
+        if not prop:
+            printerr("'prop' wasn't initialized")
+            return
+        
+        # fail and terminate
+        # Compiled scripts in final binary do not include assert statements
+        assert prop
+
+    # Use an autoload.
+    # Dangerous for typical nodes, but useful for true singleton nodes
+    # that manage their own data and don't interfere with other objects.
+    func reference_a_global_autoloaded_variable():
+        print(globals)
+        print(globals.prop)
+        print(globals.my_getter())
+
+  .. code-tab:: csharp
+
+    public class MyNode
+    {
+        // Slow, dynamic lookup with dynamic NodePath.
+        public void Method1()
+        {
+            GD.Print(GetNode(NodePath("Child")));
+        }
+
+        // Fastest. Lookup node and cache for future access.
+        // Doesn't break if node moves later.
+        public Node Child;
+        public void _Ready()
+        {
+            Child = GetNode(NodePath("Child"));
+        }
+        public void Method2()
+        {
+            GD.Print(Child);
+        }
+
+        // Delegate reference assignment to an external source
+        // Con: need to perform a validation check
+        // Pro: node makes no requirements of its external structure.
+        //      'prop' can come from anywhere.
+        public object Prop;
+        public void CallMeAfterPropIsInitializedByParent() {
+            // Validate prop in one of three ways
+
+            // Fail with no notification
+            if (prop == null)
+            {
+                return;
+            }
+            
+            // Fail with an error message
+            if (prop == null)
+            {
+                GD.PrintErr("'Prop' wasn't initialized");
+                return;
+            }
+            
+            // Fail and terminate
+            Debug.Assert(Prop, "'Prop' wasn't initialized");
+        }
+
+        // Use an autoload.
+        // Dangerous for typical nodes, but useful for true singleton nodes
+        // that manage their own data and don't interfere with other objects.
+        public void ReferenceAGlobalAutoloadedVariable()
+        {
+            Node globals = GetNode(NodePath("/root/Globals"));
+            GD.Print(globals);
+            GD.Print(globals.prop);
+            GD.Print(globals.my_getter());
+        }
+    };
+
+Accessing data or logic from an object
+--------------------------------------
+
+Godot's scripting API is duck-typed. This means that if a script executes an
+operation, Godot doesn't validate that it supports the operation by **type**.
+It instead checks that the object **implements** the individual method.
+
+For example, the :ref:`CanvasItem <class_CanvasItem>` class has a ``visible``
+property. All properties exposed to the scripting API are in fact a setter and
+getter pair bound to a name. If one tried to access 
+:ref:`CanvasItem.visible <class_CanvasItem_property_visible>`, then Godot would do the
+following checks, in order:
+
+- If the object has a script attached, it will attempt to set the property
+  through the script. This leaves open the opportunity for scripts to override
+  a property defined on a base object by overriding the setter method for the
+  property.
+
+- If the script does not have the property, it performs a HashMap lookup in
+  the ClassDB for the "visible" property against the CanvasItem class and all
+  of its inherited types. If found, it will call the bound setter or getter.
+  For more information about HashMaps, see the
+  :ref:`data preferences <doc_data_preferences>` docs.
+
+- If not found, it does an explicit check to see if the user wants to access
+  the "script" or "meta" properties.
+
+- If not, it checks for a ``_set``/``_get`` implementation (depending on type
+  of access) in the CanvasItem and its inherited types. These methods can
+  execute logic that gives the impression that the Object has a property. This
+  is also the case with the ``_get_property_list`` method.
+
+  - Note that this happens even for non-legal symbol names such as in the
+    case of :ref:`TileSet <class_TileSet>`'s "1/tile_name" property. This
+    refers to the name of the tile with ID 1, i.e.
+    :ref:`TileSet.tile_get_name(1) <class_TileSet_method_tile_get_name>`.
+
+As a result, this duck-typed system can locate a property either in the script,
+the object's class, or any class that object inherits, but only for things
+which extend Object.
+
+Godot provides a variety of options for performing runtime checks on these
+accesses:
+
+- A duck-typed property access. These will property check (as described above).
+  If the operation isn't supported by the object, execution will halt.
+
+  .. tabs::
+    .. code-tab:: gdscript GDScript
+    
+      # All Objects have duck-typed get, set, and call wrapper methods
+      get_parent().set("visible", false)
+
+      # Using a symbol accessor, rather than a string in the method call,
+      # will implicitly call the `set` method which, in turn, calls the
+      # setter method bound to the property through the property lookup
+      # sequence.
+      get_parent().visible = false
+
+      # Note that if one defines a _set and _get that describe a property's
+      # existence, but the property isn't recognized in any _get_property_list
+      # method, then the set() and get() methods will work, but the symbol
+      # access will claim it can't find the property.
+
+    .. code-tab:: csharp
+
+      // All Objects have duck-typed Get, Set, and Call wrapper methods
+      GetParent().Set("visible", false);
+
+      // C# is a static language, so it has no dynamic symbol access, e.g.
+      // `GetParent().Visible = false` won't work
+
+- A method check. In the case of 
+  :ref:`CanvasItem.visible <class_CanvasItem_property_visible>`, one can
+  access the methods, ``set_visible`` and ``is_visible`` like any other method.
+
+  .. tabs::
+    .. code-tab:: gdscript GDScript
+
+      var child = GetChild(0)
+    
+      # Dynamic lookup
+      child.call("set_visible", false)
+
+      # Symbol-based dynamic lookup
+      # GDScript aliases this into a 'call' method behind the scenes.
+      child.set_visible(false)
+
+      # Dynamic lookup, checks for method existence first
+      if child.has("set_visible"):
+          child.set_visible(false)
+  
+      # Cast check, followed by dynamic lookup
+      # Useful when you make multiple "safe" calls knowing that the class
+      # implements them all. No need for repeated checks.
+      # Tricky if one executes a cast check for a user-defined type as it
+      # forces more dependencies.
+      if child is CanvasItem:
+          child.set_visible(false)
+          child.show_on_top = true
+        
+      # If one does not wish to fail these checks without notifying users, one
+      # can use an assert instead. These will trigger runtime errors
+      # immediately if not true.
+      assert child.has("set_visible")
+      assert child.is_in_group("offer")
+      assert child is CanvasItem
+
+      # Can also use object labels to imply an interface, i.e. assume it implements certain methods.
+      # There are two types, both of which only exist for Nodes: Names and Groups
+
+      # Assuming...
+      # A "Quest" object exists and 1) that it can "complete" or "fail" and
+      # that it will have text available before and after each state...
+
+      # 1. Use a name
+      var quest = $Quest
+      print(quest.text)
+      quest.complete() # or quest.fail()
+      print(quest.text) # implied new text content
+
+      # 2. Use a group
+      for a_child in get_children():
+          if a_child.is_in_group("quest"):
+              print(quest.text)
+              quest.complete() # or quest.fail()
+              print(quest.text) # implied new text content
+    
+      # Note that these interfaces are project-specific conventions the team
+      # defines (which means documentation! But maybe worth it?).
+      # Any script that conforms to the documented "interface" of the name/group can fill in for it.
+
+    .. code-tab:: csharp
+
+      Node child = GetChild(0);
+
+      // Dynamic lookup
+      child.Call("SetVisible", false); 
+
+      // Dynamic lookup, checks for method existence first
+      if (child.HasMethod("SetVisible"))
+      {
+          child.Call("SetVisible", false);
+      }
+
+      // Use a group as if it were an "interface", i.e. assume it implements certain methods
+      // requires good documentation for the project to keep it reliable (unless you make
+      // editor tools to enforce it at editor time.
+      // Note, this is generally not as good as using an actual interface in C#,
+      // but you can't set C# interfaces from the editor since they are
+      // language-level features.
+      if (child.IsInGroup("Offer"))
+      {
+          child.Call("Accept");
+          child.Call("Reject");
+      }
+
+      // Cast check, followed by static lookup
+      CanvasItem ci = GetParent() as CanvasItem;
+      if (ci != null)
+      {
+          ci.SetVisible(false);
+
+          // useful when you need to make multiple safe calls to the class
+          ci.ShowOnTop = true;
+      }
+
+      // If one does not wish to fail these checks without notifying users, one
+      // can use an assert instead. These will trigger runtime errors
+      // immediately if not true.
+      Debug.Assert(child.HasMethod("set_visible"));
+      Debug.Assert(child.IsInGroup("offer"));
+      Debug.Assert(CanvasItem.InstanceHas(child));
+
+      // Can also use object labels to imply an interface, i.e. assume it implements certain methods.
+      // There are two types, both of which only exist for Nodes: Names and Groups
+
+      // Assuming...
+      // A "Quest" object exists and 1) that it can "Complete" or "Fail" and
+      // that it will have Text available before and after each state...
+
+      // 1. Use a name
+      Node quest = GetNode("Quest");
+      GD.Print(quest.Get("Text"));
+      quest.Call("Complete"); // or "Fail"
+      GD.Print(quest.Get("Text")); // implied new text content
+
+      // 2. Use a group
+      foreach (Node AChild in GetChildren())
+      {
+          if (AChild.IsInGroup("quest"))
+          {
+            GD.Print(quest.Get("Text"));
+            quest.Call("Complete"); // or "Fail"
+            GD.Print(quest.Get("Text")); // implied new text content
+          }
+      }
+    
+      // Note that these interfaces are project-specific conventions the team
+      // defines (which means documentation! But maybe worth it?)..
+      // Any script that conforms to the documented "interface" of the
+      // name/group can fill in for it. Also note that in C#, these methods
+      // will be slower than static accesses with traditional interfaces.
+
+- Outsource the access to a :ref:`FuncRef <class_FuncRef>`. These may be useful
+  in cases where one needs the max level of freedom from dependencies. In
+  this case, one relies on an external context to setup the method.
+
+..tabs::
+  ..code-tab:: gdscript GDScript
+    
+    # child.gd
+    extends Node
+    var fn = null
+
+    func my_method():
+        if fn:
+            fn.call_func()
+  
+    # parent.gd
+    extends Node
+
+    onready var child = $Child
+
+    func _ready():
+        child.fn = funcref(self, "print_me")
+        child.my_method()
+
+    func print_me():
+        print(name)
+
+  ..code-tab:: csharp
+    
+    // Child.cs
+    public class Child extends Node
+    {
+        public FuncRef FN = null;
+
+        public void MyMethod()
+        {
+            Debug.Assert(FN != null);
+            FN.CallFunc();
+        }
+    }
+
+    // Parent.cs
+    public class Parent extends Node
+    {
+        public Node Child;
+        
+        public void _Ready()
+        {
+            Child = GetNode("Child");
+            Child.Set("FN", GD.FuncRef(this, "PrintMe"));
+            Child.MyMethod();
+        }
+
+        public void PrintMe() {
+        {
+            GD.Print(GetClass());
+        }
+    }
+
+These strategies contribute to Godot's flexible design. Between them, users
+have a breadth of tools to meet their specific needs.

+ 288 - 0
getting_started/workflow/best_practices/godot_notifications.rst

@@ -0,0 +1,288 @@
+.. _doc_godot_notifications:
+
+Godot notifications
+===================
+
+Every Object in Godot implements a
+:ref:`_notification <class_Object_method__notification>` method. Its purpose is to
+allow the Object to respond to a variety of engine-level callbacks that may
+relate to it. For example, if the engine tells a
+:ref:`CanvasItem <class_CanvasItem>` to "draw", it will call
+``_notification(NOTIFICATION_DRAW)``.
+
+Some of these notifications, like draw, are useful to override in scripts. So
+much so that Godot exposes many of them with dedicated functions:
+
+- ``_ready()`` : NOTIFICATION_READY
+
+- ``_enter_tree()`` : NOTIFICATION_ENTER_TREE
+
+- ``_exit_tree()`` : NOTIFICATION_EXIT_TREE
+
+- ``_process(delta)`` : NOTIFICATION_PROCESS
+
+- ``_physics_process(delta)`` : NOTIFICATION_PHYSICS_PROCESS
+
+- ``_input()`` : NOTIFICATION_INPUT
+
+- ``_unhandled_input()`` : NOTIFICATION_UNHANDLED_INPUT
+
+- ``_draw()`` : NOTIFICATION_DRAW
+
+What users might *not* realize is that notifications exist for types other
+than Node alone:
+
+- :ref:`Object::NOTIFICATION_POSTINITIALIZE <class_Object_constant_NOTIFICATION_POSTINITIALIZE>`:
+  a callback that triggers during object initialization. Not accessible to scripts.
+
+- :ref:`Object::NOTIFICATION_PREDELETE <class_Object_constant_NOTIFICATION_PREDELETE>`:
+  a callback that triggers before the engine deletes an Object, i.e. a
+  'destructor'.
+  
+- :ref:`MainLoop::NOTIFICATION_WM_MOUSE_ENTER <class_MainLoop_constant_NOTIFICATION_WM_MOUSE_ENTER>`:
+  a callback that triggers when the mouse enters the window in the operating
+  system that displays the game content.
+
+And many of the callbacks that *do* exist in Nodes don't have any dedicated
+methods, but are still quite useful.
+
+- :ref:`Node::NOTIFICATION_PARENTED <class_Node_constant_NOTIFICATION_PARENTED>`:
+  a callback that triggers anytime one adds a child node to another node.
+
+- :ref:`Node::NOTIFICATION_UNPARENTED <class_Node_constant_NOTIFICATION_UNPARENTED>`:
+  a callback that triggers anytime one removes a child node from another
+  node.
+
+- :ref:`Popup::NOTIFICATION_POST_POPUP <class_Popup_constant_NOTIFICATION_POST_POPUP>`:
+  a callback that triggers after a Popup node completes any ``popup*`` method.
+  Note the difference from its ``about_to_show`` signal which triggers
+  *before* its appearance.
+
+One can access all these custom notifications from the universal
+``_notification`` method. 
+
+..note::
+  Methods in the documentation labeled as "virtual" are also intended to be
+  overridden by scripts.
+  
+  A classic example is the
+  :ref:`_init <class_Object_method__init>` method in Object. While it has no
+  NOTIFICATION_* equivalent, the engine still calls the method. Most languages
+  (except C#) rely on it as a constructor.
+
+So, in which situation should one use each of these notifications or
+virtual functions?
+
+_process vs. _physics_process vs. *_input
+-----------------------------------------
+
+Use ``_process`` when one needs a framerate-dependent deltatime between
+frames. If code that updates object data needs to update as often as
+possible, this is the right place. Recurring logic checks and data caching
+often execute here, but it comes down to the frequency at which one needs
+the evaluations to update. If they don't need to execute every frame, then
+implementing a Timer-yield-timeout loop is another option.
+
+.. tabs::
+ .. code-tab::
+    
+    # Infinitely loop, but only execute whenever the Timer fires.
+    # Allows for recurring operations that don't trigger script logic
+    # every frame (or even every fixed frame).
+    while true:
+        my_method()
+        $Timer.start()
+        yield($Timer, "timeout")
+
+Use ``_physics_process`` when one needs a framerate-independent deltatime
+between frames. If code needs consistent updates over time, regardless
+of how fast or slow time advances, this is the right place.
+Recurring kinematic and object transform operations should execute here. 
+
+While it is possible, to achieve the best performance, one should avoid
+making input checks during these callbacks. ``_process`` and
+``_physics_process`` will trigger at every opportunity (they do not "rest" by
+default). In contrast, ``*_input`` callbacks will trigger only on frames in
+which the engine has actually detected the input.
+
+One can check for input actions within the input callbacks just the same.
+If one wants to use delta time, one can fetch it from the
+:ref:`Performance <class_Performance>` singleton as needed.
+
+.. tabs::
+  .. code-tab:: gdscript GDScript
+
+    # Called every frame, even when the engine detects no input
+    func _process(delta):
+        if Input.action_just_pressed("ui_select"):
+            print(delta)
+
+    # Called during every input event
+    func _unhandled_input(event):
+        match event.get_class():
+            "InputEventKey":
+                if Input.is_action_just_pressed("ui_accept"):
+                    print(Performance.get_monitor(Performance.TIME_PROCESS))
+
+  .. code-tab:: csharp
+
+    public class MyNode : public Node {
+
+        // Called every frame, even when the engine detects no input
+        public void _Process(float delta) {
+            if (GD.Input.ActionJustPressed("UiSelect")) {
+                GD.Print(string(delta));
+            }
+        }
+
+        // Called during every input event. Equally true for _input().
+        public void _UnhandledInput(InputEvent event) {
+            switch (event.GetClass()) {
+                case "InputEventAction":
+                    GD.Print(string(GD.Performance.GetMonitor(GD.Performance.TIME_PROCESS)));
+                    break;
+                default:
+                    break;
+            }
+        }
+
+    }
+
+_init vs. initialization vs. export
+-----------------------------------
+
+If the script initializes its own node subtree, without a scene,
+that code should execute here. Other property or SceneTree-independent
+initializations should also run here. This triggers before ``_ready`` or
+``_enter_tree``, but after a script creates and initializes its properties.
+
+Scripts have three types of property assignments that can occur during
+instantiation:
+
+.. tabs::
+  .. code-tab:: gdscript GDScript
+  
+    # "one" is an "initialized value". These DO NOT trigger the setter.
+    # If someone set the value as "two" from the Inspector, this would be an
+    # "exported value". These DO trigger the setter.
+    export(String) var test = "one" setget set_test
+
+    func _init():
+        # "three" is an "init assignment value".
+        # These DO NOT trigger the setter, but...
+        test = "three"
+        # These DO trigger the setter. Note the `self` prefix.
+        self.test = "three"
+  
+    func set_test(value):
+        test = value
+        print("Setting: ", test)
+
+  .. code-tab:: csharp
+
+    // "one" is an "initialized value". These DO NOT trigger the setter.
+    // If one set the value as "two" from the Inspector, this would be an
+    // "exported value". These DO trigger the setter.
+    [Export]
+    public string Test = "one"
+    {
+        get;
+        set
+        {
+            Test = value;
+            GD.Print("Setting: " + Test);
+        }
+    }
+
+    public void _Init() {
+        // "three" is an "init assignment value".
+        // These DO (NOT?) trigger the setter.
+        Test = "three";
+    }
+
+When instantiating a scene, property values will set up according to the
+following sequence:
+
+1. **Initial value assignment:** instantiation will assign either the
+   initialization value or the init assignment value. Init assignments take
+   priority over initialization values.
+
+2. **Exported value assignment:** If instancing from a scene rather than
+   a script, Godot will assign the exported value to replace the initial
+   value defined in the script.
+
+As a result, instantiating a script versus a scene will affect both the
+initialization *and* the number of times the engine calls the setter.
+  
+_ready vs. _enter_tree vs. NOTIFICATION_PARENTED
+------------------------------------------------
+
+When instantiating a scene connected to the first executed scene, Godot will
+instantiate nodes down the tree (making ``_init`` calls) and build the tree
+going downwards from the root. This causes ``_enter_tree`` calls to cascade
+down the tree. Once the tree is complete, leaf nodes call ``_ready``. A node
+will call this method once all child nodes have finished calling theirs. This
+then causes a reverse cascade going up back to the tree's root.
+
+When instantiating a script or a standalone scene, nodes are not
+added to the SceneTree upon creation, so no ``_enter_tree`` callbacks
+trigger. Instead, only the ``_init`` and later ``_ready`` calls occur.
+
+If one needs to trigger behavior that occurs as nodes parent to another,
+regardless of whether it occurs as part of the main/active scene or not, one
+can use the :ref:`PARENTED <class_Node_constant_NOTIFICATION_PARENTED>` notification.
+For example, here is a snippet that connects a node's method to
+a custom signal on the parent node without failing. Useful on data-centric
+nodes that one might create at runtime.
+
+..tabs::
+  ..code-tab:: gdscript GDScript
+
+    extends Node
+
+    var parent_cache
+
+    func connection_check():
+        return parent.has_user_signal("interacted_with")
+        
+    func _notification(what):
+        match what:
+            NOTIFICATION_PARENTED:
+                parent_cache = get_parent()
+                if connection_check():
+                    parent_cache.connect("interacted_with", self, "_on_parent_interacted_with")
+            NOTIFICATION_UNPARENTED:
+                if connection_check():
+                    parent_cache.disconnect("interacted_with", self, "_on_parent_interacted_with")
+  
+    func _on_parent_interacted_with():
+        print("I'm reacting to my parent's interaction!")
+
+  ..code-tab:: csharp
+
+    public class MyNode extends Node {
+
+        public Node ParentCache = null;
+
+        public void ConnectionCheck() {
+            return ParentCache.HasUserSignal("InteractedWith");
+        }
+
+        public void _Notification(int What) {
+            switch (What) {
+                case NOTIFICATION_PARENTED:
+                    ParentCache = GetParent();
+                    if (ConnectionCheck())
+                        ParentCache.Connect("InteractedWith", this, "OnParentInteractedWith");
+                    break;
+                case NOTIFICATION_UNPARENTED:
+                    if (ConnectionCheck())
+                        ParentCache.Disconnect("InteractedWith", this, "OnParentInteractedWith");
+                    break;
+            }
+        }
+         
+        public void OnParentInteractedWith() {
+            GD.Print("I'm reacting to my parent's interaction!");
+        }
+    }

+ 17 - 0
getting_started/workflow/best_practices/index.rst

@@ -0,0 +1,17 @@
+Scene workflow
+===============
+
+.. toctree::
+   :maxdepth: 1
+   :name: toc-best-practices
+
+   introduction_best_practices
+   what_are_godot_classes
+   scene_organization
+   scenes_versus_scripts
+   autoloads_versus_internal_nodes
+   node_alternatives
+   godot_interfaces
+   godot_notifications
+   data_preferences
+   logic_preferences

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

@@ -0,0 +1,24 @@
+.. _doc_introduction_best_practices:
+
+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 "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.

+ 162 - 0
getting_started/workflow/best_practices/logic_preferences.rst

@@ -0,0 +1,162 @@
+.. _doc_logic_preferences:
+
+Logic preferences
+=================
+
+Ever wondered whether one should approach problem X with strategy Y or Z?
+This article covers a variety of topics related to these dilemmas.
+
+Loading vs. preloading
+----------------------
+
+In GDScript, there exists the global
+:ref:`preload <class_@GDScript_method_preload>` method. It loads resources as
+early as possible to front-load the "loading" operations and avoid loading
+resources while in the middle of performance-sensitive code.
+
+Its counterpart, the :ref:`load <class_@GDScript_method_load>` method, loads a
+resource only when it reaches the load statement. That is, it will load a
+resource in-place which can cause slowdowns then it occurs in the middle of
+sensitive processes. The ``load`` function is also an alias for
+:ref:`ResourceLoader.load(path) <class_ResourceLoader_method_load>` which is
+accessible to *all* scripting languages.
+
+So, when exactly does preloading occur versus loading, and when should one use
+either? Let's see an example:
+
+.. tabs::
+  .. code-tab:: gdscript GDScript
+
+    # my_buildings.gd
+    extends Node
+
+    # (note how constant scripts/scenes have a diferent naming scheme than
+    # their property variants).
+  
+    # This value is a constant, so it spawns when the Script object loads.
+    # The script is preloading the value. The advantage here is that the editor
+    # can offer autocompletion since it must be a static path.
+    const BuildingScn = preload("building.tscn")
+
+    # 1. The script preloads the value, so it will load as a dependency
+    #    of the 'my_buildings.gd' script file. But, because this is a
+    #    property rather than a constant, the object won't copy the preloaded
+    #    PackedScene resource into the property until the script instantiates
+    #    with .new().
+    # 
+    # 2. The preloaded value is inaccessible from the Script object alone. As
+    #    such, preloading the value here actually does not benefit anyone.
+    # 
+    # 3. Because the user exports the value, if this script stored on 
+    #    a node in a scene file, the scene instantation code will overwrite the
+    #    preloaded initial value anyway (wasting it). It's usually better to
+    #    provide null, empty, or otherwise invalid default values for exports.
+    # 
+    # 4. It is when one instantiates this script on its own with .new() that
+    #    one will load "office.tscn" rather than the exported value.
+    export(PackedScene) var a_building = preload("office.tscn")
+
+    # Uh oh! This results in an error!
+    # One must assign constant values to constants. Because `load` performs a
+    # runtime lookup by its very nature, one cannot use it to initialize a
+    # constant.
+    const OfficeScn = load("office.tscn")
+
+    # Successfully loads and only when one instantiates the script! Yay!
+    var office_scn = load("office.tscn")
+
+  .. code-tab:: csharp
+
+    using System;
+    using GD;
+
+    public class MyBuildings : public Node {
+
+        public const PackedScene Building { get; set; }
+        
+        public PackedScene ABuilding = GD.load("office.tscn") as PackedScene;
+
+        public void MyBuildings() {
+            // Can assign the value during initialization or during a constructor.
+            Building = ResourceLoader.load("building.tscn") as PackedScene;
+
+            // C# and other languages have no concept of "preloading".
+        }
+    }
+
+Preloading allows the script to handle all the loading the moment one loads the
+script. Preloading is useful, but there are also times when one doesn't wish
+for it. To distinguish these situations, there are a few things one can
+consider:
+
+1. If one cannot determine when the script might load, then preloading a
+   resource, especially a scene or script, could result in further loads one
+   does not expect. This could lead to unintentional, variable-length
+   load times on top of the original script's load operations.
+
+2. If something else could replace the value (like a scene's exported
+   initialization), then preloading the value has no meaning. This point isn't
+   a significant factor if one intends to always create the script on its own.
+
+3. If one wishes only to 'import' another class resource (script or scene),
+   then using a preloaded constant is often the best course of action. However,
+   in exceptional cases, one my wish not to do this:
+
+   1. If the 'imported' class is liable to change, then it should be a property
+      instead, initialized either using an ``export`` or a ``load`` (and
+      perhaps not even initialized until later).
+
+   2. If the script requires a great many dependencies, and one does not wish
+      to consume so much memory, then one may wish to, load and unload various
+      dependencies at runtime as circumstances change. If one preloads
+      resources into constants, then the only way to unload these resources
+      would be to unload the entire script. If they are instead loaded
+      properties, then one can set them to ``null`` and remove all references
+      to the resource entirely (which, as a
+      :ref:`Reference <class_Reference>`-extending type, will cause the
+      resources to delete themselves from memory).
+
+Large levels: static vs. dynamic
+--------------------------------
+
+If one is creating a large level, which circumstances are most appropriate?
+Should they create the level as one static space? Or should they load the
+level in pieces and shift the world's content as needed?
+
+Well, the simple answer is , "when the performance requires it." The
+dilemma associated with the two options is one of the age-old programming
+choices: does one optimize memory over speed, or vice versa?
+
+The naive answer is to use a static level that loads everything at once.
+But, depending on the project, this could consume a large amount of
+memory. Wasting users' RAM leads to programs running slow or outright
+crashing from everything else the computer tries to do at the same time.
+
+No matter what, one should break larger scenes into smaller ones (to aid
+in reusability of assets). Developers can then design a node that manages the
+creation/loading and deletion/unloading of resources and nodes in real-time.
+Games with large and varied environments or procedurally generated
+elements often implement these strategies to avoid wasting memory.
+
+On the flip side, coding a dynamic system is more complex, i.e. uses more
+programmed logic, which results in opportunities for errors and bugs. If one
+isn't careful, they can develop a system that bloats the technical debt of
+the application.
+
+As such, the best options would be...
+
+1. To use a static level for smaller games.
+
+2. If one has the time/resources on a medium/large game, create a library or
+   plugin that can code the management of nodes and resources. If refined
+   over time, so as to improve usability and stability, then it could evolve
+   into a reliable tool across projects.
+
+3. Code the dynamic logic for a medium/large game because one has the coding
+   skills, but not the time or resources to refine the code (game's
+   gotta get done). Could potentially refactor later to outsource the code
+   into a plugin.
+
+For an example of the various ways one can swap scenes around at runtime,
+please see the :ref:`"Change scenes manually" <doc_change_scenes_manually>`
+documentation.

+ 62 - 0
getting_started/workflow/best_practices/node_alternatives.rst

@@ -0,0 +1,62 @@
+.. _doc_node_alternatives:
+
+When and how to avoid using nodes for everything
+================================================
+
+
+Nodes are cheap to produce, but even they have their limits. A project may
+have tens of thousands of nodes all doing things. The more complex their
+behavior though, the larger the strain each one adds to a project's
+performance.
+
+Godot provides more lightweight objects for creating APIs which nodes use.
+Be sure to keep these in mind as options when designing how you wish to build
+your project's features.
+
+1. :ref:`Object <class_Object>`: The ultimate lightweight object, the original
+   Object must use manual memory management. With that said, it isn't too
+   difficult to create one's own custom data structures, even node structures,
+   that are also lighter than the :ref:`Node <class_Node>` class.
+
+   - Example: see the :ref:`Tree <class_Tree>` node. It supports a high level
+     of customization for a table of content with an arbitrary number of
+     rows and columns. The data that it uses to generate its visualization
+     though is actually a tree of :ref:`TreeItem <class_TreeItem>` Objects.
+
+   - Advantages: Simplifying one's API to smaller scoped objects helps improve
+     its accessibility improve iteration time. Rather than working with the
+     entire Node library, one creates an abbreviated set of Objects from which
+     a node can generate and manage the appropriate sub-nodes.
+
+   - Note: One should be careful when handling them. One can store an Object
+     into a variable, but these references can become invalid without warning.
+     For example, if the object's creator decides to delete it out of nowhere,
+     this would trigger an error state when one next accesses it.
+
+2. :ref:`Reference <class_Reference>`: Only a little more complex than Object.
+   They track references to themselves, only deleting loaded memory when no
+   further references to themselves exist. These are useful in the majority of
+   cases where one needs data in a custom class.
+
+   - Example: see the :ref:`File <class_File>` object. It functions
+     just like a regular Object except that one need not delete it themselves.
+
+   - Advantages: same as the Object.
+
+3. :ref:`Resource <class_Resource>`: Only slightly more complex than Reference.
+   They have the innate ability to serialize/deserialize (i.e. save and load)
+   their object properties to/from Godot resource files.
+
+   - Example: Scripts, PackedScene (for scene files), and other types like
+     each of the :ref:`AudioEffect <class_AudioEffect>` classes. Each of these
+     can be save and loaded, therefore they extend from Resource.
+
+   - Advantages: Much has
+     :ref:`already been said <http://docs.godotengine.org/en/latest/getting_started/step_by_step/resources.html#creating-your-own-resources>`
+     on :ref:`Resource <class_Resource>`'s advantages over traditional data
+     storage methods. In the context of using Resources over Nodes though,
+     their main advantage is in Inspector-compatibility. While nearly as
+     lightweight as Object/Reference, they can still display and export
+     properties in the Inspector. This allows them to fulfill a purpose much
+     like sub-Nodes on the usability front, but also improve performance if
+     one plans to have many such Resources/Nodes in their scenes.

+ 391 - 0
getting_started/workflow/best_practices/scene_organization.rst

@@ -0,0 +1,391 @@
+.. _doc_scene_organization:
+
+Scene organization
+==================
+
+This article covers topics related to the effective organization of
+scene content. Which nodes should one use? Where should one place them?
+How should they interact?
+
+How to build relationships effectively
+--------------------------------------
+
+When Godot users begin crafting their own scenes, they often run into the
+following problem:
+
+They create their first scene and fill it with content before the creeping
+sense that they need to split it up into re-usable pieces haunts them. They
+save branches of their scene into their own scene. However, they then notice
+that the hard references they were able to rely on before are no longer
+possible. Re-using the scene in multiple places creates issues because the
+node paths do not find their targets. Signal connections established in the
+editor break.
+
+To fix these problems, one must instantiate the sub-scenes without them
+requiring details about their environment. One needs to be able to trust
+that the sub-scene will create itself without being picky about how one uses
+it.
+
+One of the biggest things to consider in OOP is maintaining
+focused, singular-purpose classes with
+`loose coupling <https://en.wikipedia.org/wiki/Loose_coupling>`_
+to other parts of the codebase. This keeps the size of objects small (for
+maintainability) and improves their reusability so that re-writing completed
+logic is unnecessary.
+
+These OOP best practices have *several* ramifications for the best practices
+in scene structure and script usage.
+
+**If at all possible, one should design scenes to have no dependencies.**
+That is, one should create scenes that keep everything they need within
+themselves.
+
+If a scene must interact with an external context, experienced developers
+recommend the use of 
+`Dependency Injection <https://en.wikipedia.org/wiki/Dependency_injection>`_.
+This technique involves having a high-level API provide the dependencies of the
+low-level API. Why do this? Because classes which rely on their external
+environment can inadvertantly trigger bugs and unexpected behavior.
+
+To do this, one must expose data and then rely on a parent context to
+initialize it:
+
+1. Connect to a signal. Extremely safe, but should use only to "respond" to
+   behavior, not start it. Note that signal names are usually past-tense verbs
+   like "entered", "skill_activated", or "item_collected".
+
+   ..tabs::
+     ..code-tab:: gdscript GDScript
+     
+       # Parent
+       $Child.connect("signal_name", object_with_method, "method_on_the_object")
+
+       # Child
+       emit_signal("signal_name") # Triggers parent-defined behavior
+
+     ..code-tab:: csharp
+
+       // Parent
+       GetNode("Child").Connect("SignalName", ObjectWithMethod, "MethodOnTheObject");
+
+       // Child
+       EmitSignal("SignalName"); // Triggers parent-defined behavior
+
+2. Call a method. Used to start behavior.
+       
+   ..tabs::
+     ..code-tab:: gdscript GDScript
+     
+       # Parent
+       $Child.method_name = "do"
+
+       # Child, assuming it has String property 'method_name' and method 'do'
+       call(method_name) # Call parent-defined method (which child must own)
+
+     ..code-tab:: csharp
+
+       // Parent
+       GetNode("Child").Set("MethodName", "Do");
+
+       // Child
+       Call(MethodName); // Call parent-defined method (which child must own)
+
+3. Initialize a :ref:`FuncRef <class_FuncRef>` property. Safer than a method
+   as ownership of the method is unnecessary. Used to start behavior.
+       
+   ..tabs::
+     ..code-tab:: gdscript GDScript
+     
+       # Parent
+       $Child.func_property = funcref(object_with_method, "method_on_the_object")
+
+       # Child
+       func_property.call_func() # Call parent-defined method (can come from anywhere)
+
+     ..code-tab:: csharp
+
+       // Parent
+       GetNode("Child").Set("FuncProperty", GD.FuncRef(ObjectWithMethod, "MethodOnTheObject"));
+
+       // Child
+       FuncProperty.CallFunc(); // Call parent-defined method (can come from anywhere)
+
+4. Initialize a Node or other Object reference.
+       
+   ..tabs::
+     ..code-tab:: gdscript GDScript
+     
+       # Parent
+       $Child.target = self
+
+       # Child
+       print(target) # Use parent-defined node
+
+     ..code-tab:: csharp
+
+       // Parent
+       GetNode("Child").Set("Target", this);
+
+       // Child
+       GD.Print(Target); // Use parent-defined node
+
+5. Initialize a NodePath.
+       
+   ..tabs::
+     ..code-tab:: gdscript GDScript
+     
+       # Parent
+       $Child.target_path = ".."
+
+       # Child
+       get_node(target_path) # Use parent-defined NodePath
+
+     ..code-tab:: csharp
+
+       // Parent
+       GetNode("Child").Set("TargetPath", NodePath(".."));
+
+       // Child
+       GetNode(TargetPath); // Use parent-defined NodePath
+
+These options hide the source of accesses from the child node. This in turn
+keeps the child **loosely coupled** to its environment. One can re-use it
+in another context without any extra changes to its API.
+
+.. note::
+
+  Although the examples above illustrate parent-child relationships,
+  the same principles apply towards all object relations. Nodes which
+  are siblings should only be aware of their hierarchies while an ancestor
+  mediates their communications and references.
+
+  ..tabs::
+    ..code-tab:: gdscript GDScript
+    
+      # Parent
+      $Left.target = $Right.get_node("Receiver")
+
+      # Left
+      var target: Node
+      func execute():
+          # Do something with 'target'
+
+      # Right
+      func _init():
+          var receiver = Receiver.new()
+          add_child(receiver)
+          
+    ..code-tab:: csharp
+
+      // Parent
+      GetNode("Left").Target = GetNode("Right/Receiver");
+
+      // Left
+      public Node Target = null;
+
+      public void Execute()
+      {
+          // Do something with 'Target'
+      }
+
+      // Right
+      public Node Receiver = null;
+
+      public Right()
+      {
+          Receiver = ResourceLoader.load("Receiver.cs").new();
+          AddChild(Receiver);
+      }
+    
+  The same principles also apply to non-Node objects that maintain dependencies
+  on other objects. Whichever object actually owns the objects should manage
+  the relationships between them.
+
+.. warning::
+
+  One should favor keeping data in-house (internal to a scene) though as
+  placing a dependency on an external context, even a loosely coupled one,
+  still means that the node will expect something in its environment to be
+  true. The project's design philosophies should prevent this from happening.
+  If not, the code's inherent liabilities will force developers to use
+  documentation to keep track of object relations on a microscopic scale; this
+  is otherwise known as development hell. Writing code that relies on external
+  documentation for one to use it safely is error-prone by default.
+  
+  To avoid creating and maintaining such documentation, one converts the
+  dependent node ("child" above) into a tool script that implements
+  :ref:`_get_configuration_warning() <class_Node_method__get_configuration_warning>`.
+  Returning a non-empty string from it will make the Scene dock generate a
+  warning icon with the string as a tooltip by the node. This is the same icon
+  that appears for nodes such as the
+  :ref:`Area2D <class_Area2D>` node when it has no child
+  :ref:`CollisionShape2D <class_CollisionShape2D>` nodes defined. The editor
+  then self-documents the scene through the script code. No content duplication
+  via documentation is necessary.
+  
+  A GUI like this can better inform project users of critical information about
+  a Node. Does it have external dependencies? Have those dependencies been
+  satisfied? Other programmers, and especially designers and writers, will need
+  clear instructions in the messages telling them what to do to configure it.
+
+So, why do all this complex switcharoo work? Well, because scenes operate
+best when they operate alone. If unable to work alone, then working with
+others anonymously (with minimal hard dependencies, i.e. loose coupling).
+If the inevitable changes made to a class cause it to interact with other
+scenes in unforeseen ways, then things break down. A change to one class could
+result in damaging effects to other classes.
+
+Scripts and scenes, as extensions of engine classes should abide
+by *all* OOP principles. Examples include...
+
+- `SOLID <https://en.wikipedia.org/wiki/SOLID>`_
+
+- `DRY <https://en.wikipedia.org/wiki/Don%27t_repeat_yourself>`_
+
+- `KISS <https://en.wikipedia.org/wiki/KISS_principle>`_
+
+- `YAGNI <https://en.wikipedia.org/wiki/You_aren%27t_gonna_need_it>`_
+
+Choosing a node tree structure
+------------------------------
+
+So, a developer starts work on a game only to stop at the vast possibilities
+before them. They might know what they want to do, what systems they want to
+have, but *where* to put them all? Well, how one goes about making their game
+is always up to them. One can construct node trees in a myriad of ways.
+But, for those who are unsure, this helpful guide can give them a sample of
+a decent structure to start with.
+
+A game should always have a sort of "entry point"; somewhere the developer can
+definitively track where things begin so that they can follow the logic as it
+continues elsewhere. This place also serves as a bird's eye view to all of the
+other data and logic in the program. For traditional applications, this would
+be the "main" function. In this case, it would be a Main node.
+
+    - Node "Main" (main.gd)
+
+The ``main.gd`` script would then serve as the primary controller of one's
+game.
+
+Then one has their actual in-game "World" (a 2D or 3D one). This can be a child
+of Main. In addition, one will need a primary GUI for their game that manages
+the various menus and widgets the project needs.
+
+    - Node "Main" (main.gd)
+        - Node2D/Spatial "World" (game_world.gd)
+        - Control "GUI" (gui.gd)
+
+When changing levels, one can then swap out the children of the "World" node.
+:ref:`Changing scenes manually <doc_change_scenes_manually>` gives users full
+control over how their game world transitions.
+
+The next step is to consider what gameplay systems one's project requires.
+If one has a system that...
+
+1. tracks all of its data internally
+2. should be globally accessible
+3. should exist in isolation
+
+...then one should create an
+:ref:`autoload 'singleton' node <doc_singletons_autoload>`.
+
+.. note::
+  
+  For smaller games, a simpler alternative with less control would be to have
+  a "Game" singleton that simply calls the
+  :ref:`SceneTree.change_scene() <class_SceneTree_method_change_scene>` method
+  to swap out the main scene's content. This structure more or less keeps
+  the "World" as the main game node.
+  
+  Any GUI would need to also be a
+  singleton, be transitory parts of the "World", or be manually added as a
+  direct child of the root. Otherwise, the GUI nodes would also delete
+  themselves during scene transitions.
+
+If one has systems that modify other systems' data, one should define those as
+their own scripts or scenes rather than autoloads. For more information on the
+reasons, please see the
+:ref:`'Autoloads vs. Internal Nodes' <doc_autoloads_versus_internal_nodes>`
+documentation.
+
+Each subsystem within one's game should have its own section within the
+SceneTree. One should use parent-child relationships only in cases where nodes
+are effectively elements of their parents. Does removing the parent reasonably
+mean that one should also remove the children? If not, then it should have its
+own place in the hierachy as a sibling or some other relation.
+
+.. note::
+
+  In some cases, one needs these separated nodes to *also* position themselves
+  relative to each other. One can use the
+  :ref:`RemoteTransform <class_RemoteTransform>` / 
+  :ref:`RemoteTransform2D <class_RemoteTransform2D>` nodes for this purpose.
+  They will allow a target node to conditionally inherit selected transform
+  elements from the Remote\* node. To assign the ``target``
+  :ref:`NodePath <class_NodePath>`, use one of the following:
+
+  1. A reliable third party, likely a parent node, to mediate the assignment.
+  2. A group, to easily pull a reference to the desired node (assuming there
+     will only ever be one of the targets). 
+
+  When should one do this? Well, it's up to them to decide. The dilemma
+  arises when one must micro-manage when a node must move around the SceneTree
+  to preserve itself. For example...
+
+  - Add a "player" node to a "room".
+  - Need to change rooms, so one must delete the current room.
+  - Before the room can be deleted, one must preserve and/or move the player.
+    Is memory a concern?
+    - If not, one can just create the two rooms, move the player
+      and delete the old one. No problem.
+    - If so, one will need to...
+      - Move the player somewhere else in the tree.
+      - Delete the room.
+      - Instantiate and add the new room.
+      - Re-add the player.
+  
+  The issue is that the player here is a "special case", one where the
+  developers must *know* that they need to handle the player this way for the
+  project. As such, the only way to reliably share this information as a team
+  is to *document* it. Keeping implementation details in documentation however
+  is dangerous. It's a maintenance burden, strains code readability, and bloats
+  the intellectual content of a project unnecessarily.
+
+  In a more complex game with larger assets, it can be a better idea to simply
+  keep the player somewhere else in the SceneTree entirely. This involves...
+  
+  1. More consistency.
+  2. No "special cases" that must be documented and maintained somewhere.
+  3. No opportunity for errors to occur because these details are not accounted
+     for.
+  
+  In contrast, if one ever needs to have a child node that does *not* inherit
+  the transform of their parent, one has the following options:
+  
+  1. The **declarative** solution: place a :ref:`Node <class_Node>` in between
+     them. As nodes with no transform, Nodes will not pass along such
+     information to their children.
+  2. The **imperative** solution: Use the ``set_as_toplevel`` setter for the
+     :ref:`CanvasItem <class_CanvasItem_method_set_as_toplevel>` or
+     :ref:`Spatial <class_Spatial_method_set_as_toplevel>` node. This will make
+     the node ignore its inherited transform.
+
+.. note::
+
+  If building a networked game, keep in mind which nodes and gameplay systems
+  are relevant to all players versus those just pertinent to the authoritative
+  server. For example, users do not all need to have a copy of every players'
+  "PlayerController" logic. Instead, they need only their own. As such, keeping
+  these in a separate branch from the "world" can help simplify the management
+  of game connections and the like.
+
+The key to scene organization is to consider the SceneTree in relational terms
+rather than spatial terms. Do the nodes need to be dependent on their parent's
+existence? If not, then they can thrive all by themselves somewhere else.
+If so, then it stands to reason they should be children of that parent (and
+likely part of that parent's scene if they aren't already).
+
+Does this mean nodes themselves are components? Not at all.
+Godot's node trees form an aggregation relationship, not one of composition.
+But while one still has the flexibility to move nodes around, it is still best
+when such moves are unnecessary by default.

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

@@ -0,0 +1,179 @@
+.. _doc_scenes_versus_scripts:
+
+When to use scenes versus scripts
+=================================
+
+We've already covered how scenes and scripts are different. Scripts
+define an engine class extension with imperative code, scenes with
+declarative code.
+
+Each system's capabilities are different as a result.
+Scenes can define how an extended class initializes, but not what its
+behavior actually is. Scenes are often used in conjunction with a script so
+that the scene acts as an extension of the scripts declarative code.
+
+Anonymous types
+---------------
+
+It *is* possible to completely define a scenes' contents using a script alone.
+This is, in essence, what the Godot Editor does, only in the C++ constructor
+of its objects. 
+
+But, choosing which one to use can be a dilemma. Creating script instances
+is identical to creating in-engine classes whereas handling scenes requires
+a change in API:
+
+    .. tabs::
+      .. code-tab:: gdscript GDScript
+
+        const MyNode = preload("my_node.gd")
+        const MyScene = preload("my_scene.tscn")
+        var node = Node.new()
+        var my_node = MyNode.new() # Same method call
+        var my_scene = MyScene.instance() # Different method call
+        var my_inherited_scene = MyScene.instance(PackedScene.GEN_EDIT_STATE_MAIN) # Create scene inheriting from MyScene
+
+      .. code-tab:: csharp
+
+        using System;
+        using Godot;
+
+        public class Game : Node
+        {
+            public const Script MyNodeScr = ResourceLoader.load("MyNode.cs") as Script;
+            public const PackedScene MySceneScn= ResourceLoader.load("MyScene.tscn") as PackedScene;
+            public Node ANode;
+            public Node MyNode;
+            public Node MyScene;
+            public Node MyInheritedScene;
+
+            public Game()
+            {
+                ANode = new Node();
+                MyNode = new MyNode(); // Same syntax
+                MyScene = MySceneScn.instance(); // different syntax
+                MyInheritedScene = MySceneScn.instance(PackedScene.GEN_EDIT_STATE_MAIN); // Create scene inheriting from MyScene
+            }
+        }
+
+Also, scripts will operate a little slower than scenes due to the
+speed differences between engine and script code. The larger and more complex
+the node, the more reason there is to build it as a scene.
+
+Named types
+-----------
+
+In some cases, a user can register a script as a new type within the editor
+itself. This displays it as a new type in the node or resource creation dialog
+with an optional icon. In these cases, the user's ability to use the script
+is much more streamlined. Rather than having to...
+
+1. Know the base type of the script they would like to use.
+
+2. Create an instance of that base type.
+
+3. Add the script to the node.
+
+   1. (Drag-n-drop method)
+
+      1. Find the script in the FileSystem dock.
+
+      2. Drag and drop the script onto the node in the Scene dock.
+
+   2. (Property method)
+
+      1. Scroll down to the bottom of the Inspector to find the ``script`` property and select it.
+
+      2. Select "Load" from the dropdown.
+
+      3. Select the script from the file dialog.
+
+With a registered script, the scripted type instead becomes a creation option
+like the other nodes and resources in the system. One need not do any of the
+above work. The creation dialog even has a search bar to look up the type by
+name.
+
+There are two systems for registering types...
+
+- `Custom Types <doc_making_plugins>`
+
+   - Editor-only. Typenames are not accessible at runtime.
+
+   - Does not support inherited custom types.
+
+   - An initializer tool. Creates the node with the script. Nothing more.
+
+   - Editor has no type-awareness of the script or its relationship
+     to other engine types or scripts.
+     
+   - Allows users to define an icon.
+
+   - Works for all scripting languages because it deals with Script resources in abstract.
+
+   - Set up using :ref:`EditorPlugin.add_custom_type <class_EditorPlugin_method_add_custom_type>`.
+
+- `Script Classes <https://godot.readthedocs.io/en/latest/getting_started/step_by_step/scripting_continued.html#register-scripts-as-classes>`_
+
+   - Editor and runtime accessible.
+
+   - Displays inheritance relationships in full.
+
+   - Creates the node with the script, but can also change types
+     or extend the type from the editor.
+
+   - Editor is aware of inheritance relationships between scripts,
+     script classes, and engine C++ classes.
+
+   - Allows users to define an icon.
+
+   - Engine developers must add support for languages manually (both name exposure and
+     runtime accessibility).
+
+   - Godot 3.1+ only.
+
+   - The Editor scans project folders and registers any exposed names for all
+     scripting languages. Each scripting language must implement its own
+     support for exposing this information.
+
+Both methodologies add names to the creation dialog, but script classes, in
+particular, also allow for users to access the typename without loading the
+script resource. Creating instances and accessing constants or static methods
+is viable from anywhere.
+
+With features like these, one may wish their type to be a script without a
+scene due to the ease of use it grants users. Those developing plugins or
+creating in-house tools for designers to use will find an easier time of things
+this way.
+
+On the downside, it also means having to use largely imperative programming.
+
+Conclusion
+----------
+
+In the end, the best approach is to consider the following:
+
+- If one wishes to create a basic tool that is going to be re-used in several
+  different projects and which people of all skill levels will likely use
+  (including those who don't label themselves as "programmers"), then chances
+  are that it should probably be a script, likely one with a custom name/icon.
+
+- If one wishes to create a concept that is particular to their game, then it
+  should always be a scene. Scenes are easier to track/edit and provide more
+  security than scripts.
+
+- If one would like to give a name to a scene, then they can still sort of do
+  this in 3.1 by declaring a script class and giving it a scene as a constant.
+  The script becomes, in effect, a namespace:
+
+  .. tabs::
+    .. code-tab:: gdscript GDScript
+
+      # game.gd
+      extends Reference
+      class_name Game # extends Reference, so it won't show up in the node creation dialog
+      const MyScene = preload("my_scene.tscn")
+
+      # main.gd
+      extends Node
+      func _ready():
+          add_child(Game.MyScene.instance())

+ 137 - 0
getting_started/workflow/best_practices/what_are_godot_classes.rst

@@ -0,0 +1,137 @@
+.. _doc_what_are_godot_classes:
+
+What are Godot classes really?
+==============================
+
+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.
+
+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.
+
+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...
+
+- 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.
+
+.. tabs::
+  .. code-tab:: gdscript GDScript
+    
+    # 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.
+
+  .. code-tab:: csharp
+
+    // Main.cs
+    using System;
+    using Godot;
+
+    namespace ExampleProject {
+        public class Main : Resource
+        {
+            public Node Child { get; set; }
+
+            public Main()
+            {
+                Child = new Node(); // Construct the child.
+                Child.Name = "Child"; // Change its name.
+                Child.Script = ResourceLoader.load("child.gd") as Script; // Give it custom features.
+                Child.Owner = this; // Serialize this node if this is saved.
+                AddChild(Child); // Add "Child" as a child of this.
+            }
+        }
+    }
+
+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.
+
+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.
+
+It helps to define...
+
+- what objects are available to the script?
+
+- how are they organized?
+
+- how are they initialized?
+
+- what connections to each other do they have, if any?
+
+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.
+
+**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.

+ 1 - 0
getting_started/workflow/index.rst

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