Engine Programming

Started by
23 comments, last by Servant of the Lord 13 years ago
Why don't you want to have your own engine which uses other libraries like sfml or allegro?

Advertisement

[quote name='TTT_Dutch' timestamp='1301283679' post='4791193']
But the whole point of creating things is to learn. You should only use an engine if you can code your own. This is almost the same as saying, just use Game Maker instead of learning c++ and OpenGL/Window system because it is easier.


While we're at it, why not use assembler instead of higher level languages? I mean, if you can't create your own programming language, why use C++? ;)
We're all standing on the shoulders of giants and we should make the most of it. And constant reinventing of the wheel is definately not the answer, that's not what progress is about.
[/quote]

Sorry I wasn't very clear. I mean that with this guys goal, he wants to learn how to make games. Now making games in the industry does consist of re-inventing the wheel a little. There comes a point where it is useless to re-invent something just for the purpose of creating games. Like inventing another c++ just for a game. I mean if this guy wanted to learn to make games with assembly then you would be right, but who wants to do that? This guy learned c++ and he should use the basic tools that are used in the industry (such as c++, platform specific windowing system, and OpenGL/Directx) to learn to make games.

Sometimes trying to reinvent the wheel is very informative, because even if you don't end up inventing a BETTER wheel, you will know how to BETTER USE the existing wheels.


You just posted what I meant to say, but shorter. :)

Several times in the past I've tried to go the route of designing an engine and a game... usually it starts to work at first, but then gets really complicated as unexpected things pop up.
Currently, I'm writing a game, and I'm doing my best to keep my code clean and concise. As I'm writing the game, I see logically how it's separating into three different types of code: general code, genre-specific code, and game-specific code. So I then separate those types of code into three different folders (which I call, 'Common', 'Engine', and 'Game', respectively).

As I'm writing my game, the engine falls out of it if the game is coded well. If the game isn't coded well, me trying to make an engine will result in an engine that isn't coded well and can't be used anyway.smile.gif

Your solutions are:
1) Code a game poorly. Result: You have a completed game.
2) Code an engine poorly, and a game alongside it. Result: [color="#1C2837"]You have a not-working engine, and stop working on the game, because the engine doesn't work.
[color="#1C2837"]3) Code a game properly. Result: You have a completed game... and a completed engine that pops out of nowhere!
[color="#1C2837"]4) Code an engine properly. Result: You have an completed engine. But to code an engine properly, you have to have experience coding a finished game properly in the past anyway, so you are probably a professional already.

[color="#1C2837"]The game to learning how to make good game engines in the future is to make good games in the present. If you aren't focusing on the game, then all you are doing is making a fancy API by wrapping whatever API you are already using.mellow.gif

[color="#1C2837"]
Also i have a question about collision... I don't know when to check for collision, I guess i'd have to check inside the main loop if all the sprites in the game are solid and if they are solid if they are colliding with each other OR with the tiles wich are solid... because if i just check for collision on a key down for example, i'm only checking for the player and I want to check for the enemies also...

[color="#1C2837"]After a keypress, call something like Player->Move(). After the AI thinks, the AI calls something like Enemy->Move(). The 'Move()' function could check for collision, not the keypress handling function.

[color="#1C2837"]
But that looks like it's gonna eat too much cpu[/quote]
[color="#1C2837"]If your CPU can run advanced 3D games from two or three years ago, why worry about a few 2D images like what they used to make 20 years ago?
[color="#1C2837"]It can handle your game. Only start optimizing your game when your game drops below 20 frames per second. Otherwise, wait until your game is
[color="#1C2837"]complete, then optimize it using a proper profiler, not guesswork.wink.gif

[color="#1C2837"]
[color="#1C2837"]And that's the basic structure (wich is probably bad), what do you think?[color="#1C2837"][/quote]
[color="#1C2837"]Don't second guess yourself or put yourself down. Just run hard, and when you hit a wall, dust yourself off and run again.
[color="#1C2837"]It's good to have something to run toward, though, otherwise you are running at the wrong goal. Making an engine, even for learning, isn't the best goal. It's an 'acceptable' goal, but a better goal is to make a game. Simple and friendly advice that a lot of people are offering you - you can accept it, reject it, or store it away for later, it's your call!

[color="#1C2837"]I fully understand the desire to make an engine because it sounds so cool. Just don't let it stop you from making your game; and if you fail, don't let it stop you from picking yourself up again, and if you succeed, don't let it go to your head. tongue.gif
[/quote]


