Jump to content

  • Log In with Google      Sign In   
  • Create Account


Member Since 02 May 2010
Offline Last Active Dec 21 2012 06:19 AM

#4956429 [Help] How do you properly organize game architecture?

Posted by on 06 July 2012 - 01:03 PM

In simple words, a message queue is where messages are stored until they're handled. Call it a buffer if you'd like. If you've ever used SDL, its events are put into a queue, which you pull the events from at a good time in your main loop. A message queue is required here because your program can't just stop in its tracks when ever SDL receives a new input and asks your program to handle it. Instead, you get the option to look at it later.

This is called asynchronous message handling. You fire off an event and it may be handled at what ever time the receiver thinks is a good time. Much networking works like this and things like Node.js make use of it to a great extent.

The opposite is synchronous message handling in which case something fires off the event and wont continue execution until the event is handled. No queue is required here, because the receiver will only handle one message because the sender wont be able to send more than one message at the time.

Apart from being essential for networking and multi-threading, a message queue can also be used if you want to send events that wont be handled until the next game turn or "tick". Of course, a message queue can be polled at less frequent intervals.. I don't have much say in that. But the most normal use would be for it to handle events each iteration of the game loop.

#4956151 Global variables in comparison to #define

Posted by on 05 July 2012 - 05:42 PM

So basically you're all saying that if I can use a global constant rather than a #define, I should?

You can only benefit by doing so. Const values can be defined in headers as well. If you need a global variable (god forbid) you'll have to use the extern keyword in the header and define it in an implementation file.

#4956137 Global variables in comparison to #define

Posted by on 05 July 2012 - 05:01 PM

I'm assuming you mean C++.

A define statement replaces -any- instance of "money" in your code, no matter if it's a variable or function in any namespace or scope. You get no namespace and the possibility of name clashes is pretty much guaranteed unless you give it a very long and unique name like "MYPROJECT_MONEY". A const global can be overridden in a scope defining another instance of "money" and you can even put it in a specific namespace avoiding other files declaring the same name.

Defines are uncontrollable and will find a way of leaking into places where you don't want it unless you give them very specific and ugly names. The windows.h header is a great example of this.. you better define LEAN_AND_MEAN before using it and hope all the defines really get undefined.

They're only "global" in the sense that if you include a file with it, you'll include the define it contains as well. But the same goes for globally defined const values, so there's no difference there.

#4956112 [Help] How do you properly organize game architecture?

Posted by on 05 July 2012 - 03:33 PM

About performance: It still requires a very large amount of events before it's bogged down and as I said: it's not always the event system that needs to be fast. The logic gets a message, it does something that's probably pretty heavy relative to the actual event transmission and then it sends it's own event. The most performance will most likely still be required in the logic itself and the observer pattern will most likely remain one of the better options for that, since it's more direct. The best way is simply to stress test your event system if you're unsure and see how many calls to how many handlers you can pull off per second. If it were to happen that an event system would be saturated you can lessen the load by batching and revisiting the need for some events. It's likely you can stretch it quite far. All I'm saying, don't write it off until you've tested it for the current case.

I'm using events only as a glue between input handling, logic, networking, rendering and other systems. You can use it internally in the logic as well, but that could become a performance issue a lot faster. There's another issue of event systems: it can make the larger picture more difficult to follow and the order of execution between events may not be explicit which can cause determinism issues. This is especially true if used in the game logic because it tend to become quite intricate. Using it just to notify other systems keeps it rather simple.

An event system can also help if you plan on adding some sort of scripting. The scripting engine can be detached and communicate with the logic via events, rather than littering the logic with the scripting. Same with AI, which most likely will be using some scripting itself. Make higher level functions in the logic be accessible via events, and both GUI and scripting will be able to access them easily.

About ØMQ: it gives you a highly efficient queuing system. I'm mainly using it because it lets me have a thread safe messaging system. ØMQ's context is completely thread safe which makes it possible for different threads to pass events between them. If you keep the messaging system the only means of communication between threads, it practically removes the issues with race conditions and many other problems related to threads. It's not a holy grail of multithreading, but I find it fitting for my purposes and you might not. Main issue would be it's asynchronous nature, which isn't as efficient in a single threaded environment.

