Kotlin, Box2d, gRPC and Robots
Tags: kotlin, grpc, game
Published: 2018-09-05 14:18:51

---
title: Kotlin, Box2d, gRPC and Robots
published: true
description: A kotlin game server inspired by robocode
tags: kotlin, grpc, game
---

# The idea

I have always been a fan of robocode, but it seems to be a while since a new update happened to that community. With the launch of grpc for streaming communication and the rise of kubernetes, it seemed that writing a GameServer that could handle bots deployed as pods would not be a far away idea.

So I started this with the current design in mind:

* The server is written in [gRPC](https://grpc.io), so that clients can be created using any language that has bindings to it.
* Clients react to events (HIT, ENEMY_DETECTED, HIT_WALL) and emit actions (FIRE, THROTTLE, ROTATE) to the server.
* The server handles all the physics (using and learning [jbox2d](https://github.com/jbox2d/jbox2d) a port of the amazing [box2d](https://box2d.org/) physics engine), and enforces rules (reload speed, health)
* Besides gRPC a web based endpoint helps control the server lifecycle
* A websocket based dashboard to draw the world for visualization

# Putting it in motion

I chose gRPC due it's support for bi-directional streaming. Since the engine world updates 30 times per second (30 FPS), that is very easy handled by gRPC message streaming. Also clients can easily react to events on the bi-directional stream.

```protobuf
service GameService {
    rpc connect(stream Action) returns (stream FrameUpdate);
}
```

So your bot only need to create a client to connect to the server and handle events and emit actions. It's really up to each bot implementation to decide what to do best.

## Server side

On the server side the main class to handle a simulation is called `ArenaService` it contains all the bots and a `suspended` function that tries to run at least 30 per second. One of the very important things in game simulation is [getting your main loop right](http://higherorderfun.com/blog/2010/08/17/understanding-the-game-main-loop/), you need to make sure you compute a delta step between frames, that won't always be 1/30 of second spaced, so that your physics calculation don't go crazy.

This class then only loops over each bot, updating it state, it then `steps` into the world (a box2d feature that allows it to compute collision and update fixture features such as speed), and finally it broadcast all the queued events to the bots.

## Competing consumers/producers

The first problem I bumped into was the `World` class. It turns out it's not thread safe. And because each bot could create an event such as `FIRE` that creates a projectile into the world, I rapidly ran into concurrent issues.

My first naive attempt was to use locks, and then it become a nightmare to manage all that. 

But since the main loop is the only place where we run game logic I turned into using a `ConcurrentQueue`, this way any changes to the world are first stacked into the queue, and then only one thread at the main loop modifies it.

Take the following code that is trigged via a listener attached to the `World` instance. It detects collisions between a `bullet` and a `wall`. It then stacks a `WorldEvent` to the queue, that later will destroy the `bullet` from the `world` and also update the `ServerProjectile` collection that hosts all the active bullets on the simulation.

```kotlin
FixtureType.WALL -> {
                if (targetData.type == FixtureType.BULLET) {
                    worldEvents.offer(WorldEvent(WorldEventType.DESTROY_BULLET, mapOf("id" to targetData.context["id"]!!)))
                }
            }
```

# Current State

I'm still playing with all this, a lot of problems are coming from concurrent modifications and lack of better understanding of box2d (I'm learning more about this engine as I go)

You can find the project on [https://github.com/viniciusccarvalho/robo-cloud](https://github.com/viniciusccarvalho/robo-cloud) but it's still very unstable, no build, and still too many open bugs to call it a real project. As soon as I'm done with all the experimentation around box2d, and feel confident enough with the physics engine, I'll move into polishing it more into a consistent build.

And here's a video of the current state of the project. Physics are ok, raycasting to detect bullets are still a miss after change in coordinate system

{% youtube OH3iljmvDRQ %}