• Advertisement


  • Content count

  • Joined

  • Last visited

Community Reputation

0 Neutral

About dp304

  • Rank

Personal Information

  • Interests
  1. Not everything is clear to me: what class hierarchy (if any) you currently have; what programming language you use etc., but I will try to help. If you are talking about one type of item with several instances (I suppose a power plant doesn't create just a single Energy item and/or there may be multiple power plants) then I don't find this at all overkill; in fact this is what I might do. I wouldn't do this, especially if the Item class already has some abstract superclass or virtual functions (I'm assuming C++ or some similar language here). It may be a better idea to have a virtual bool isTradeable() or bool isEnergy() function, and override it in the Energy subclass (what you suggested in point 3) so that it returns false instead of true (or vice versa). If by abstracting out the energy class you mean creating a separate Energy class (or some other entity) independent from the Item class, then imho this can be a sufficiently elegant solution in case you hadn't intended to subclass Item (or in general use some sort of common class hierarchy for both Energy and regular Items) in the first place. (At least right now I can't come up with something better.)
  2. Writing subjects in present and past is hard

    "Make" becomes "Maked", "Destroy" becomes "Destroied" -- or did I miss something?
  3. Your answers have been very helpful. Especially the last paragraph with the timing estimates. Probably I won't bother optimising my game loop (at least not the way I described). Not even when working on a computer from '98. Thanks again!
  4. Thanks for the quick answer! I was suspecting something like that, but looking at the trend of reducing the amount of inheritance and virtual function calls in games (e.g. by using Entity-Component-System frameworks instead), I became unsure; although probably the trend is due to those tens of thousands of virtual calls (involving game objects). (But if I understand correctly, there used to be a time when even a couple of virtual calls per frame was a concern that needed to be optimised - there were games developed in C++ as early as 1998, weren't there? If I ever target a very low-end platform, on the level of a Pentium-II - which I probably won't - should I refactor virtual calls? Or in that case should I forget about C++ altogether?)
  5. Hello! As far as I understand, the traditional approach to the architecture of a game with different states or "screens" (such as a menu screen, a screen where you fly your ship in space, another screen where you walk around on the surface of a planet etc.) is to make some sort of FSM with virtual update/render methods in the state classes, which in turn are called in the game loop; something similar to this: struct State { virtual void update()=0; virtual void render()=0; virtual ~State() {} }; struct MenuState:State { void update() override { /*...*/ } void render() override { /*...*/ } }; struct FreeSpaceState:State { void update() override { /*...*/ } void render() override { /*...*/ } }; struct PlanetSurfaceState:State { void update() override { /*...*/ } void render() override { /*...*/ } }; MenuState menu; FreeSpaceState freespace; PlanetSurfaceState planet; State * states[] = {&menu, &freespace, &planet}; int currentState = 0; void loop() { while (!exiting) { /* Handle input, time etc. here */ states[currentState]->update(); states[currentState]->render(); } } int main() { loop(); } My problem here is that if the state changes only rarely, like every couple of minutes, then the very same update/render method will be called several times for that time period, about 100 times per second in case of a 100FPS game. This seems a bit to make dynamic dispatch, which has some performance penalty, pointless. Of course, one may argue that a couple hundred virtual function calls per second is nothing for even a not so modern computer, and especially nothing compared to the complexity of the render/update function in a real life scenario. But I am not quite sure. Anyway, I might have become a bit too paranoid about virtual functions, so I wanted to somehow "move out" the virtual function calls from the game loop, so that the only time a virtual function is called is when the game enters a new state. This is what I had in mind: template<class TState> void loop(TState * state) { while (!exiting && !stateChanged) { /* Handle input, time etc. here */ state->update(); state->render(); } } struct State { /* No update or render function declared here! */ virtual void run()=0; virtual ~State() {} }; struct MenuState:State { void update() { /*...*/ } void render() { /*...*/ } void run() override { loop<MenuState>(this); } }; struct FreeSpaceState:State { void update() { /*...*/ } void render() { /*...*/ } void run() override { loop<FreeSpaceState>(this); } }; struct PlanetSurfaceState:State { void update() { /*...*/ } void render() { /*...*/ } void run() override { loop<PlanetSurfaceState>(this); } }; MenuState menu; FreeSpaceState freespace; PlanetSurfaceState planet; State * states[] = {&menu, &freespace, &planet}; void run() { while (!exiting) { stateChanged = false; states[currentState]->run(); /* Runs until next state change */ } } int main() { run(); } The game loop is basically the same as the one before, except that it now exits in case of a state change as well, and the containing loop() function has become a function template. Instead of loop() being called directly by main(), it is now called by the run() method of the concrete state subclasses, each instantiating the function template with the appropriate type. The loop runs until the state changes, in which case the run() method shall be called again for the new state. This is the task of the global run() function, called by main(). There are two negative consequences. First, it has become slightly more complicated and harder to maintain than the one above; but only SLIGHTLY, as far as I can tell based on this simple example. Second, code for the game loop will be duplicated for each concrete state; but it should not be a big problem as a game loop in a real game should not be much more complicated than in this example. My question: Is this a good idea at all? Does anybody else do anything like this, either in a scenario like this, or for completely different purposes? Any feedback is appreciated!
  • Advertisement