Thanks for the idea, but I have a question.
Say your making an FPS. Would window handling, menu system, subscription system (you can "subscribe" functions to be called during the game loop), and sound system be in common folder? And then the AI, Collision, Rendering system, and (I don't know what else is part of a game) in the Engine folder. And then the main game loop and logic in the game folder?

[quote name='Servant of the Lord' timestamp='1301262360' post='4791095']
Currently, I'm writing a game, and I'm doing my best to keep my code clean and concise. As I'm writing the game, I see logically how it's separating into three different types of code: general code, genre-specific code, and game-specific code. So I then separate those types of code into three different folders (which I call, 'Common', 'Engine', and 'Game', respectively).
[color="#1C2837"]

Thanks for the idea, but I have a question.
Say your making an FPS. Would window handling, menu system, subscription system (you can "subscribe" functions to be called during the game loop), and sound system be in common folder? And then the AI, Collision, Rendering system, and (I don't know what else is part of a game) in the Engine folder. And then the main game loop and logic in the game folder?[/quote]
Well, this is my first time doing it this way, so I'm working it out as I go. smile.gif
I've moved some chunks of code back and forth between 'Engine' and 'Game' several times, struggling to find the balance between "Logically it should go in 'game', but class 'x' in Engine needs to access it, so I have to put it in 'Engine'" and similar problems. (Anything in 'Common' can only access other stuff in 'Common' (or any external libraries), anything in Engine can only access other stuff in 'Engine' or stuff in 'Common', anything in 'Game' can access anything in 'Game', 'Engine', or 'Common' - this helps me make each separate part of the code self-contained, and to reduce dependencies).
The main loop in my code is actually outside all three folders, though it could just as easily be in 'Game'.

One example of struggling to find the balance and moving files back and forth is my 'Player' class. Does the Engine know about the Player or only the Game? All 2D RPGs will have a Player, so I'd prefer for it to be in 'Engine'. On the other hand, different games will have the Player have different stats. Game A might use 'Defense', 'Strength', and 'Agility', but Game B could be entirely different! So it should go in the 'Game' folder... except I figured out a (clean, concise, and logical) way to make Player be in 'Engine' and leave his stats undefined, so I went with that and put him back in Engine. I may encounter problems with that method down the line, and be forced to move the Player class back to 'Game' - we'll see. cool.gif
I went through something similar with my 'GameStructure' class that ties the different parts of my program together. Since it 'owned' the player, every time I moved the player, I had to move the GameStructure too.laugh.gif An alternative option, might be to have a GameState own the player, or make Player global in 'Game' (though I'm trying to avoid globals (with some exceptions like my logger).

My current setup is this:
In "Common" I basically have stuff like my Lua binding code, my logging code, my different structs (Color, Point, Rect, Size, etc...),


Common:
- Logger
- Scripting
- String (string conversion (bool to string, point to string, etc...), and string flags (used in a dozen places to store information in a textual format))
- Types
- ConfigFile
- RichTextFile
- Image
- Time
- FormattedTime
- Basic Types
- Color
- Fraction
- Point
- Rectangle
- Size

Engine:
- Window
- Animation + Animator
- Localizer
- World
- 12 visual representation of the world classes.
(Area -> Chunk -> Floor -> Layer -> Tile, tile image caching, tile special attributes, tile animating, etc...)
- Collision with world classs
- Structure
- Camera
- Avatar
- GameFlags
- GameState + GameStateManager
- 'GameStructure' class that ties the various pieces of the engine together.

Game:
- States
- Exploring (currently my only game state)
('Game' will soon receive more classes - currently, I have a few game-specific classes in 'Engine' that I need to move to 'Game', but also 'Game' will grow once I get past my current Todos and start adding more game specific features)

Outside of any folder is 'main' (but it could easily be part of 'Game' and would make sense for it to be - I may move it there in the future), which loads the primary resources, initializes the logging, and then pushes the first GameState onto the GameStateManager, kicking off the program execution.

Looking at 'Common', 'Engine', and 'Game', 'Common' is the biggest as it's the most generic. 'Engine' is next largest (and is almost equal to 'Common'), and 'Game' is least. This makes sense, and makes the code re-usable, and visually tells me what code I may want to use for future projects and which code probably wont be helpful. I expect 'Common' to grow, but I think 'Engine' will out-pace it as my game gets closer to completion. If I was focusing on making a generic "Game Engine", I'd probably fall into the trap of adding feature after useless feature, and actually end up making lots of "Common" code, and less "Engine" code, and no "Game" code. But by focusing on the end-product, "Game", 'Engine' automatically comes about, and 'Common' springs from 'Engine'.


'Common' for me is self-contained and isolated classes or functions that mostly function on their own (ConfigFile class, or the three self-contained but complimentary scripting related classes). They are tools to be used. Engine is the actual structure of a game, and instead of being a generic game, hones in specifically to the type of game I'm making: A turn based RPG with a 2D tile-based world. Game is only the specifics of the current game that aren't common to most 2D turn based RPGs, and only common to this turn based RPG.

So, to answer your question:
Say your making an FPS. Would window handling, menu system, subscription system (you can "subscribe" functions to be called during the game loop), and sound system be in common folder? And then the AI, Collision, Rendering system, and (I don't know what else is part of a game) in the Engine folder. And then the main game loop and logic in the game folder?[/quote]
Everything you described for 'Common' actually would be part of 'Engine', if I was doing it. But your 'Vector3D' and 'Matrix' classes, your self-contained AStar pathfinding classes, and perhaps your generic 'Texture' class, would go into 'Common', along with your self-contained logging system, your generic networking classes (if your API of choice isn't good enough on it's own), and your encryption and compression functions or classes.


It really depends on what feels right, on a case by case scenario. Does it feel self-contained and re-usable even for non-FPS games? Probably goes in 'Common'. Or does it feel like a large 'system' that provides a 'service' (or is it a small class that was created specifically for that system)? Probably goes in 'Engine'.

And just because something goes in 'Game' doesn't mean it *can't* be re-used. My next project will probably have a 'MainMenuState' similar to my current project (once I get around to adding a main menu to my current project), so I'd probably copy and paste that 'MainMenuState' and tweak it for my next project - but everything in 'Engine' I'd probably copy and paste and instead of tweaking to fit my new project, it'd work right out of the box, and I'd build upon it (new engine features) instead of rip stuff out of it (game-specific features).

Again, this is my first time using this system, so I don't know whether it'll prove beneficial in the long run - I only know that it's certainly more organized and maintainable than my previous project. wink.gif So even if it's a dismal failure compared to what others are using, it's still a big step up for me.biggrin.gif

This topic is closed to new replies.

Advertisement