77

Now how does the game handle those 30 Projectile and 70 units by handling them on 100 different threads No, never do that. Never create a new thread per resource, this doesn't scale in networking, neither does it in updating entities. (Anyone remember the times when you had one thread for reading per socket in java?) 1 thread that moves all of them ...


57

Update: In 2018, Unity is rolling out a C# Job System as a way to offload work and make use of multiple CPU cores. The answer below predates this system. It will still work, but there may be better options available in modern Unity, depending on your needs. In particular, the job system appears to resolve some of the limitations on what manually-created ...


42

Yes, this is normal for a real-time game to try to use 100% CPU to perform as fast and good as it can. So that player sees as much frames per second or as good physics simulation or anything else as his PC can provide. In your case - No, this looks like an inefficient design, to take a thread and make it poll for events in a loop (while true do ...


39

Rule number one of multithreading is: Don't use it unless you need to parallelize on multiple CPU cores for performance or responsiveness. A requirement "x and y should happen simultaneously from the users point of view" is not yet sufficient reason to use multithreading. Why? Multithreading is hard. You have no control over when each thread gets executed ...


36

What you have here is a classic O(n²) algorithm. The root cause of your problem has nothing to do with threading and everything to do with the fact that your algorithm has a high complexity. If you haven't come across "Big O" notation before, it basically means the number of operations required to work on n elements (this is the super-simplified explanation)...


27

For a simple 2D engine with sprites, a single-threaded approach is perfectly good. But since you want to learn how to do multithreading, you should learn to do it correctly. Do not Use 2 threads that run more or less lock-step, implementing a single-threaded behavior with several threads. This has the same level of parallelism (zero) but adds overhead for ...


26

The other answers have handled the threading and power of modern computers. To address the bigger question though, what you are trying to do here is avoid "n squared" situations. For example if you have 1000 projectiles and 1000 enemies the naive solution is to just check them all against each other. This means you end up with p*e = 1,000*1,000 = 1,000,000 ...


22

Ok at first glance there are some things you should try out. At first you should try to reduce your collision checks, you can do this by using some kind of spatial structure like a quadtree. This will allow you to reduce the second foreach count, as you will only query entities close the first one. Regarding your threading: Try not to create a thread every ...


20

When you load an scene with SceneManager.LoadSceneAsync() there are actually two things happening: The gameObjects of the scene are loaded into memory. Then the whole scene is enabled. All Awake() and Start() callbacks will be called for the objects in the scene. The second step, enabling the scene, is what actually freezes unity, because unity is running ...


17

Do not create threads per resource/object but per section of your program logic. For example: Thread to update units and projectiles - logic thread Thread for rendering the screen - GUI thread Thread for network (eg. multiplayer) - IO thread The advantage of this is that your GUI (eg. buttons) does not necessarily get stuck if your logic is slow. User can ...


13

Rule number one of multithreading: Don't even think about it, unless you really need to use multiple CPU cores for performance reasons*. Multithreading opens up a whole can of worms of obscure and impossible to reproduce bugs: Race conditions! Because you have no control over the thread scheduling of the OS, you have no control over the order in which ...


10

Honestly, the first thing you should do is switch to a better algorithm. Parallelizing your simulation can, even in the best possible case, speed it up only by a factor equal to the number of CPUs × cores per CPU × threads per core available on your system — i.e. somewhere between 4 to 16 for a modern PC. (Moving your code to the GPU can ...


10

You're right on track with using the context only from a single thread. You can only use an OpenGL context from one thread at a time, but you can do everything else in another thread. The simplest way to take advantage would be to do all the loading as you normally would, but send some kind of "event" back to your main thread to actually call the OpenGL ...


9

In a word, synchronization. If you have some data (your world) which you're reading from one thread (the rendering thread), and writing to in another thread (the logic thread), it is possible that your data will be read in an inconsistent state (for example, half the world has been updated, but not the other half). To maintain consistency, you will probably ...


9

Games will not benefit that much by having 4 cores instead of two. Here's why. Basic Game Engine: 1 Thread The problem with graphics API like DirectX and OpenGL is that it must be runned on one thread, and one thread only. So a basic game engine will run all of the logic and render logic into a single thread. These engines will often use a time delta to ...


9

A game with a constant active window refresh will mostly be ran in full-screen mode and be the only (big) program of the machine managed by the OS. So it is totally acceptable to use 100% of CPU, because nothing else should need it. However, that doesn't means of course you have to always use 100% whatever your game state. Most game loops use a sleep method ...


9

There are a few drawbacks of aiming to use all available CPU time in a PC or mobile game. System requirements: Even if a game is playable on the PC where you develop your game, it might not be playable on a weaker PC owned by someone who bought your game. Limiting CPU use will keep a game usable on machines that more people are likely to already have. If ...


8

Was it necessary for a game developer (in Android, game consoles, online, or in desktop) to display the loading screen to cover unfinished rendered game environment and to prevent from other users thinking that this game is either lagging or freeze. Yes, loading screens are used to hide resource loading and it's somehow a more entertaining way to tell ...


8

Best practices: One central loop in main / rendering thread which also handles sound, network buffering etc. - basically, this centralises communication with OS and other threads. All processor-intensive tasks (for example, mesh building, AI, physics) may be submitted ad-hoc, in bite-sized work units, to existing worker threads. These threads are kept alive ...


8

Generally it's best not to over-engineer, solving problems you may not really have. If you want to make a "simple 2D fighter," well, remember we had those on the NES and even earlier. Even a single core on today's machines is vastly more capable than the systems on which you first learned to love fighting games, I'd wager. So, have you encountered any ...


7

What matters is not the number of threads, but their CPU time Probably you do not need your threads to have full utilization. If you do, get better hardware. In fact, you can use CPU utilization as an ad hoc metric to decide when to improve your hardware. Let us say that your server threads have to complete a tick each 50ms, yet, your CPU is fast enough ...


7

I think this might be a viable architecture. The biggest source of bugs in multithreaded applications is shared access to data. So when the rooms have little to no communication with each other and need little to no access to the data not explicitly owned by them, then they seem like the obvious candidate for units of parallelization. If you are worried ...


6

Another optimization answer that has nothing to do with threads. Sorry about that. You're calculating the Distance() of every pair. This involves taking a square root, which is slow. It also involves several object lookups to get the actual sizes. You can optimize this using the DistanceSquared() function instead. Precalculate the maximum distance at which ...


6

This is flawed. Some reasons here The goals in game development: Keep development costs down. Developing with threads is more costly, it requires more developer hours. Indies can't afford it and big companies only use it when there is a proven benefit. Do not complicate maintenance more than needs be. Debugging and even sometimes reading code that uses ...


6

One of the options is using the Dispatcher pattern. The idea of this pattern is to create an object for each thread you want to invoke on(main thread in your case) which maintains list of delegates that is being polled and executed(e.g. in Update method). Since there is no implementation in Unity I am aware of, you either need to find Dispatcher ...


5

Sorry about thread necromancy, but this problem is my FAVORITE pet-project for learning and teaching concurrency models and frameworks! Running every client/mob in their own thread does give a natural division, but as several have noted threads are expensive when you use more of them than you have CPU cores. If this isn't a compelling reason not to use it ...


5

I can give you only general information, based on my own experience. I have worked on AAA game engine development, but as a graphics programmer I was never involved with loading assets efficiently. We already had a system for that. Yes, streaming assets in from disk should happen on a separate thread (or a few) and never on the same thread as your game ...


5

First, please use a real GPU profiling tool rather than inaccurate measurements. There is a good GPU and CPU profiler built into Visual Studio, so you don't have to hunt around to find decent tools. That out of the way... Standard industry practice is to render first, then do game logic and physics, then finally call Present. That way you parallelize the ...


5

Each OpenGL context can only be "active" in a single thread at a time. If you wish to be making OpenGL calls from two threads simultaneously (as in your example of one "loading thread" which is creating textures, VBOs, etc), and one "rendering thread", then as you say, you need to create a second context, with shared data between the two contexts. Do note ...


Only top voted, non community-wiki answers of a minimum length are eligible