What can help me transition from intermediate web OOP to game OOP

5    06 Jun 2015 07:48 by u/sec

I feel like I am hitting a road block in learning in web development. I have always wanted to get into C++ and make a game (maybe in web?) but for career purposes, I feel like having a solid grasp on C++ would be advantageous...However, I have no clue where to start. I am not talking about learning how to set variables, but like, how does a game function from an architectural point of view?

Any direction would be appreciated

6 comments

4

Haha, interesting. Coming from a game/application background this is such a strange question but I suppose it makes sense. I imagine the paradigm in web development is an infinite event driven system. Games are much more simple from an architectural (although generally vastly more complex from an implementation) point of view. It's just a state system with constant looping in the game itself.

  • state intro = display splash go to menu
  • state menu = display menu, poll for input
  • state menu.game started = display game intro, go into while(playing) {do some stuff} then go to menu
  • state menu.game exited = bye

The game loop itself is going to be made up of input querying, AI updating, physics updating, rendering, and so on. That is where the actual complexity comes in but from a broad architectural point of view games are trivial.

1

While I agree with you for simple games, mobile games, stuff like Flappy Bird, more complex games like World of Warcraft, Hearthstone, or Civilization require and highly benefit from well thought out systems architecture. Having well defined and well built systems makes the inevitable iteration that much faster to implement. Building modular systems using standard design patterns makes adding content to the game a task to be done by content designers rather than engineers. Again, allowing for rapid iteration.

Apologies for the rambling. I work in games and we spend a LOT of time building well architected systems. We iterate on the game systems almost as much as we iterate on the interface or game mechanics.

All that said, to get back to the OPs question. Build a game! Try to build the underlying systems to be reusable. Then build another game and reuse those systems. Learn what kinds of assumptions you made wrong and what patterns you like. Rinse and repeat. I promise your first game will be a spagetti mess of code, but you will learn a lot. If you don't know OO concepts and design patterns well, start reading and exploring these concepts!

2

Any game regardless of complexity is going to have an identical basic architecture. Well at least any local game. Get into games where you're running a dependent client and not a stand-alone application and the architecture becomes different, but even a game like Civilization is going to have an identical architecture at the most fundamental level. Modular design, design patterns, and all of this is an entirely tangential discussion. There are an enormous amount of details and concepts in between but that is a matter of design and ultimately implementation - not a broad spectrum layman's consideration of the way to begin to think about how it works.

2

First, get yourself a good C++ book. I'd recommend something like Effective Modern C++.

Next, get yourself started with Visual Studio for an IDE and SFML for video/audio/thread library. I know a lot of game programmers poopoo the idea, but SFML is a decent way to learn the basic architecture of C++ game without having to go from grounds up.

Basic architecture is to run worker threads to update graphics, another worker thread to run the sound, and another to loop the game and so on. SFML gives you some thread management capability, so you have that going for you.

Here's an example code:

#include "GameEngine.h"
int main(int argc, char* argv[])
{
    GameEngine game;
    game.start();
    return 0;
}

The GameEngine will have implementaion like this:

void GameEngine::start(void) {
    this->loadSettings();
    int width = 0;
    int height = 0;
    this->mGameSettings.getResolution(width, height);
    this->mWindow.create(sf::VideoMode(1920,1200,32), "Game Title");
    this->mWindow.setPosition(sf::Vector2i(0,0));
    this->mWindow.setSize(sf::Vector2u(width,height));
    m_gameState = InitLoading;
    while(!isExiting()) {
        this->playGame();
    }
    this->mWindow.close();
}
bool GameEngine::isExiting() {
    if (m_gameState == AppState::Exiting)
        return true;
    else
        return false;
}
void GameEngine::playGame() {
    sf::Event currentEvent;
    while (mWindow.pollEvent(currentEvent)) {
        switch (m_gameState) {
        case AppState::InitLoading:
            {
                AssetManager assetMgr(this->mGraphicAssets, 
                    this->mSoundAssets);
                sf::Thread loaderThread(&AssetManager::loadAssets,&assetMgr);
                LoadingScreen initLoading(this->mWindow, assetMgr, this->m_gameState);
                loaderThread.launch();
                initLoading.run();
                break;
            }
        case AppState::AtMainMenu:
            {
                MainMenuScreen mainMenu(this->mWindow, this->mGraphicAssets, this->mSoundAssets, this->m_gameState);
                mainMenu.run();
                break;
            }
        case AppState::sp_challenge:
            {
                SpChallenge spChallenge(this->mWindow, this->mGraphicAssets, this->mSoundAssets, this->m_gameState);
                spChallenge.run();
                break;
            }
        default:
            break;
        }
        if (currentEvent.type == sf::Event::Closed || m_gameState == AppState::Exiting)
            mWindow.close();
    }
}
void GameEngine::loadSettings() {
    this->mGameSettings.readFromCfg();
    this->mGameSettings.setResolution(1200, 
        VideoSettings::AspectRatio::SixteenToTen, 32);
}

and you'd need somesort of application loop control:

AppLoop.h

#pragma once
#include "GameEngine.h"
#include "AppCommon.h"
#include <list>
class AppLoop
{
public:
    AppLoop(sf::RenderWindow& appWindow, AppState& appState);
    virtual ~AppLoop(void);
    void run(void);
    virtual void doInit(void) {};
    virtual void handleEvents(sf::Event sfEvent);
    virtual void update(void) {};
    virtual void draw(void);
    virtual void doOverlay(void) {};
// helper methods
    bool isReadyToExit(void) const;
    void setReadyToExit(void);
    float getElapsedTime(void) const;
protected:
    // reference to app
    sf::RenderWindow& mAppWindow;
    AppState&   mr_appState; 
    // draw loop draws this
    std::list<std::reference_wrapper<sf::Sprite>> mDrawSpriteList;
    std::list<std::reference_wrapper<sf::Text>> mDrawTextList;
private:
    bool        mIsReadyToExit;
    void        getAppLoopElapsedTime();
    sf::Clock   mElapsedClock;
    float       mElapsedTime;   
};

You can then inherit AppLoop in various game modes.

Enjoy.

0

Thank you very much for this,

1

You totally must watch Handmade Hero.

It's video stream of making game completely from scratch (c-style c++) targeted at beginners.