Good Enough Guide to Unity’s Unet Transport Layer (LLAPI)

I was excited to see that just as I was getting ready to start my first networked multiplayer Unity project, Unity was releasing their new Unet networking APIs. “What great timing!”, I thought. However, I was a total noob when it comes to working with sockets and communicating over a network and after playing around with Unet’s HLAPI (High-Level API) it quickly became clear to me that I’d have to dive deeper to get the functionality that I was looking for. So I began to read the documentation for the LLAPI (Low-Level API) which was not pleasant at all. After seeking advice and guidance from everyone I found shake down I managed to get everything working, connecting, and sending messages to and fro.

So here is my tutorial on working with Unity’s Unet LLAPI in C# for networking noobs. There are 4 main parts to any socket networking setup, opening a socket, connecting to another socket, sending messages and receiving messages:

Starting a “Host” (or Opening a Socket)

First make a new Unity project, 2D or 3D, it doesn’t matter for this tutorial. Then add an Empty GameObject to the scene and name it Transport. Then add a new C# script to the object and open the script.

We’re going to setup our socket right as the application begins so let’s begin in the Start() method. First thing we want to do is call initialize on the NetworkTransport class (don’t forget to add using UnityEngine.Networking to the class):

public void Start() {
  NetworkTransport.Init();
...

Next we just follow Unity’s documentation and add the ConnectionConfig. For most situations using the default config is fine, so let’s just go with that:

...
ConnectionConfig config = new ConnectionConfig();
...

Up next we need to add a channel and keep the channelId handy so we can use it later for sending/receiving. To do this we’ll add an int member variable to the class (not just the Start() method). We’ll also use the QosType of Reliable when setting up our channel. You don’t really need to know what this means right now (read: I don’t know enough about what this means and I still survive):

int myReliableChannelId; // above Start()
...
  myReliableChannelId = config.AddChannel(QosType.Reliable); // within Start()
...

This next part pretty much just sets the max number of connections allowed on your soon to exist socket:

...
  int maxConnections = 10;
  HostTopology topology = new HostTopology(config, maxConnections);
...

and finally we open the socket. One of the main stumbling blocks when trying to understand the LLAPI based on Unity’s documentation is that many thing are just named poorly. For starters, there is NetworkTransport.AddHost(). This doesn’t actually add a “Host” like the HLAPI does. This command actually just starts up a socket, I’m pretty sure they should change the name of the method to AddSocket, but who am I?? When we start the socket we have to tell it which port to listen to and in this case we use port 8888. Also the AddHost() method returns an int which is the “HostID” but screw that name we’re going to call it what it is, a SocketId. This SocketId also has to be accessible from other methods in this class so let’s put it up with the channelId:

int socketId; // above Start()
int socketPort = 8888; // Also a class member variable
... // back in Start()  
  socketId = NetworkTransport.AddHost(topology, socketPort);
  Debug.Log("Socket Open. SocketId is: " + socketId);
} // closing curly for Start()

And with that we have our code which sets up a socket! It’ll run right away when you click the Play button in Unity. You should see the debug message appear in the console, probably with the socketId of 0. It’s not that cool yet but we’re getting there.

Connecting to the socket

Once our socket is open we use it to connect to another socket, typically on another device. We can worry about getting another device in the mix later. For now, let’s just write our Connect() method.

int connectionId;
...

public void Connect() {
  byte error;
  connectionId = NetworkTransport.Connect(socketId, "localhost", socketPort, 0, out error);
  Debug.Log("Connected to server. ConnectionId: " + connectionId);
}

We need to keep the connectionId available to all methods because later we’ll use it to send messages. NetworkTransport.Connect() … connects us to another server (Hey! They did a proper job naming that one!). We pass in our socketId, the ip for the remote device (in this case we’re just connecting with ourselves, like a long weekend alone in the woods), the socketPort of the remote machine (same as ours in this case), 0 (I forget what this is but whatever), and if there is a problem we get an error out.

