I'm making a Java multi-player turn-based game and I want to limit the time that each player have to make their move, the game is composed of game sessions or rooms and each room have 4 players.
The game have around 40 game sessions and each sessions have a minimum of 160 turns.
First I looked into the java.util.Timer, then I found out about the ScheduledExecutorService which seems much better, I could have a SingleThreadScheduledExecutor for each game session, create a new runnable each turn and if the player make is move before the runnable is executed I could call the ScheduledFuture.cancel() method.
In theory it seems fine but I have some concerns, so I want to know if:
Is this the right approach? or there are better alternatives?
Could I just have a ScheduledThreadPool for all game sessions instead
one SingleThreadScheduledExecutor for each game session?
I noticed that canceling a ScheduledFuture will keep it in the
memory until his execution time, could this be a problem for the
memory usage?
And last, is it possible to reuse the same runnable (1 for each game
session) instead of creating a new one each turn.
A ScheduledExecutorService is a fine place to start. Just remember to properly synchronize your access to game state.
It is generally legal to recycle a runnable, but that is probably not the best option here.
Unless the number of turns were going to be huge, the overhead for cancelling tasks is not worth it. Instead, include in your runnable information on what turn in what game is being timed. When the task executes, check the game state to see if that is still the current turn, and do nothing if the turn count has already moved on.
This avoids race conditions between cancel() completing and the task executing, as would happen when a move is submitted close to the deadline.
Related
It is the first time I want to write a java game, and I chose to do a Snake Line.
I learnt from a piece of source code from online. It updates the game states and displays in one thread. I changed around that code, and when I changed the FPS (from 60 to 30), animation slows down. More to this, the game behavior changes too. It is duck shooting game, and the space between ducks get narrower.
So I decided to separate the game thread and the display thread to avoid the above problem. But then I realize it brings out the concurrency problem which will be all over the place.
So as the title indicates, is it good to separate game thread and display thread? What is the common practice and why?
From the changes you experience, it sounds like you are using frame as a unit of time measurement. Or, more precisely, you use pixel/frame(or something like that) for velocity and second for time.
This might be OK for a simple game like yours, ones that are light enough on the system resources so that the delay between frames you specify in the code is practically the same as the real delay, meaning you are in complete control over the FPS. When the game get heavier and modern systems can no longer guarantee that property, you have a problem.
The solution is usually not to separate the game and display loops to separate threads, but to not use frames as unit of measurement for game mechanics calculations. Instead, each frame measure the time from the previous frame and use that value for the calculations, eg. multiply it by the speed to know how much to move a game object in this frame.
Not that separating those loops is such a bad idea. You don't get concurrency problems "all over the place", since the interaction between the game logic and the display shouldn't be "all over the place". The interaction should be one-way: the game loop writes data and the display loop reads it. That means you shouldn't have race conditions, but you can still get other multithreading hazards, which you can solve with volatile variables.
I'm writing my first ever Android game.
It's a simple card game where player will have 3 BOT players.
Right now i'm writing a core logic for it in pure java. (Not thinking much about AndEngine and graphics yet)
The game has two phase:
Initially all players would draw a match of card asynchronously
After a first phase control moves serially (Synchronously) from one player to next one to draw a card.
So, i'm confused about how many threads would i need?
shall i put each player into a separate thread? (as phase 1 may need it)
OR
Or should i carry out this in one single thread? (as in Phase 2 synchronous behavior is needed)
If i put each player into different thread how can i serialize those threads to do sequential tasks (Phase 2- control move to player one after other)????
ALso
Right now the logic I'm writing is in pure java. Will it give me any trouble while configuring it with AndEngine?? I mean is there any specific format of handling inputs and using this logic in ANdEngine?? Its all about just calling methods of those classes to start game and to perform any operation on game.
I think Synchronous. If you think of a card game, you can't do anything until the previous player has made their move anyway.
If you start using separate threads you are just over-complicating things for yourself.
How would one go about implementing a mouselistener (or some other way, doesn't matter) that will handle a mouse click event at ANY part of the program? Preferably returning to the line it left off at when the click event handler method completes.
I am using swing. The 'context' is a GUI that constantly updates, but must respond to a mouse click from the user at any time with no delay. Indeed I do have experience with events, using and overwriting their handlers etc., not too in-depth I suppose but what i do know has been sufficient in anything until now.
I could not understand your first para, so my answer goes for your second para, if I understood that correctly. ;)
Swing follows single thread model. So, you should be updating the UI from Event Dispatch Thread (EDT). This thread is responsible for delivering the events to your code too, hence the name. If you are continuously updating an UI in a loop then that is going to keep the EDT busy and blocked. The end effect will be an UI which does not respond to user events. This because the events are getting queued and EDT can pick them and deliver them to your code when it becomes free.
Games typically encounter this kind of scenario. You might have noticed that games typically have one fixed rate of refresh which they call FPS (Frames Per Second). Typically maintaining 60 FPS is good enough. That is, you need to draw your UI 50 times per second, but right now it seems that your render loop (which updates the UI) is running continuously.
You need to have separate thread continuously running which is responsible for drawing the UI. This should draw into a buffer (Image). And then invoke repaint() on the UI element to be updated. That UI element's paintComponent() needs to overridden, so that it can copy the image in Image buffer and paint that on the graphics context.
Now comes the real trick. The loop which calls repaint() must do some arithmetic to make sure it does not go beyond drawing 60 times, i.e. looping 60 times, per second. If and when it does then it must call Thread.sleep(sleepTime), where sleepTime is the number of milliseconds left in a second after looping 60 times. It might happen sometime that your loop may take more than a second to complete 60 iterations, then don't just go ahead for next iteration, but call Thread.yield(). This will give other threads a chance to use the CPU, e.g. maybe your EDT. To make the matter more complicated, do not keep yielding always, so might want to put some logic to make sure that yield for only x consecutive times. This last scenario should be very rare, if at all. This scenario means the system is under heavy load.
Remember, repaint() is thread safe and allowed to be called from any thread. It schedules a paint() call on EDT. So, calling repaint() does not guarantee a paint. So, you may want to experiment with different values of FPS to find the one which suites you.
By the way, the trick of rendering to an in-memory Image is technically called Double buffer. This gives us the ability to render nice smooth animations.
Further reading:-
LANSim - Wrote this code a long time back. You can use this code as an example.
http://java.sun.com/docs/books/performance/1st_edition/html/JPSwingThreads.fm.html
Killer Game Programming in Java - This book is on this subject.
Have you looked at SwingWorker? It's a simple framework that lets you run computations in the background and periodically publish updates to the GUI thread.
I'm writing a game in Java. And, oh wonder, i have performance issues. I benchmarked the paint itself - 1000 cycles in 3 ms tops. The game logic is even below that. So far, so good. But i still encounter an annoying lag: When scrolling, when zooming, when clicking. The problems get worse when i zoom in and more objects are placed. But still - even when I loop the painting a 1000 times the lags stays more or less the same, so that cant be it.
I tried putting the loop in a task - still the same. I tried pausing the task in between paints - still the same.
Animations run as smooth as silk (since the framerate is stable and high, that makes sense). So how on earth do i organize the inputs in an orderly fashion? Put them all in a seperate thread?
Any input would and will be greatly appreciated!
It sounds like you're using listener callbacks directly on the Swing Event Dispatch Thread, where the UI updates are being done. You should use a command queue, and put events on the queue when a callback is invoked, with the nature of the command, then you use this in the main game update loop that has nothing to do with the EDT.
Edit: This makes alot more sense to me now that i've taken a step away from the code, thanks for the help.
Just found stack overflow the other day through Coding Horror and it looks awesome. Figure that i'd ask the community about a problem i'm currently trying to work out.
I'm developing a roguelike sortof game using j2me for midp 2.0 phones. The project is still in the basic stages of development as I figure out how it's going to work. The part i'm currently stuck on has to do with threading.
The game has a custom HaxCanvas class which extends GameCanvas and Implements runnable. It's run method calls repaint() and then sleeps for 50 ms, resulting in a frame rate of 20 FPS. This allows me to write the rest of the game without having to put repaint everywhere and should make animations and effects easier to do later on. (at least in theory).
The flow of the game is controlled by a GameManager class, which loops through all the NPC's on the map, taking their turns, until it's the player's turn. At this point I need to get input to allow the player to move around and/or attack things. I originally was calling gameManager.runUntilHeroTurn() in the keyPressed method of my HaxCanvas. However after reading up on j2me system threads I realized that putting a method with the potential to run for a while in a callback is a bad idea. However I must used keyPressed to do input handeling, since i need access to the number keys, and getKeyStates() does not support this.
Sofar my attempts to put my gameloop in it's own thread have resulted in disaster. A strange "uncaught ArrayIndexOutOfBoundsException" with no stack trace shows up after the game has run for several turns .
So i suppose my question is this:
For a "turn based" game in j2me, what's the best way to implement the game loop, allowing for input handeling only when it's the player's turn?
Although not j2me specifically you should capture user input, the general strategy is to queue the input it until its time to process the input.
input ---> queue <---> Manager(loop)
This way you can even script input for debug purposes.
So you don't need a new thread. Each time the user presses key you store them in a buffer, and then process the contents of the buffer when necessary. If the player buffer has no input, the manager should skip all gameplay, do animations and then start over (since the game is not an action game).
I would avoid threading for the game logic as J2ME threading, depending on manufacturer of course, does not do a great job of sharing the limited resources. You will often see pauses while a thread does heavy processing. I would only recommend threads for loading or network connectivity features as in this case you will just be giving the user basic "Loading..." feedback.
To handle this, I would not have sub-loops to update each of the AI in one frame. I would do something like following in the run function:
public void run() {
while(true) {
// Update the Game
if(gameManager.isUsersTurn()) {
// Collect User Input
// Process User Input
// Update User's State
}
else {
// Update the active NPC based on their current state
gameManager.updateCurrentNPC();
}
// Do your drawing
}
}
You want to avoid having everything updated in one frame as 1) the updating might be slow, resulting in no immediate visual feedback for the user 2) you can't animate each individual NPC as they make their action. With this setup you could have NPC states, NPC_DECIDE_MOVE and NPC_ANIMATING, that would allow you further control of what the NPC is doing. NPC_ANIMATING would basically put the game in a waiting state for the animation to take place, avoiding any further processing until the animation is complete. Then it could move on to the next NPC's turn.
Also, I would just have a gameManager.update() and gameManager.paint(g) (paint would be called from paint) that would handle everything and keep the run method thin.
Finally, did you look into flushGraphics()? With the GameCanvas you usually create a Graphics object, draw everything to that and then call flushGraphics(), then wait. The method you mention is the way of tackling it for the Canvas class. Just thought I would mention this and post a link:
Game Canvas Basics