When we first decide to create any application we have
to keep in mind that our app can be ported or migrated to
other platforms. Maybe we will never have to do it but keeping this in mind we
will create a better app. So we will need a good layer design to get this goal. A
good way is to follow the MVC (model view controller)
paradigm. In a few words:
- Model: The
logic that remains under any application. Also known as Business Rules.
- View: The tier that paints to
the screen.
- Controller: The
middle layer that connects Model and View and handles user events by
calling the model and displaying to the screen to the View layer.
Keeping these layers separated will allow you to switch your UI framework with less changes than
expected.
If we think in terms of oop, we can implement
this architecture by creating interfaces between
view and controller layers. This will force
you to keep this model and avoid the temptation to mix these
layers. If you are able
to abstract the view layer, it will be easier to implement an
application based on the MVC architecture
For instance, look at our view interface that
we are using to develop our remote client in our multiplayer
game: “Snake the net”…
public interface ClientNibbles {
public void getSet();
public void go ();
public void update (Board game);
public Movement getMovementDirection();
public int getPlayerId();
public int getIdGame();
public int getnumPlayerGame();
public void setPlayerId(int id);
public void setIdGame(int idGame);
public void setnumPlayerGame(int NumPlayerGame);
}
There is actually two main operation to implement:
update method and getMovementDirection . We send, each tick, to the view
layer a board object with the position of each players. The view layer just
needs to read this object and paint a representation of it to the screen. The
Controller and model layers just deal with the server which movements to do
but, once commited, they just send a “photo” to the view layer in order to
paint the screen. In the reverse way, the controller layer will get own
movements by calling getMovementDirection (). The rest of the interface defines
control method to configure an incoming game. I think that is an exciting and
simple approach. Isn’t it?
If we follow this proposal of architecture we will
just need to port the upper (view) layer in some scenarios. In detail:
Our game is intended to be, at first, an Android game.
Therefore, we only have the option of using Java as a programming language. You
could be tempted to go to Android Studio (or ADT) and start right away. Wait a
minute… Test and debug a mobile game is always more complex compared to an
standalone app. Thus, basing on our MVC model, we will make fisrt a
standalone application, fix bugs and once we have stabilized we will
just write the part of android view. Think what you will get:
·
-
Keeping just one source of the code (Controller and
logic).
- Once developed the
project in Android, if we detect incidents related to the core It’s easier
to come back to standdalone platform to find out the problem instead of
using android. Then once fixed the error, we would check
that everything is ok at mobile scope.
In our app, we started by implementing a standalone client that implemented the interface defined at view level. This allow us to test the model layer without using any mobile device or simulator, just simple java client apps. By doing this, we are also creating an pure Java game that can be played by his own.
Once stabilized we just need to implement the defined
interface (view layer) at android scope. We created dedicated activities,
layouts and event custom views to handle this. Once done, we are
able to test the game using two different types of clients: swing java and
android clients.
Tests with different remote clients(Java(Android) |
But above all, we have to recall that we are designing
a multiplayer game. It will be a game that needs someone to accept
or discard the movements done by each movement. The asynchronous approach (peer
to peer) won’t work since we need someone to decide if a remote movement is on
time or late and if we let the clients decide this acceptance or not, it can
produce different games in each client… and this would be a disaster. So, we
need a mandatory server to handle this. And a server has
clients…
So, actually, we have two components to implement:
client and server. We also decided to separate these components through interface
contracts. So once implemented the server side and deployed where we
decided we wouldn't need to change anything (lifecycle apart). While each part
implements his side everything will be OK.
Let's turn back at the client side. There are some
theories that tell us that remote players in multiplayers games should be something
like a thin client. This means that each client will wait until the server
sends the players movement message to paint into the screen. You can imagine
how laggy will be perceived by the user. To improve this scenario, and
overcome the perceived latency we decided that clients are
going to predict his own movements. We will implement a mandatory server and a client
who makes predictions. (The server consolidates and send back to each
client the consolidated movements for each tick.). By doing this,
every client can’t move on his own (or almost).
So the client won't be a thin client. He may also
needs to play. Actually, he needs to have the same logic that the server so we
will share the logic code, or almost, by the client and the server.
Again we will share the model code between client and server.
There are just Two differences with the server:
- The client does not consolidate any movement. He
just makes his own prediction and moves his own players. He will move the
rest of players once received the consolidated movements by the
server
- If we are wrong in our prediction we will get
back to the last tick and we will replay our own movement based
on the server information.
To deal with these differences you just
need to create an additional layer in order to handle these
differences without affecting the common part.
No comments:
Post a Comment