Which networking approach on cannon-fodder like game ?

First of all … Hi :),

My name is chillum and i’m studying informatics on the University of Kassel / Germany.

I just found this Forum and i’ve read a few hours this night,

its just great :).

If my english might sound weird in the following post, i excuse me in advance, it’s pretty late and i’m damn tired atm, but i just want to get some opinions as soon as possible :wink:

I’ll begin why i’m interested in the network part of a multiplayer game :slight_smile:

Yesterday I got an exercise to program a simple server/client chat with chatrooms, so i played with sockets and PrintStreams and so on.

After a few hours of reading and gathering of implementations types, i choosed the Multithreaded version and
finished it yesterday. It wasn’t that hard. All runs fine.

It’s based on a server with a thread, which listens for clients.
if a client connects, it opens a own new Thread on the server specially for one client.
This thread listens for an incoming String, processes it and send an answer back to the client.

Like I said, all runs fine, but i’m not happy about the processing of the incoming data.

It’s only based on Strings and a wild bunch of if/else operations, which check if the user wants to create a room or something like that.

Now the game part :

Today i played a cannon-fodder like game, where 2 players play on the same keyboard and i felt to build a clone, but only with a multiplayer part and some “cool” modifications and new features ;). There will be 2 player objects with a bunch of AI-comrades and even more Monsters, which have to be killed. I think there will be ~100 Objects on the GameField PLUS temporary objects like Bullets, Addons and so on.

And here the network part kicks in. My first idea was using the String Style Method, like in the chat-programm.

But then i thought at the amount of if/else operations and couldn’t believe that this will be any kind of elegant or fun.

So i found the class ObjectStream and thought it should be much better to pass objects directly, if a monster position changes, the server sends the monster object with the new status/position to the client, and the client replaces his monster object with the new one.

But this could be very slow, i thought. So i searched a lot more and found RMI … i thought PERFECT … got a Bingo Sample from SUN to work and then realized, way to complicated for the first steps in game networking.

Now, late at night i had the idea to create an Object for every possible action in the game. E.g. MOVE …

so i don’t need to pass the whole monster or player object with all his data, but a special fitted object which only contains the changes, that should be made.

For Example:

class Player , which basically contains of
int ID;
int x,y; // coordinates on the screen
Weapon weapon; //current weapon

then i create a
class move, which contains only the changes occuring during movement
int id; //which object should be moved ?
int x,y; // to which position it wants to be moved or how many pixel refering to its old position

So when the player wants to move (or movement key is pressed )
a new move object is created and the constructor Move(id,x,y) is called.
eg Move doMove = new Move(id,x,y);
then:
out.writeObject(doMove); //or something like that, don’t worked with ObjectStreams before :confused:

the server gets the object, identifies it with isTypeOf and handles it.
The server reads out the id, and changes the x,y values of his Object with this id.
then he creates an own move object with the same id and sends it back to the client, which updates
his object.

I hope its clear what i mean :P.

Could this type of networking work with an max. object count of ~300 ?

Or should i use only functions which will code the performed action in a
String instead of doAction-Objects ?

I would prefer the Object approach :wink: , it just fells … ehrmnn … right :wink:

Hope this wasnt too confusing at all :slight_smile:

And thanks for reading :slight_smile:

Good Night/Morning all ;D

Hi

Your on the right path using update messages. Some people around here have passed objects using object streams, when I’ve done simple things like this before I’ve written message passing libraries so that I don’t have to serialise and deserialise java Objects, which can be considered slow. I’ve not micro bench marked it, but logic suggests it’s faster to do a switch statement on an integer message code than it is to do a whole bunch of if then else statements to find the instanceof that matches and run that.

If you do want to use objects you could always have an interface for each object you pass around that has a perform method or the likes, and call that, and the object knows what it is meant to do, so a ‘Move’ object for example, knows how to perform the move, that way you get rid of the if then else block. Messages could be made smaller too.

JGN (forums here) has an idea of a sharable object, that handles the network layer forr you. I’ve not used it myself though.

