InVected: GlobalGameJam Game that uses Elixir

In the weekend of 26-28 January, I worked together with five other programmers and a musician at this years’ Global Game Jam. For who has not heard of the GGJ before: This is a yearly event that is hosted at the same time in many places around the world, where teams build a game from scratch in 48 hours time, with a theme that is only going to be known once the competition starts.

The theme of this year was ‘Transmission’.

The game we ended up with is valled InVected: Survival of the Sickest

Now, besides our game itself being stylized as ‘transmission of sickness’ (everyone is a virus attempting to take over the host by caputring the most area, the theme also appeared in our submission in another way: Players are able to join the game at any time by pointing their mobile (or other) device to a given IP-address and enter the correct room code, and then control one of the virus-characters using a ‘joystick’ on their screen.

In this way, more than sixteen people are able to play at the same time. (At the event, we were able to try it out with a max. of ten, but the system seems to scale rather well).

The game (both the main game logic and the graphical display logic) itself is written in Unity, but the network code where players can join and control a character, is written using Elixir. We use Phoenix to host the joystick player-control page, and :gen_tcp to link the Unity-game with the server.

The Elixir application is structured in a classical OTP-way: We have a TCP listener that will start a new game whenever a Unity-game instance makes a request. This new game is handled by its own GameServer process. The list of GameServers is managed by a GameServerBucket process. Both of these are managed by the main Application supervisor, because the application is not more complex than just mentioned :smiley: .

The code is available on GitHub,(The elixir-application can be found in the snapp_server directory) but be warned that this is hackathon-code, which means that most of it was written in the middle of the night, after a lot of sleep deprivation, while being under a lot of duress from the rapidly approaching deadline: It is not clean code. We are currently in the process of rewriting the game without Unity, and also cleaning up the Elixir codebase while we are at it, but this will be done slowly :sweat_smile:.

Here’s a small video of the stuff in action:
https://twitter.com/WiebeMarten/status/957945699596996610

We had a blast, and at our GlobalGameJam-location in Groningen, we won the prize for Best Technology for the system in which we were able to incorporate all these mobile devices with the main game: Jackpot for Elixir! :smiley: .

I thought it would be nice to share this stuff with you, and I’d love to answer some of your questions as to why we made certain choices in this project, if there are any. Thanks!

~Wiebe-Marten/Qqwy

19 Likes

The game looks awesome - congrats Wiebe-Marten :023:

2 Likes

Very inspiring! Thanks for sharing this.

1 Like

Whoo, sounds like it would fit well as a stock html5 game actually. :slight_smile:

This looks fun though! ^.^

Yeah, the new cleaned-up version (when/if it gets finished) will run in the browser, probably using Three.js or something similar to allow for fancy shader graphics.

Thanks for your cheerful responses, everyone! :slight_smile:

2 Likes

It was a really pleasant surprise that @chrismccord featured InVected as an example during his talk at ElixirConf.EU! :heart_eyes:

So for some people who are wondering about the internals: The Elixir Server keeps on running, and then when the Unity game is started, it will attempt to connect to this server over TCP; on the Elixir side, a new game GenServer will then be made, which its unique ‘game code’ that will be sent back to Unity.

In Unity, the ‘game code’ will be displayed on the screen, and people will be able to visit the Phoenix server’s webpage on their phone and enter the code there, which will open up a Phoenix Channel connection that sends player movements from the phone to the game server.

Every time the game server’s state changes because of a player moving, its internal state is recomputed (Functional-Reactive Programming style) and then sent as a TCP packet to Unity.

Inside Unity, besides the normal Game loop, there is a separate thread that is waiting for game state changes and updates the stored game state whenever a new packet arrives.


There is a lot to improve here, but of course it was hackathon-code. I now know that there is a C# Phoenix Channels client library, for instance. That would have made our own TCP-packet code a whole lot less arcane.

Of course, in the full rewrite that we’re doing that hopefully will be finished in the far future, Unity is out of the picture; the rendering being done in WebGL in the users’ browsers (and Elixir, possibly with internal Rust NIFs because it’s a reason to fiddle with Rust handles all the state changes then).

4 Likes

Interesting project :slight_smile:

A question, so where does the actual game state live (player positions, etc.), in the unity application?

I’ve been toying with a game idea like this, but it would involve more units and positions and while I at first wanted to keep this at the elixir side, I don’t know about the scalability. Because elixir is not good at number crunching and you would just be sending all the game data to the clients otherwise.

What was your approach?

Thanks!

1 Like