Skip to content

Commit 2886f9b

Browse files
authored
Merge pull request #9642 from Incognito357/Incognito357-update-docs-scene_organization
Update scene_organization.rst
2 parents e7ba9ce + 750879c commit 2886f9b

File tree

1 file changed

+71
-75
lines changed

1 file changed

+71
-75
lines changed

tutorials/best_practices/scene_organization.rst

Lines changed: 71 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ Scene organization
44
==================
55

66
This article covers topics related to the effective organization of
7-
scene content. Which nodes should one use? Where should one place them?
7+
scene content. Which nodes should you use? Where should you place them?
88
How should they interact?
99

1010
How to build relationships effectively
@@ -21,10 +21,9 @@ possible. Re-using the scene in multiple places creates issues because the
2121
node paths do not find their targets and signal connections established in the
2222
editor break.
2323

24-
To fix these problems, one must instantiate the sub-scenes without them
25-
requiring details about their environment. One needs to be able to trust
26-
that the sub-scene will create itself without being picky about how one uses
27-
it.
24+
To fix these problems, you must instantiate the sub-scenes without them
25+
requiring details about their environment. You need to be able to trust
26+
that the sub-scene will create itself without being picky about how it's used.
2827

2928
One of the biggest things to consider in OOP is maintaining
3029
focused, singular-purpose classes with
@@ -35,8 +34,8 @@ maintainability) and improves their reusability.
3534
These OOP best practices have *several* implications for best practices
3635
in scene structure and script usage.
3736

38-
**If at all possible, one should design scenes to have no dependencies.**
39-
That is, one should create scenes that keep everything they need within
37+
**If at all possible, you should design scenes to have no dependencies.**
38+
That is, you should create scenes that keep everything they need within
4039
themselves.
4140

4241
If a scene must interact with an external context, experienced developers
@@ -46,7 +45,7 @@ This technique involves having a high-level API provide the dependencies of the
4645
low-level API. Why do this? Because classes which rely on their external
4746
environment can inadvertently trigger bugs and unexpected behavior.
4847

49-
To do this, one must expose data and then rely on a parent context to
48+
To do this, you must expose data and then rely on a parent context to
5049
initialize it:
5150

5251
1. Connect to a signal. Extremely safe, but should be used only to "respond" to
@@ -148,14 +147,14 @@ initialize it:
148147
GetNode(TargetPath); // Use parent-defined NodePath.
149148

150149
These options hide the points of access from the child node. This in turn
151-
keeps the child **loosely coupled** to its environment. One can reuse it
150+
keeps the child **loosely coupled** to its environment. You can reuse it
152151
in another context without any extra changes to its API.
153152

154153
.. note::
155154

156155
Although the examples above illustrate parent-child relationships,
157156
the same principles apply towards all object relations. Nodes which
158-
are siblings should only be aware of their hierarchies while an ancestor
157+
are siblings should only be aware of their own hierarchies while an ancestor
159158
mediates their communications and references.
160159

161160
.. tabs::
@@ -201,21 +200,21 @@ in another context without any extra changes to its API.
201200
}
202201

203202
The same principles also apply to non-Node objects that maintain dependencies
204-
on other objects. Whichever object actually owns the objects should manage
203+
on other objects. Whichever object owns the other objects should manage
205204
the relationships between them.
206205

207206
.. warning::
208207

209-
One should favor keeping data in-house (internal to a scene) though as
208+
You should favor keeping data in-house (internal to a scene), though, as
210209
placing a dependency on an external context, even a loosely coupled one,
211210
still means that the node will expect something in its environment to be
212211
true. The project's design philosophies should prevent this from happening.
213212
If not, the code's inherent liabilities will force developers to use
214213
documentation to keep track of object relations on a microscopic scale; this
215214
is otherwise known as development hell. Writing code that relies on external
216-
documentation for one to use it safely is error-prone by default.
215+
documentation to use it safely is error-prone by default.
217216

218-
To avoid creating and maintaining such documentation, one converts the
217+
To avoid creating and maintaining such documentation, you convert the
219218
dependent node ("child" above) into a tool script that implements
220219
``_get_configuration_warnings()``.
221220
Returning a non-empty PackedStringArray from it will make the Scene dock generate a
@@ -234,7 +233,7 @@ in another context without any extra changes to its API.
234233
So, why does all this complex switcheroo work? Well, because scenes operate
235234
best when they operate alone. If unable to work alone, then working with
236235
others anonymously (with minimal hard dependencies, i.e. loose coupling)
237-
is the next best thing. Inevitably, changes may need to be made to a class and
236+
is the next best thing. Inevitably, changes may need to be made to a class, and
238237
if these changes cause it to interact with other scenes in unforeseen ways,
239238
then things will start to break down. The whole point of all this indirection
240239
is to avoid ending up in a situation where changing one class results in
@@ -251,44 +250,43 @@ by *all* OOP principles. Examples include...
251250
Choosing a node tree structure
252251
------------------------------
253252