Project Darkstar is designed for Massivly Multiplayer Online games, and is more difficult to get your head around, and probably offers more features than you want at this stage.

Welcome to the forums :slight_smile:

HTH

Endolf

P.S. Are you going for 2D or 3D game play?. For 2D I would recomend you look at Slick for 3D jMonkeyEngine. Other API’s exist, but those seem to be popular ones.

Hi endolf,

thx for your comment. If i unterstood you right, the (String)Message Passing Method is the “standart” used one in small games ? :slight_smile:

I would like to try the ObjectApproach, but i have to read something about the serialization, and Object Passing.

Is it Possible to send an Object of e.g. Type MOVE from client to server,

and the Server just saves it in an simple

Object newObject = objIn.readObject( );

and after that determine, if its an move, shoot or build a house object with “instanceof” … (dunno where i got isTypeOf from ??? )

But i don’t understand this:

[quote]If you do want to use objects you could always have an interface for each object you pass around that has a perform method or the likes, and call that, and the object knows what it is meant to do, so a ‘Move’ object for example, knows how to perform the move, that way you get rid of the if then else block. Messages could be made smaller too.
[/quote]
How to determine if the passed Object is a “move”, “walk” or “die” -Object without instanceOf or many if/else statements ?

I thought interfaces are only “raw blueprints” for a class and they can’t have any code in themselves which
can change something at the gamestate, like movePlayer(this.x + newMove.x, this.y + newMove.y) ?

If you find the time, can you explain it again to me :slight_smile: ? Thank you…

P.S.
The game should be in 2D, but i’ll try to write it without extern Game API’s. It will probably be pain, but i want the learning effect, which comes with the pain ;D .

I did a SpaceInvaders Tutorial before ( think it was a spanish site), without scrolling but with BufferedImage, Sound, CollisionDetection aso. Was pretty much fun and not that hard at all.

Hi

Message passing seems to be, but not very often strings. For example, in my current project a ‘object update’ message is a bunch of bytes, the first 4 are a byte encoded version of an integer, this integer is a message type id. Then a bunch more bytes representing the object ID as an int, then some bytes that represent floats that represent a vector object etc.

It means I transmit the minimal number of bytes I can. The raw data just looks like a heap of bytes that have no meaning, it’s only the message classes that gives it any meaning. You could see this as fast object serialisation, but it’s done outside of the standard serialisation methods.

When I was talking about passing objects with interfaces I meant that every object (move object, quit object) you passed across implemented a common interface, lets call it GameAction. When you do your Object newObject = objln.readObject(), because you know they all implement GameAction, you can do GameActionnewObject = (GameAction)objln.readObject();. Then you can do newObject.run(); the move object itself would have to know what to do to perform it’s job. No instanceof needed as you don’t care if it’s a move or a walk or die object, the object knows.

You will need to figure out some way for the object to get hold of the game data model so it can do it’s magic, but you could just pass that in.

E.g.


public interface GameAction {
    public void run(GameData dataModel);
}


public class GameData {
    public Player getPlayer() {
        // Return the player object
    }

    public GameObject getGameObject(int objectId) {
        // Look up and return the object
    }
}


public class Walk implements GameAction {
    public void run(GameData gameData) {
        gameData.getPlayer().walkTo(this.x, this.y);
    }
}


public class Move implements GameAction {
   public void run(GameData gameData) {
       gameData.getGameObject(this.objectToMoveId).moveTo(this.x,this.y);
   }
}

In your network layer, you now don’t care if it’s a move, or a walk, you just call run(GameData) on the newObject.

Hope that makes sence.

Endolf

Thanks for this Explanation, I think i got it.

i have some spare time today, and i’ll try to draw a rectangle on the server and then
move it slowly. I’ll try the ObjectPassing to motivate myselfe before i break my head on the bytecoding approach :slight_smile:

You helped me a lot, don’t see the end of the tunnel, yet, but you turned the lights in it on :slight_smile:

Thanks again :smiley:

As Endolf suggested, this is something that JGN inherently supports. You might give it a try. :wink:

…however, I’m somewhat biased since I wrote it. :stuck_out_tongue: