Hi all,
I've tried searching for this before posting but couldn't find something concrete.
Basically I'm looking for resources or advice on general game engine design, but from the game logic point of view, not rendering. I'm using Mogre and plan to use more addons and libraries, so most things are covered for me already. All I'm left with really is stringing it all together and managing the game logic.
To be clearer, here are some questions on my mind:
- Should I strive for as many game logic updates as possible, i.e Update() between each two frames without H-sync? Or should I aim to call Update() only every specific interval?
- If I go for intervals in the previous questions, should I try and compensate for the lack of sync between the render frames and the game ticks by rendering "half movement"?
- Should I have an Actor base class that contains lots of functionality in it and rely on subclassing, or should I have compositions of objects each responsible for different parts of he actor like moving, animation, physics, AI, etc.
- Should I have one big list of Actors and iterate through all of them each game logic cycle calling Update(), or should I try to minimize this big iteration in some way?
- Should the game be single threaded or is it advisable to employ multi-threading?
These are just some examples of the sort of questions that I'm looking for resource about and I was wondering if anyone here could point my in the right direction? Any book or article on the matter will be appreciated and of course forum members own opinions and experiences.
General game engine / game logic design
Hi.
However, make sure that the Actor is a base class for code sharing needs, not because it's an interface. If your renderer, or your simulation, or your collision tester, or any part of your system expects "Actors", you're in trouble. A renderer should expect renderables (which may be actors), the simulation should expect updatables (which may be actors), and so on: this lets you decide whether to keep a one actor = one renderable = one updatable correspondence or move away from it. .
Until you absolutely, positively determine that object A behaves exactly like object B, keep them separate in two different lists. If you need to share code between the two, have them implement a common interface for that specific functionality (say, both pick-ups and enemies can collide with the player, so they should both have a collision detection method and a "collided player" event: group these facts in a dedicated interface) and write code that works on objects with that interface.
Quote:Original post by amirabiriDepends on the game. Working with fixed-duration update steps is usually easier on the brain cells of the programmer, especially without a sturdy math background. You can also run different subsystems at different frequencies (such as movement 100 times per second, but checking for player/enemy death 10 times per second).
- Should I strive for as many game logic updates as possible, i.e Update() between each two frames without H-sync? Or should I aim to call Update() only every specific interval?
Quote:- If I go for intervals in the previous questions, should I try and compensate for the lack of sync between the render frames and the game ticks by rendering "half movement"?No. Try updating faster than you render. If it turns out that there are too many things moving around, 80% of these things will be of the same type (usually particles or similar low-intelligence entities) and you can then implement interpolation specifically for that type.
Quote:- Should I have an Actor base class that contains lots of functionality in it and rely on subclassing, or should I have compositions of objects each responsible for different parts of he actor like moving, animation, physics, AI, etc.You shouldn't care about that. How you factor common code out of your program is something that should and will evolve as you work on it, so you should strive to keep it as flexible and easily refactored as possible.
However, make sure that the Actor is a base class for code sharing needs, not because it's an interface. If your renderer, or your simulation, or your collision tester, or any part of your system expects "Actors", you're in trouble. A renderer should expect renderables (which may be actors), the simulation should expect updatables (which may be actors), and so on: this lets you decide whether to keep a one actor = one renderable = one updatable correspondence or move away from it. .
Quote:- Should I have one big list of Actors and iterate through all of them each game logic cycle calling Update(), or should I try to minimize this big iteration in some way?It's a basic fact of life that a bullet does not behave like a player, and an enemy does not behave like a pick-up. Trying to treat the the same way will result in a warm fuzzy feeling of "design" (yes, with quotes) and daily pains when the program design does not match the game design.
Until you absolutely, positively determine that object A behaves exactly like object B, keep them separate in two different lists. If you need to share code between the two, have them implement a common interface for that specific functionality (say, both pick-ups and enemies can collide with the player, so they should both have a collision detection method and a "collided player" event: group these facts in a dedicated interface) and write code that works on objects with that interface.
Quote:- Should the game be single threaded or is it advisable to employ multi-threading?Multi-threading is a skill in itself. Using it will make development harder and may detract you from your objective. Unless multi-threading is absolutely critical to what you are trying to achieve or made insanely easy by your libraries or programming language (say, on the level of Erlang), go for it. Otherwise, wait until you feel comfortable with single threaded design.
Thank you for your reply, what you say makes a lot of sense.
Another question that pops to mind is if I should be worried about the performance penalties of too much polymorphism and virtual methods, or not worry about that. For I could have a collection of IMoveable objects with a Move() method, and various implementations of that like LinearMovement and BallisticMovement? On the other hand I could save the virtual method by having two collections: one of LinearMovement objects and one of BallisticMovement objects and just iterate both from my Update() method. That can be done for ICollidable, IRenderable etc.
What you say about update intervals makes sense. In 75Hrz with vsync I will have 1 render cycle approx. every 13.33ms. Then I can iterate all moveables every 10ms or so but iterate collidables every 100ms and so on. My question is if there are any established patterns of how to keep all of this in sync?
Another question that pops to mind is if I should be worried about the performance penalties of too much polymorphism and virtual methods, or not worry about that. For I could have a collection of IMoveable objects with a Move() method, and various implementations of that like LinearMovement and BallisticMovement? On the other hand I could save the virtual method by having two collections: one of LinearMovement objects and one of BallisticMovement objects and just iterate both from my Update() method. That can be done for ICollidable, IRenderable etc.
What you say about update intervals makes sense. In 75Hrz with vsync I will have 1 render cycle approx. every 13.33ms. Then I can iterate all moveables every 10ms or so but iterate collidables every 100ms and so on. My question is if there are any established patterns of how to keep all of this in sync?
Although the vtable fetch might not seem like an issue these days, it`s not those couple of CPU clocks, but a memory fetch that matters.
Of course, if you have about a dozen gameplay objects, that doesn`t really matter.
But if you wanted to have about thousand (or more) - you definitely do not want to do that for every single instance.
Plus, a simple array might be better (e.g. for instancing). It will be easier to transfer that stuff over to shaders later, too. And if you traverse the array in a cache-friendly way, that will give you an immense performance boost.
As with everything, understand the trade-offs.
Remember - the player doesn`t give a damn about the underlying class design.
But he sure as hell cares if the game suddenly stutters.
Of course, if you have about a dozen gameplay objects, that doesn`t really matter.
But if you wanted to have about thousand (or more) - you definitely do not want to do that for every single instance.
Plus, a simple array might be better (e.g. for instancing). It will be easier to transfer that stuff over to shaders later, too. And if you traverse the array in a cache-friendly way, that will give you an immense performance boost.
As with everything, understand the trade-offs.
Remember - the player doesn`t give a damn about the underlying class design.
But he sure as hell cares if the game suddenly stutters.
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement