|
|
|
|
Reply From: |
Warlaan |
There are different ways to answer that question, so I’ll just pick one and start from there: “I’m just coming from a programmer perspective where you have some API into graphics and audio.”
The kind of APIs you are used to often refer to themselves as “frameworks” to make a distinction from engines like Godot or Unity.
So what’s the difference between frameworks and engines and what does that have to do with having to use objects?
The difference is that frameworks facilitate typical workflows like creating a window, loading a mesh or texture from diverse file formats, playing audio etc. That helps a lot in getting assets on screen, but it doesn’t do much to improve performance, because it basically just wraps the calls you would be making if you were using DirectX or other more low-level APIs.
Engines on the other hand improve performance by making assumptions about the kind of game you want to create. The more specific these assumptions are the less viable an engine becomes for different kinds of games, but the easier it is to add performance enhancing algorithms that make use of the fact that they can expect a certain kind of scene.
That was a bit theoretical so what does this mean for Godot?
Pretty much any mainstream engine today uses one such assumption, and that is that your game is made of “objects” (sometimes called GameObjects, Entities, Nodes etc.)
That means that every element of your game is expected to have a position and a size. This is the most important assumption you can make, because it allows the engine developers to implement so called “culling” mechanisms. Culling means that objects that aren’t visible / can’t be heard / can’t affect physics / won’t interest other players on the network are removed from the output stream that is sent to the graphics card / audio device / physics engine / network server.
So if everything is an object and everything has a position and a size it’s easy to detect whether or not the bounding box of an object intersects with the area that is visible from the camera. Anything that doesn’t is not relevant for the graphical output and is not sent to the graphics card.
So that explains “objects”, but why “nodes”?
Let’s say in your game there is a ship. On the ship there are sailors. In your game the sailors can’t leave the ship, so it’s safe to assume that as long as you can’t see the ship you won’t need to check if you can see any of the sailors, you can just assume that all of them are invisible too. That’s how scene graphs work. Objects that are expected to move together are structured in a tree, so that the tree can be culled beginning with the root node and ending with the leaf nodes, and if the root node of a branch is invisible (inaudible, not relevant for physics etc.) all of the child nodes don’t need to be considered. (disclaimer: it’s a little more complicated than that, but the details won’t help understand the basic idea.)
That explains “nodes”, but why make a distinction between “nodes” and “scenes”?
The most intutive way to write a program is to use the paradigm of “procedural programming”. A procedure is a sequence of commands that alter the state of its environment, like a cooking recipe. A cooking recipe won’t tell you to get a stove first, it will just assume that there is one available. It’s not written in a way that makes sure that you can perform multiple recipes at the same time in the same kitchen. It just gives you a series of tasks that will result in there being a cake or something in your kitchen when you are done.
This is easy to understand, but it is problematic once you have multiple things going on, since you can’t always rely on the state of the environment being what you need, since you can’t know who touched a resource last and what state it has left it in. That’s why the concept of object orientation came up.
In object oriented code you define objects (e.g. a car) and have your commands only access resources that are part of that object (e.g. the combustion process only uses the engine that is part of the car, fuel that is taken from the car’s fuel tank etc.). That way you can easily make sure that two objects can perform their methods without interfering.
Godot is an object oriented engine and scenes are classes. The root node is the base class of the scene and the immediate children are member variables (I am leaving out scripts for now, which can add members as well).
You can tell that scenes are classes because they
- can be instantiated
- can be exchanged as long as they have the necessary base class (e.g. you can exchange any sprite with any scene that has a sprite as a root node, i.e. polymorphism)
- can inherit from each other
So the reason why they are called scenes is because they are more than just nodes and they are more than just classes as well. They are classes that inherit from Node, so they combine the idea of encapsulation and that of common culling criteria.
If you think about it like that the name “scene” does make sense, because it’s a very unspecific term that describes any group of things that are adjacent and somehow belong to each other.
Wow, thank you for your detailed answer.
What you say about optimisation makes sense, specifically chosing assumptions that allow more tighly controlled mechanisms in construction. That seems like a valuable thing to keep in mind when approaching a game engine.
One thing that confuses me with the scene / nodes approach is that everything goes in there. Yes, the game will have physical objects with position and child association but what about code ? Global variables ? Events and the game loop ? What happens on bootup ? Godot solves this with scripts attached to nodes … I dunno. Thats why I said this is like domain driven design. So a node or scene isnt just a physical object but an idea, some concept like the score … Which plays to classes.
I need to go. Will circle back a bit later.
Further to your answer, this page makes the distinction between Library, Framework and Game Engine. GameDev Glossary: Library Vs Framework Vs Engine – GameFromScratch.com
They say that a game engine must have a scene graph and a level editor … Which fits precisely with what you are saying.
The other thing I’ve thought about is that Godot has a lot of features. I was reading the latest devblog posts about the new renderer. I suppose something like that wouldn’t be included in a framework ? Or if not - if a game engine is just about scenes and an editor - why not separate out the features like physics and rendering and make them pluggable into the editor ?
This is all rhetorical. I need to re-read the docs several more times (and use the engine!) to get a sense of what it does and why …
Thanks again.
I just added a comment to the gamesfromscratch-article. It’s nice to see that I am not the only one fighting the windmills and trying to keep up that distinction. It’s not out of pedantry, it’s because knowing about this distinction allows you to understand what you are sacrificing by using an engine or by using a framework, since both approaches have their benefit.
As you said you are experienced with frameworks, so you’ll know that there isn’t much of a difference between painting an image on screen once and painting it 10 times, you just call draw…() a couple of times more before clearing the screen.
But since engines need to have some concept that allows them to detect what is visible and what is not they need to have some additional information, so most engines will wrap something like an image in an object, which means that painting 10 copies of an image means that you have to create 10 objects which of course does introduce a certain overhead.
There are two things that the article got wrong though: you don’t need to have an editor in an engine (the article mentions OGRE as a framework, which actually is an engine - the name stands for object-oriented graphics rendering engine - and which doesn’t have a mandatory editor) and scene trees aren’t the only container suitable for culling. But it’s true that something like a scene tree is a vital part of an engine.
There’s one more distinction we didn’t mention yet. There are graphics engines and game engines. Actually there are even more than that, there are sound engines, physics engines, network engines etc., but as people tend to focus on what you see they usually only care about the distinction between graphics and game engines.
Game engines combine the different types of engines in one, which makes sense because the concept of having objects works about equally well for all the different kinds of engines. An object that is very far from the camera’s location will most likely be not visible, not audible, not relevant for physics and not relevant for network clients.
So making it possible to turn off features like physics doesn’t change much in the workflow, it’s not going to make the work with a game engine a lot easier.
The other reason to make them pluggable would be so you can switch physics engines, audio engines etc.
There are game engines that are built in a way that allow you to exchange these feature engines, but unlike graphics engines those other engines aren’t as strictly targeted at a special use case. For example there are graphics engines that are optimized for 2d rather than 3d, for lots of simple objects rather than a few complex ones, for flat open-world-like environments rather than indoor environments that extend in all three dimensions…
There aren’t as many factors that influence which physics, audio or network engine to use. So being able to exchange these engines is something that helps programmers when after a couple of years there is a better alternative, but it’s not something you would do on a per-project basis.
Warlaan | 2017-02-27 09:07
Very interesting.
Yes - with the frameworks distinction I wonder why not just pull together all the best libraries out there - graphics, physics, sound, networking. What is the point of Godot or Unreal ?
I suppose having everything all under one roof makes it cleaner / quicker. But that all probably happened because people started with several libraries, developed their own best practices and eventually conglomerated it into Their Engine.
To be honest I’ve lost why exactly I was looking at all this in the first place. Godot seemed like a good tool to use. (I especially liked how small it was in MB). Honestly, until I use it and see things through I’ll never really know what it is and what it’s limitations are …
I don’t really have anything to add to this conversation but I just wanted to mention I enjoyed reading the questions and responses. I was some interesting context that we don’t normally think about but is useful to have. Thanks!
cowhand214 | 2017-02-28 22:09
Thank you for saying so !