Math to the rescue…again!

Specifically trig…and you thought you’d never use trig outside of school, huh?

If you just want to see some things blowing up, you can scroll down to the bottom if you really want to. But if you are a math nerd, this just might interest you.

One of the reasons I majored in Computer Science was because I saw a potential to merge both math and computers together…my two favorite subjects. So what in particular did I need math for this time? It’s a little more complicated than the last time I wrote a post about some of the math used while developing Shape Sprout, although…I’m a little embarrassed to say I still initially forgot about Mathf.Rad2Deg and Mathf.Deg2Rad. 

Working on our new game, Castle Clans, we are in a 3D environment rather than just a 2D environment like Shape Sprout, so it adds another dimension (pun intended) of complexity to our calculations. If you haven’t read my previous post about Castle Clans, the overall gist of the game is you own a castle with some sort of medieval weapon(s) protecting it. Your weapon(s) shoot boulders toward the enemy castle in hopes that you will either destroy all their weapons or their castle first so you can win the round, loot their gold and buy/upgrade your stuff to take out more difficult opponents. There are a ton of physics going on here between boulders flying between both castles and the fragments of destroyed objects. Well, to get to that point in my game, I had to tell each boulder that gets launched from the weapon how much velocity it needed to reach the enemy side of things. Since each brick in your castle is independent from every other brick, and each weapon is independent as well, the weapons have to target those objects very accurately.

So what did we have and what did we need to figure this out? What we needed is the initial velocity of the boulder so it could reach its target from the angle that it was shot. Unity has a few features that make vector math a little easier.  So, what we DO have is distance to the target (on the xz plane), the direction it needs to head, the initial and final height of the boulder, and the angle at which the boulder will be launched…in this case, the ballista’s launch angle is about 30°.

Now that we have determined what we know, we can figure out our initial velocity by using this equation in our code.

equ

 

 

 

So lets see what that looks like:

 // Makes for easier readability 
 Vector3 target = parentEntity.GetEntityData().GetTarget().transform.position;
 Vector3 origin = transform.position; 

 // Pull out our angle
 float radians = transform.eulerAngles.z * Mathf.Deg2Rad;

 // First need a direction on xz plane
 Vector3 direction = new Vector3(target.x, 0, target.z) - new Vector3(origin.x, 0, origin.z);

 // Now we need to see what the distance is on the x/z plane
 float distance = direction.magnitude;

 // Now need to calculate the height on the Y axis for the angle it shoots at
 direction.y = distance * Mathf.Tan(radians);

 // We will also need our height offset between the two objects
 float heightOffset = origin.y - target.y;

 // Now we need to normalize the direction into a single unit
 Vector3 normalizedDirection = direction.normalized;

 // Calculate what our velocity should be
 float firstPart = 1f / Mathf.Cos(radians);
 float secondPart = 0.5f * -Physics.gravity.y * Mathf.Pow(distance, 2);
 float thirdPart = distance * Mathf.Tan(radians) + heightOffset;
 float initialVelocity = firstPart * Mathf.Sqrt(secondPart / thirdPart);
 
 // And apply it to our final velocity
 Vector3 velocity = normalizedDirection * initialVelocity;

Our “target” variable is the position that the boulder will hit and the “origin” variable is the initial location of the boulder. Direction on the “xz” plane is done pretty easily by creating new Vectors that don’t have a “y” component, then just subtracting them. Like I said, Unity make is pretty easy to do vector math. Does anyone else think of “Dispicable Me” now anytime you hear the word “Vector”? No?tmb_990_480

Okay, never mind then, guess it’s just me.

After getting the direction to the target on the xz plane, we can also get the distance by retrieving the magnitude of our direction vector…again, Unity makes this pretty easy. We still do need to calculate the “y” component of the vector so the boulder launches at a 30° angle. We know this because when we attached the boulder to the launch rail, it placed it at that angle. To calculate our launch angle (so it looks like the boulder is leaving the launch rail), we can use (distance * Tan(θ)) to give us the “y” component. So now the direction vector is complete up to this point. One of the last components we need is the height difference between the initial and final locations…that is pretty important considering the boulder doesn’t leave and land on the same height. Taking our origin height and subtracting the target height from it gives us this value. Before we calculate the actual velocity (we’ve only calculated direction up to this point), we need to normalize our direction vector which gives us a unit vector. From there we can use our unit vector and multiply it by the velocity we are about to calculate to give us the final vector in 3D.

I split the velocity function into three parts in my code to make things easier and I could see what the values were as I was debugging the code if needed. The first part is (1/Cos(θ)) in front of the radical, the second part is the numerator under the radical and the third part is the denominator under the radical. Once I had these three parts calculated, I put it all together according to the function and then multiplied it by our unit vector and voila, you have the correct vector needed to apply to the rigid body component of your boulder. Lets see how well it works now…

In this particular test run, the enemy’s weapons have an accuracy of about 48%, that is why some boulders miss and some don’t. It wouldn’t be as exciting if your boulders hit the target every single time!

There is something oddly satisfying about watching a structure being destroyed one brick at a time…

And yes, there WILL be flaming boulders…there WILL be.

A classic game reimagined

