2 Thread one for drawing and one for logic

Hi, After some thinking I tought that the logic would be better off in a different Thread then the drawing code.

So I create 2 Threads and fire them both off.
I know to cap the fps in the view Thread, but what about logic? :s
In killergaming the author describes how to call multiple logic updates when the frame is bigger then the desired frame length. To come closer to the desired fps…
But how do you count updates per second then, and how do you tell how many updates should be done in one frame, 1 2 or mayby 3?

also In the javadoc of thread is stated that when the wait command is done, locks remain on objects.
So if this situation occurs( A new score)
In the logic Thread:
controller.setScore(5)
In the view Thread:
logic.wait
controller.getScore
a deadlock would happen right? >:(

Your making it much more difficult than it needs to be.

I don’t think you need to create an extra Thread for the logic. Remember that a program is already a thread itself. So when you create a seperate Thread for your graphics it is seperate from the normal program. You can do the logic in there.

Regarding the update skips: your game loop gets the time before it runs and after it runs. You then determine the sleep time. Suppose you want 50 FPS, that would mean 1 update, 1 render, 1 draw every 20ms. Now say the loop takes 44ms to complete. That means you’ve used the time for 2 loops. So you store the time that was overspent and during the next loop you make up for that by doing extra updates for every 20ms subtractable from the time overspent. You can also specify a max number of updates to be repeated as well.

All of this is covered in Killer Game Programming in Java.

Thanks for the reply,

[quote]I don’t think you need to create an extra Thread for the logic. Remember that a program is already a thread itself. So when you create a seperate Thread for your graphics it is seperate from the normal program. You can do the logic in there.
[/quote]
Please correct me if i’m wrong
There is my own Thread drawing & doing logic Logic because it calls logic() as a function inside the Thread run method.
The program Thread that creates the objects, or does it do more?
The key, mouse events Thread

Also I now better understand that it is all about the fps, more ups is not needed, only when frames are running behind.

you can have as much thread as you want to. But regardless to the heap size of your resulting thread-stack, it is important to group the whole as a threading-tree (see ThreadGroup), know I’m saying? then, using more threads can become interesting at the engine-acceleration level. :wink:

pay attention to the fact that the more threads you create simultaneously, the longer you’ll spend your time to get the whole stuff synchronized. So I’d suggest you to focus on what resources are used from “drawing” and “logic”. but that’s alright. ;D ;D ;D ;D ;D ;D

My apologies, I was thinking about something else here. Yes, the logic is called from the Thread which handles updating/rendering/drawing.

Have a look at this:
Here’s a simple game loop:


   START
     |
 INITIALIZE
     |
  [loop]<-----.
     |        |
   logic      |
     |        |
draw objects  |
     |        |
[finished?]---^ no
     |
     | yes
  CLEANUP
     |
   EXIT

To control the FPS you need to know how much time elapsed from the beginning of the game loop to the end of the game loop. If everything is in one Thread then it’s easy, just take the time before and after and determine the sleep time and if it’s necessary to do extra updates.

If you are going to use a separate Thread for logic then you’re going to run into this:
If the logic Thread takes longer to execute than the Draw Thread then you’re never going to be drawing the state correctly:
This tables shows the total time elapsed and the loop nr for the logic and draw.

[tr][td]time[/td][td]logic[/td][td]draw[/td][/tr]
[tr][td]10[/td][td]1[/td][td]1[/td][/tr]
[tr][td]20[/td][td]1[/td][td]2[/td][/tr]
[tr][td]30[/td][td]2[/td][td]3[/td][/tr]
[tr][td]40[/td][td]3[/td][td]4[/td][/tr]
[tr][td]50[/td][td]3[/td][td]5[/td][/tr]

I’d say the time taken during the drawing routine would be roughly the same every loop, but the time needed for the logic can change more due to whatever is currently happening. So in the above table your drawing loop is going to be drawing along happily while the logic Thread is still trying to figure out what moves where. If the inverse was going to happen (ie. updates quicker than drawing) then you’re going to have updates not drawn to the screen. So in the worst case you’re either going to have updates skipped, or resources wasted due to excessive drawing. To ensure this doesn’t happen you’re going to have to synchronize the threads and that will probably be by having the one thread wait for the other to finish one iteration of the loop.

If you take a look at the single Thread method then that is exactly what is happening. So basically in the single Thread the drawing follows the logic so you don’t have to synchronize. Now if the loop was to take longer than the required time then you just add a few extra updates in the next loop iteration until you’re on time again. So in both cases you might have updates skipped, but there’s less to take care of in the single Thread method.

I have done a simple shooter base on the KGPJ book using his single Thread method and it works fine. You just have to take care to not place the game logic directly into the GPanel class.

seems to get best effort from each threads, but that can be annoying if you want to skip frames. Hence a more precise desc. may be necessary, as I have one logical structure already running fine :


Sprite <- [got the image loaded in IO cache]
Animation <- [got the sprites buffer loaded in cache]
Model <- [got the animations buffer loaded in cache]
 ^---------------- waits for offscreen to be painted for 3 sec. limitation, the main rendering Timer (> 3 sec. frame is skipped)
 ^----------------- offscreen/buffer Timer waits for the main rendering Timer to finish 1-frame-rendering task

Model has one more subclass : InteractiveModel that processKeyEventsStack() right before painting.
All Component validation methods are held on a separate Thread stack (ThreadGroup) and all paint() methods are waiting for the Component to be declared valid. Sprite, Animation and Model extends JComponent but are used for active rendering throughout a dedicated draw(Graphics, AffineTransform).

Summary :
Total threads : JComponent have 1 validation Thread each (+ 1 for Animation buffering)+ main render scene 2x1 Timer each for buffer and paint + InteractiveModel has 1+ extra Thread stack for KeyEvents reading/validation = 4+ Threads count all running at priority level 5-10 (NORM < lvl < MAX)
logic will be held in 1 extra Threads nearby the KeyEvents, naturally.

:smiley:

You gain nothing by drawing the screen 10 times if the logic has only been updated once! It’s the same screen that has been drawn 10 times!

Multithreading is more troublesome than it’s worth if you’re doing simple games. Make sure you use it properly.

This is actually a big interest to me, how to utilize these multicore processors, I don’t think there are any games libraries in Java that split concerns up in threads.

I’m no expert on threads, but the way I see it is that you only split into threads if those parts should run concurrently.

The Thread used in the game panel is used to split Swing/AWT from the game loop. That way your input handling works independently from the rest. If it wasn’t done this way you would have to pause everytime you wanted input. I understand the reason for why you want to do the split to keep unrelated items apart. But you should not see it as the logic being part of the drawing. The logic and drawing are both part of the game loop (which runs in its own Thread).

If your logic is very resource intensive then you could split your logic into threads to, say, run them on multiple cores. But then the drawing section should still follow the logic and not run concurrently with it.

Just keep in mind that the game loop is a linear process, the subsections can be subdivided into threads but the overall game loop should be kept as a single process.

Depends how you set up your logic. You can for instance use simple direction/velocity calculations every frame and more advanced stuff that updates the parameters for the former in a long living thread. This way you can let your objects move on screen, while you are calculating the next logical update.

This could be achieved by waiting for your logic thread(s) to finish in the game loop before drawing the next frame. To effectively make use of multicores, you may need a thread pool, to which you can pass “jobs” to be done on the next free “execution slot”.

Thx for the replies