21 April 2012

Games from Belgium

The gaming industry is slowly growing in Belgium. I notice it online on blogs and websites. Let me give you some interesting links.

It has been a while since I've revisited Fabrice l'été's post on his blog with links to game studios in Belgium. This post exists already for some years and is still growing. There are at least 10 more companies since I last looked! I've just added four more in the comments and you'll find some other interesting links there.

The Digital Arts and Entertainment course (amongst others) delivers each year more and more students skilled to start in this industry or even start their own company.

There's talk with the federal government and the Flemish government to support this growing industry financially and some projects are getting funding already.

The Flemish government has a whole website on this very subject, with various links in the industry. They also come with a list of gaming companies.

I recently worked for Eurautomat, a company that makes gambling games and websites. The technology they use is the same used in 'classic' games: for the arcade games Unity is used, flash for the website, Linux and OpenGL, etc. The games are mostly simple 2d flash-like games but the bonus games can grow into full 3d animated scenes. I attended the ICE event this year where I learned that the gambling-game industry is big, very big. Unity also had a booth there and has one next year.

Now the Belgian gambling commission has begun restricting online gambling sites, which is a good thing. There is a white list with 10 websites, which have all received B+ licenses, and 4 with A+ licenses. There's also a black list, it's forbidden by law to play on these websites and you can get fined for it. This protects the players but also makes competition in Belgium fair. All I want to say with this: these are just 10 more websites that will be needing games to be developed and at least some of them are already developed in Belgium.

So I see a bright future for games in Belgium. Who's attending Gamehub next week? Is there a community growing?

Have some other interesting links? Post them in the comments!

19 April 2012

Perforce on a freenas

Lately I installed an old pc with freenas 8.0.2 for backup purposes as well as a centralized depository for our home media, music and pictures.

At both Larian and Newfort we used perforce for source control. I also have worked in the past with svn, cvs, git and plastic scm. My scm of choice remains perforce, I feel most confident with that system.

Perforce is now free for 20 users and 20 work spaces which is a huge improvement over their former 2 users. So for my own projects at home, let's install perforce on the freenas. Mind you, I have almost no experience with linux/unix (I worked with some debian version at the KULeuven) so I made a lot of beginner mistakes.

  1. Make sure to activate the ssh service on the freenas, that way you can use putty to login on the freenas via the network instead having to be connected to the pc. You start in the C-shell, which is important since some commands that are available in csh are not in bash and vice versa. For example, setting environment variables in bash is done with 'export', while in csh it's done with 'setenv'.
  2. I have a disk of 122 GB where I created a ZFS volume on called p4disk.
  3. Then I setup the folders, get the p4 and p4d binaries and make them executable
    cd /mnt/p4disk/
    mkdir bin
    mkdir p4root
    cd bin
    wget http://www.perforce.com/downloads/perforce/r11.1/bin.freebsd70x86/p4d
    wget http://www.perforce.com/downloads/perforce/r11.1/bin.freebsd70x86/p4
    chmod +x p4 p4d
  4. On another drive I created a folder to store the journal. Since you need this to restore the server it should not be on the same drive as the server.
    cd /mnt/TERRA01
    mkdir p4
  5. Then we need to make sure the server is run when the freenas boots. It seems like there are a million ways to accomplish that (I hate that) and this is how I did it. If there is a better way please tell me :)
    mount -uw /
    cd /conf/base/etc/rc.d/
    nano perforce
    The first command is needed to make the drive writable, and then we need to add our service in the rc.d folder. But not in the /etc/rc.d/ folder since that one is always reset after a reboot. 'nano perforce' opens the nano editor to write our service script.
  6. Paste this:
    #!/bin/sh -e
    export P4ROOT=/mnt/p4disk/p4root
    export P4PORT=1666
    PATH="/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/bin:/mnt/p4disk/bin"
    p4d -J /mnt/TERRA01/p4/journal &
  7. Save the file and continue:
    chmod +x perforce
    cd /conf/base/etc/
    nano rc.conf
  8. Go to the last line and add:
    perforce_enable="YES"
  9. Reboot and done!

If I read these steps again it seems simple enough. I had some weird issues though, all because I'm not that Linux-savvy. A difficult one was that my server was very slow. If I called 'p4 info' on my PC, it took 5 seconds to get a reply. After much googling I found out this was due to a reverse dns look up on the server that failed. Some perforce calls, 'p4 info' among others, perform a reverse dns look up and that slowed it down.

The solution offered by perforce was to include all clients in the hosts file, which is not much of a solution if you ask me. I eventually found out that the server, and all my PC's in the house too, received three ip-addresses of dns-servers from the router: the router itself and two from my ISP. However my router is not a dns server, so all reverse dns calls on my router failed, causing the delay. A firmware update for the router is not available, so unfortunately I had to set the dns ip's from my ISP by hand on the freenas. From then on, perforce ran smooth. Gonna buy myself a new router I think.

With the steps I describe the perforce server is run by the root user. Some other how-to's, like for example installing svn on a freenas, say I should've created a perforce group and user and let that user run the server. I didn't bother and have no idea whether or not that's a good thing. If not, tell me why :). The main reason why I skipped it was because the 'sudo' command wasn't available on the freenas and I could not find how to install it.

Now that all runs fine, I can start experimenting with everything I read in my Effective C# book. I was afraid that the book wouldn't be as good as I hoped, but it turns out to live up to expectations. I'll post something about what I've read later.