The Unity documentation mentions that we can check the error with:

if (error != kOk) // wat?

But I have no idea what kOk is and judging by all the red squiggles it certainly isn’t a byte. If you know what kOk is please tell someone (preferably me) we need to figure this out people! Basically, I just include the out error parameter because I have to.

I used my Android phone as the remote device but you can use another computer if you have one available. But for now you can do most of your testing by connecting to your own socket (I’m sure there is a rude joke in there).

Lastly, go into Unity and add a UI button and set the OnClick event to fire off our Connect() method. If you don’t want to do that I suppose you can just call Connect() at the end of Start() after our code that adds the socket. That would be good enough for now if you don’t want to make the button.

Sending a Message!

Finally (half of) the thing we actually want to do! Here we turn a string into a stream of bytes then send those bytes out our socket connection.

public void SendSocketMessage() {
  byte error;
  byte[] buffer = new byte[1024];
  Stream stream = new MemoryStream(buffer);
  BinaryFormatter formatter = new BinaryFormatter();
  formatter.Serialize(stream, "HelloServer");

  int bufferSize = 1024;

  NetworkTransport.Send(hostId, connectionId, myReliableChannelId, buffer, bufferSize, out error);
}

Quick run down: Declare another (unused) byte variable called errorCreate byte array called buffer and set it’s length to 1024 (this is the max length of our message when it is in byte form). The next 3 lines do the conversion from string to byte array. I don’t know the details about it, but it works, so it’s good enough. We also send over the size of our buffer byte array as an int (which is bufferSize). Lastly we put all the stuff together, starting with out class variables hostId, connectionIdand myReliableChannelId then adding the rest.

Now that we’ve got our SendSocketMessage() method you can go back into Unity and add a UI button to fire off the method on the buttons OnClick event.

Listening for NetworkEvents (or Receiving a Message)

Last part! We can send a message to other connected devices but now we have to make our application do something when it gets these messages. Otherwise we’re just shouting into the void. We need to always be checking for new messages coming in so this portion is added to the Update() method.