I see the possibility of networking as an added benefit. I lay out the structure of my game so that communicating with a remote client is virtually the same as communicating with the local neighboring thread client. It sends the same messages, only via a different pipe. ØMQ will also gladly take any number of channels to communicate, meaning an indefinite number of clients (network or threads or just objects) can be added with relative ease. I've heard claims of some mmo's using ØMQ and that it was quite sufficient, but I can't really back it up..That's enough of me selling ØMQ for now =P

I'm not making a real time game, which wouldn't be as simple as just 'hooking it up remotely' the way I put it. You have to do prediction algorithms and other jazzy stuff.. a good reason why network multiplayer is such a pain in most cases.

But as I said, it's probably a good thing to wait with ØMQ anyway but it's good to know that it's there.

#4955925 [Help] How do you properly organize game architecture?

Posted by on 05 July 2012 - 04:50 AM

I really like how the event driven system sounds and is exactly what I'd prefer to build. Can you give any pointers on how you start building such architecture?
Again, I'm doing this in C#, if it matters.

Well, I'm using C++ and I don't know what extra tools you get in C# at all, unfortunately. This article inspired me a lot for my current event system. What I've done most recently is to wrap an interface such as this around ØMQ, allowing me to fairly safely send complete objects as messages. Using ØMQ allows it to be either thread safe in-process messaging, inter-process or over TCP almost completely fluidly. ØMQ is blazing fast too and optimized to take some million requests a second on large servers but still really easy to use compared to handling classic connection sockets. There's C# api (and many others) but I can't vouch for it. It's also not all that common in games from what I understand.

The basic idea anyway, is to have listener objects registering to a dispatcher object. It's basically the observer pattern, but a bit more centralized. You register to certain 'global' events, rather than all events from a specific object. Any object wanting to send an event does so via the dispatcher. Fight the temptation of making it a singleton though.

Event systems have one downside, especially if you're using one big (or a couple*) central one(s) such as I do. It's not very performance optimized, since you've got a big middle hand between all objects that communicate via it. The flexibility added usually outweighs this problem imo and the more performance intensive algorithms are usually isolated in one of the modules. But keep in mind that they can be saturated if there's a lot going on in a real time game.

I'm using two dispatchers in my current project. One for strictly local application events, such as window, input and inter-module communication (I've got a server object running on it's own thread). The other one is for the game events which the rendering and network listens to.

There's also a few varieties of how and when to handle the messages. You can put messages into a queue and poll them when it's the objects turn to update. This is what I do with my ØMQ version. This means the queue has to be handled at regular intervals. A second and not very thread safe way is to make them call instantly. My first did so. The message handling took place inside the send method of the dispatcher, as it looked up and triggered the event handlers of the listeners. It's a matter of taste and need which you'll chose.

Since you're not familiar with the concept yet I'd recommend not to use ØMQ or threads for your first few projects. Make a simple 'instant' message dispatcher and tweak it until you're happy with what it's capable of doing. When you feel more comfortable with that, move on to the more advanced and flexible ones.

#4955463 Selecting units in a 3d evironment

Posted by on 03 July 2012 - 04:10 PM

The inverse matrix exactly reverses the transformations you did to get the screen coordinates. I forgot to mention that you also need the depth buffer value as the z coordinate in this case and normalizing the xy coordinate which you mentioned..

I also realised that it's probably just the view-projection you'd want to get the coordinate. The model matrices can be left out..*

A single matrix multiplication and you're done, as long as you got the inverting right.
VPmatrix * WorldPos = NormScreenCoord
InverseVPmatrix * NormScreenCoord = WorldPos

No need for a raycast search or compensation for scaling, but still requires a spatial search of some kind to get the object.

Regarding the ID buffer, maybe the tapping could be resolved by sampling an area rather than a single pixel. Check the pixels for an ID, and if there's more than one that isn't just background, count which one there's more of. Or something like that.. I don't really know how touch screens calculate those things.

In my current project I'm using both. The ID buffer to look up objects, since it's a pretty fast mapping, but for moving things I use the screen-to-world transformations. I don't know how optimal it is, but it lets me get away with mapping things without keeping more advanced query structures that can do spatial and ray cast searches.

* I'll have to look this up though

#4955298 Help me change my life and career.

Posted by on 03 July 2012 - 08:01 AM

of course each language has its use and I merely stated what I didn't like about it. I didn't say they're all awful for every purpose and that you should never use them. I'm not such a C++ bigot that I can't see that.

