Search This Blog

Tuesday, May 17, 2016

SignalR as network protocol

SignalR is the web socket implementation written by Microsoft. It is actually a quite good implementation of web socket and let you develop using only a .NET language on the server side and JQuery on the client side.

You can call from JS C# function as well as from C# call JS functions. Objects are serialized / deserialized for you as well.

To create a chat with SignalR is really not complex and a good start point can be found here:
http://www.asp.net/signalr/overview/getting-started/tutorial-getting-started-with-signalr

However I use it for other purposes as well, it allows me to contact a server even if I'm behind a firewall and have real-time bi-directional communication. To do so I simply use the SignalR Client package (nuget) and from C# you can call a SignalR server and communicate with it.

Sure if it's just a pure "call function" SOAP / REST could be a better option, but they will never offer the bidirectional and fast reaction web sockets offers.

A good start point could be:
http://www.asp.net/signalr/overview/guide-to-the-api/hubs-api-guide-net-client

Friday, May 13, 2016

Stat & Skills => the first editor is actually a viewer

While creating a game maker or actually any software you need always need to think about who will use it and make it so that your soft can actually be used by your audience.

Some software are quite simple to use, and just require a well done interface, others on the other hand may require a "new comer" interface as well as allowing advanced users to access more powerful tools.

For example in many 3D graphical software you will find the option to develop your own tools or automate tasks either by writing some scripts, or developing full plugins. While this is certainly not something every new comers will start with, it's something bigger companies may need to integrate the different tools of their pipeline and at the end save time / money.

For our game maker the situation is a bit similar, we must offer a relatively simple "click to create" option where all what's needed will be provided as default, with options to tweak some rules and yet if we really want to offer a good option as game engine, we must offer a more advanced way for developers to develop.

Therefore the current choice is to offer both a scripting language which is near Javascript as syntax, and at the same time "Wizards" to just tweak parameters without having to edit the code. The concept is currently fully implemented and it seems to work quite well. To show the "wizards" editor, I made a first "stats" and "skills" editor which actually only allows you to view the defined stats & skills.



On top of the page you see the possible tweakable values, while under you see the original code. Most likely the code will not be shown by default to avoid to scare the new comers, however currently I thought it was fun to see all at once.

Offering an incomplete implementation of the tools allows to discuss the matter with example on hand, and therefore let others fully understand the concept which otherwise could seems overly complex or completely unclear.

Thursday, May 12, 2016

JS Profiling

In order to make your game fluid / fast, you should ideally reach around 60 FPS. Ensuring about 60 FPS also allows to ensure that all players will play with the same pace.

The first step in this direction is to see how well your game behave, and for this a little "gadget" could be handy:

http://darsa.in/fpsmeter/

This little tool shows a graph and a few values to see if your game manage to keep the needed speed.

Now that you have a view of your current speed, you may as me have the issue that the game is not optimized enough, however if your code is not just a few lines of code you may start to wonder what takes time.

In the old days the solution was to put a "stop watch" around some critical areas and see how long those areas took. Today even browsers starts to have really good debugging / profiling tools. I will here discuss only Chrome but for most parts you can use any other browser (maybe with some additional plugins).

To start the debugger press simply F12:


You will see the debugger contains loads of "tabs" and each of those is specialized in a different task. I usually end up using a lot the "Source" tab as it allows me to see my JS / TS code, put breakpoints and see how it is going within my code.

In this case as we want to debug the performances of the game we will use the "Profiles" tab. Once you click on the "Profiles" tab, you are greeted with a selection of the type of profiling you want to run. To see which function takes more time choose "Collect JS CPU Profile" and click the "Start" button.

At this point use your game as you usually do. But don't spend too much time on it. I would say about 10-20 sec should be enough to collect all the data you need. Once you decide you collected enough data click on the "Stop" button of the profiler, and here the magic happens:


On top of the result page, you will see a gray bar allowing to choose a few things. The first button allows to choose different type of views for the collected data, I find personally "Tree (Top Down)" more intuitive to read as it represents also the calls of your code. In my case, before I started to optimize, you see that 67.9% of the time is spent inside Play.GameLoop, expanding it, I see that 49% of the total time is within WorldRender.Render and digging again I find WorldArea.GetObjects taking 31%.

Clearly the I should work on this GetObjects function and see if I can speed up my soft. After nearly a day of work, I managed indeed to speed up a lot my engine:


From a first impression you may think: "Wait! We still have about 62% inside the Play.GameLoop!" yes, that's true, however if I dig down you see that now inside my WorldRender.Render most of the time is consumed by "drawImage" which is nothing else as the Canvas 2D drawImage function itself. This function cannot be directly optimized as it's an API call and therefore I indeed speed up my soft.

Before optimization I was about 20-30 FPS and now I run about 58-60 FPS, which is nearly a 2x improvement.

As you see, using the debugging / profiling tools offered by the browsers can indeed help you pin point where your soft is eating up resources / time. Just a quick note, if you see that all the time is eat up by a single function but you don't get more info than that, simply split your function in smaller pieces and the profiler will then be able to tell you in which of this piece the time is spent.

Wednesday, May 11, 2016

Action timer

Game balance is one of the hardest part of a game design in my opinion. I don't say that a render engine is easy to code, or that AI are always a piece of cake, however for me, balancing power / difficulty / fun factor is really something not easy.

With this game engine, I thought I would offer the game owner decide which skills the player will have, and each skill will be able to do whatever the game owner want... or nearly. By default I will offer some "default skills" as said, and to balance their power each skill will have a sort of "cool down" timer.

