Engine Subsystems calling each other

Started by
22 comments, last by Hodgman 7 years, 12 months ago

Hello everybody I'm back again with another task I'm attempting to solve. So I'm at a point in my project where I was working on cleaning up some early code that I was using for testing rendering of maps to the screen and I started to realize that I have several of the sub systems for my game engine using a pointer to a graphics object to send their own drawing commands to the graphics system. I'm looking at this code and I'm wondering if I should let it continue working this way or is their a better way?

My original goal for the game engine and the game as a whole was to have each sub system handle one specific task, Graphics, Input, Audio, etc... with the idea that the main class for the game right now simply being called Game having an object for each sub system and the game class would call each systems update method each frame if needed. The idea being that the Game class would handle calling all drawing commands, it would check for key entry and if so it would update all systems that need to know about it, etc...

The problem I'm running into with this so far is that there are several sub systems that need to draw things to the screen and up until now I haven't figured out what the best way would be for them to pass drawing commands without having a pointer to the graphics system object and just calling drawing commands them selves. So far I have been doing just that passing a pointer around to the systems and letting each system draw but I feel like this may not be the best idea for how to handle this?

I'm wondering what everybody's thoughts are? Am I overthinking this and should just let each system have access to drawing or is there a great way to handle this? I'm not afraid of researching and writing any complex systems if I need to but I am just not sure what the best way to handle this is?

Thanks in advance for any and all advice on this topic.

Darcmagik

Of all the things I've lost I miss my mind the most.

Advertisement

Can you be more specific about what systems you're talking about, what dependencies you have between them, and what pointers you're passing around?

You might be overthinking this. If you have a low level graphics system and higher level systems that depend on that, the easiest thing to do is just have a global graphics object/interface that other systems use. No need to even pass any pointer around because you'd just access the gGraphics (or whatever you call it) object. If you have to pass a pointer around, that should be a pointer to some context data that actually changes from frame to frame, or render pass to render pass, etc.

So here is what I have I have a class for graphics that creates the DirectX 11 object, and the device context and everything else it needs to get graphics displaying on the screen. This class also contains a Map that contains all textures in the game they are tied to a name in the map. This class also contains certain methods for drawing graphics to the screen I have methods like Draw Object which you can pass in the name of the texture and the position you want it at. I have other methods like that in the class.

The other sub systems I'm referring to are like I have a class for the Console window that handles everything related to displaying a console on the screen and accepting commands.

I have a system that I'm working on that will be a level editor for the game this level editor right now is only going to be used by the internal team for developing the content for the game but that may change when the game gets closer to release. This system will be heavily tied in with the Console class.

Then I have my map and game world classes the game world class contains all the maps for the game I haven't gotten very far with this class yet as I'm working on just getting a single map displaying on the screen and updating properly with animations and when user input is present.

Right now I am passing the graphics pointer from the Game class to Map, and its various classes and what not, and I'm also passing this pointer to the Console and Level Editor classes.

I'm a little embarrassed to say that I didn't think of the idea of using an interface to the Graphics system of my game to be honest I have never implemented one before in a class I guess I will need to go do some research on how to properly do this because I do remember reading about using interfaces in game development just never implemented one myself.

Darcmagik

Of all the things I've lost I miss my mind the most.

Start by defining your sub systems. A well defined design would solve almsot all your issues.

Game engines tend to be more component-oriented. Meaning each "sub system" is a reusable and replaceable component. Each component is an abstract idea.

For example, a "console host" is not abstract, it's a concrete type of a gui.

Therefore you want to define an interface like "IDisplayMessages" (Name might not be the best, but suits the idea for now).

A gui for console would imeplement it with cout, but a gui with openGL rendering would use glfw or glut to implement it.

The second thing you want to do is seperating your logic into groups, buisness (Game), graphics (Rendering), input,aduio, database , etc...

A map doesnt need to know how you draw it, it has some system called IDrawingService which does the actual drawing.

*Note:
It may not be the best way to design a real time application, many flaws may arise when trying to speed up the rendering.

So here is what I have I have a class for graphics that creates the DirectX 11 object, and the device context and everything else it needs to get graphics displaying on the screen. This class also contains a Map that contains all textures in the game they are tied to a name in the map. This class also contains certain methods for drawing graphics to the screen I have methods like Draw Object which you can pass in the name of the texture and the position you want it at. I have other methods like that in the class.

The other sub systems I'm referring to are like I have a class for the Console window that handles everything related to displaying a console on the screen and accepting commands.

I have a system that I'm working on that will be a level editor for the game this level editor right now is only going to be used by the internal team for developing the content for the game but that may change when the game gets closer to release. This system will be heavily tied in with the Console class.

Then I have my map and game world classes the game world class contains all the maps for the game I haven't gotten very far with this class yet as I'm working on just getting a single map displaying on the screen and updating properly with animations and when user input is present.