Scripting is great for productivity. Most games doesn't need blazing performance for their logic or general structure, and puts most of its effort into the graphics engine. Those engines are low level and handles those things where the scripting doesn't have to.

Tools and pre-processing data is part of a production tool chain, which is naturally part of making a game, but my post was about the core language making the heavy lifting. I didn't crack down on scripting languages, so ease down.

Yes, java is used largely in server applications, search engines and management software, and it is mainly the standard there. It doesn't mean people using it actually enjoys working with it, even though it gives reasonable production value. As for learning via Java, I have no say other than that I found learning C++ and it's "memory management" less difficult than it's made out to be. How ever, learning java is a top down approach to learning how to program. It shields a programmer much like you said, from more low level operations. There's a lot to unlearn when going to lower level languages after and I think it's more benefiting to go bottom up. Just my opinion.

My post was about my experiences, which was what the OP asked for. Make an objective case instead next time.

#4955275 Selecting units in a 3d evironment

Posted by on 03 July 2012 - 07:03 AM

There's two ways, as far as I know.

The first, revert the clicked screen coordinate to world coordinates by using your projection in reverse. This is done by inverting the modelviewprojection matrix, which if you aren't familiar with it is going to be tricky. Then use the world coordinate to look up the nearest unit.

The second and simpler approach is to have an ID buffer. Objects (or their selection area) should render a uint unique ID to a buffer, which you then sample at the point you click with glReadPixels. Then just have a lookup of the ID to get the object.

#4955263 Help me change my life and career.

Posted by on 03 July 2012 - 06:37 AM

Java has a huge standard library.. I mean, it's humongous! If you're the kind of guy who thinks 'more is better', then go for java. Personally, I hate the language. It's pure mess in so many ways, and oracle is just in it for the money. I really don't know why anyone wants to willingly use java.

So, enough about that.. C++ is my forté and while it has its own set of issues, I think it's a great language. It's low level while still being manageable and it's extremely versatile. This comes at the price of being fairly complex, but the features are well thought through (in most cases anyway) and it doesn't jump on what ever is all the rage at the moment. If you learn it now you should find out what's special about the latest specification, C++11. It introduces smart pointers in the standard, and many other things which makes a world of difference to manage your objects.

C++11 isn't fully supported by any compilers yet though. It's simply too soon since its release. But a good few things are already implemented in pretty much every compiler, which includes: smart pointers, the auto keyword, lambdas.. which I find the most useful anyway.. you won't need the rest for a year or so while learning the language anyway.

I started with python actually, but I was so put off by its performance. A year programming python and I moved on to C++. The problem with going from a managed language to C++ is to learn the differences about object lifetimes. Python, java and C# runs garbage collection, which sucks a lot of performance at unspecific times. C++ has scope lifetimes. When an object reaches the end of a scope, it destructs. Simple as that really. You exactly control the lifetime of your objects this way. Old C++ had some issues with this, but the new smart pointers makes it so easy even a beginner will be unlikely to have much problems with it (exceptions to this rule may apply).

I've been programming for some.. 5 years I think, in a semi-serious way. I've had a few jobs and some education along side it, but I've learned the trade solely via the internet. So it's quite achievable to learn to program with just the net as a tutor. You'll probably find out more up-to-date knowledge by actively reading on the net (and books!) than going to any school. Collage/uni has a great merit value though, and for someone who's never programmed it may be fitting. I'll be trying to get a computer science degree, starting this fall. It's mostly a way for me to get some income (living in Sweden, I get paid to educate myself), and to get a job after if I don't manage to pull off releasing a successful game before I'm done!

But hear this: Don't expect to make a game in a year from now if you're just starting out. You'll be able to make something very simple and maybe only a proof of concept demo.

Learning a language is merely a fraction of what it takes to build a game. You need to be a good code designer, and learning how to be that takes years. You got to get accustomed to different development tools to be effective, such as version controls, your IDE and debugger, documentation generators, repository sites. Not to mention getting to know the libraries you'll use for your games for the graphics, sound and even logic and system structures.

It's daunting! It's difficult and plain frustrating.

Is it worth it? Hell yes

#4955246 c++: memory deallocation (and freeing) not working?

Posted by on 03 July 2012 - 05:43 AM

Vectors keep their claim to the memory they've allocated, even after you've cleared it's content. It destructs all the elements, but it does not deallocate them. This is a precaution for when you re-use the vector. If it's grown to a certain size once, it's a good chance it will again. That's how they reason anyway..

