LibGDX postRunnable interface. How to use it, why it’s needed. Examples based on a client written using KryoNet.

In this project based course you have to create a multiplayer online game using LibGDX gamedev framework and Java programming language. Because the project is supposed to be a multiplayer game, then this might cause some interesting events while trying to make your client (that is your game) to communicate with the server.

In Java (as well as many other programming languages) there is a term called “Thread”. You can think of it as a stream of some functionality of a part of your code, e.g one thread is doing some mathematical calculations while the other thread is drawing/filling up a table based on some values. A Thread in a programming language is extremely similar to a thread in a CPU. Usually there is no communication between threads (this does not mean there can’t be, but for our project we can think of it this way :) ), what often happens is that we wait for the result of the first thread then wait for the second thread and then on the so called Main thread we combine the results and use them as we deem fit.

This is relevant for us, because LibGDX and KryoNet run on separate threads and if you try to modify your LibGDX object directly in a KryoNet Listener then you will get an exception and the change will fail. (Now the real reason is not actually the fact that they run on different threads, although that of course matters as well, but the problem is that LibGDX internally uses OpenGL, which is available on its (LibGDX’s) thread, but it’s not available on the KryoNet Listener’s thread and so the exception is thrown).

Example: EnemyListener Example Let’s review the image above. First of all, we see that we made a class called EnemyListener which extends the base KryoNet Listener class. We also can observe, that this class has an inner private variable with type Character, which is a custom class, which is based on LibGDX base class, that I have created, it’s used for the mane character the user is playing as. Every KryoNet listener requires us to @override the received method. In the image above the listener is waiting for 2 types of requests: EnemySpawnedMessage and EnemyMovedMessage. The logic now is that depending on which type of request the listener catches the program should manipulate the LibGDX object. Now here is where the Gdx.app.postRunnable interface becomes useful. By using it we can run the code, written inside this runnable, on the LibGDX’s thread, which allows us to change the LibGDX Character object that we have.

Now you should be aware of the fact that this is just one way to handle the communication between the client and server and updating the game based on received requests/messages. In this example the LibGDX object is modified directly in the KryoNet’s Listener, which can be quite handy in some situations.

NB! Similar logic works with Netty framework as well.

Another way to build your logic is to use a similar coding style like is used for State Machines, where when you receive a message from the server you update some state in your game, and when that state changes the LibGDX objects are changes accordingly.

More examples! More examples