void Update() {
  int recHostId;
  int recConnectionId;
  int recChannelId;
  byte[] recBuffer = new byte[1024];
  int bufferSize = 1024;
  int dataSize;
  byte error;
  NetworkEventType recNetworkEvent = NetworkTransport.Receive(out recHostId, out recConnectionId, out recChannelId, recBuffer, bufferSize, out dataSize, out error);
...

All we’re doing is declaring all the variables we need then setting up a NetworkTransport.Receive() method. Almost all those variables are assigned as a result of a message being received (all the parameters that begin with out). The recBuffer contains the byte array message that was received, while recNetworkEvent is an enum with 4 possible event types:

  • Nothing – When no messages are received.
  • ConnectionEvent – A socket connection is made.
  • DataEvent – A message is received.
  • DisconnectEvent – A device that was connected as told us it is closing the connection.

We’re going to use these event types to decide what to actually do with the messages we receive. So we’re going to continue to add on to our Update() method with a big ol’ switch statement:

...
switch (recNetworkEvent) {
  case NetworkEventType.Nothing:
    break;
  case NetworkEventType.ConnectEvent:
    Debug.Log("incoming connection event received");
    break;
  case NetworkEventType.DataEvent:
    Stream stream = new MemoryStream(recBuffer);
    BinaryFormatter formatter = new BinaryFormatter();
    string message = formatter.Deserialize(stream) as string;
    Debug.Log("incoming message event received: " + message);
    break;
  case NetworkEventType.DisconnectEvent:
    Debug.Log("remote client event disconnected");
    break;
}

So based on the type of network event we have a few different debug messages display.  With the event type Nothing we do… nothing. This message comes in every Update() that a message of some other type is not received so we can ignore it. With ConnectionEvent we just want to be notified of the connection, but in a game you might do something like load a player prefab or display some text that a new player has connected.

DataEvent is the real meat and potatoes. This is where a message is received from a connected device and our application has to do something based on that message. Since our SendSocketMessage() method currently only sends a string we’ll only include code to handle string messages received (it’ll still try to convert any bytes into a string, so if you send something other than a string you’ll get an error or a garbage string (probably? Didn’t try it.)).

You can see that in the DataEvent case we’re doing almost the same thing as we did in the SendSocketMessage() method but instead of making a string into bytes, now we’re making bytes into a string. Once the message is back in a string form we display it as part of a debug message. Bam! Message Received!

Lastly there is the DisconnectEvent type. I don’t do anything with that event type here except log it to the console but you can image using this event as the time to do things like remove a player’s prefab, or display a disconnect message on screen.

Try it out

That should be all you need to get up and running. You have an application that, on startup, makes a socket available for connections. With the press of your Connect button the application uses it’s socket to connect to another device’s socket. Pressing your Send Message button will blast a string message from your socket to the remote devices socket and the remote device will receive the message, unpack it and display it in the console.

I did my testing initially just having my computer running Unity connect to it’s own socket, just as a way to rapidly test things. Because of this I saw the connect message in the console 2x, since one event was made for each side of the connection. After I got everything working like this, I changed the “localhost” to my computer’s IP address then built the project and sent it to my Android phone. I would then run the application in the Unity editor so I could see the console and I used the app on my phone to connect and send the message. It was really rewarding to hit the Send Message button on my phone and see the message appear in Unity’s console on my PC!

Expanding

This post is already super long, but I just want to give some final thoughts and extra tips.

How do I use this to make a game?

You can have another switch statement that executes different methods or series of methods based on the message received. So getting a message like “ChangeToNight” can trigger a method that changes the time in your game environment.

Does the message have to be a string?

No! It can be any object, all you have to do is serialize the object in a similar way to how we serialized the string. For instance I have experimented with sending JSON messages so that I can transport more complex objects. Using JSON .NET for Unity made this super easy.

Where can I read more about sockets?

While trying to figure all of this out I was directed to Beej’s Guide to Network Programming. It’s pretty advanced, written for C++ and I didn’t read much of it, but the What is a socket? section helped clear up some of my confusion about sockets.

I hope this helps some people who want to dive into Unity’s new networking API but don’t know a thing about network programming prior. If you are an experienced network programmer and have noticed things that I am wrong about, or things that could be expanded upon please let me know and I’ll update this guide.

Twitch Streaming Game Development

I’ve recently started streaming some parts of Nano’s development on my Twitch channel at http://www.twitch.tv/munkeyxis and you can follow me there to get notified whenever I stream. There isn’t any scheduled time which I’ll be streaming, just whenever I have the time to work on the game for a bit.

I did a couple streams over the weekend and it went pretty well. Even with my petty number of viewers there was still discussion in the chat about coding, Unity and some aspects of the game itself. I’m going to try and provide some tutorial-ish commentary during my streams along with insight into some of the design choices.

The topics covered while streaming so far:

A map that allows for player movement when map tiles are clicked: http://www.twitch.tv/munkeyxis/b/662025812

Creating a Hearthstone-like Inventory/Deck UI in Unity, Part 1: http://www.twitch.tv/munkeyxis/b/662361477

Each of these topics will have a blog post associated with them, those are coming soon. Next time streaming will be Inventory/Deck UI Part 2!

Events

In Nano, Events are the primary way the player interacts with the game world. Events are also the most direct way the player learns about the environment they are taking part in, meaning Events play double duty by providing game play and story elements. While the story is something that will develop overtime, the functionality of Events is something that the game needs right away. Events are also the feature that I wrestled with the most when trying to come up with a solid development design.

It was clear what Events had to be, they were to display some story text to the player, a few buttons with text on them representing the player’s available choices, and upon selecting a choice a result is shown that also has story text as well as displaying any rewards the player is given. Think of the event system in games like FTL. This type of system is generally referred to as a dialog tree, decision tree, or most specifically a simple directed graph. There are many plugins for Unity that provide varying levels of decision tree functionality, but I wanted to take a stab at rolling my own first.

So far a very simple Event model is in place along with Choices and Results. When a player enters a new location an Event is chosen from the list of possible Events which is then displayed on screen. To manage the Event’s display is the Event UI Controller class which is attached to prefab in Unity. This Event prefab uses Unity’s new UI features to display text and buttons. This is my first attempt at working with this new UI system, before this all objects displaying text used Text Mesh components which I find to be clunky and lacking a lot of features that are needed for displaying even a modest amount of text.

The early Event UI screen.
The early Event UI screen.

There is still a lot to be done to get Events fully functional. The player still needs to be able to select one of the choices and be presented with the result. Events will also be the primary way that combat is triggered. Some choices should only be available to the player if certain conditions are met, like having a particular item equipped. There is also the daunting task of creating a large amount of Events all with multiple choices which in turn have a variety of rewards.

C-C-C-COMBO SYSTEM! Part 2

Last time we talked about how players will build Combo Points by playing cards in the right order. This time we’ll learn how that glorious combo can be ripped down in an instant if you’re not paying attention!

Interrupts

Not going with the flow

You can’t just rack up Combo Points carefree. Combos can be interrupted meaning you lose all of the combo points you’ve built up and perhaps even worse! Sometimes you may be able to play a card that is the color needed for you followup Combo Color, as is the case when you don’t have a card of the necessary color in your hand. In this situation you will still want to play a card in order to continue damaging your enemy, but when a card is played that is not the color of the required Combo Color your combo will be interrupted. Having your combo interrupted means setting your Combo Points back to zero and missing out on any combo bonus effects you had been building up! So try to manage your deck and cards in hand to maximize your combos.

Combo Breaker!

Your enemy isn’t going to sit there and let you wail on them all day! Enemies attack the player every few seconds, depending on the enemy. When an enemy attacks it will interrupt any combo you’re trying to put together. In addition to having your combo interrupted you will also be effected by the enemy’s attack typically in the form of being dealt damage. Ideally, the player will want to conclude their combos with a Finisher before an enemy’s attack timer fills resulting in the best combo bonuses while mitigating the enemy’s damage. One last thing, just as the player is given bonus for completing combos, the enemy will get bonuses for breaking the player’s combos!

Finish that combo quick! Dummy strikes back soon!
Finish that combo quick! Dummy strikes back soon!

So there is an overview of the current combo system used during combat. Things are still being tested to see what works and what needs to be changed. The need for the right card colors will hopefully play into the deck building aspect of the game, urging players to be mindful of the cards they put in their deck and to hunt down the perfect cards to fit their strategy.

C-C-C-COMBO SYSTEM! Part 1

Ok, now this is starting to look and feel more like a game. The combo system has been added to the game in a basic, minimum viable product sort of way. Just the minimal amount necessary to demonstrate the idea has been implemented. The code is still a bit of a mess and some refactoring is certainly in order but there are too many ideas to get out. Some other UX improvements have also been added.

Dragon Drop

The ability for a user to drag and drop (I prefer to call this Dragon Drop) cards during combat has been added, making for a much more fluid combat experience. Cards are now flicked at the enemy portrait in order to use the card. This flicking motion lends itself towards faster card plays which feeds into the combo system.

Combos

The idea is relatively simple, all cards are given a color and most cards have a Followup Combo Color. When a card is played and then the next card played is the color of the previous card’s Followup Combo Color the player’s Combo Points are increased. The player can continue to rack up combo points until the combo ends. A combo ends either through the use of a Finisher or by being interrupted. A combo can be interrupted either by the player not following up a card with a card that is not the Followup Combo Color or by being attacked by the enemy.

Finishers

Finishers are almost the same as Followup Combo Colors. Where most cards have a Followup Combo Color, many of them also have a Finisher Color. When a card with a Finisher Color is played and then followed by a card that is the color of that Finisher Color the combo is completed granting the player bonus damage and/or effects. The player’s Combo Points are then reset and a new combo can begin.

sweetCardArt
Early card examples showing card color, name, Combo Color and Finisher Color.

 

Next time we’ll cover how combos can be interrupted and all the terrible things that take place when that happens.

Half Combat

Half of the super basic combat system works! For testing purposes, whenever a player clicks the Explore button, combat is initiated with my good ol’ pal Test Dummy. Yep, that bag of straw and anger is back to take another kicking. preAlpha_Combat01

Once in combat the player’s starting hand get’s drawn. When a card is used it’s cardPower is deducted from the Test Dummy’s health. This continues until the Test Dummy has no health left to lose, at which point the combat window is closed and the player is given a random reward.

Like the patient dummy he is, Test Dummy doesn’t fight back yet. That’s next on the agenda, I can tell he’s itching to strike back… or maybe the itching is from the straw… I’m so corny.

How to handle the Deck, Hand, and Discard

I spent a long time thinking about the best way to handle this aspect of the combat system. The inventory system already has the player’s deck as a Dictionary with a Card as the key and the Quantity as the value for each row and at first I thought I could just use this Dictionary as the deck in combat as well. First I tried to give the Card class a inHand and inDiscard boolean property. The idea was to just toggle these boolean values as the card moved from deck to hand to discard and back to deck again. This quickly became apparent that it wouldn’t work easily and that it would be best if each card had its own row meaning having 2 Punch cards would result in having 2 rows in the Deck array.

So I switched to a List, no big deal. At the start of combat the Combat Manager loops through the deck dictionary and turns it into a deck list. Now I could just look through the list for cards that have inHand and inDiscard booleans set to false and I can draw one of them!

Wait, no, that kinda sucks too! Doing that would make randomly selecting a card difficult as i’d always have to check to see if the card selected was inHand or inDiscard, if it was in either of those places, select another random card and keep doing that until an available card was found. Laaaame!

So the inHand and inDiscard boolean idea was scraped too and two new Lists were added, the Hand List and the Discard List. Now, a random card could be selected and removed from the deck list and added to the hand list. No having to make sure a card in the deck list was currently in the player’s hand. If a card was in the deck and was available to be drawn!

So there I was, spending all this time thinking up the right way to do it, the when I started implementing what I thought was the right, it turned out to be very wrong and the right thing fell right into my lap. I’m a little embarrassed I didn’t think of it sooner!

Nano Inventory and Deck UI Ready

Slapped away at the keyboard today and got the inventory and deck editing features put in, it looks pretty nice actually. I hope I can get someone to do a code review of it sometime, as I’m sure there are some more efficient ways to achieve what I’ve made. No matter, it works and that’s good enough for me.

An inventory system isn’t terribly exciting but now that it’s out of the way the fun part can begin, combat! Well, before there can be combat, there has to be something to combat against, so the next things to implement are Enemies.

To start, only a few simple, punching bag type enemies will be added so that the work on the player’s side of combat can begin. The player will start combat by shuffling their deck, then drawing a hand of cards from it. After that combat is turn based and after the player chooses a card to play, the enemy will perform its attack, then back to the player. Attacking back and forth will continue until someone dies, then a reward will be given to the player… as long as the player isn’t the one who died.

That’s the super high level overview of how combat will work. For me, the implementation of the player’s side of combat will probably go something like this:

  1. Add Enemies
  2. Create combat UI
  3. Add ability to draw cards from player’s deck at random and add to player’s hand
  4. Display cards in hand to player in combat UI
  5. Add ability for player to select a card to play, removing the card from their hand and drawing a new card

You’ll notice that having the cards do anything is not on that TODO list. That’ll come after all those basic things are in place, this is still just UI and basic functionality we’re talking about here.

 

Nano with Unity: Fresh Start

I’ve started to remake Nano using Unity. Nano will no longer be a browser game, instead I plan to release it for PC, tablet and phones. It’s a bit odd for me to say “release it” as if I’ll ever finish it. It would be really cool if I did and that is the plan but you surely know how these kinds of personal projects go.

So far I’ve got some of the basic UI in place, enough for some testing and experimenting. So far this UI is limited to displaying the player’s health points, a few buttons with placeholder actions and an early take on the inventory system.

Next up will be improving the inventory system and adding the Deck feature. Cards in the player’s inventory can be added to their deck, which is used in Nano’s combat system. Though, before combat can take place Enemies will be need to be added.

So that’s the game plan. I’m excited to be working on this project again, here’s to the hope that it’ll go further and be better than the browser version. It wouldn’t take much to be better than that ol’ thing.

Lil Critters – Class structure and the Nervous System

I’ve started working on the Lil Critters “Evolution Sim” project again. First thing to do was some refactoring, so I made many more classes and split up the methods. The classes and structure of the project is kind of interesting, since I am loosely modeling it after how the nervous system in living creatures tend to work. I’m no expert in biology, neurology or anything like that so I’m taking a more broad and general approach to the nervous system.

A critter’s “nervous system” is made up of three main classes which are Stimulus, Brain, Response. As you can probably guess, Stimulus is in charge of receiving input from the world outside of the critter and relaying those inputs to the Brain. The Brain chooses a response based on the input and sends this choice to Response. Lastly, Response allows the critter to perform some action as dictated by the Brain. There are other classes each critter has as well such as Raycast (to draw sight line) and Metabolism (to manage energy consumption). There will also be plenty more added as the project grows. The way I’ve been thinking of these classes in more specific terms is:
BasicCritterClasses
Raycast: Photons that hit the eye.

Stimulus: The eye that forms information from the photons that hit it and the neurons that transport that information to the brain.

Brain: Takes care of brain stuff… makes choices to call for particular responses based on input.

Response: The muscle system, applying forces to the critter when instructed to by the brain.

Metabolism: The chemical reactions and burning of energy in order to power the muscles and also just to maintain life.

It’s almost soothing to organize the series of inputs, analysis and outputs like this. This project often makes me think about real life a bit differently. While we all get the general idea that out bodies and minds are set up in this way, we typically don’t give this idea any weight or importance. I find it interesting to be building these little critters with this structure as a guide, which developed over billions of years of evolution.

12-1 Mage Arena Deck

I’ve gotten 12 wins in Hearthstone’s Arena a number of times, but usually ending at 12-2. This time I managed 12 wins and only 1 lose. The deck itself is pretty powerful with 3 Fireballs, 2 Flamestrikes, a Frostbolt and Onyxia to finish the job but many other cards did some serious work.

Here’s the deck in its entirety:

2 Flamestrikes can get you 5 wins easy, throw in 3 Fireballs and 7 wins is no problem.
2 Flamestrikes can get you 5 wins easy, throw in 3 Fireballs and 7 wins is no problem.

Some other key players were the Mana Wraith and Nerub’ar Weblord. Now these aren’t great cards but they were the best of a few shit choices. However they ended up allowing me to control the board early game. Coin into Weblord followed by turn 2 Mana Wraith and now all the opponent’s plans are on hold. These cards just screw up the enemy’s flow, which allowed me to get off a turn 3 Arcane Intellect for both card and board advantage.

One key thing to do when playing as a mage is to try and act as if you don’t have Flamestrike in your hand, even though we all know that every mage has a Flamestrike in their hand on turn 7. When you ping a Taz’Dingo down to 4 on turn 6 your opponent knows you’re lining up a Flamestrike and will play around it. Also, try to maximize the value of the Flamestrike by waiting until the opponent’s hand is empty or near so. Also, look for ways to deal with the board without using Flamestrike even if you have it. If turn 7 comes around and you don’t use Flamestrike, many people will assume you don’t have a Flamestrike and will feel better about filling up the board with his minions, then is the time to strike… FLAMESTRIKE.