[KryoNet] Game Loop

Perhaps this is obvious, and/or I’m simply way too tired…but how should my server’s game loop be handled when using KryoNet?

My main game logic takes place using an entity system, so I’m not sure how to integrate KryoNet’s message handling with this. For instance, when the user sends a IWantToMovePacket, should I handle the movement in the receiving (KryoNet’s) thread? Couldn’t that cause synchronization problems? Or is it exactly that, and I need to synchronize something (and if so, what)?

My problems would be solved if KryoNet could be run in the same thread as the rest of the game, but I don’t think that would work.

Any help would be greatly appreciated!

From what I understand you don’t want the Server to handle the task in the receiving because this can block it from receiving additional inputs. Here’s what I did for my game; it may help.

I extended the Kryonet Connection object:

public class UserConnection extends Connection
{
    //any other parameters you might want (user name, etc...)
    private ExecutorService tasks = Executors.newSingleThreadExecutor();

    
    
    public void addTask(Runnable newTask) { 
        tasks.execute(newTask); 
    }

Then make the server object return your UserConnection object. In your Server code override new connection to:

protected Connection newConnection() {

                return new UserConnection();
            }
        });

Then override received:

public void received(final Connection connection, final Object object) {
                ((UserConnection) connection).addTask(new Runnable() {

                    public void run() {
                        //game logic here

                    }
                });

hi,

I did this a different way in my game : when I receive a message, I put it in a ConcurrentLinkedQueue somewhere.
Then at the beginning of my game loop, I read this queue and process the messages. This way I don’t have any synchronization issue and I know for sure when my messages are being processed during the game loop :



protected ConcurrentLinkedQueue<AbstractMessage> clientMessageQueue;


listener :


public void received(Connection con, Object msg) {
	super.received(con, msg);
	if (msg instanceof AbstractMessage) {
		clientMessageQueue.add((AbstractMessage)msg);
	}
}

to be called in the game loop :


public void processMessages() {
	AbstractMessage msg;
	while ((msg = clientMessageQueue.poll()) != null) {
		msg.process();
	}
}

hope this helps :slight_smile:


   while ((msg = clientMessageQueue.poll()) != null) {
      msg.process();
   }

Using a threadsafe queue is a fantastic concurrency pattern, but watch out what you do while the queue is null. You might be interested in BlockingQueue if your behavior is simply to wait til there’s a message available. Even when it does need to do something periodically inbetween mesages, I like sending “tick” messages periodically down the message queue rather than code it into the message loop itself.

I’m not sure to understand your point here, if the queue is empty, the poll method returns null so the loop exits directly … why would it spin the CPU to 100% ?

A Blocking queue is exactly what I don’t want, the processMessages() is supposed to be called in the game loop … so using a BlockingQueue will block the main game loop. I want the processMessage() method to exit immediately if the queue is empty.

I read the logic in reverse, and edited my post, but not in time, sorry :frowning: Queues are a great concurrency pattern, and the non-blocking approach is indeed better when you know you have a batch to process rather than a constant stream with delays between.

(I thought SMF was supposed to warn you if there was a reply while you were editing, but I guess that’s just for posts)