Skip navigation

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: http://tflig.ht/Qn0nfr

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!

I have updated my previous example program with textures on the terrain and road generation.

In screen shot 1, you will see the road drawn with a line along the path generated from my previous post about path generation on height mapped terrains.

In screen shot 2, the example program has been upgraded to generate vertex information for the “sides of a road”.  These are marked with small while pylons.

In screen shot 3, a mesh has been generated out of the vertex info and a texture has been applied to it.

 

This brings me to a good starting point for putting together the CatPhone project.  The next step will be making the road segments interact with each other well.

 

Wish me luck.

I have had a game idea brewing in the back of my head for quite some time.  The game involves at some point, being able to place (something like) a road on a terrain.  The player would need to decide when placing a road between two points is advantageous.  Once the decision has been made to place such a road, the player should be able to select a start and end point to the path and have the game do the rest.  Now, its not good enough just to draw a road as the bird flies – obstacles might be in the way and it might be more “expensive” to climb a hill than cross flat land.  Obstacles might be anything from ponds, to buildings, to hill sides too steep to build a road over.

Pair this desire to learn Unity 3D ever since my partner left for a AAA game company causing me to not want to maintain our Game Framework and you get this demo:

As you can see, a path has been drawn around the hill because climbing over that hill would have been more expensive than going around it.

 

Program Download (PC): TerrainExample

Description:

The terrain is 2000×2000 world units large (4M nodes in graph if taken like that, but I step by 5 units when solving).

Arrow keys to move the camera.

First click sets start point and solves the graph. Once graph is solved, mouse move calculates the path from start point to position under mouse. Second click sets the end point as the final path solution – mouse movements will not recalculate after 2nd mouse click. Subsequent mouse clicks start the process over.

Partner Leaving

So my partner who wrote and maintains the Game Framework that is used to build all the iPhone games we have been making has taken a job at Rock Star.  You might know them from such games as “Grand Theft Auto”, “Max Payne”, and “Red Dead”.  While he was told by his new management that he should try to keep his involvement in the game company he helped build, their legal department put a stop to that idea.  Can’t say I blame them.

Life Changes

My life has also taken a change.  At my day job, I am a project lead on a new piece of software.  And while I still enjoy making games in my spare time, I have very little of it.  I work on average about 60 hours a week, and I just don’t have it in me to program more than 70 or 80 hours a week.  Between that, and trying to have a life that does not involve being glued to one keyboard or another, its very hard to find time to make games in my spare time.

Outcome

Because of these two realities, I have decided to stop programming against our Game Framework.  It was really cool to build it ourselves and we learned a lot from it.  If you really want to learn game programming, making your own framework is the best way to do it.  But lets get something straight, that is exactly what you will be doing, making a game framework – not making games.  I want to spend what personal programming time I have left on making games.

Thus, I plan to start using Unity 3D, a game .making middleware  At first, I plan to just use the basic version of the main and iPhone packages they offer.  It cost $400 for those and its well worth not spending my time framework programming.  I have 2 games I want to do in it:

  • Tanks Online Reboot
  • Undisclosed Name (Code Name: “CatPhone”)

More on these later.