Skip navigation

Category Archives: Tanks Online

The Tanks Online HD beta process has started and I am using some new tools to get the job done better.  Without having to release Tanks Online HD to the app store, I can get up to 100 devices to install my beta app via the Ad hoc distribution method.  The problem is, how does one manage all the communication, sign ups, user recruitment, user management, and beta app distribution of the beta process?   Test Flight is the answer to that.  Test Flight allows you to manage all of that and even offers an SDK to collect testing information as the users test your app.

Sign up:

If you are interested in beta testing Tanks Online HD, please sign up to my Test Flight team:

So Unity 3D is super easy to use and you can make really cool stuff rapidly.  The first “professional” release I am trying to do involves Unity’s networking layer because Tanks Online is a multi-player game.  For me, this is where Unity starts to stumble – or at least is not very developer friendly.  I got Tanks Online running a few weeks ago in a very alpha form with networking enabled – meaning multiple players could connect and shoot at each other.  That was the easy part.  I have spent about 25 hours since then ironing out the plethora of networking bugs.  Here is two of my “favorites” – meaning it took about 10 of those 25 hours to figure out and fix.

Who’s your daddy?

Hosts (players) can use Network.Instantiate(…) to create objects in the scene (world).  When Network.Instantiate(…) is used, all the hosts regardless of type (server or client, remote or local) create that object.  This works like a charm and in very little time I had tanks running around and shooting at each other.  Now, I needed to do a little bit of collision detection for when a projectile hits a tank.  It’s important to know who “owns” the tank and who “owns” the bullet so you can tally the correct stats on death and not register a “hit” when a tank is colliding with a projectile it created.  Unity offers this through the network information (NetworkView) of a object that was instantiated with Network.Instantiate(…).  I was doing this check on the collision of a projectile with a tank and getting good results on the server but not the client hosts.  It turns out that the server is the only host who really does know who the “owner” of each object is, but the other hosts all think that the server is the owner of the Network Instantiated object (tank).  I think this is because the server is the one to brodcast RPC calls (of which Network.Instantiate(…) is a special case) to all the other hosts, even when the RPC is called on a client host.

The solution was to add an OnNetworkInstantiate “callback” on the tank object that sends a RPC only to the server that asks for the NetworkPlayer who owns the newly created tank.  The server sends a RPC back that has the “owning” NetworkPlayer.  The tank object stores that away in a member variable.  Now when a projectile and a tank collide, each host can correctly check the owner.

This seems like quite a bit of overhead that could have been avoided if Unity would have correctly assigned the owner of the NetworkView on each host.  Hopefully they will correct that some day and this convoluted way to get the correct owner of a network object can go away.

Give up the ghosts

Network.Instantiate(…) is a buffered call, meaning new hosts will get these objects even if they are created before that new host joins the network game.  Cool!  When a tank dies in Tanks Online, the tank’s Game Object that represents that player is removed from the game using Network.Destroy.  Everything looks great when you are fooling around with a few players – everyone spawns correctly and when they die all the hosts see the player’s tank disappear.  However, Network.Destroy is apparently not a buffered call because if a player died and a new host shows up, that new host will create an instance of a tank (where it originally spawned) that was destroyed on the network before the new host showed up to the party.  And because no one is using that tank any more, it just sits there, un-moving and absorbing any project’s sent it’s way.  An indestructible ghost of a player’s past.

I looked online and the proscribed solution was to call Network.RemoveRPCs on the NetworkView associated with the tank that was about to be destroyed.  But that didn’t work – apparently more than a few people have run into this problem and there is no solution yet.  Luckily for me, the only buffered RPC’s I am using are creating a new tank when a player spawns – so they don’t need to there forever, I can clear all the RPC’s from that player when the tank dies.  Network.RemoveRPCs allows you to pass in a NetworkPlayer and it blasts away all the buffered calls on the network from that player.  So that’s what I did.    If I had a more complicated game this bug would have gotten in my way, but because spawning a tank is the only buffered call that is made, I lucked out and can brute force hack my my out of this one.

The History

The first incarnation of Tanks Online was what I will call a limited success.  It was the first game that caused a payout from Apple into my company’s bank account.  It also gathered a small following in it’s very short lifetime.   More than 2 thousand people played the game.

However, it suffered from horrendous networking lag and bugs.  The bug that finally made me bring down the servers permanently was never solved.  One of the smartest guys I know and I sat down for 2 days straight vetting every line of code for the problem and we never found it.  The servers would crash because of this bug and at the time I did not have the time or the energy to re-write the game.  There was nothing that could be done other than take down the game from the App Store and shut off the servers.

The Reincarnation

Fast forward two (?) years.  I am learning Unity 3D and trying to make a game or two out of it.  After fooling around with some ideas I had for a new game, I thought it might be best to take a game full-cycle before starting on such an ambitious project.  Because I already have all the assets for Tanks Online and Unity offers a fairly simple Networking infrastructure, I thought I would take the smaller plunge and re-write Tanks Online using Unity.

I put a lot of research into what it would take (although, I am finding it was not enough research) and started writing the game about 2 weeks ago.  The very first problem I ran into is that Unity does not have a natural way to handle 2D games.  It’s a 3D game engine and they all but ignore the needs of 2D games.  How was I goign to render the 2D sprites with no “sprite” mechanism available?  I had 2 choices at this point.

  1. I could hand roll my own sprite mechanism inside Unity using meshes.  This would probably take about 2 weeks.
  2. I could admit that I am not here to make frameworks any longer (as discussed earlier) and buy a 2D sprite framework from the Unity Asset Store.

I chose option 2.  There are a few different 2D sprite frameworks on the Unity Asset Store, and I chose the most popular one: 2D Toolkit.  The guy who made this must be making bank and I got to hand it to him – its a very nice plugin to Unity.  It does nearly everything I need it to, and what it does not do I can easily extend it in my custom code areas.  Also, he is very responsive with any support requests.

So now I am about 2 weeks into the real development of Tanks Online and this is what I have to show for it:

First screen shot of Tanks Online

First screen shot of Tanks Online


More to come!