I am working on developing a game engine using DirectX 11 and C++ (using the default Visual Studio template) and I have some questions that I cannot find answers to online.
So there are three main components for the game, the actual game class, a renderer and a logic class. The game class would look like this
class Game {
Game();
~Game();
Logic* m_Logic;
Renderer* m_Renderer
}
(If you are curious, I am doing this for two reasons, 1. to play around with classes, I've done it the conventional way before so I want to try something else and see if it has any real benifits. 2. so that the code for both are completely abstracted from eachother)
My question here is if it is a bad idea to make the two subclasses into singletons (given the game class is). I understand when and why one might use them, but considering that there will only ever be a single instance within the game class, would this work fine? What if the game class wasn't a singleton, and could instead run multiple copies at the same time (thus allowing for running multiple games at the same time, once again out of curiosities sake)
NOTE: Since everyone keeps pointing this out. I know they aren't a good idea. This is a test/experiment. I am having my fun programming. Let me have my fun :P
EXAMPLE: An example of why I might want a renderer to be a singleton when the game class can have multiple instances. Since the renderer will be identical between different instances of the game, there is no need for there to be multiple instances of it. Think of it as a container of all the functions that just takes the various variables stored in the game class and does the things to it to output to screen. Same goes for the logic class.
Some would say that "Singletons are never a good idea", but this statement is not held by engineers behind many popular game engines to this day. I will advise you to minimize their use everywhere possible, but there will be situations that they are well-suited for. In fact, "Game Engine Architecture" written by Jason Gregory over at Naughty Dog has a whole section on their uses. I will give an example that I kind of regard as a hybrid approach.
If you read through the code base of Unreal Engine (or at least use the engine), you will find something along the lines of:
extern class UEngine * GEngine
UEngine is actually the base class of all Engine implementations (and there are multiple as there is a need for different variants). During startup, the launcher determines which variant it needs to load and then proceeds to construct a single instance that the entire system will then use. This is similar to your approach, but rather than making multiple Singletons, you can have a global reference to your Game object that gets set once during initialization:
extern std::unique_ptr<Game> game; // Global game reference in some .h file
(in .cpp)
std::unique_ptr<Game> game;
int main(int numArgs, char ** args) {
game = std::make_unique<Game>( ... ); // Initialize game exactly once!!
...
}
This approach allows you to do some interesting things, especially if you make Game an interface like the engineers behind Unreal Engine decided to do and then have multiple implementations depending on the need behind it.
Should each object that Game maintains be a Singleton? I would not think so as it actually limits what you can do later. Game needs to at least support the following:
Creation, start up and shut down of things like Logic and Renderer, in the correct order (it owns all of these objects it creates, so all code that interfaces with Game inevitably interacts with them!)
Ability to retrieve references to things like Logic and Renderer, or whenever possible keep them hidden but provide a limited interface to gain access to their functionality
Since Game is now your only/one of your only global variables, it becomes the gateway into your engine environment and thus you can do a lot of stuff to encapsulate the components that it maintains rather than making many singleton objects
I consider this a better approach than making all of your core classes singletons.
Related
I've built myself a basic EEPROM burner using a Teensy++ 2.0 for my PC bridge, and it's working great, but as I look to expand its compatibility, my code is getting rather hacky. I'm looking for some advice for a proper design for making this code expandable. I've taken a class in software design patterns, but it was awhile ago, and I'm currently drawing a blank. Basically, here's the use case:
I have several methods, such as ReadByte(), WriteByte(), ProgramByte() (for FlashROMs that require a multi-byte write sequence in order to program), EraseChip(), etc. so basically I have an EEPROM pure virtual base class that gets implemented by concrete classes for each chip type that I want to support. The tricky part is determining which chip type object to generate. I'm currently using a pseudo-terminal front-end on the Teensy++ serial input, a basic command-line type interface with parameters, to send options like the chip type to the Teensy++. The question is, is there a design pattern (in C/C++), something like a Factory Pattern, that would take a string input of the chip type (because that's what I'm getting from the user), and return an EEPROM object of the correct derived type, without having to manually create some big switch statement or something ugly like that where I'd have to add the new chip to a list any time I create a new chip derived class? So something like:
public const EEPROM & GetEEPROM(const std::string & id)
and if I pass it the string "am29f032b" it returns a reference to an AM29F032B object, or if I pass it the string "sst39sf040" it returns a reference to an SST39SF040 object, which I could then call the previously mentioned functions on, and it would work for the specified chip.
This code will be run on an AVR microcontroller, so I can't have anything with a huge OOP overhead, but the particular microcontroller I'm using does have a relatively large amount of program flash and work RAM, so it's not like I'm trying to operate in 2kb, but I do have to keep in mind limited resources.
What you're looking for is a Pluggable Factory. There's a good description here. It's attributed to John Vlissides (1 of the Gang of Four) and takes the Abstract factory pattern a few steps further. This pattern happens to also be the architectural foundation of COM.
The usual way of implementing one in C++ is to maintain a static registry of abstract factories. With judicious use of a few templates and static initialisers, you can wrap the whole lot up few lines of boiler-plate which you include in each concrete product (e.g. chip type).
The use of static initialisers allows a complete decoupling of concrete products from both the registry and the code wanting to create products, and has the possibility of implementing each as a plug-in.
You could have a singleton factory manager that keeps a map of string->factory object. Then each factory class would have a global instance that registers itself with the manager on startup.
I try to avoid globals in general, and singletons in particular, but any other approach would require some form of explicit list which you're trying to avoid. You will have to be careful with timing issues (you can't really assume anything about the order in which the various factories will be created).
When I was younger, I used a tool called Game Maker a lot. I started to learn to program from it. I'm far beyond that now, but looking back on it, some of it's features and designs are quite interesting. I'm wondering- How would I implement functionality similar to this tool using C++?
I'm wondering about:
Objects/classes
Game Maker had a list of 'Objects' that you would create which were essentially just different classes all derived from the same base class (I'll call it GameObject for now) amd a system function called 'instance_create' that would take an object type as a paramater.
In c++ this would look something like this (Though syntatically very incorrect):
class MyGameObject : GameObject
{
//...
}
GameObject instance_create(class objecttype)
{
objecttype newinstance = new objecttype();
return newinstance
}
GameObject* gameobjectinstance = instance_create(MyGameObject);
How would I go about implementing that?
system variables/functions
Game Maker had system variables and functions that could be accessed from anywhere. Period. Anywhere. I'm thinking globals, but I know that's bad design. I'm thinking Having a global class, and have the variables/functions as static, but then they cannot be altered. How would I do that?
var
Game Maker had only one data type- a var. It could be a string, an integer, a decimal, anything. And there were system functions for conversion between those.
Lastly, how could I define the object types in some kind of script? Like, if I want to add a new type of object, create a new script? I don't think C++ can create object types at runtime, so how would I do this?
Using a template.
template<typename T> GameObject* instance_create()
{
return new T;
}
GameObject* gameobjectinstance = instance_create<MyGameObject>();
However, the design you have specified is highly questionable (at best) and definitely not suited to C++. You should strive to implement a well-designed system, and one appropriate to the language, not re-create a system from the past.
I especially think that since you mention run-time interpretation of scripts, that in fact the GameMaker classes and C++ classes have nothing to do with each other. And you definitely cannot create C++ classes at run-time, nor can you pass types around at run-time, nor can you instantiate templates at run-time.
You would be best suited simply whipping out a scripting language, such as Lua, and writing only the necessary high-performance components in C++.
Game Maker enables us to control game functionality through "objects", each composed out of "events", which are triggered at certain times during a game. Within events are "actions". Firstly, it's worth noting that comparing Game Maker development with C++ is like comparing chalk and cheese. However, theoretically speaking, I'd imagine you could mirror GM functionality (albeit very inefficiently) in C++ as follows:
The base object class could look something like this:
class CObjectBase
{
public:
CGameSprite* sprite;
int x, y;
...
virtual void onEventCreate( void ) {};
virtual void onEventDestroy( void ) {};
...
virtual void onEventKeyPressedUp( void ) {};
virtual void onEventKeyPressed...
...
... (there are lots of these)
// The draw event in GM (from memory) had in-built functionality:
virtual void onEventDraw( void )
{
CGameEngine::getSingleton()->DrawSpriteAtLocation( sprite, x, y );
}
};
You'd derive from this class and override the functions ("events") that are relevant to your object (the statements that compose these functions are your "actions"). Then there would be some sort of object instance manager singleton class which holds a list of all object instances in the current "room" and loops through each every frame (and handles instancing), triggering relevant events by calling their respective functions.
Interestingly, this actually roughly demonstrates why a system like Game Maker lacks a degree of efficiency. There is additional, unnecessary overhead that exists in order to keep options open for the developer. The bloated base object that all objects derive from is often overkill for specific situations. For example, imagine an object with just two events used out of 50 - the object manager still blindly checks for all these other events even if they aren't utilised. Obviously optimisations can be made, but overall, the breadth of the engine ultimately results in reduced performance.
As for your query relating to a single 'var' type, as has been stated already, this is more a characteristic of scripting, not C++. This proves that Game Maker cannot simply be modeled by C++ alone.
I'm having a little circular-dependency problem. It works fine, but it makes for ugly-seeming code. It's in the context of a Snake game.
I have a class, Snake, which contains a vector of SnakeSegments, and manages their interaction (for instance moving and growing as a unit, rather than as separate entities).
When a SnakeSegment collides with a Food object, it flips its hasEaten member to true. The Snake routinely queries the SnakeSegments, essentially for this member. If any of the queries return positive (i.e. one has hit food), then the Snake will grow as a unit (i.e. expand the head and shrink the tail). This is all fine and good, but I'd much prefer a more signal-based approach, where, when a SnakeSegment hits food, it sends an alert (signal, interrupt, etc.) to the Snake class, which tells it to grow. This means I wouldn't have ugly code in my Snake's Update function, checking all the segments; and I would instead have an OnEat() function in my Snake class.
However, this leads to circular dependencies; the Snake contains a vector of SnakeSegments, and the SnakeSegments have a Snake& or Snake* member, which tells them whom to alert when they eat. In the code, I essentially just have to pre-declare the Snake class:
class Snake;
class SnakeSegment
{
...
Snake* alertOnEat;
...
};
and my Snake class just works normally
#include "SnakeSegment.hpp"
class Snake
{
...
std::vector segments;
...
void OnEat();
...
};
Are there any nicer designs to this? Note that it isn't just a problem occuring here; a similar problem occurs in a number of areas (e.g. the GameWorld contains a Snake member, and the Snake alerts the GameWorld when it dies), so a solution specific to Snake and SnakeSegment isn't what I'm looking for.
Your current design is perfectly fine in most situations. Yes, it creates a circular dependency, but it also is the simplest and the clearest way to do it.
However, you should limit those dependencies between interfaces or base classes rather than to the derived classes directly. The world-snake dependency is a good example. You probablly don't necessarily want the World class to know about all the possible game object types. However, what you can do is derive all your game objects from a common GameObject class and make World and GameObject interdependant.
There are also more complicated ways to avoid dependencies all with their pros and cons, they mostly differ on the level of separation and clarity. Among those, function pointers, delegates, observers, listerners, functors, etc.
In the end, it always come down to how much complexity you are ready to introduce to your architecture in exchange of flexibility and clear separation of concerns.
Never forget that design is compromise.
What you may want to look at for this problem is the Observer/Observable design pattern. It allows you to create objects that observe (Snake) observable objects (SnakeSegment) and get notified right away when their state has changed.
Wikipedia has a good example of it written in many languages including C++.
It's a common pattern used in a lot of GUI development so the View layer can change when any of the underlying Model data changes.
I have a chess variants engine that plays suicide chess and losers chess along with normal chess. I might, over time, add more variants to my engine. The engine is implemented completely in C++ with proper usage of OOP. My question is related to design of such a variant engine.
Initially the project started as a suicide-only engine while over time I added other flavors. For adding new variants, I experimented using polymorphism in C++ first. For instance, a MoveGenerator abstract class had two subclasses SuicideMoveGenerator and NormalMoveGenerator and depending on the type of game chosen by user, a factory would instantiate the right subclass. But I found this to be much slower - obviously because instantiating classes containing virtual functions and calling virtual functions in tight loops are both quite inefficient.
But then it occurred to me to use C++ templates with template specialization for separating logic for different variants with maximum reuse of code. This also seemed very logical because dynamic linking is not really necessary in the context as once you choose the type of game, you basically stick with it until the end of the game. C++ template specialization provides exactly this - static polymorphism. The template parameter is either SUICIDE or LOSERS or NORMAL.
enum GameType { LOSERS, NORMAL, SUICIDE };
So once user selects a game type, appropriate game object is instantiated and everything called from there will be appropriately templatized. For instance if user selects suicide chess, lets say:
ComputerPlayer<SUICIDE>
object is instantiated and that instantiation basically is linked to the whole control flow statically. Functions in ComputerPlayer<SUICIDE> would work with MoveGenerator<SUICIDE>, Board<SUICIDE> and so on while corresponding NORMAL one will appropriately work.
On a whole, this lets me instantiate the right templatize specialized class at the beginning and without any other if conditions anywhere, the whole thing works perfectly. The best thing is there is no performance penalty at all!
The main downside with this approach however is that using templates makes your code a bit harder to read. Also template specialization if not appropriately handled can lead to major bugs.
I wonder what do other variant engine authors normally do for separation of logic (with good reuse of code)?? I found C++ template programming quite suitable but if there's anything better out there, I would be glad to embrace. In particular, I checked Fairymax engine by Dr. H G Muller but that uses config files for defining game rules. I don't want to do that because many of my variants have different extensions and by making it generic to the level of config-files the engine might not grow strong. Another popular engine Sjeng is littered with if conditions everywhere and I personally feel thats not a good design.
Any new design insights would be very useful.
"Calling virtual functions in tight loops are inefficient"
I would be pretty surprised actually if this caused any real bloat, if all the variables of the loop have the same dynamic type, then I would expect the compiler to fetch the corresponding instruction from its L1 cache and thus not suffer much.
However there is one part that worries me:
"obviously because instantiating classes containing virtual functions [is] quite inefficient"
Now... I am really surprised.
The cost of instantiating a class with virtual functions is near undistinguishable from the cost of instantiating a class without any virtual functions: it's one more pointer, and that's all (on popular compilers, which corresponds to the _vptr).
I surmise that your problem lies elsewhere. So I am going to take a wild guess:
do you, by any chance, have a lot of dynamic instantiation going on ? (calling new)
If that is the case, you would gain much by removing them.
There is a Design Pattern called Strategy which would be eminently suitable for your precise situation. The idea of this pattern is akin, in fact, to the use of virtual functions, but it actually externalize those functions.
Here is a simple example:
class StrategyInterface
{
public:
Move GenerateMove(Player const& player) const;
private:
virtual Move GenerateMoveImpl(Player const& player) const = 0;
};
class SuicideChessStrategy: public StrategyInterface
{
virtual Move GenerateMoveImpl(Player const& player) const = 0;
};
// Others
Once implemented, you need a function to get the right strategy:
StrategyInterface& GetStrategy(GameType gt)
{
static std::array<StrategyInterface*,3> strategies
= { new SuicideChessStrategy(), .... };
return *(strategies[gt]);
}
And finally, you can delegate the work without using inheritance for the other structures:
class Player
{
public:
Move GenerateMove() const { return GetStrategy(gt).GenerateMove(*this); }
private:
GameType gt;
};
The cost is pretty much similar to using virtual functions, however you do not need dynamically allocated memory for the basic objects of your game any longer, and stack allocation is a LOT faster.
I'm not quite sure if this is a fit but you may be able to achieve static polymorphism via the CRTP with some slight modifications to your original design.
I've got a game engine where I'm splitting off the physics simulation from the game object functionality. So I've got a pure virtual class for a physical body
class Body
from which I'll be deriving various implementations of a physics simulation. My game object class then looks like
class GameObject {
public:
// ...
private:
Body *m_pBody;
};
and I can plug in whatever implementation I need for that particular game. But I may need access to all of the Body functions when I've only got a GameObject. So I've found myself writing tons of things like
Vector GameObject::GetPosition() const { return m_pBody->GetPosition(); }
I'm tempted to scratch all of them and just do stuff like
pObject->GetBody()->GetPosition();
but this seems wrong (i.e. violates the Law of Demeter). Plus, it simply pushes the verbosity from the implementation to the usage. So I'm looking for a different way of doing this.
The idea of the law of Demeter is that your GameObject isn't supposed to have functions like GetPosition(). Instead it's supposed to have MoveForward(int) or TurnLeft() functions that may call GetPosition() (along with other functions) internally. Essentially they translate one interface into another.
If your logic requires a GetPosition() function, then it makes sense turn that into an interface a la Ates Goral. Otherwise you'll need to rethink why you're grabbing so deeply into an object to call methods on its subobjects.
One approach you could take is to split the Body interface into multiple interfaces, each with a different purpose and give GameObject ownership of only the interfaces that it would have to expose.
class Positionable;
class Movable;
class Collidable;
//etc.
The concrete Body implementations would probably implement all interfaces but a GameObject that only needs to expose its position would only reference (through dependency injection) a Positionable interface:
class BodyA : public Positionable, Movable, Collidable {
// ...
};
class GameObjectA {
private:
Positionable *m_p;
public:
GameObjectA(Positionable *p) { m_p = p; }
Positionable *getPosition() { return m_p; }
};
BodyA bodyA;
GameObjectA objA(&bodyA);
objA->getPosition()->getX();
Game hierarchies should not involve a lot of inheritance. I can't point you to any web pages, but that is the feeling I've gather from the several sources, most notably the game gem series.
You can have hierarchies like ship->tie_fighter, ship->x_wing. But not PlaysSound->tie_fighter. Your tie_fighter class should be composed of the objects it needs to represent itself. A physics part, a graphics part, etc. You should provide a minimal interface for interacting with your game objects. Implement as much physics logic in the engine or in the physic piece.
With this approach your game objects become collections of more basic game components.
All that said, you will want to be able to set a game objects physical state during game events. So you'll end up with problem you described for setting the various pieces of state. It's just icky but that is best solution I've found so far.
I've recently tried to make higher level state functions, using ideas from Box2D. Have a function SetXForm for setting positions etc. Another for SetDXForm for velocities and angular velocity. These functions take proxy objects as parameters that represent the various parts of the physical state. Using methods like these you could reduce the number of methods you'd need to set state but in the end you'd probably still end up implementing the finer grained ones, and the proxy objects would be more work than you would save by skipping out on a few methods.
So, I didn't help that much. This was more a rebuttal of the previous answer.
In summary, I would recommend you stick with the many method approach. There may not always be a simple one to 1 relationship between game objects and physic objects. We ran into that where it was much simpler to have one game object represent all of the particles from an explosion. If we had given in and just exposed a body pointer, we would not have been able to simplify the problem.
Do I understand correctly that you're separating the physics of something from it's game representation?
i.e, would you see something like this:
class CompanionCube
{
private:
Body* m_pPhysicsBody;
};
?
If so, that smells wrong to me. Technically your 'GameObject' is a physics object, so it should derive from Body.
It sounds like you're planning on swapping physics models around and that's why you're attempting to do it via aggregation, and if that's the case, I'd ask: "Do you plan on swapping physics types at runtime, or compile time?".
If compile time is your answer, I'd derive your game objects from Body, and make Body a typedef to whichever physics body you want to have be the default.
If it's runtime, you'd have to write a 'Body' class that does that switching internally, which might not be a bad idea if your goal is to play around with different physics.
Alternatively, you'll probably find you'll have different 'parent' classes for Body depending on the type of game object (water, rigid body, etc), so you could just make that explicit in your derivation.
Anyhow, I'll stop rambling since this answer is based on a lot of guesswork. ;) Let me know if I'm off base, and I'll delete my answer.