11 April 2012

Restarting a service with powershell

It was one of those days. I realized that I've been doing the same small task over and over and so I thought: let's put that into a script. But then the writing of the scripts turns out to be a bit more complicated as expected. I should stop then and get on with my work, but nah, the challenge's there, I can't help it.

I should start writing all those little scripts down, just as a reference for later if I need it again but can't find it anymore. Let's do that now for one particular task.

What I needed to do: shutdown a service on a remote computer, copy some files on that remote computer from a remote computer (but only from the last added folder) and then start the service again. So I started with a bat file (windows, yes) but quickly discovered that determining the last added folder isn't that easy in a bat file. You can check whether a date is equal, but not if it's smaller or greater.

So let's try a powershell script for a change! I used to install software for that on XP, but now that I'm using Windows 7 that's not needed anymore, luckily.

Do not forget to set the execution policy, because default it is set to 'restricted' and I for one always forget on a new pc

    cmd
    powershell
    Set-ExecutionPolicy Unrestricted

After much googling I came up with this script:

&"sc.exe" \\192.168.1.yyy stop NameOfService
sleep -s 5
$from = "\\192.168.1.xxx\from\"
$to= "\\192.168.1.yyy\to\"
$a = Get-ChildItem $from| Where-Object {$_.PSIsContainer -eq $True} | sort -prop LastWriteTime | select -last 1
&robocopy "$from$a" $to*.* /S
&"sc.exe" \\192.168.21.yyy start NameOfService

Use sc to stop the service. Wait for 5 seconds because it can take a while before the service actually stops (should be a while-loop that checks the state perhaps, but 5 seconds was enough for me in all cases encountered). And then we have the power of powershell, we get all the folders sorted by last write time and select the last one, and the result of that is used in a robocopy call. At the end the service is started again.

God that was easy. I never go back to bat files again. It's only a matter of time and practice and I'll be writing them as quickly as a bat file.

10 April 2012

Does the file exist? No easy question.

I shout 'How do I check whether a file exists in C#' and somebody immediately responds 'File dot Exists'.

I shout 'How do I check whether a file exists in C++' and I get no answer.

It is something I can get really frustrated from. C++ is widely regarded as a good and high level language, and I'd like to agree, but in the year 2012 I expect more from a language. How on earth is it possible that experienced C++ developers cannot answer that simple question in a snap? I googled the question, and the answer is far from clear. I have the impression that this is the best method:

#include <sys/stat.h>
bool FileExists(const char* filename)
{
      struct stat buf;
      return (stat(filename, &buf) != -1);
}

Another good option I found was:

#include <fstream>
bool FileExists(const char *filename)
{
 std::ifstream ifs(filename);
 return ifs.is_open();
}

That's almost the same as the previous one and fstream is included more often. However in the first version you're not actually opening the file afaik.

The next one is horrible, it even throws an exception! For a file check! And it's platform dependent.

#include <Windows.h>
bool FileExists(char* filePath)
{
 DWORD fileAtt = GetFileAttributesA(filePath);
 if(fileAtt == INVALID_FILE_ATTRIBUTES)
  throw GetLastError();
 return ( ( fileAtt & FILE_ATTRIBUTE_DIRECTORY ) == 0 ); 
}

There are a bunch of variations of above three circulating on the web. Boost also has a function, so if you use boost you'd probably should use that.

If you do not want to write this function in every cpp where you'd need it, you should put it in a header. If you don't want the name to collide with another existing function with the same name, you should put it in a namespace. You might put it in a library with some other common functions, a toollib or something that you include in all your projects, which means that you need to compile it to various targets, perhaps various platforms. The toollib gets changes in every project, so you need to keep it compatible across projects, or you'll be having various versions of your toollib...

So this is what saddens me. Why is it so hard to have some changes in the language? wouldn't it be ideal if we had

#include <fstream>
...
if(std::ifstream::exists(filename))
{
...

in our code where we want the check. Just as C# has it for example:

...
if(System::IO:File.Exists(filename))
{
...
It would be in the stl, every compiler would implement it as efficient as possible, live would be beautiful.

02 April 2012

Effective C#

Now that I own the c++ coding standards book, I also want to buy the Effective C++ book by Scott Meyers. I also already read it at Larian front to back and I know its worth.

But since I'm currently developing more in C# I thought I'd look for similar quality books about that language. I just ordered Effective C# by Bill Wagner and I hope it's as good as the C++ books.

While looking for it, I also found this code project article that has the same title. It offers some tips but unfortunately without explaining why the tips apply. But at least I learned some small ideas that I can use in the future:

  • I can write strings with an @ in front and then I don't have to worry about double backslashes to have a single backslash in my path.
  • I really should start using stringbuilders, I know I have to use them but the only time I want to concatenate strings is when I want to have some debugging output. I'm too lazy to create stringbuilders at that time and since they're only executed in debug mode I don't want to bother with them. But when I do concatenate strings in release, I should use stringbuilders, let's do that from now on.
  • Let's look into ngen
  • Wow, 'checked', handy keyword!

    And concerning the 'for' versus 'foreach' discussion: I want to delve more deeply into that because let's face it, foreach is soooo easy to use that I do not want to ditch it just because it would be a little less efficient. I want to know for sure that's the case and when that's the case. I hope my new book (arriving in 2-3 days) will provide me with an answer.