Right now I am passing the graphics pointer from the Game class to Map, and its various classes and what not, and I'm also passing this pointer to the Console and Level Editor classes.

I'm a little embarrassed to say that I didn't think of the idea of using an interface to the Graphics system of my game to be honest I have never implemented one before in a class I guess I will need to go do some research on how to properly do this because I do remember reading about using interfaces in game development just never implemented one myself.

Ok so it sounds like you have a Game class that creates the Graphics object and then passes a pointer to that to anything that needs to render? This is really not needed because you just create your D3D device and that's what gets used all the time. So yeah, you just need a global pointer to your Graphics class which you can instantiate once when your app starts (before anything tries to render or create any graphics resources). If you extern that pointer in your graphics header file then you're set because now anything that includes it can call functions on that class.

As far as that graphics class interface, if you make it generic then you can implement it however you want based on what platform you're supporting. So for now you have just a D3D implementation, but you might want an OpenGL one later. If your interface doesnt rely on any D3D specific concepts or code, then you should be fine.

OK I understand where you are going with that, I'm going back to my project now and see if I can implement things correctly related to what people have suggested. I will hopefully not be back with more problems related to this but you never know...

Darcmagik

Of all the things I've lost I miss my mind the most.

OK so I am attempting to use an external variable for the graphics system because with the way I'm doing things it seems like the best idea. So I have an issue with a link error now. I am defining the extern g_graphicSystem variable inside the Graphics System's Header file at the bottom after the class. Then in the game class header file I have it defined like I am supposed to from what I am reading in reference material, and in the Game class I call the constructor of the Graphics class to make sure that the new g_graphicSystem variable is defined.

The error I'm now getting is if I have the variable declaration inside of the game class I get an unresolved external symbol link error but if I have the declaration line in the game header but outside of the game class I then get a link error related to the g_graphicSystem already being defined.

One thing I should point out that may give somebody an aha moment for somebody is that the way my class structure is setup is that the actual game entry point the WinMain is part of a class called Win32_Window this class instantiates a Game variable sets up the loop and then passes control over to the game class so the Win32_Window class basically doesn't get touched again until the window closes.

I'm very sorry if what I'm saying sounds like it doesn't make sense but I have been looking at my code for many hours as I attempt to fix all of these crazy issues and try to move the project forward towards completion.

Darcmagik

Of all the things I've lost I miss my mind the most.

OK me again ignore my rants and my dumb questions I figure it out I had to move the actual declarations from the game header file to the game cpp file and the error went away and everything works again so this was a simple dumb error on my part. But you live and you learn and I have learned quite a bit today so kudos to everybody that gave me their thoughts on this and thanks to everybody on this website because I have learned so much from these forums and the various articles on here as well.

Darcmagik

Of all the things I've lost I miss my mind the most.

OK me again ignore my rants and my dumb questions I figure it out I had to move the actual declarations from the game header file to the game cpp file and the error went away and everything works again so this was a simple dumb error on my part. But you live and you learn and I have learned quite a bit today so kudos to everybody that gave me their thoughts on this and thanks to everybody on this website because I have learned so much from these forums and the various articles on here as well.

Sounds like you solved it. One thing I would recommend is to separate things out into logical units as much as possible, and try to keep your dependencies so that lower level systems dont have to depend on higher level ones. So, it sounds to me like you have your graphics code and then your game code, and possibly other code that will need to render stuff. But, that other code should not depend on the game code, because in theory your game code is the highest level. What that means is that your g_graphicSystem variable should be declared in the graphics code so that other systems can use it, but not in the game code.

Now I dont know exactly how your code is structured, but I'll give some examples going along with what I think you're doing:

// lowest level

graphics.h (extern your g_graphicSystem pointer variable here)

graphics.cpp (includes graphics.h, define your g_graphicSystem variable here)

// mid level

console.h (includes graphics.h)

console.cpp (includes console.h, you can now use g_graphicSystem variable here since you included graphics.h through console.h, and dont need to include game.h)

// highest level

game.h (includes console.h)

game.cpp (includes game.h, you can use anything in graphics.h or console.h)

Basically you want each system to know only as much as it needs to. Your g_graphicSystem variable will need to be used in either the graphics, console, or game modules, so you put it at the lowest level... the graphics module. Then you work your way up from there. The game module (in this example) is the highest level and you only want other things at that level to include game.h. So the game module knows about the console module, but the console (or graphics) modules should never need to know about the game module.

I hope that's helpful and that I didnt misunderstand your problem.

Do what WoopsASword suggested. Split your Console classes into two entities: Console itself and ConsolePresentation. Console has a bunch of typical methods and a pointer to ConsolePresentation. ConsolePresentation is an interface responsible for drawing console contents. This way you'll separate console logic from visualization details and the code related to console rendering will be in one place which will make it easier to maintain in case of changes in Graphics subsystem. Plus as WoopsASword said you'll be able to have different console representations (std::cout, UI or using your renderer).

This topic is closed to new replies.

Advertisement