Growing up playing on older video game systems, there are certain games that stick out in your head because the game play itself was simple and addictive. InspirationOne of those games was named Artillery for the old Apple ][e. It was a simple game in which you try to guess the correct angle and power of your cannon to hit your opponent. This is the inspiration for our next game, Castle Clans! We want to try and keep the game pretty simple but at the same time put our own spin on it as well. Because of my fascination with 3D graphics and the mathematics that are involved, I’ve always wanted to delve into that side of game development. Some years back I had created a simple transform and rotation class in C++ for basic 3D objects by utilizing matrices. The code didn’t take visual perspective into account, so what you saw on the screen was only orthogonal in nature but it stoked my interest in learning more. I haven’t had a chance to really play with that side of things since then but I believe this game will be a good opportunity to get back into that. We’ll be using Blender for all the 3D models that are created along with Gimp to help with the textures our models will use. I had used Blender off and on in the past just because I was curious about it, it’s nice I can put some of what I learned to use in this game. Importing models from Blender is as easy as copying the .blend file over into Unity. There are some things you still need to do with the model before creating a prefab out of it, especially if you have animations attached to the model. You also have to be a little careful in that Blender considers “up” as the Z-axis while Unity considers “up” as the Y-axis. There is a trick I found that helps with this “up” axis issue. Unity implements a lot of the groundwork for physics and detecting collisions to your meshes just like it does when you create a 2D based game. That will let us concentrate more on the game content and less on the boilerplate code.

Speaking of game content…we want to try and embody the simplicity of the original game but give it a bit of our own twist. You’ll be protecting your own castle with a couple of different types of weaponry that can be purchased. As you destroy enemy castles you can take their gold and use it to upgrade your stuff or even buy bigger castles. We don’t want to make the management part of the game too detailed and cumbersome as we think it’ll take away from the core of keeping the game simple, instead, we want to use it to give the player a longer game play experience and more challenges. I’ve already created some of the initial 3D models that we’ll be using and finally got a chance to play with Inverse Kinematics in Blender to create some of the animations we’ll use in our game.

This is a sort of “first go” at creating an animated ballista. I’ll use the multiple animation sequences I have to make it look like it’s loading up a boulder and shooting it out…no boulder just yet on here, it’s just the animation,

I plan on adding some other things to this ballista, but it gives me a basic animated model to work with in the game so I can flesh out some other parts. The challenge will be to keep the complexity of the models down to a minimum while still making them look decent so the game can be played on a wide range of mobile devices. The terrain for each map area (I call them domains) are on the scale of 2000 meters x 2000 meters…there are quite a few vertexes/triangles that make up the landscape alone. Your castle will use a “magic portal” to move from one land to another (how else are you going to attack enemy castles in other parts of the world?) Magic solves everything, right? I see it as sorta the duct tape of the fantasy world.

Optimizing each mesh’s material (the actual texture used on the 3D object) was also something I had to take into consideration. I had read about it before in the past but haven’t dealt with it yet until now. Essentially, the more separate textures per model, the lower the performance of your game. I saw it explained as each texture you have for the same model is like the device having to take a pause to “dip” it’s paint brush into another color so that it can paint that part of the 3D model. The idea is to have one texture for your whole model and specify areas on that texture that the certain parts of your model use for it’s particular texture. For instance, the castle has multiple rock/stone textures but they all reside on the same texture file. The bricks will just grab from one part of that texture while the base of the castle grabs from a different part of it.  Here is an example of what the texture for one of the castles look like. So instead of there being three separate textures, I combined them all into just one.

Needless to say, I was able to significantly improve performance once I figured out how to do it. There is still a TON of stuff to do on this game, it’s going to be a a great adventure!

Kung Pow Cards – Milestone 3…Done!

“Wait…what happened to Milestone 2??”

Well, I sorta blew through Milestone 2 without posting an update. You know how it is, you get in the coding zone and don’t want to stop for anything.  Or is that just me?

So on the last post for Milestone 1, we had a lot of the basic core features and GUI layout figured out, we’ve added quite a few things since then. For Milestone 2, you are now able to play against another player or against one of the NPCs.  We are using our custom Game Server to serve up the matches so the app won’t have to rely on Push Notifications for communications or on slower Web-services. If something does happen to the Game Server, the app will fall back to one of the other two communication methods to keep the game going. For Milestone 3 we added the store to the app. We don’t have the in-app purchases implemented just yet, but you are able to purchase Skill Cards with coins that you have from winning matches and sell any Skill Cards you don’t want. For Milestone 4, we’ll have the in-app purchases in place and the ability to buy “bundles”. Bundles are groups of themed Skill Cards you can purchase for a small discount vs. buying them one at a time.

wpChallenges1“So, what exactly does that all look like?”

Glad you asked! We’ve changed up the Challenges screen just a bit to make room for longer profile names. The summary section at the top was organized a bit differently and we’ve added a symbol on the right side of the summary area to designate your current belt color so you don’t have to go back to the Profile screen. When you look at the Match Info (by touching your opponent’s name), you can see what Events are active on them so you can get a good idea of what you are up against.


“Wait…Events? You didn’t say much about that!”

 

wpChallenges2Right, I only briefly mentioned them. Basically, Events are effects applied to your profile on a Personal or a Global scale. We will occasionally make Global events that apply for everyone playing the game. i.e. Bonus match points when you play during a certain weekend. Personal events are those you create by using Camp type Skill Cards. [GM] Michael here has a Camp card that guards his stamina, meaning he can go into a match without using any stamina. We also have another Camp type Skill Card named “Shinatobe’s Wrath” that will steal one point from the base value of your opponent’s card and give (transfer) it to you. When you use this Camp card, this effect will be applied to your profile and last for 90 minutes (Skill Card names and effect times are subject to change!).
So, this effect will be applied to every hand you play for the next 90 minutes wpEvents. It gives you quite a bit of an advantage but not a guaranteed win! If your opponent is strategic enough in using the Skill Cards they bring into the match, they can still win…never underestimate your opponent! These types of Skill Cards will not be available in the store for purchase. They can be acquired from random drops after defeating your opponent. We didn’t want to give an unfair advantage to people who would buy a lot of coins to purchase these cards vs. people who just want to play the game casually. Let’s face it, not everyone will spend money on a game but they still want to be able to enjoy it!

 

We changed one of the names of the screens from Friends to Players. The Players screen will give you the list of your Rivals and anyone you’ve Blocked. wpPlayersIf someone is bothering you via messages or they continually try to create matches with you, you can block them. Rivals are people you like playing against and would like to create a match against at any time.

We originally were going to call this the Friends list…but it didn’t quite fit…so we thought maybe Enemies…but that didn’t fit either….and we BRIEFLY though about naming it Frenemies, but quickly decided against it, so we settled on Rivals.

We still have one issue at the moment we are trying to figure out. Finger scrolling on every device I have EXCEPT an iPad  (which I DON’T have) works like it is supposed to.  Now why does it work correctly on an iPhone but not an iPad? My development iPhone is an older one that can only be upgraded to iOS 7…my brother uses an iPad with iOS 8…hmm…wonder if there is something with that?

wpStoreOur store is pretty self explanatory. You touch the skill cards you want to buy and how many (depending on how many times you touch it or use the slider) and then purchase them by touching the “Buy these!” button. Coins can be acquired in different ways. When you create a profile, you’ll start out with a pretty good amount of coins to get you started. Winning matches gives you coins of course, but even if you lose a match, we’ll still give you some coins! Some of the Skill Cards in the Bundle drops can give you coins as well when you activate those Skill Cards.

“Umm…what’s with all the question marks?”

Yeah…just ignore those, I haven’t gotten around to creating the graphical assets for those just yet and needed a placeholder…


wpKPC3During a game, you can use the Skill Cards you brought into the match. You simply pick one before you lay down your next card. You can pick a Skill Card by touching the tab for the slide out tray on the right. You’ll be able to see what the card in your hand is before you play it, so you can better strategize which Skill Card would help you the most. Just don’t take too much time or your card will be auto-played! You don’t have to use Skill Cards if you don’t want to. “Kari the Shape Fairy” and I play each other without using Skill Cards and we still have a blast! The other two tabs at the top are for sending short in-game messages to your opponent and seeing a history of what in-game messages your opponent has sent to you.

 

 

wpMatchResultsAfter the match is over, you’ll see the final results. This tells you how many coins and match points you won (or match points you lost if you lost the match), if you received any drops from playing your opponent along with a few other stats.

One of the big steps that we’ve accomplished toward getting this released  is running the app on the production code, production databases, production Game Server and production APN servers. Only working and testing in the Dev environment up to this point, we weren’t 100% sure of the changes we’d have to make when we “flipped the switch” to go to production as there is various logic in the code to respond differently depending on if you are in the Dev or Production environments. There were only a few things that needed to be tweaked to this point, but for the most part it has been fairly painless.

“Wait, you don’t have a QA/Test environment?? For SHAME!”

Yeah, well, live with it.

wpSettingsAnd of course, in the process of uploading KPC to iTunes to try out their TestFlight program, I discovered they don’t accept builds unless you compile it for 64-bit. I vaguely remembered reading about it, but hadn’t uploaded anything to iTunes since we released Jumble Attack. This was before they changed their agreement. Luckily I was able to figure out fairly quickly what settings needed to be changed in Unity (4.6.x) to make it compile for 64-bit.  In the Player Settings for iOS, just change the Scripting Backend from Mono (2.x) to IL2CPP. I also changed the Architecture to Universal. I noticed the amount of files that Xcode compiles is about 10x of what it was before…so unfortunately, build times went WAY up.

So what’s left? Lots of testing and implementing in-app purchases and implementing the purchases of bundles…I think. Hopefully I can remember what I learned about SOOMLA during the last project and implement it fairly quickly. I still have to finish setting up the app store listings for iTunes, Google Play Store and the Amazon appstore…those can take a bit of time to do. Oh yeah…and we want to try to get “Kari the Shape Fairy’s” voice into the game more just cause she’s so stinkin’ cute AND those final graphical assets.

And what’s next after KPC? Yup, that’s right, we are already thinking about our next project! We’ve got a lot of ideas for an old school RPG type game…but first we’ll finish up KPC!

and

Update on Kung Pow Cards

It’s been a while since I last posted an update on Kung Pow Cards, as any adult knows, life tends to get pretty busy at times with other responsibilities. We are still pushing forward pretty hard on getting Kung Pow Cards out the door and we’ve made some good progress on game play itself. My brother and I are currently doing initial testing on both iOS and Android devices. We also decided to implement some AI on our server as a form of an NPC that you will be able to challenge; these NPCs will gain match points and work up their levels just as any normal player would as they play against other people.  These special players will reward you with increased match points and coins if you win against them. We figured having a chance to challenge an NPC for extra rewards would add some excitement to the game play.

“Kari the Shape Fairy” tends to take over anytime I’m testing our games…here she is playing against…uh…her alter ego on a second Android device. She always promptly lets me know when something doesn’t work like it is supposed to.P1070521

Now for the technical part…warning, if your eyes glaze over after the first sentence, feel free to stop.  That is unless you are trying to go to sleep, in that case read on, you should be asleep by the fourth sentence.

We’ve decided to implement an additional method of communication that we’ll use primarily during actual game play. Beforehand, I had implemented two forms of communication between the database and the two devices that were playing a match; those were web-services and Push Notifications. Web-services are mainly used while on the Camp screen for things like updating your profile, your skill cards book, pulling down any challenges you may have, messages from other players, etc… The Push Notifications were used to to let the device know if it needed to pull down information that had been updated in the database. We were using a combination of web-servcies and Push Notifications during the match, and while it seemed to work okay, I wasn’t okay with depending on a 3rd party server (Google Cloud Services & Apple Push Notification Servers) to reliably deliver these messages when they needed to. Thinking of how many thousands of messages per second these 3rd party servers probably process, any small hiccup could delay game play. Users want smooth and fast game play especially when playing a card game, so we decided to go ahead and create a game server on our web server that the devices could connect to. This would give both devices a dedicated communications channel to the database and hopefully limit any delays that could happen waiting for a Push Notification to be delivered to a device. So now we have three forms of communication between the devices and the database. The device’s primary communication channel will be the game server during game play, secondary will be web-services + Push Notifications and the last one, will be just web-services if Push Notifications fail. Since Unity does not support sockets for iOS and Android in the free version, we had to create our own plugins using Java (Android) and Objective-C (iOS). That set us back time wise a bit but luckily I was already familiar with sockets programming in C++; however, doing this in Objective-C was a bit of a challenge as it feels quite different than your C/C++/C#/Java flavor. So, with the Java plugin done, the Objective-C plugin done, the C# plugin (for testing in PC Standalone Unity) done and the PHP Game Server done, it’s just a matter of testing and working out any bugs in the Server/Client setup for this part of Kung Pow Cards. The only thing I’m not too sure about is how well a PHP Game Server will be able to keep up with traffic. I imagine I’ll probably end up creating a C based Game Server that runs on the web-server instead of going the PHP route…I guess we’ll see if that needs to happen during testing!

and

Kung Pow Cards – Milestone 1…Done!

So…what does that mean exactly? It means we’ve implemented a certain set of basic features and functionality of the game and have tested them to be working across both Android and iOS devices.

“Oh, so you are almost done then?”

AH HA HA HA…AH HA HA HA HA…..sniff…..no. But we are getting there fairly quickly. The features we’ve implemented so far are for the basic operation of one part of the game…managing your profile and everything that goes with it. We didn’t say this was your standard run-of-the-mill card game of War/Battle now did we? So what exactly was implemented in Milestone 1? When playing Kung Pow Cards (KPC for short), you will spend most of your time either on the Camp screen or on the Playing Mat. The Camp screen and anything needed to implement its features (such as profile creation) is what we are focusing on at the moment. challengesScreenShotThe Camp screen has multiple sections that will allow you to see various pieces of information. One of these sections is called the Profile section which allows you to see attributes of your profile such as how your journey to the top is progressing. Another section is the Skill Book section which allows you to decide which skill cards you want to take into the next game. And the Challenges section will let you see what challenges have been received, which ones you’ve sent out to other people and if there is one you can join right now. There are quite a few other sections as well on the Camp screen that I’ll talk about as the game’s development progresses. For this to all work together, a communications framework had to be setup to allow the devices to “talk” to each other so they knew who was online, offline and busy in another match, what challenges they had, who was waiting for them to join them right now on the playing mat, etc.. This communication framework also gives us the ability to setup various events that happen on a global or personal scale. i.e. Receive 2x more coins if you play during this weekend.

Granted we can’t play an actual game of War just yet (that will be milestone 2 BTW), it gives us the ability to test out matchmaking based on players ranks and to synchronize the players once they enter the playing mat.

There just aren’t enough hours in the day…

So, whats going on with Kung Pow Cards?

We’ve been head deep working on our next app, Kung Pow Cards so it’s been a while since anything has been posted. This app is quite a bit larger and more challenging than any of our other ones to date, but the challenge is half the fun! Lots of parts and pieces are going into making Kung Pow Cards…a bit more complex than I anticipated in some areas. We are implementing push notifications via the app42 plugin for Unity and there is a ton of backend work required to setup push notifications on both Android and iOS. app42 has TONS of plugins not just for Unity but for other platforms as well…and they have a free version just for us Indie devs! Up to this point, we’ve worked out most of the game design and rules, designed and implemented a pretty good backbone to the database…we have created about 17 tables and only minor changes have had to be made up to this point, implemented a working push notification test on Android devices, created about 70% of the graphical assets, implemented around 25% of the PHP web services and implemented around 20% of the code in Unity. We haven’t implemented anything SOOMLA yet for our purchases, but we did implement it in our last game, so we have a pretty good handle on how that all works. When the app is closer to being finished, we’ll post a few pictures. We are very excited about this project and the multiplayer gameplay it will allow players to experience!

So, you want to communicate data between your app and web server?

Before we delve into this, you may want to read about the legal implications on including encryption in your app, how to configure an HTTPS server and how to encrypt data in your app.

Once we are done here, you’ll have a good foundation for being able to send encrypted data between our app and web server. This just adds an extra layer of protection on top of HTTPS along with giving you the chance to store encrypted data on the local device. So, what’s the first thing we need to do? Let’s take a look at the functionality Unity provides to communicate with a web server. There are two classes we’ll look at for this, “WWW” and “WWWForm”. Unity makes it pretty easy to send info to a web server and wait for the result. Here is a basic example of how to do this:


// Set up form to send POST data
WWWForm wwwForm = new WWWForm();
wwwForm.AddField("yourField", data);

// Send data and wait for result
www = new WWW("https://yourUrlHere", wwwForm);
yield return www;
error = www.error;

// Process the data
if (String.IsNullOrEmpty(error) == true) {
  ProcessResults(www.text);

You can add as many fields as you would like for sending data to your web server. So if you were sending a player name and a score, you create two fields on your WWWForm object. When you send the data, your script on the web server will process the data and send back a result that your app can then respond to. One thing to point out, we use a “yield return www” statement, this effectively allows the app to continue without waiting for a response from our web server. That yield statement is where the app is just waiting for the script shown below to complete while allowing the other code to run. This is done through coroutines which I’ll talk about in a bit. For now lets jump to the PHP side to see how we’d process this info and then we’ll get into a more complicated example that includes retrying our result if there was a problem and encrypting the data before we send it to our web server.

So in PHP on your web server we’ll access the data in the request using the $_POST variable. This will look something like this:

// Note that we named the variable "yourField" from
// the C# portion of the code above
$yourFieldData = $_POST["yourField"]; 

// Do something here with $yourFieldData like insert it in a database

header("Access-Control-Allow-Origin: *");
print("Some sort of return value(s) for your app to process");

That is what we are looking at from the PHP side. We take the data sent in from our app, process it, then respond by outputting something that our app will then read  Maybe like a return code so it knows if things were process properly or the ranking of the record just inserted in comparison to all the other records in that table. Now that we’ve got the basic idea down of how that all works, we can add things to it like encryption and retrying if there was a communications issue. I’ll cover caching the results to the device in another post so that if the user quits out of the game and the data hasn’t been saved yet to our server or there was a complete loss in communications, the request will be retried again later. For now, we are going to assume the transaction goes through the 2nd or 3rd time we try it if there was a slight hiccup in the communications between our app and the web server.

First thing we’ll do is setup our code for making calls to our web server. I created a script named DAO.cs (This stands for Data Access Object) and made it a static singleton instance. The reason I did this was because StartCoroutine is a method of the Monobehaviour class and needs an instance to be able to be called since StartCoroutine is not static. If StartCoroutine is called from a script that can be destroyed (i.e. calling your StartCoroutine then calling Application.LoadLevel() right afterwards), the StartCoroutine also dies because it is called from your scene’s instance (derived from Monobehaviour) even if that call to StartCoroutine isn’t finished yet. This had me very confused at first when my coroutine was killing out during an HTTPS request because I had called a LoadLevel() to get to the next scene of my app. I assume (falsely) that a coroutine was similar to a thread and would continue independent of what had called it. So came the necessity to make our DAO script and attach it to a game object that just goes with us through the life of that gaming session. In the script below, you see the methods themselves of the DAO class are static, but we still use the static singleton instance of the DAO object to call StartCoroutine from. I guess you don’t have to make the DAO methods static since you have a static singleton instance of the DAO class following you around, but when I first designed it, I didn’t think I’d need this static singleton DAO instance. The following code is more of a guide/example, I pulled it from one of my working projects and cut it down a bit, so you’ll have to modify it to fit your needs.

For passing data in your POST, you could pass a separate key/value for each and just encrypt the values on each key. What I decided to do is have just one key and pass in multiple key/values on that one parameter and separated each key/value with a pipe. I let my PHP code split up everything once the payload made it there. You could also use serialization or pass the data in an XML string if you wanted. So, in effect, what I have is a query string passed to the web server that looks something like “https://some-web-page.php?data=key1=value1|key2=value2|key3=value3“. However you decide to pass data to your web server is really up to you.

Some things to note:

  • Wait…you can’t pass an equal sign/spaces/whatever special character safely to your web server without URL encoding it! Yes, you are right, but my payload is encrypted (via the Crypt class) and effectively URL encoded. So passing equal signs are okay here since the value part of the “data” parameter looks something like “g1tThXzmX1Mjunux1Eto5YA” when it is sent along its way to the web server.
  • Make sure the function you want to call via StartCoroutine has a return parameter of IEnumerator. This will allow us to do some nice things like yield for a return while allowing the rest of the code to run. Pseudo-multi-threading I guess is the best way to define this.
  • We define a maximum amount of attempts we’ll try the request ALONG with a slight pause in between trying multiple times. If there is a small hiccup in communications, we want to give the device a little bit of time to correct before retrying.
  • www.text will be the response we receive from the web server. Again, this is up to you on how you want your PHP script to respond to this request. For your PHP script to respond, all you have to do is simply print() something before exiting the PHP script.
  • You did read How can I securely save my app data?, right?
  • Don’t hate on the use of prepended underscores for private variables 🙂
using UnityEngine;
using System;
using System.Collections;

public class DAO : MonoBehaviour {

  // Specific instance of this class
  public static DAO instance = null;

  // Max attempts to send data to the web server
  private static int _maxAttempts = 3;

  /**
  */
  void Start() {
    // Making sure we only have one instance of this game object
    if (DAO.instance == null) {
      DAO.instance = this;
      DontDestroyOnLoad(this);
    }
    else {
      Destroy(gameObject);
    }
  }

/**
 */
  public static IEnumerator GetScores() {
    int attempts = 0;
    string error = "ERROR";
    WWW www = null;
    // This is the payload to your web server. For a simple
    // GetScore type of functionality, you might pass it
    // a date to get scores inserted past a specific date
    string data = "key1=value1|key2=value2";
    // This is the key you share between your app and
    // your web server so that you can encode/decode
    // information
    string key = "yourKeyHere";
    string encryptedData = Crypt.Encrypt(data, key);

    // Try maxAttempts times to get the data
    while (attempts < DAO._maxAttempts && String.IsNullOrEmpty(error) == false) {
      // Sleep for 3 seconds before trying multiple times
      if (attempts > 1)
        yield return new WaitForSeconds(3f);

      // Set up form to send POST data
      WWWForm wwwForm = new WWWForm();
      wwwForm.AddField("data", encryptedData);

      // Send data and wait for result
      www = new WWW("https://yourURL", wwwForm);
      yield return www;
      error = www.error;
      attempts++;

      // Process the data and put it into an
      // array if there were no errors
      if (String.IsNullOrEmpty(error) == true) {
        DAO.PopulateScores(www.text);
      }
      else {
        // Handle any errors here
      }
    }
  }

/**
 */
  public static void PopulateScores(string text) {
    // This is the key you share between your app and
    // your web server so that you can encode/decode
    // information
    string key = "yourKeyHere";
    try {
      string decryptedText = Crypt.Decrypt(text, key);
      if (decryptedText.Contains("|") == true) {
        string[] scores = decryptedText.Split('|');
        // Do something with "scores"
      }
      else {
        // Invalid return from web server
      }
    }
    catch (Exception e) {
      // Handle exception here
    }
  }
}

To call this from your app, all you have to do is something like:

DAO.instance.StartCoroutine(DAO.GetScores());

This uses the instantiated static singleton DAO object “instance” to call StartCoroutine on the static method GetScores(). And because we are using a static instance, we don’t have to worry about the coroutine killing out if we go to another scene while the coroutine might still be running.

So how about the PHP side of things? In this example, we are retrieving scores from a database and returning the data so the app can do something with that data like display it. Again, how you decide to structure the return data is up to you. We could easily return something like “score1|score2|score3|score4” (which is the structure this example is expecting) and when our app receives the data, splits the string into an array or you could use serialization on your objects or even XML as well. It would probably be more “proper” to use serialization or XML. I’m actually not very fond of using XML in this instance due to how verbose XML can be. I want the smallest amount of data transfer as possible…especially with mobile devices.

For pulling back the scores, let’s pretend we have a table named “PlayerScores” in our MySQL database and it consists of three columns, an “id”, “name” and “score”. Below is some PHP code that uses this structure to query for the data and send it to our app who is patiently waiting for a response from our web server via the “yield return www” C# statement.

Some more things to note:

  • Procedural code? That’s so 1990s. Yeah well, think of it as an exercise to convert it to object oriented code.
  • Wait…where did “Decrypt” come from? That isn’t a PHP function. Yup, you are right. “Decrypt” is one of the the sister functions to our Crypt class in C#. More on that a little later.
  • Again, this code is cut down from one of my projects and so doesn’t have some error handling, so it may not be fully functional as is but it gives you a very good direction on how to go about doing something like this.
  • Depending on how you passed the data in your POST from your app, you will need to design your “WhateverFunctionYouCreateToExtractYourData” function to handle it.
  • Whats up with the header(“Access-Control-Allow-Origin: *”); code in your PHP? This just has to do with my Unity Web Player hosted on Dropbox trying to call my PHP scripts on a different domain. I’m just letting the browser know it is okay to do this.

<?php
  // Include whatever classes and files you need here

  // Make sure things look right from the request
  // This simply makes sure we are communicating across HTTPS
  // and "data" is present in our POST
  if (!isset($_SERVER["HTTPS"]) || !isset($_POST["data"])) {
    die();
  }

  $key = "whateverKeyYouUsedInTheAppToEncryptTheData";
  $decryptedData = Decrypt($_POST["data"], $key);
  $values =
    WhateverFunctionYouCreateToExtractYourData($decryptedData);

  // Check to make sure all expected keys are present
  if (!isset($values["key1"]) || !isset($values["key2"])) {
    die();
  }

  // You'll have to supply the connection information below
  // based on how your database is setup
  $link = mysqli_connect($server, $userName, $password, $database);
  $result =
    mysqli_query($link, "SELECT score FROM PlayerScores ORDER BY score DESC");

  // Putting scores into data
  $allScores = array();
  while (($scores = mysqli_fetch_assoc($result)) != false) {
    $allScores[] = $scores;
  }

  // Cleaning some things up
  mysqli_free_result($result);
  mysqli_close($link);

  // Encrypting the data and sending it back to the requestor
  $encryptedData = Encrypt(implode("|", $allScores), $key);
  header("Access-Control-Allow-Origin: *");
  print($encryptedData);
?>

For this to all work like it needs to, our PHP code needs to be able to decrypt the data sent to it and then encrypt a response. Before returning our scores, we encrypt the string and print() it out. Once the script does this, the “yield return www” completes and we now have our response data in www.text on the C# side. Here is how you’d create some Encrypt/Decrypt functionality on the PHP side. Most of this encryption/decryption code here is NOT mine.

<?php
  /**
   *
   * @param Info to encrypt $data
   * @param Used to generate key $secret
   */
  function Encrypt($data, $secret) {
    // Generate a key from a hash, use 192 bit key
    $key = bin2hex(substr(md5(utf8_encode($secret), true), 0, 12));

    // Pad for PKCS7
    $blockSize = mcrypt_get_block_size('tripledes', 'ecb');
    $len = strlen($data);
    $pad = $blockSize - ($len % $blockSize);
    $data .= str_repeat(chr($pad), $pad);

    // Encrypt data
    $encData = mcrypt_encrypt('tripledes', $key, $data, 'ecb');
    return (base64_encode($encData));
}

  /**
   *
   * @param Info to decrypt $data
   * @param Used to generate key $secret
   */
  function Decrypt($data, $secret) {
    // Generate a key from a hash, use 192 bit key
    $key = bin2hex(substr(md5(utf8_encode($secret), true), 0, 12));
    $data = base64_decode($data);

     // Decrypt data
    $data = mcrypt_decrypt('tripledes', $key, $data, 'ecb');
    $block = mcrypt_get_block_size('tripledes', 'ecb');
    $len = strlen($data);
    $pad = ord($data[$len-1]);
    return (substr($data, 0, strlen($data) - $pad));
  }
?>

The PHP code feels a bit simpler than the C# code for encrypting/decrypting. Once you have this in a PHP script, include it in the other script above, then you can call Encrypt() and Decrypt() to your heart’s desire! Now your app and web server should be able to send encrypted data to each other across HTTPS! Got any suggestions or tips? Share them in the comments below, I’m always looking for ways to make my code better.

Some final thoughts about “Jumble Attack”

“Jumble Attack” is now live on the Google Play Store, Amazon App Store, Apple Appstore and Facebook! From cradle to grave this little app took us about a month and a half to complete which isn’t too bad considering some of the new technologies we introduced into our game along with the authorizations we had to get from the government. I was a little concerned about the restrictions Apple places on their apps as it is sometimes difficult to get approval, but the approval went through the first time…it still took a good 7 days though from submissions until they approved it. Now that we’ve figured out how to encrypt data, include in-app purchases and communicate with a web server, we can concentrate on the content in our next game rather than how to make the technology work. We are pretty excited about our next project, but it is a lot larger than anything we’ve done thus far. If you like card games with a twist, stay tuned for more info about our next project, Kung Pow Cards!

Poor man’s HTTPS

If you are thinking of using HTTPS to communicate data or encrypting your data in your apps, please read this post first

What do you mean I have to be “properly authorized” to use encryption in my apps?

We were looking at adding some interaction between our mobile apps and our web server and wanted to use HTTPS for this so we’d have a layer of security on top of the communications. I had never setup HTTPS on a web server before, but knew a decent amount of what would have to go into it. So I started looking around cPanel and found the following icon under “Security”

SSL/TSL

After clicking this icon, we are taken to an area where we need to do three things. First is to generate a private key, the second is to create a Certificate Signing Request (CSR) and lastly, place a certificate on our server. Luckily the interface in this version of cPanel (v11.44.1 (build 18)) makes it pretty easy to do.

 

Screen Shot 2014-09-09 at 8.38.48 PM

Screen Shot 2014-09-09 at 8.38.18 PMAfter clicking on the “SSL/TSL” icon, Click on the link here to go to the next screen to generate a private key.  I just used our company name in the description. Once the private key is generated, make sure to save it to a file on your computer.

 

 

 

 

 

Screen Shot 2014-09-09 at 8.38.55 PMScreen Shot 2014-09-09 at 8.39.24 PM

For a Certificate Signing Request
(CSR), go back to the previous screen and click on the link to generate a CSR, select the description you chose in the previous step in the drop down box and fill out the rest of the information and generate your CSR. Again, save it to a text file.

 

Screen Shot 2014-09-09 at 8.39.01 PMScreen Shot 2014-09-09 at 8.40.05 PM

Once this is done, go back to the previous screen again and manage the certificates on your web server. Install a self signed certificate by filling out the information and selecting the key you want to use. Now, a self signed certificate will allow you to use HTTPS on your site BUT you’ll be greeted with an ugly warning message by the browser that the site could not be verified so the certificate could not be trusted. We’d need to send off the CSR we created in the previous step to a Certificate Authority (CA) to receive a verified certificate to remove that warning from the browser.

Well, we only need HTTPS for communications between our app and our web server; so a self signed certificate should be good enough since the user won’t be interacting directly with our website across HTTPS. I did a quick search to see how much a certificate would cost, they vary wildly but seeing stuff for $175/yr. Why spend money on something we don’t need immediately? But, we do have everything we need to get a valid certificate if we decide to use HTTPS for direct user interactions with our website. That is why I call this the poor man’s HTTPS.

Updated:

So I’ve now come across a site that offers free SSL certificates. WOO HOO! I’ve seen mixed reviews, some people swear by them, others don’t seem to like them very much. But I thought I’d give it a shot. The site is https://www.startssl.com. Since I already created my certificate with them, I can only go through the steps again so much.  But it should be enough to figure out. What got me looking at this again was since we are communicating data between our website and our app, the Unity Web Player relies on the browser and JavaScript to do that (More on that one in a later post). Since our web server was only using a self signed certificate for HTTPS, the browser was blocking/complaining about the JavaScript AJAX calls to our web server when running the app using the Unity Web Player. This makes sense, but it didn’t occur to me during development.

Login Page

Head on over to https://www.startssl.com/?app=12. Just click the “Sign-up” button to get started. Please note the first time I tried this, their site was having some overloading issues…I just patiently waited a bit and was able to get on after a while.

Sign Up

There really isn’t too much information here to fill out, but please READ CAREFULLY and take your time to make sure you’ve filled the information out properly. The reason I say this is because there appears to be a price on revoking an SSL cert. Once you’ve finish the sign up process, they’ll send you an email to confirm your account.

homeOnce you have verified your account, StartSSL asks to install a certificate in your browser so you can log in. So if you go to https://www.startssl.com, you should see a page similar to the following. If not, just click the “Authenticate” button.

 

manage-certsIt would be a good idea to back up this certificate they just gave you. In Chrome, you can do it this way: Go to “Settings”, then click the “Advanced” link at the bottom. Find HTTP/SSL “Manage Certificates” and click on it. Find the one for StartSSL and export it and keep it somewhere. This will allow you to reimport the certificate at a later time if you need to.

Validate Domain Name - Step 1

Now we need to let them know that we own the domain we are attempting to get a class 1 SSL cert for.  I don’t know exactly the differences between all the classes of SSL certs, but we only need a class 1 for our purpose. I do know that a Class 1 doesn’t support wildcard domains but it will support a top domain name and a sub-domain…in fact it asks you to specify a sub-domain later in the process. So, once you’ve navigated back to https://www.startssl.com, click on the “Validation Wizard” tab and select “Domain Name Validation” from the drop down box.

Validate Domain Name - Step 2

Just put in your domain name here, pretty easy really.

 

 

Validate Domain Name - Step 3

 

It takes a couple of seconds, but a list of email addresses associated with the domain name pop up. You have to have control over one of those email addresses so they can send you a link for domain verification. Just pick one from the list that you are in control of and click “Continue”. Again, I had some issues with this part of the process. It kept telling me it could not verify the email address.  So again, I waited and after a bit it worked. Once you get the email, follow the directions to verify that you own the domain.

Create SSL Cert - Step 1

Now we are able to create an SSL cert for our domain! Click on the “Certificates Wizard” tab at the top and select “Web Server SSL/TLS Certificate” from the drop down box.

 

Create SSL Cert - Step 2

 

From here we can create the keys we need to create our certificate…but we already did that earlier, so click the “Skip” button.Create SSL Cert - Step 3

 

 

Go and find the Certificate Signing Request (CSR) that you saved earlier…you DID save it, right? Simply open it up in a text editor, copy the contents and pate them into the provided box.  Make sure you get the header and footer! Continue following the directions to finish up. After a while (I think I waited about an hour), you’ll receive an email that says you now have a certificate.

 

Retrieve CertClick on the “Tool Box” tab there at the top and select “Retrieve Certificate” from the list of options on the left. After selecting the certificate, (it should already be selected) click the “Continue” button to reveal the certificate.  Copy and paste this info into a plain text file. Once you have this, go back to your web server and install the certificate just like you did for your self signed certificate. Then just remove your self signed certificate.  One of the things I noticed was that even though https://www.nikywilliams.com was covered under the SSL cert, https://www.nikywilliams.com was not. At the moment, this isn’t much of an issue since we don’t have any front facing websites that need HTTPS. Ideally, you’d want both covered under your certificate. Our app is the only thing accessing HTTPS and we can make sure https://www.nikywilliams.com is specified in the code. I’ve seen what looks like a few ways around this. 1) You’d have to get at least a Class 2 certificate so that you can secure both with and without the “www” prefix. 2) Find a way to redirect all https://www.nikywilliams.com requests to https://www.nikywilliams.com. I haven’t verified either way since it isn’t critical to what we are trying to accomplish. In any case, this is still a poor man’s HTTPS since we haven’t spent a dime!

How can I securely save my app data?

Before we look at encrypting data on a device, you may want to read up on this.

What do you mean I have to be “properly authorized” to use encryption in my apps?

Unity has this very nice feature of being able to easily store data on the device via “PlayerPrefs”. The only problem is that it is stored in plain text. If you don’t really care, then it’s not that big of a deal, but if you are caching information to send back to your web server because the user doesn’t have any internet connectivity at the time, then it could be an issue.  Especially if that data contains information you don’t want tampered with like scores, ranking, etc… We’ll take a look at some encrypting functions we can throw into our code that will make encrypting/decrypting information pretty trivial. I’ve pulled in this code from various places so I can’t take credit for most of it. We’ll be using the Triple DES encryption capabilities that we have access to and once done, this should also make it safe to send via POST to a web server without mangling the data since the final data is encoded to BASE64. I’ll have another post detailing how I setup app-to-web server communications here in a bit. I created a file named Crypt.cs and made all the functions static so that we could call these functions anywhere in our code. We just have to pass in what we want to encrypt and the key we will be using. So from anywhere in the code we can call something like:

// Encrypt the data
string data = "Something to encrypt";
string key = "your_key";
string encryptedData = Crypt.Encrypt(data, key);

// Decrypt the data
data = Crypt.Decrypt(encryptedData, key);

Something that bothered me is having the key all in one place like that. So, you could just have it split up in various places in your app and create a function to put the key back together again and pass that in. So, here is the code I used (for the most part) to do this, just take it and put it in a .cs file.


using UnityEngine;
using System;
using System.Collections;
using System.Security.Cryptography;
using System.Text;

public class Crypt : MonoBehaviour {

/**
 */
 private static string GetMd5Hash(MD5 md5Hash, string input) {
 // Convert the input string to a byte array and compute the hash.
 byte[] data = md5Hash.ComputeHash(Encoding.UTF8.GetBytes(input));

 // Remove last 8 bytes to make it 192 bits (24 bytes) and compatible with the DES key property
 byte[] finalData = new byte[12];
 for (int i = 0; i < 12; i++) {
 finalData[i] = data[i];
 }

 // Create a new Stringbuilder to collect the bytes
 // and create a string.
 StringBuilder sBuilder = new StringBuilder();

 // Loop through each byte of the hashed data
 // and format each one as a hexadecimal string.
 for (int i = 0; i < finalData.Length; i++) {
 sBuilder.Append(finalData[i].ToString("x2"));
 }

 // Return the hexadecimal string.
 return (sBuilder.ToString());
 }

/**
 */
 public static string Encrypt(string data, string secret) {
 TripleDESCryptoServiceProvider des = new TripleDESCryptoServiceProvider();
 MD5 md5 = MD5.Create();

 string key = GetMd5Hash(md5, secret);
 byte[] finalKey = System.Text.Encoding.UTF8.GetBytes(key); 

 des.Mode = CipherMode.ECB;
 des.Key = finalKey;

 des.Padding = PaddingMode.PKCS7;
 ICryptoTransform DESEncrypt = des.CreateEncryptor();
 Byte[] Buffer = ASCIIEncoding.ASCII.GetBytes(data);

 return (Convert.ToBase64String(DESEncrypt.TransformFinalBlock(Buffer, 0, Buffer.Length)));
 } 

 /**
 */
 public static string Decrypt(string data, string secret) {
 TripleDESCryptoServiceProvider des = new TripleDESCryptoServiceProvider();
 MD5 md5 = MD5.Create();

 string key = GetMd5Hash(md5, secret);
 byte[] finalKey = System.Text.Encoding.UTF8.GetBytes(key); 

 des.Mode = CipherMode.ECB;
 des.Key = finalKey;

 des.Padding = PaddingMode.PKCS7;
 ICryptoTransform DESEncrypt = des.CreateDecryptor();
 Byte[] Buffer = Convert.FromBase64String(data.Replace(" ", "+"));

 return (Encoding.UTF8.GetString(DESEncrypt.TransformFinalBlock(Buffer, 0, Buffer.Length)));
 }

}