Structuring a state game engine and creating a Makefile?

I work on the state game engine and get what I'm happy with.

There is an abstract class GameState.hpp with virtual methods that I use (init, run, pause, etc.).

There is GameEngine.cpp / hpp, which is a class that contains a stack of GameState objects and sets up a game loop by running the corresponding current appropriate methods.

My test game TestGame.cpp creates a GameEngine object and pushes an instance of TestState and starts, etc. Everything works as I expect.

I want to structure the source tree, rather than compiling everything from the same directory, and thought about the following, since each game will have several states:

src/ +Engine/ +GameEngine.cpp +GameEngine.hpp +GameState.hpp +TestGame/ +States/ +TestState.cpp +TestState.hpp +TestGame.cpp 

When creating, I'm not sure if I understand what needs to be compiled with and where the objects should be compiled.

So far my initial thoughts are:

  • Compiling GameEngine.cpp / hpp with GameState.hpp gives GameEngine.o

  • Compile each state of the game, for example. TestState.cpp / hpp with GameState.hpp, gives TestState.o

  • Compile TestGame.cpp / hpp with GameEngine.o / hpp, GameState.hpp, TestState.o / hpp (and any other states), gives TestGame.bin

Am I on the right track? Should GameEngine build a lib, or is it a normal .o normal? I'm still a little hazy about whether to include headers in every compilation. In addition, the ouput files for each compilation go in the same directory as the source, or should be in a structured bin /?

I will have a game and post some makefile attempts and output. Let me know if I should post code, maybe just 200 lines. No actual graphics implementation, etc. At the moment, this is just a framework.

Thanks guys, any help is much appreciated!

EDIT: Thanks for the quick replies of the people. I read the comments below and wanted to give an update and clarify some points.

Firstly, I look in autotools, but this is basically a training project, and part of this is grokking make files. I also come from the background of Java, so I really want to understand what exactly I create and how my project fits together. As above, I don’t even know if something should be a library or just point to compilation time.

Overview of my goal: I see the engine almost like a subproject. Despite its being simple (<10 files), it downloads what I think of as “states” and digitizes the methods [ handle events, update, display ] that determine the state. I have an algorithm that aims at a constant number of updates per second, changing the frame rate if necessary.

For example, being able to display a method, it uses SDL-enabled display functions with an engine support (perhaps a tile mechanism, a state can say “load these resources, display these fragments” or a library widget, whatever ...) to present a representation of the game world model . A method to handle events can use an abstract keyboard interface. I want to be able to add such functionality to the engine. The update will drive a model that represents the game world. He will track objects in the world (scene, player, and np), apply motion based on physics and collision detection, etc.

I think I want to be able to build this and just include the object (and the headers?) In the game I'm working on. Regardless, 'copy the source source directory to the root of the game project and add it to the main Makefile, put it all together' or 'run make on the engine whenever it changes, build a game project with a copy of the last object of the engine (, common an object, something else?) and headers, which will make it easier for me to work with several small game projects using one engine? How would I like to set myself up so that I can hit the ground with random game ideas, since I have them, for example p, 2-week encodings, etc.

States are any other kind and many interactions. The engine has a LIFO state stack, so a simple game can have the following states on the stack: DrivingMode - PauseMenu - Settings In a real game, there is an instance of GameEngine, and it would add DrivingMode to start the game. The user pauses, which pauses the DrivingMode state and pushes the PauseMenu state (starts its init, run, etc. When clicked). Here, the user selects settings that suspend the PauseMenu state and load the settings ... When they exit the system, the states are started (cleaning, etc.) are started first, and the upper state is resumed.

Wow, now heaps. I will add more or ask new questions as I move. Thank you so much for your help.

+6
source share
2 answers

First of all, do you really need states to be modular? If you plan on writing an engine for a specific purpose, your states probably won't change much and probably should be compiled as part of the engine itself.

The presence of states separated from the engine will add an additional level of complexity and make implementation more difficult.

The next problem is whether you want your engine to be the library for which the game was used, or if the source of the engine fell in a subfolder of the game and compiled with it.

Your options:

  • Compile the engine and states as one library (possibly the static one with which you are linking your game)
  • Compile the engine as a static library, and then compile the states as shared objects that can be dynamically linked (this will correspond to the modular state, but this will add a lot of complexity).
  • Compile the entire engine + game into one large executable file, which eliminates the need to link the library (but also makes the engine and game more connected)

In my opinion, option 1 looks like the best.

With any parameters, I will keep the engine in my own subdirectory from the game. Your file structure still looks pretty solid, and you should stick to it.

If you nevertheless decide to allow the game to define its own states, then you will want to go with option two and implement several basic states in your engine (perhaps something like INIT, MAIN_MENU, SHUT_DOWN), as well as something like a “plugin manager ", which in this case will be responsible for registering game states with the game engine.

Each state can be individually compiled as a shared object (.so) and dynamically loaded when the game loads.

As for the Makefile, it really depends on what you plan to use (CMake, GNU autotools, etc.)

GNU Makefiles has a fairly simple syntax, but learning how to use them well can be a little trickier.

They consist of goals that are defined as follows:

 default: gcc [...] all: gcc [...] gcc [...] <...> 

The first goal is the default goal when make is called without arguments. I will not describe in detail how to use make files (for GNU Make: this link )

You should be aware that makefiles are quickly becoming incredibly tedious to maintain, and a solution such as autotools is usually preferred.

Please note that autotools is a very large system consisting of many programs and can be quite laborious to learn. If you want to focus on developing your game engine, I would strongly suggest using a project IDE, such as Code :: blocks , to compile the code and link for you.

EDIT

In response to your editing, I will add the following:

You seem to know very well where you are going, which is the most important part. From what you said, you would be much better if the game engine was its own static library, which is associated with your many games.

Your engine will then provide an interface for registering the states that the games will use to say “Here, my state is called the name”, and later tells the engine to “switch to the state called the title” when necessary.

One thing you might want to consider is a few basic conditions that all games (enforced by the engine itself) should register.

Now the engine will become a project, and game projects will simply have a copy of the engine library in / lib, for example. Then you statically linked the engine to your game at compile time.

If you want more information on how you can structure state objects, let me know.


+6
source

Many of the things you ask for do not have a definitive answer; these are often personal preferences.

I get the impression that you are also compiling your headers, you should not compile headers, they should only be included in .cpp files and other headers. Then they are compiled as part of cpp. Files should only include the headers they really need.

As long as your project is small, it is important that everything in one directory is the best, but if you know that it will grow, then a good directory structure is a good idea. Separating a potentially reusable GameEngine from a real game, just like you, is good.

Creating a library is useful when this part will be reused in other projects or when your project becomes so large that the number of .o files becomes very high. Therefore, if it is applicable to GameEngine, do it lib. For reusable projects, such as a game engine, it is often also useful to store the headers in a separate directory. Because projects that depend on it only need headers and libs, they don't need other sources.

When projects grow larger using separate directories for the source, intermediate (.o) and final executables help keep your files manageable, since storing .o with your sources usually increases the number of files in your src directory by 50%.

If you want to configure it very well, you may need to look at autoconf and automake. They have a steep learning curve, but many Makefiles will be required from their hands. These are the tools that create the script configuration found in the source distributions of many open source packages.

+2
source

Source: https://habr.com/ru/post/891263/


All Articles