254-
So, a developer starts work on a game only to stop at the vast possibilities
255-
before them. They might know what they want to do, what systems they want to
256-
have, but *where* to put them all? Well, how one goes about making their game
257-
is always up to them. One can construct node trees in countless ways.
258-
But, for those who are unsure, this helpful guide can give them a sample of
259-
a decent structure to start with.
253+
You might start to work on a game but get overwhelmed by the vast possibilities
254+
before you. You might know what you want to do, what systems you want to
255+
have, but *where* do you put them all? How you go about making your game
256+
is always up to you. You can construct node trees in countless ways.
257+
If you are unsure, this guide can give you a sample of a decent structure to
258+
start with.
260259

261-
A game should always have a sort of "entry point"; somewhere the developer can
262-
definitively track where things begin so that they can follow the logic as it
263-
continues elsewhere. This place also serves as a bird's eye view of all of the
264-
other data and logic in the program. For traditional applications, this would
265-
be the "main" function. In this case, it would be a Main node.
260+
A game should always have an "entry point"; somewhere you can definitively
261+
track where things begin so that you can follow the logic as it continues
262+
elsewhere. It also serves as a bird's eye view of all other data and logic
263+
in the program. For traditional applications, this is normally a "main"
264+
function. In Godot, it's a Main node.
266265

267266
- Node "Main" (main.gd)
268267

269-
The ``main.gd`` script would then serve as the primary controller of one's
270-
game.
268+
The ``main.gd`` script will serve as the primary controller of your game.
271269

272-
Then one has their actual in-game "World" (a 2D or 3D one). This can be a child
273-
of Main. In addition, one will need a primary GUI for their game that manages
270+
Then you have an in-game "World" (a 2D or 3D one). This can be a child
271+
of Main. In addition, you will need a primary GUI for your game that manages
274272
the various menus and widgets the project needs.
275273

276274
- Node "Main" (main.gd)
277275
- Node2D/Node3D "World" (game_world.gd)
278276
- Control "GUI" (gui.gd)
279277

280-
When changing levels, one can then swap out the children of the "World" node.
281-
:ref:`Changing scenes manually <doc_change_scenes_manually>` gives users full
282-
control over how their game world transitions.
278+
When changing levels, you can then swap out the children of the "World" node.
279+
:ref:`Changing scenes manually <doc_change_scenes_manually>` gives you full
280+
control over how your game world transitions.
283281

284-
The next step is to consider what gameplay systems one's project requires.
285-
If one has a system that...
282+
The next step is to consider what gameplay systems your project requires.
283+
If you have a system that...
286284

287285
1. tracks all of its data internally
288286
2. should be globally accessible
289287
3. should exist in isolation
290288

291-
... then one should create an :ref:`autoload 'singleton' node <doc_singletons_autoload>`.
289+
... then you should create an :ref:`autoload 'singleton' node <doc_singletons_autoload>`.
292290

293291
.. note::
294292

@@ -298,78 +296,76 @@ If one has a system that...
298296
to swap out the main scene's content. This structure more or less keeps
299297
the "World" as the main game node.
300298

301-
Any GUI would need to also be a
302-
singleton; be a transitory part of the "World"; or be manually added as a
303-
direct child of the root. Otherwise, the GUI nodes would also delete
304-
themselves during scene transitions.
299+
Any GUI would also need to be either a singleton, a transitory part of the
300+
"World", or manually added as a direct child of the root. Otherwise, the
301+
GUI nodes would also delete themselves during scene transitions.
305302

306-
If one has systems that modify other systems' data, one should define those as
307-
their own scripts or scenes rather than autoloads. For more information on the
308-
reasons, please see the
309-
:ref:`Autoloads versus regular nodes <doc_autoloads_versus_internal_nodes>`
310-
documentation.
303+
If you have systems that modify other systems' data, you should define those as
304+
their own scripts or scenes, rather than autoloads. For more information, see
305+
:ref:`Autoloads versus regular nodes <doc_autoloads_versus_internal_nodes>`.
311306

312-
Each subsystem within one's game should have its own section within the
313-
SceneTree. One should use parent-child relationships only in cases where nodes
307+
Each subsystem within your game should have its own section within the
308+
SceneTree. You should use parent-child relationships only in cases where nodes
314309
are effectively elements of their parents. Does removing the parent reasonably
315-
mean that one should also remove the children? If not, then it should have its
310+
mean that the children should also be removed? If not, then it should have its
316311
own place in the hierarchy as a sibling or some other relation.
317312

318313
.. note::
319314