If you really want to get rid of the allocated memory, replace the vector with a new empty one to force it. C++11 has included the vector.shrink_to_fit() method, but it's a request that may not be fulfilled by the implementation.

myFollicle = std::vector<myFollicles::myFolliclesLib>();

You only need to explicitly free raw pointers! Never call the destructor or a delete on an object in a container. Vector, when clearing, removing or erasing, will call the appropriate destructor (not delete) on the objects it contains. If this is a raw pointer, the actual object it points to will not be deleted unless you call delete explicitly. It's however recommended to use a unique_ptr in this case rather than a raw pointer.

#4954889 std::vector vs std::unique_ptr

Posted by on 02 July 2012 - 07:03 AM

So nobody mentioned std::array yet huh?

Pfft, I did. Fourth post ;)

#4954886 [Help] How do you properly organize game architecture?

Posted by on 02 July 2012 - 06:57 AM

Doesn't have to be UML, just atleast graph it out on paper so you have a rough idea how things are connected that is clear to you (and the future you). Some people like going with the top-down approach, all the way down. I don't remember which book it was that described the process, but it went something like this:
Start with a general overview of the whole system. Then for each object, make a general overview of it that's more specific. Re-iterate until it'd be easier to code it than to describe it, and so code it.

I'm not one that implements this method though. I do tend to sketch up a graph once in a while, but most my design decisions happen while coding. This is fine for a one-man project, but not to recommend if cooperating with other programmers. I can usually envision the relationships in my head, and a good system should be easy enough to do so, but sometimes it does require a less abstract viewing. Even some algorithms, like geometric problems often occurring in games, benefits of a visualization to make it easier to get your head around it.

Some people don't like to, but I use an event system in the core of my program. It is passed to game logic, networking and rendering, so that they can be separated. An event system makes it possible for systems to exists independently of one another.
Example: Logic creates a new object and sends an event about it. Now the rendering system can chose to register to such an event and handle it. Change of position and other states that can be useful for the rendering engine and can be sent as events as well. The rendering system then creates the right visual object for the game object and changes visual queues depending on the changes of state in this object.

Comments in code is good, and should be describing in short and accurate terms what is happening in blocks of code. This is however more difficult than it seems with long term projects. Preferably, take those blocks of code and make them into functions with a name that describes what happens in the function. If it's difficult to name a function it's probably not a well defined function. I do this frequently, much a constantly ongoing process. Comments can get old because it's seldom updated when the code is, which leads to comments making more damage than self describing code. I'm not saying you should be extremist towards one or the other. Just keep the issues of comments in mind, as well as littering your code with too many functions which makes it more difficult to gain an overview of!

#4954832 Start with SFML or SDL?

Posted by on 02 July 2012 - 02:46 AM

I always go for SDL 1.2 with OpenGL for rendering. It's low level compared to most multimedia libraries and once you've done the init code and some basic abstraction over the event system you'll practically never touch SDL in your game again. That's the way I like it.

SFML has too many 'nifty' tools that I never use. It has the aim of being more of a helper library and tend to seep in everywhere. It just imposes itself a bit too much for my taste. The api is pretty OK for what it is though and most people doesn't want to get their hands gritty with opengl calls the way I do..

The many nifty things that it includes are indeed nifty, but they're usually not as versatile as if you'd get another specialized library for the specific purpose. It has network sockets for instance, which is nice and all, if you want something really simple in that way, but they are fairly limited.

If you need the easy basics of rendering a 2D game you should go for SFML. But if you're like me and want to try a few more advanced techniques on your own and rather not have anything in your way, I'd say SDL because it's just there silently in the background.

#4954530 Map editor: Fill Command help

Posted by on 01 July 2012 - 08:06 AM

You mean like a flood fill?

#4954116 std::vector vs std::unique_ptr

Posted by on 29 June 2012 - 04:12 PM

One use-case I have, is to create a vector of data that need to be temporarily forwarded externally (in this case a vertex attribute list forwarded to an OpenGL VBO). Using std::unique_ptr, I can use the get() function to get a pointer. Is it allowed to use &v[0], where v is a std::vector?

It is not only allowed, it is considered idiomatic.

In C++11 this can now be replaced with the data() method, which returns a pointer to the first value just like &v[0], but with a bit clearer intent. It's also a const pointer, which &v[0] doesn't provide.