20150530

PaaS and static typing

I have mentioned Google App Engine - "Google App Engine is a Platform as a Service (PaaS) offering that lets you build and run applications on Google’s infrastructure."

You can build apps in Python, Java, PHP or Go. PHP sucks, Go is not that popular as the other three candidates, Java has a runtime penalty, and Python is a dynamic language.

What do I mean by runtime penalty? First, we need to know how GAE works: each time a client sends an HTTP request to the app server, an instance of the code is spawned to provide a response. For Python, this doesn't require a lot: just fire up the interpreter, interpret the script, and you are good. But for Java, this means you have to fire up the VM, and then run the Java code. The catch is, if there were no requests in the last 30 seconds, the VM shuts down, so next time it has to be started again. (Also, there is no way a free app could have a background process running indefinately. Task Queue and Cron is the closest you can have - or Background processes in the Module API, but I forgot why I ruled it out, and I'm lazy to check it again.)

In itself, this wouldn't be a big problem for my game, but combined with my hatred for Java, this is enought to not choose this. So this leaves my Python. I thought that maybe I just oversensitively annoyed by dynamic typing - it might not be that bad. I was wrong.

When I create a module in Haskell, the compiler spits out a thesis on why I should feel bad about myself - in the form of error messages, of course. Two points to mention: a) it is fast, b) if I fix those errors, I can be 90% sure my code works as it is intended. This is very different from working with Python: you write a syntactically correct code, and that's it - nobody's there to defend you from yourself, so you have to test everything in order to be sure that you will not shoot yourself in the foot. I usually write a few lines of Python code, then start the game, while watching the logs from Google App Engine Launcher, only to find my code just tried to call some method on the None object, because I forgot to check if the object is None. (Fore the record: there is no Null object in Haskell - if you want a Nullable type, you have Maybe - but it has to be said explicitly in the type signature (you use type signatures, right? RIGHT????), so when you work with a function that can have a Nullable object, you are aware of it, because the type checker makes sure. Bothersome in the short run, but you will thank for it every day after you wrote the script.)

I was patient with myself, kept telling "this is not so wrong, you just have to have discipline, and everything is good". Well, after years coding in Haskell, I have everything but discipline. It is so comfortable to know that there is a typechecker to cover my back that I'm happily rummaging through the codebase and creating a mess that I hope will work. (And I have the courage to call myself a "programmer".)

After a week, I gave up. I can't do it. I'm a lousy coder, I need my typechecker, I need my functional language, and I need my Haskell. So I'm now searching for something like GAE but for Haskell. I know that at FPCenter, I have a Haskell IDE on the cloud, and a free server that is ideal for testing, I just need to find some PaaS that is sized for my wallet. (I don't have $100 for a server at Amazon EC2.) I love GAE, but I hate the languages it lets me use.

On the bright side, I have learnt a lot from GAE: I learn how to use the NDB/Datastore, how to use the Tast Queue, how to use POST and GET requests, learnt about what the cron is good for, and I'm thankful for all of these.

20150526

Networking

Being multiplayer, a game needs a server hosting. The question arises: where and how to host a server?

To answer the question, we have to know what our needs are.
- Lobby
- Persistence (ranking and matchmaking, last few matches, statistics, etc.)
- Medium speed / latency, no realtime is required (hooray for turn based games)
- >99% uptime

Since I am a wannabe indie developer, I am tight on budget. I could pay, however I rather wouldn't until this game has at least some success. But later I might have to rent a server (due to traffic), so ideally I would like to find some host which grants a free plan that can later be upgraded.

First, look at the options:
  • Find a free webhost that lets you use PHP or some kind of scripting language.
    • + Free
    • - PHP!!!
    • - Not really meant to be a game server
  • Rent a server
    • + Use your favourite language
    • + Uptime is usually guaranteed
    • - Money
  • Cloud / Google App Engine (Did not consider Amazon or any other possibility)
    • + No need to use PHP, you can use Python (or Java or Go)
    • + Have free plans
    • + Scalable
    • - Very complexity, so features, wow, much buzzwords
There are other solutions, however this area is so new to me I wanted to cry from all the informations. These are the ones I still can remember. I chose Google app engine, since users praised it. I have downloaded Python 2.7, the Google App SDK, and created a simple web server locally, that replied "Hello world" to any incoming connection. Then I went to Unity, and added this little chunk of code:

void StartMultiplayer() {
  string url = "localhost:8080";
  WWW www = new WWW(url);
  StartCoroutine(GetResponse(www));
}