A quick action bar will be visible on the bottom of the screen allowing you to place up to 10 skills / items you will be able to switch / use using the 0-9 number keys. Switching to another active skill will then trigger another action when clicking on a monster.

So my default skills will be (hopefully) balanced for an average game, but game owners will be able to change all the game balance just by changing the cool down timer, or tweaking more, or even changing the logic code. That allows game owners to have easier or harder games, and play with the rules as much as they want.

Just one world of warning: once the game starts to be used, tweaking too much the rules is not good as it usually annoy a lot the players. So even if the balance is not perfect, once they start to play keep the rules as much as possible.

Monday, May 9, 2016

Skill script starts to work

Now that the parser is up and running (at least as it's infancy) it's time to go back to the game engine itself and implements the stats & skills.

The first skill I wanted to try is the "attack" skill which should hurt an enemy when you click on it, and the enemy is nearby. Ideally the attack should have a timer and while you remain in the range the game will attack every time the timer is over.

All that should be implemented at the script level, so that every game owner is then free to fully change the rules for his/her game. Of course we will provide some default rules to start with. Those rules will also quite certainly have a set of values you will be able to change via a simpler interface (not needing to go to the code level directly).

Anyhow that's all the "future". Currently I wrote one of the most plain attack skill possible:
// Default attack skill. Will be invoked while clicking on a monster.
function MonsterClick(monster)
{
    // Kill the monster if its nearby\n\
    if(Monster.DistanceToPlayer(monster) < 32)
        Monster.Kill(monster);
}
This code is run every time you click on a monster, then the code checks if the monster is in the range of 32 pixels and if yes kill the monster. Of course that's not how it should be, we should reduce the monster life and only if the life of the monster is 0 or smaller then kill it. However it's a good start to see that the engine is able to mix JS code (the own engine code) and our own little scripting language.

If multiple skills implements the "MonsterClick" function then currently all the skills functions will be invoked.

Finally, to make the code writing maybe a bit easier for the game owners we decided to make it case insensitive, which means lower or upper case don't change the meaning of the code.

Wednesday, May 4, 2016

Execution of the AST

Now that the parser is finished, I worked on the AST execution. The simplest (and quite certainly not the smartest or most optimized) way to do it is simply have a "Execute" function on each of your statement nodes. For example our "2", "+", "1" tree would have the "+" on top, and if I call the Execute function it will then check the 2 children of the node and execute them as well. As in this case the children are static numbers they would simply return the value and my main node would then sum the 2 values.

The same concept works for much more complex trees with function calls, variables or  whatever you can put inside your AST.

But what if you want to execute multiple "statements" like lines of code? Well simply you have an array of statements and you go through it from first to last.

For a procedural language (as it is in our case) we have a first "pass" of execution which will store the functions in the "known function list" and then when needed run them.

Variable scopes can is another issue to deal with when you develop a language. A variable defined in a block (like in a function) should not be accessible outside of the block. A simple way to implement it is to have an "execution environment" which contains all the variables in the scope, and once you enter a new scope you change your "execution environment".

All this is good, but what if we would like to gain speed? Multiple ways are open to optimize your script execution (only a few here but you may find many many more):

  1. AST optimization which basically tries to simplify your AST for example to pre-calculate constant operations. If you write "2+3*2" it doesn't make sense to run the whole tree all the time and could be replaced with the same value: "8".
  2. Loop unfolding: from a for loop, transform it to multiple lines of code, which would avoid to run checks and more which simply cost time.
  3. Dead code removal: remove nodes which cannot be called
  4. JIT like operations: you may transform your AST into something faster, in my example, transform my AST directly into Javascript and eval it having then the speed of Javascript and not the overhead of my AST on top.
All those can be done one after the other such to gain each time more speed. Of course the old statement that optimization tends to make the code harder to read is always true: if you implement AST optimization and JIT you will make your parser a lot more complex and harder to debug. So be sure it's really needed before entering this road.

Tuesday, May 3, 2016

3 step parsed language

The work on the parser is going forward, and actually is working quite well. The parser will be a 3 step parsed language:

  • Tokenize the source
  • Parse statements
  • Execute the AST
The first step is to be able to recognize the different parts of the source string into different pieces. For example "1+2" would be 3 tokens: [Number:"1", Operator:"+", Number:"2"]
Tokens are responsible of just having a content and knowing the type of data but don't yet know if it's valid to have a given type after another.

Parsing statement uses the tokens produces by the first step, and basically cascade the parsing from "expression", "and operator", "or operator" down to the "base statement". The order of the cascade actually defines the order of precedence of the different pieces, for example multiplications must be done before an addition: 3*2+4 must be done as (3*2)+4 and not 3*(2+4) as the result is not the same. In this step the parser can detect syntax errors, for example missing a parenthesis. At the end of this process we will have a AST (https://en.wikipedia.org/wiki/Abstract_syntax_tree) which can then be run.

Executing the AST is after that quite simple, each node knows how to execute its own operation and nothing more. Also if the AST is well built the execution of it should be fast. Ideally AST optimizations should be a step before the execution, and an AST could ideally be transformed into a binary code directly run by the CPU (that would produce a JIT if done on run-time).

Now you may wonder but why do I need to write all that, and yes it's not a small piece of software? Yes there is available parsers like the Javascript function "eval" or use 3rd party libs which would implement a scripting language for you. Well the answer is pretty simple: eval would be easy to use and cheap for the developer (me). However it would have a major issue: security, any valid code would be able to run, for example even nasty operations. 3rd party libs may actually much bigger than what we would ideally want and may be harder to integrate or debug in case of issues.

Stay tuned to see my parser first in action!