Game Engines

Started by
3 comments, last by Grant1219 17 years, 6 months ago
I am currently making a simple 2d game engine, and I recently read the Enginuity series, and now I'm a bit confused about a few things. The thing is, I think I'm trying to find something that will say "This is how your engine structure should be" (even though thats really not possible), but I realize that you can design an engine multiple ways. As for my questions. I don't have a memory manager, but each of my "systems" cleans up after itself separately, is that ok? Or should I have a centralized memory manager? Also, I didn't use "smart" pointers, functors, or dators. I see how using these could help, but do most of you use those techniques? I guess I just want other peoples opinions on basic game engine structure, and how to handle the engine "objects". So I can get some more ideas and decide how to structure my engine.
Advertisement
Quote:As for my questions. I don't have a memory manager, but each of my "systems" cleans up after itself separately, is that ok? Or should I have a centralized memory manager?

That's fine. As the engine/game gets larger and more complex, though, being able to track and pool memory becomes important. Going back later and refactoring use of the heap can be a real pain. But, generally, you're fine with just the CRT new/delete as long as you're doing small PC games. But I'm still proactive and persistent about finding memory leaks by using the debug CRT. The last thing I do in the code is call _CrtDumpMemoryLeaks, and every time I run I make sure the output is the same as last time. It can also, with a bit of work, help you pinpoint where memory is allocated if there is a leak.
Quote:Also, I didn't use "smart" pointers, functors, or dators. I see how using these could help, but do most of you use those techniques?

Smart pointers can probably make some things easier, but I don't use them much. It's something I need to spend time exploring. When I use functors, I typically use them for messaging delegates, asynchronous callbacks, and for using <algorithm>. But lately I've been playing with using inheritance for delegates. That's a different thread, though. I'm not familiar with the word 'dator'.

Quote:I guess I just want other peoples opinions on basic game engine structure, and how to handle the engine "objects".

In most of the code I've seen, lower-level classes that have to deal with memory management just comprise direct pointers to data that they own, or is owned by a resource manager. The resource manager, when there is one, does all the memory footwork and the client code just deals with the resource manager. Doing it that way also makes it easier to refactor the heap later if you have time.

For example there might be a simple "Model" structure. The "Renderable" class might have a list of Model pointers, and a function called "AddModel" that goes off and uses some loader class or function to turn a file into a model (a task where functors can be useful) and store it internally in a list. Then an "Entity" class might inherit Renderable and implement a Spawn function that calls AddModel. When Entity needs to refer specifically to one of the Models that it AddModel-ed, it typically uses a handle/pointer returned from AddModel, or a helper function called FindModel that returns a handle/pointer. This may or may not be good design, but it's something that I've seen a hundred times and it works.

My tendency on personal projects is to do everything "right" from the start. I also usually fail to to complete any personal projects, because every approach has drawbacks. "Get it done" is really the most important consideration for me, with "Don't screw the next guy who has to work on it (including myself)" being a close second. YMMV.

Quote:Original post by Jaymar
In most of the code I've seen, lower-level classes that have to deal with memory management just comprise direct pointers to data that they own, or is owned by a resource manager. The resource manager, when there is one, does all the memory footwork and the client code just deals with the resource manager. Doing it that way also makes it easier to refactor the heap later if you have time.


Uhh, I'm not quite sure I understand the difference between the resource and memory manager. It seems to me they almost do the same thing. What I though a resource handler was, was a class which held the images/sounds/other data you need for a game.
Yes, the distinction is subtle in a way now that you mention it.

A memory manager will typically override global new, delete, malloc, and free in order to gain complete control over memory use. That allows you do things like, say, keep statistics about how much RAM is in use at any given time, or the high-water mark (which is useful for consoles). And since you're essentially overriding the default memory functions, doing this includes things like STL and sometimes even other libraries that you don't have the source for. With a little extra work, you can even track which parts of the code are allocating memory, how often they're doing it, and what size blocks they're allocating. And, with even more work, you can see all this in real-time as the game is running.

A resource manager will typically use the memory manager in order to ensure that, for example, when two pieces of code try to load the same texture, the texture is only actually loaded one time. A resource manager might also employ some kind of memory pool to reduce fragmentation, or it might use a freelist to try and avoid dynamic allocation completely.

I guess you could say that the difference is that everything uses a memory manager, but only game objects that need to load things from the disk will use a resource manager. Or you could say that the key is in how you define the word "resource". I mean it as a very specific chunk of game data.

This is just how I think about it, other people may have different opinions.
Ok, thanks for explaining that. I searched around some other sites on memory management and they pretty much say most of the things you said, like overiding the new, delete, etc, and also reference counting which doesn't seem too difficult either. I'll try making a simple and see how it works.

This topic is closed to new replies.

Advertisement