For an example of a C++ event manager that is type safe, simple to use and very efficient, see SimpleSignal.
As far as I have found, it provides the optimal solution for me.
Did you make that?
It was created by Tim Janik, I just put a copy in Github to make it more accessible to my projects and others that would need it. It is not copyrighted by Tim, but there is a readme that clearly attributes the source to him.
Posted by larspensjo
on 07 January 2014 - 04:24 PM
For GUI, I recommend libRocket. It is general purpose, independent on other game engines, and can easily be adapted for OpenGL (which is what I did). On the negative side, it takes some effort to interface. On the positive side, it is very efficient and powerful. You will be able to control the GUI with a design similar to html and css.
Posted by larspensjo
on 01 January 2014 - 06:22 AM
I'm currently learning modern OpenGL. So far I have been programming everything within the same scope of the primary cpp file, but the more I learn, the more that file becomes very lengthy and cluttered. So naturally, I have been trying to break up my code by putting some within a user defined function and even a user defined class, but I keep having the same problem in that I just have a black screen instead of a rendered triangle.
Sorry, I don't have a specific answer to your question. You have the experienced the black screen of death in OpenGL. There are quite a lot of single point of failures when programming OpenGL, and many of them will give you a black screen.
My personal experience is to do as follows:
Whenever something works, I check it in to a version control.
I make many small check ins, making it easy to back step when something stops working.
I make sure every small step still works.
This relates not only to OpenGL, of course. Now and then, I grow more confident as I feel I have enough experience. And then I suddenly have to spend a lot of time debugging and try to understand why something was broken.
Otherwise, I would say you are on the right path. That is, you need to create a library/framework for using OpenGL (or use a library from someone else). OpenGL is low level programming, and it has helped me to add some layers above it.
Posted by larspensjo
on 30 December 2013 - 04:25 AM
A camera can be seen like any other object in the world, and as such it can be placed in the world.
That is a common misconception, which makes it hard to understand. Actually, the camera is stationary! You move the whole world (using the view matrix), and you turn the whole world, to get what you want in front of the camera. Looking at it that way, the transforms are obvious.
Well, no, it isn't a "misconception". It is a legitimate view onto the things. It may seem that a view space is something special but it isn't.
* Can a camera be placed in the world like any other object? Yes, it can.
* To what is a camera stationary? It is stationary to ... itself!! But that is true for any object in the scene. If you chose a reference system where you sit down, then it becomes stationary for you.
* What if you have 2 cameras in the world: How could saying that both are stationary is more intuitive?
* Is a light also special / stationary because one transforms into its local space when computing a shadow volume?
* Is an ellipsoidal shape special because, when raytracing it, one transforms into its local space where it becomes a sphere?
* Is the world special because one does collision detection within?
Mathematically there is nothing like a natural break point in the chain of transformations from any local space into the screen space. One chooses the space where a given task is best to be done. For sure, the best space for screen rendering is not the world ;)
The problem with placing the camera in the world is that you don't use the same transformation matrix as when you place any other type of object in the world. So on that regard, it is not just like any kind of object. If you want to move an object to the right in your view, you add a translation to that specific object. If you want to move the camera to the right, you subtract a corresponding translation to every object in the world.
I agree that it is valid to use any reference system (view space, word space, screen space, etc). But you can't use more than one camera. That is, if you have more than one camera, you render them one at a time. E.g. creating stereoscopic views, shadow maps or cube maps.
Posted by larspensjo
on 28 December 2013 - 02:28 PM
Hopefully you can see the LODs working in this (debug rendering) video.
I find it difficult to implement a good LOD in a voxel system that have seamless transitions when you change the distance. In your movie clip, there is such a change at 19s.
I use a shadow map for my vortex game engine. It is a full deferred shader, enabling me to use lots of lighting sources efficiently. I think this is necessary if you also want to add other lighting effects as well as screen space based algorithms. Vertex lighting could be a problem if you want dynamic shadow effects?
unfortunately shadow maps requires you to run a "shadow" rendering scene pass, which means you halve your fps for nothing at all
Agreed, it can be costly. On the one hand, it doesn't have to double your render time as the shadow map is only one of all render operations. On the other hand, you probably have to include geometry not visible to the player (outside of the frustum).
So an estimate of 1 week would in reality be 3.14 months.
On a somewhat more serious note: To make a good estimate, you need to subdivide the project into small enough parts. The parts should be small enough to make it possible to estimate each of them with confidence. If there is a part you don't know enough about, then you have to revert to the formula above.
Comparing with the Model-View-Controller, the server would be the Model.
The client can handle much of the animations. The server just sends a "jump" message, and the client animates accordingly.
Don't forget about the problem of cheating. If the client have control over things, they are fairly easy to hack. Even if the average player don't possess the skill to hack a binary, it is enough with one person doing it and giving away the result.
If the server controls the player movements, the client will need to use some kind of interpolation or extrapolation to get smooth movements between updates. This may be needed anyway when displaying other players or monsters.
To determine if a bullet or arrow hits a target requires effort. Not hard for a few of them, but quickly very hard for MMO.
If the client decides who or what is hit, there are time lag problems. The monster may have moved on the server side. If two players shoot at each other, who decides the winner? This can require complicated hand shaking.
Using a time stamp on chunks can be good. In my game, I use a checksum, for the same purpose. That way, reversible changes will require no updates. And small single changes can be broadcasted as delta.
I think you learn best from mistakes. After doing something, experiencing the problems from the design, and then learning how it should be done. That is when you appreciate the better solution, and that is when it will stick. So the absolutely best way to learn, is doing much programming, but having an experienced person pointing out improvements. If you don't have access to an experienced person, use these forums. You will always get stuck into something.
After 30 years of programming, I started a big private game project (couple of thousand hours). It turns out I did a huge amount of things wrong, so I spent (and still spend) a lot of time refactoring it the right way (hopefully). I have learned more in two years than in the previous 10.
So the last advice is, don't be afraid to refactor your code. As a minimum, it will make you more proud of it. Even the process of refactoring is precious experience, that can be reused.
What is done when programming something that is large FPS/TPS project?
In many ways, there are the same problem as with any big software. When the number of lines go above some level, you have to use various methods. In principle, you divide the big project into smaller ones, and try to keep them as independent as possible.
There are specific issues with large games. The render engine, for example, usually have to be managed as a complex system of its own.
There are ways to manage complex game logic. One such is the use of Entity-Component-System pattern, decision trees, etc.
There are also various ways to use data flow control, separation into scripting languages, etc.
I am sure other can add some major structuring methods.
See example in the EntityXlibrary how this can be done. It is C++11 based on variadic template arguments, which is a little difficult. But it also supports that you construct the component first, and then attach it.
Might work. But in general, it is VERY difficult to make a general purpose game engine.
Instead, I recommend that you make a specific game. Please use the standard OO technologies to keep dependencies to a minimum. Follow the SOLID principles, which will make it easier in the end.
Next step, when you have the first game up and running, you use it as a base for the next game. That is when you see what methods and data that need to be generalized. Be prepared for a lot of refactoring. That may also be when you find where to use scripting as a method of decoupling logic.
Do measurements. Don't measure individual components in FPS, measure them in ms. Find what the main components of the drawing are, and measure each of them. Just be careful not to measure the system time on the PC, you have to measure the time as reported by the graphics card. These are usually not the same as the graphics card will draw things in the background.
Of course, CPU-bound algorithms have to be measured using PC system time.
During development, you should continuously do these measurements and log them. That way, you get a history of changes, and can easily detect when something went wrong.
And how do you know this, have you tried writing an application in this way? Yeah it CAN lead to spaghetti code only if you design it poorly. You should never just take advice from the internet and say that it's bad beacause somebody said so..
Please don't be so negative. The OP started this thread with the intention to do an implementation and learn from it. In my opinion, that is the best way to learn, when combined with reading and discussions. Not just reading what other says, but actually assess for yourself. This should be encouraged, and I hope to learn something myself from the effort of others.
It is a library that implements the ECS pattern. I have tested it, like it a lot and found it to be very efficient. At the readme (found at the link), you will also find a tutorial that shows how to use the library.
There are some possible disadvantages with this library:
It is written in C++11, which can make it harder to understand if you don't know the language.
It depends on some external libraries, (Boost and Glog), and on cmake to install. (I have a patch that removes the dependency of glog).
Please ask if you are uncertain or have problems!
I suppose you want the hash table to make an efficient search for entities using specific components? One the one hand, it should be possible as the implementation of Entityx creates a unique id for each component. On the other hand, the library allows for attaching a variable number of components to entities, and provides iterators that finds all entities for this variable list of components. A discussion on the possibilities here would be interesting, and I am sure the library can be extended if a good design is found.