Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scala Case Classes vs. Protocol Buffers with Akka over the network

A bit of context first: I am writing a client/server game in Scala (first person shooter-like), where the client needs to send movement intentions to the server a few dozen times per second and the server sends entity states back, in real-time as well. There is physical simulation of these entities using JBullet on both the client (for graphical fluidity) and server side. Whenever a client receives updates from the server, it replaces its local states with the ones the server sent. There may be many clients on the same server at a given moment, of course. In short, in this application communication happens often, with small packets.

At the moment, I am using Akka's actors to naively send Scala case classes over the network to the server and back. Here is an example:

sealed trait PlayerMessage
case class PlayerMove(dir: Vector3, run: Boolean) extends PlayerMessage
// more case classes...

Then on the client:

server ! PlayerMove(dir, run)

On the server:

def receive = {
  case pm: PlayerMessage => pm match {
    case p @ PlayerMove(dir, run) =>
      // Move the player
      world.playerMove(dir,run)

      // More case tests..
    }

    // Send back entity states (this in fact occurs elsewhere, asynchronously)
    world.entities.foreach(ent => client ! ent.state()))

  // More message testing ...
  case _ => // ignore
}

Where ent.state returns an EntityState:

case class BulletState(pos: Vector3, quat: Vector4, lin: Vector3, ang: Vector3)

sealed trait EntityState
case class EntityStatePlayer(id: Int, bullet: BulletState) extends EntityState
// more case classes...

This is all working pretty well but as you can see there are a lot of case classes, sometimes containing other case classes, and a bunch of case tests on both client and server.

  • How can I reduce both packet size and overhead from serialization, deserialization and matching ?
  • Would using Protobuf instead of case classes cut the fat out of my application's packets ?
  • Am I looking at the wrong place for improvement of this network protocol ?
like image 218
gsimard Avatar asked Mar 19 '12 18:03

gsimard


1 Answers

Akka uses Java serialization or Google Protobufs by default (see here and here). You can define your own serializers, if you think you can code up something that's more optimized for your application.

If you want to optimize your network protocol, you'll have to break out your favorite network sniffer to find out what's actually being sent back and forth. Then you can better decide what to do.

In general, though, you can probably create a better optimized network protocol by hand, but it's more likely to be brittle and break when you need to make changes (unless you've got a lot of experience writing network protocols).

like image 178
leedm777 Avatar answered Nov 15 '22 22:11

leedm777