24 June 2012

AS3 - hate it or love it

And I'm not sure whether I hate or love it :)

The last few weeks I've been learning Flash, AS3, Flex and Air since I started developing an air app and am working on some other flash projects.
I was very reluctant to use Flash for those projects (Id' rather use Unity) but the choice for Flash was due to legacy content that I need to use. And let's face it, Unity is not an engine where we you can use vector graphics easily, nor are there much other engines that lend themselves well to vector graphics. (If there are, tell me, I'd like to get to know them - should I start using html5 perhaps?)

I was happily surprised that, all-in-all, as3 isn't that bad a programming language. In less than a weeks time I was able to get a decent looking app running on my galaxy tab. It's clear that the learning curve for as3 isn't steep.

But learning as3 via google is horror though. There are a lot of resources out there and a lot of forums where people help each other out, just as you have for other programming languages.
But the problem for flash/flex/air developers is that there is AS3 *and* AS2. AS2 looks a lot like AS3, but isn't at all the same. That makes it hard for a newbie to find help on google, because some solutions you find work for both, and some only for one language and it is sometimes not obvious to tell in what language a solution is provided.

And then there is the distinction between a flash, flex or air application. In all three there are different libraries available to get stuff done, so if you're looking on the web for help you need to be sure that the solution you find is for the right environment. For example I was looking how I can send an e-mail (with attachment) from my app on a mobile device. There are a lot of possible ways to do this, via a mailto url, via smtp, via php, etc. But these are all more for online web apps and all seem to be a little hacky to me. There's a clean solution that involves writing an 'ANE' (air native extension) that can send e-mail. I haven't found an existing one so I'll start writing my own. It took me some googling and trying out before I came to that conclusion.

So now I know: AS3 developers have no real well documented working environment, the api is hard to search, contains few examples, the web is full of people writing various opinions on how to solve things, confusing all the time as2 with as3 and flash with flex and air. Add the fact that quite some flash developers are more artist than programmer... The AS3 developers must be extremely jealous of C++/C#/Java developers who have a well documented api and lots of good code samples on the web with decent IDE's (don't get me started on those).

But what led me to write this post is this: a few days ago I added an on screen fps and memory counter -a healthy reflex of every game programmer I think- and saw immediately that the memory leaks were going through the roof. I looked for references that somehow where being kept around, but couldn't find any. So we ask our friend google-man. This post lists all actions you can take to free up memory. What the frak, it's enough to write an entire destructor in every class you have, so what's the point of having a managed environment then?

Luckily I found this and this post, explaining the inner workings of the flash garbage collector. From it I learned that I don't need to do anything else than I'm used to do in C# (that is implementing IDisposable if your class contains non-managed resources like file handles), except for this: use weak references for event listeners. I changed all my event handlers and behold, the leaking was gone.

But not many people know this, most examples that you find on the web don't use weak references, so there must be a lot of leaking swf's out there. My god, horrible.

Let me end with saying this: flash and as3 isn't bad at all, au contraire it's great that you can create nice visual elements with very few code and combine them in apps very easily. I like to work with flash because of that, you have results very fast. But for a programmer, it's horror.

17 May 2012

C# - Initialization of enums

I notice that I want to write too much based on what I have read in Effective C#, so I'll post bits and pieces instead of one big article, here comes a small one:

Initialization and enums

If an object is instantiated all member variables are initialized, with a given initializer or 0/null if none was specified. References are always null, bools are always false, number values are 0, and... enums are set to 0.

Wow! I never realized that, I kinda assumed that an enum value was set to the first value defined in the enum, but this is clearly not the case - and shouldn't be. It does imply that you always need to have a 0-value in your enums, or you risk having an enum variable with an undefined value. Also, when using the [Flags] modifier, None = 0.

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.