IEnumerator GetResponse(WWW www) {
  yield return www;
  if (www.error == null) {
    Debug.Log ("WWW Ok: " + www.text.ToString());
  } else {
    Debug.Log ("WWW error: " + www.error.ToString());
  }
}

I have added a "Multiplayer" button to the GUI, and tested it. It worked. (It took only 3 hours until I found this code snippet on the net and things finally started to work. I don't claim I understand what is happening, though.)

As I understood, I can store data in SQL table, so persistence is no problem. Lot of people on forums said that HTTP requests will be enough for turn based games (HTTP requests usually take about 1-2 seconds), so I'm optimistic about it.

20150522

Carts and food and spies

So while I was researcing the network possibilities, I gave some thought to the protocol as well. At that point I found out I have insufficient information to continue, as I didn't figure out basic stuff like recruiting units, etc. So I collected my thoughs, and...

...it turns out there are a few questions that need to be considered:

- What should happen if two carts of different teams go to the same tile?

 

Well, my initial thought was destroy both of them and let the food disappear. But it made me uncomfortable, since it was so unrealistic - I mean, what happens there? Does the two cart-driver kill each other? Let's see what other choices do I have. First, I could enable them to just stay next to each other. But that would be a special case in the rendering method, which I would rather avoid. Not to mention it would oblige me to let any two units occupy the same tile, which I'm really against - initially, I wanted that, but it would make fights really complex. Imagine there can be only one unit on a tile, and there is a fight between two units. It is very simple: barbarian beats archers, archer beats knights, knight beats barbarians. If the units of the same type fight, they are both dead. But what if two archers, three barbarians and five knights fight against 3 barbs, 3 archers and 1 knight? Or better: What if 1000 barbs fight against 1 knight? I have spent a few days trying to adjust for these questions, but ultimately it didn't work out. (Of course, in the 1 unit - 1 tile system, the same could happen, but then there would be the possibility of fleeing. It takes time to beat 1000 units for a knight. And it is not based on some hard-coded value. Those I avoid like plague.)

Then I thought about scrapping the carts from the game altogether, with the concept of food. (They seem to be so intertwined I can't have one without the other, no matter how hard I think about it.)  But it would make the game so much about fighting and not so much about good positioning, patience, and things like these. I don't want to make a fighting simulator. I want it to have more strategical depth. My principle is: if the lack of a feature makes it impossible to win without fighting, that feature will stay.

So ultimately I just settled on the disappearing carts. In a world where there are no trees on hills, anything could happen. Like units can't occupy the same kilometre-wide area...

 

 - How much food should a cart start with?

 

I avoid hard-coded values. More specifically, I hate numbers other than 0, 1 and 'n'. in this case, 'n' stands for any number that is a natural result of some well-defined ruleset or equation. Like 3 in the case of rock-paper-scissors. Or 4 in the case of "what is the smallest amount of colors I need to color a 2D map?". In the case of this game, 5 is kind of an 'n' - 3 from RPS-mechanism, 1 from spies (from Art of War), and 1 from the food-system. Arbitrary, but not as much as "let's give this unit 25 HP, and let's give that other unit 47, and it will be almost balanced".

So I didn't want any hard upper cap on food. I didn't want to say "OK, a cart will start with 100 food". Instead, I figured out that when a unit is in town, it should receive 1 food / turn. This means when it is out of town, the town should produce 2 foods / turn. (In this case, 2 is an 'n', because it was a natural result of the equation "1 + unit food needs / turn = amnt of food produced by town / turn".)

Also, when a unit leaves town, you should be able to tell how much food will it carry with itself. This needs playtesting to explore the possibilities.

 

 - Should spies be able to capture carts?

 

After giving it some thought, yes. (Same problem like cart vs cart.)

20150521

Unity WebGL + networking

While thinking about how should I implement networking, I came across a page which compared HTML5 to Unity - it said that Unity is able to export games to HTML5 (using WebGL). Well, I have tested it. I must say it works pretty well.


It needs to be tested if it works on mobile devices, but if it does, I can check compatibility from my to-do list.

I also looked into some of the networking solutions that are available with Unity: Photon, Bolt, Unity Park Suite... (Link to Forum post 1, Link to Forum post 2)

It turned out, if I want to have persistence, matchmaking, and things like that, I would be better off with some web-based technology (like using a web API with PHP on some web hosting), as Photon Cloud and such usually offer rooms for matching without any persistence. Topic needs more research.