What are scene managers and how do they work?

Started by
7 comments, last by L. Spiro 8 years, 9 months ago

The title says it all. In games I always see people have main.cpp and then game.cpp and also scenemanager.cpp. What does the scenemanager do and what does it inherit from and such. Like it is main > game > scenemanager or something?

Advertisement

They manage the scene.

Thanks for that. WOuld you provide atleast some sort of detail?

The title says it all. In games I always see people have main.cpp and then game.cpp and also scenemanager.cpp. What does the scenemanager do and what does it inherit from and such. Like it is main > game > scenemanager or something?

You have to mentally separate out the files from the classes. One file can equal ten classes, or one class can be distributed between ten classes.

I can name a file Aardvark.cpp, and it can actually contain a class called something entirely different.

File names don't matter. Only the code they contain matters.

In C++, some limited inheritance is acceptable, but you don't want to go crazy with it. If you're a beginner, and a class is inheriting more than one class, you're likely doing something wrong (unless you are using an architecture designed by non-beginners that requires you to inherit stuff). Most classes shouldn't inherit anything (depending on the nature of the overall architecture - if you are a beginner, most classes shouldn't inherit anything). Those that do inherit another class usually shouldn't inherit more than one other class, IMO.

Why would Main inherit from Game? Why would Game inherit from SceneManager, or vise-versa? It wouldn't be good code architecture.

As for your question about scene managers, I don't have personal experience with them so others can answer that who actually do have experience in that area.

The title says it all. In games I always see people have main.cpp and then game.cpp and also scenemanager.cpp. What does the scenemanager do and what does it inherit from and such. Like it is main > game > scenemanager or something?

You have to mentally separate out the files from the classes. One file can equal ten classes, or one class can be distributed between ten classes.

I can name a file Aardvark.cpp, and it can actually contain a class called something entirely different.

File names don't matter. Only the code they contain matters.

In C++, some limited inheritance is acceptable, but you don't want to go crazy with it. If you're a beginner, and a class is inheriting more than one class, you're likely doing something wrong (unless you are using an architecture designed by non-beginners that requires you to inherit stuff). Most classes shouldn't inherit anything (depending on the nature of the overall architecture - if you are a beginner, most classes shouldn't inherit anything). Those that do inherit another class usually shouldn't inherit more than one other class, IMO.

Why would Main inherit from Game? Why would Game inherit from SceneManager, or vise-versa? It wouldn't be good code architecture.

As for your question about scene managers, I don't have personal experience with them so others can answer that who actually do have experience in that area.

Then how would I link the classes together? Including them?

Then how do I link classes together? Just including? And if I do that won't my game loop class get huge? Everytime I added something I'd have to add it to it.

Yes. The general advice given is to favor composition over inheritance where possible.

Hello to all my stalkers.

Then how would I link the classes together? Including them?

Classes should favor composition over inheritance.

This is composition:


class ClassA
{
     ClassB memberVariable; 
};

Composition is when a class has other classes as member-variables.

Classes should be composed of multiple classes that they own as member variables.

A car should never inherit wheels. A car should own wheels.

Most classes should use composition and avoid inheritance, except where inheritance is necessary or desirable for a specific purpose.

One common purpose for inheritance is when you need to treat two or more different classes - with their own different logic - as if they behaved the same on the surface. Basically, each having different logic, but sharing the same interface.

A typical beginner and intermediary-level rule of thumb is to say "Has-A" (composition) and "Is-A" (inheritance).

A tiger has a tail (composition). A tiger is a animal (inheritance).

A car has a wheel. Therefore the four wheels should be owned by the car via composition.

A car is a vehicle. Therefore the car should inherit the vehicle's interface.

If you want to park a Car and a Truck into a Garage, then you make the Garage own (as member variables - composition) space for two or more MotorVehicles which provide the interface. And you make Car and Truck both be (inherit) MotorVehicle so they can both provide their own data and logic.

But often times, your code doesn't even need to care about different logic between the Car and Truck - in that case, just initialize a single class type with different values.


Vehicle myTruck("TruckImage.jpg", TruckData); //If they only differ by their *data*, just pass them different data.
Vehicle myCar("CarImage.png", CarData);

Has-A and Is-A is not the 100% best way to think of architecture, but it is the best way I know of to begin learning it. As you program, you'll expand your understanding of architecture and begin to see that this rule-of-thumb doesn't always hold true. But when starting out, it's good to force yourself to follow it whenever tempted to use inheritance unnecessarily.

Avoid inheritance entirely at first - any program you can write with inheritance, you can also write without it. It's a tool to make things easier, but it can also make things alot more complicated if you use it the wrong way. When you feel the need to use inheritance, challenge yourself to first come up with a way of not using inheritance. And then only if the inheritance way is cleaner, use it. That's my recommendation. smile.png

[Edit:] #include doesn't mean anything in code logic. It just copy-pastes two files together. Files don't mean anything - only the code they contain matter. A file is not a class. The class is the class. A file might maybe happen to contain a class. Or it could contain something entirely unrelated. Filenames and #includes don't affect the logic of your code - they only tell the compiler where to find the code.

You can fit an entire program like Halo or Call of Duty into a single .cpp file. It'd be silly to do, but it is possible. The file doesn't affect the program, only the code affects the program. The files and #includes affect only the compiling of the program, not the program's behavior.

This is just a guess, since you are not specifying what code are you talking about, what game, who are theses "people"... so whatever answer I give is based on very little facts your question presented.

Having said that, if I had a SeneManager on my code, I would probably have Scenes as well.

A scene would be any section of my game that starts and stops at some point.

For example the main menu is a scene.

The screen that shows the logo at the beginning of my game is a scene.

The screen with highscores, and the settings menu are also scenes.

Each level of the game is a scene.

Even a pop-up dialog could be a scene.

So the scene manager is in charge of, well, managing theses things. For example in can load the logo scene, and when its over somedy tell the manager to unload Logo and load MainMenu.

The manager could have more than one scene at a time: if you load a PopUpScene you put it over the current scene. You can still see the scene below, but you are currently working in the scene at the top. When the popScene exist the manager removes it and it is left the original scene at the bottom...

The manager could also be in charge of transitioning between scenes with som sort of effect (fades and whatnot).

These are all suggestion. If you have access to some code that uses a SceneManager, dig into it and find what it does...

As for the inheritance part, SceneManager does not inherit from anything (maybe if you have a Manager class before... but... mm...).

It stands on its own.

Usually the flow is: main() starts, you create a scene manager, and you put the first scene into it so it is shown on screen...

You have to mentally separate out the files from the classes. One file can equal ten classes, or one class can be distributed between ten classes.

In a perfect world there should be one class per file (private nested classes or other special-case situations ignored).
Of course what you are saying is correct, but hopefully most of the time you can assume 1 class per file (with the same name as the file).

What does the scenemanager do and what does it inherit from and such.

A scene manager manages a scene in your game.
A scene is any spacial 2D or 3D area in your game (a scene manager must be dedicated to either 2D scenes or 3D scenes, not both).
It inherits from nothing and contains and manages all objects in the scene.
This means:
  • As a container:
    • It contains a master list of all objects in the scene. All cameras, terrain instances, foliage data, sky, characters, models, static geometry, etc. The objects can be traversed linearly this way. It is not necessary to store them all in a single bucket—it is perfectly fine to store an array of terrains, an array of non-static geometry, an array of animated geometry, etc.
    • It contains a spatial partition for traversing spacially more easily. For example when gathering objects for a render and performing frustum culling, or broadphase culling for physics.
  • As a manager:
    • It manages the interactions between objects. This means kicking off the physics engine to perform physics etc.
    • It is able to abstractly gather objects together for various other sub-systems such as frustum-culling for graphics.
    • It alerts objects of certain things around them. An object doesn’t know what the player’s camera is by itself—there are many cameras in a scene, including those for rendering shadows. The scene manager uses an abstract interface to tell objects to update themselves according to their orientation with the main camera. This could be used to select LOD levels or create imposters.

For example the main menu is a scene.
The screen that shows the logo at the beginning of my game is a scene.
The screen with highscores, and the settings menu are also scenes.
Each level of the game is a scene.
Even a pop-up dialog could be a scene.

These are better described as states.

A game state manages a state of the game. The main menu, credits, gameplay area, bonus-round area, stage-select, etc.
All of these states have wildly different logic and requirements. A typical scene manager is unsuitable for this task.


The relationship is instead:
  • CMyGame inherits from CGame. CMyGame has data persistent throughout the game, such as your player stats.
    • CGame has a CStateManager object for managing game states.
  • A CStateManager object has a current state (CState). It could optionally have a stack of states depending on how you want to handle system messages such as a low battery on Nintendo Wii U.
  • CMainMenuState inherits from CState. All logic for the main menu is implemented here. There are no scene managers.
  • CGamePlayState inherits from CState. All logic for the gameplay state is implemented here. There is a single scene manager for managing the 3D world of your game. Thus CGamePlayState has an instance of CSceneManager. Upon loading, it fills the scene manager with objects based on which level is being loaded etc. The rest is largely up to the scene manager.
L. Spiro

I restore Nintendo 64 video-game OST’s into HD! https://www.youtube.com/channel/UCCtX_wedtZ5BoyQBXEhnVZw/playlists?view=1&sort=lad&flow=grid

This topic is closed to new replies.

Advertisement