320-
In some cases, one needs these separated nodes to *also* position themselves
321-
relative to each other. One can use the
315+
In some cases, you need these separated nodes to *also* position themselves
316+
relative to each other. You can use the
322317
:ref:`RemoteTransform <class_RemoteTransform3D>` /
323318
:ref:`RemoteTransform2D <class_RemoteTransform2D>` nodes for this purpose.
324319
They will allow a target node to conditionally inherit selected transform
325320
elements from the Remote\* node. To assign the ``target``
326321
:ref:`NodePath <class_NodePath>`, use one of the following:
327322

328323
1. A reliable third party, likely a parent node, to mediate the assignment.
329-
2. A group, to easily pull a reference to the desired node (assuming there
324+
2. A group, to pull a reference to the desired node (assuming there
330325
will only ever be one of the targets).
331326

332-
When should one do this? Well, this is subjective. The dilemma arises when
333-
one must micro-manage when a node must move around the SceneTree to preserve
327+
When you should do this is subjective. The dilemma arises when you must
328+
micro-manage when a node must move around the SceneTree to preserve
334329
itself. For example...
335330

336331
- Add a "player" node to a "room".
337-
- Need to change rooms, so one must delete the current room.
338-
- Before the room can be deleted, one must preserve and/or move the player.
332+
- Need to change rooms, so you must delete the current room.
333+
- Before the room can be deleted, you must preserve and/or move the player.
339334

340-
Is memory a concern?
335+
If memory is not a concern, you can...
341336

342-
- If not, one can just create the two rooms, move the player
343-
and delete the old one. No problem.
337+
- Create the new room.
338+
- Move the player to the new room.
339+
- Delete the old room.
344340

345-
If so, one will need to...
341+
If memory is a concern, instead you will need to...
346342

347343
- Move the player somewhere else in the tree.
348344
- Delete the room.
349345
- Instantiate and add the new room.
350-
- Re-add the player.
346+
- Re-add the player to the new room.
351347

352-
The issue is that the player here is a "special case"; one where the
348+
The issue is that the player here is a "special case" where the
353349
developers must *know* that they need to handle the player this way for the
354-
project. As such, the only way to reliably share this information as a team
355-
is to *document* it. Keeping implementation details in documentation however
356-
is dangerous. It's a maintenance burden, strains code readability, and bloats
357-
the intellectual content of a project unnecessarily.
350+
project. The only way to reliably share this information as a team
351+
is to *document* it. Keeping implementation details in documentation is
352+
dangerous. It's a maintenance burden, strains code readability, and
353+
unnecessarily bloats the intellectual content of a project.
358354

359-
In a more complex game with larger assets, it can be a better idea to simply
360-
keep the player somewhere else in the SceneTree entirely. This results in:
355+
In a more complex game with larger assets, it can be a better idea to keep
356+
the player somewhere else in the SceneTree entirely. This results in:
361357

362358
1. More consistency.
363359
2. No "special cases" that must be documented and maintained somewhere.
364360
3. No opportunity for errors to occur because these details are not accounted
365361
for.
366362

367-
In contrast, if one ever needs to have a child node that does *not* inherit
368-
the transform of their parent, one has the following options:
363+
In contrast, if you ever need a child node that does *not* inherit
364+
the transform of its parent, you have the following options:
369365

370366
1. The **declarative** solution: place a :ref:`Node <class_Node>` in between
371-
them. As nodes with no transform, Nodes will not pass along such
372-
information to their children.
367+
them. Since it doesn't have a transform, they won't pass this information
368+
to its children.
373369
2. The **imperative** solution: Use the ``top_level`` property for the
374370
:ref:`CanvasItem <class_CanvasItem_property_top_level>` or
375371
:ref:`Node3D <class_Node3D_property_top_level>` node. This will make
@@ -380,9 +376,9 @@ own place in the hierarchy as a sibling or some other relation.
380376
If building a networked game, keep in mind which nodes and gameplay systems
381377
are relevant to all players versus those just pertinent to the authoritative
382378
server. For example, users do not all need to have a copy of every players'
383-
"PlayerController" logic. Instead, they need only their own. As such, keeping
384-
these in a separate branch from the "world" can help simplify the management
385-
of game connections and the like.
379+
"PlayerController" logic - they only need their own. Keeping them in a
380+
separate branch from the "world" can help simplify the management of game
381+
connections and the like.
386382

387383
The key to scene organization is to consider the SceneTree in relational terms
388384
rather than spatial terms. Are the nodes dependent on their parent's existence?
@@ -392,5 +388,5 @@ that parent (and likely part of that parent's scene if they aren't already).
392388

393389
Does this mean nodes themselves are components? Not at all.
394390
Godot's node trees form an aggregation relationship, not one of composition.
395-
But while one still has the flexibility to move nodes around, it is still best
391+
But while you still have the flexibility to move nodes around, it is still best
396392
when such moves are unnecessary by default.

0 commit comments

Comments
 (0)