Test – Are you a Javascript Guru?

Javascript is a very flexible language, I made a compilation of some edge cases that you may have encountered while programming. The main goal is to point out some interesting specific behaviors.

Concatenation

1] var result = [10] + 1;
Explanation:
The Array doesn’t have a toNumber method, instead it has a toString method: [10] + 1 becomes “10” + 1.
String has a greater priority over Number with the + operator: “10” + 1 becomes “10” + “1” = “101”
2] var result = ['a', 'b', 'c'] + "";
Explanation:
The Array.toString method concatenates all it’s elements (converted to string) with the “,” separator.
3] var result = 'a' + 5;
Explanation:
In Javascript, String has a greater priority than Number for the + operator, so 5 is converted to string before being concatenated.
In PHP, the + operator is only the addition so 'a' is converted to number (gives 0) before being added.
In C, a char and an integer are of the same type. 'a' is first converted to it’s Ascii value (gives 65) before being added.

Operations

4] var result = 3.75 | 0;
Explanation:
|0 is a fast way to do a Math.floor for positive integers.
5] var result = 65 / 'a';
Explanation:
/ is only defined for Numbers so 'a' is first converted to a number (gives 0).
A division by 0 does not throw an error but results the object NaN (Not a Number).

Objects

6] var ob = {"10": 1};
ob[10] = 2;
ob[[1, 0]] = 3;
var result = ob["10"] + ob[10] + ob[[1, 0]];
Explanation:
Objects keys are strings. If you don’t provide a string, it will convert the key to string.
"10" and 10 gives "10"
[1, 0] gives "1,0"
7] var $ = {"": String};
var result = !!$[([])]();
Explanation:
$ is a valid variable name.
Parenthesis inside the key part are useless: array[(1+2)] is the same thing as array[1+2].
Objects key are first converted to string. [].toString() is "".
It is possible to have the empty string "" as an object key.
$[""] is the String object. String(val) returns val.toString(). String() returns "".
! is the negation operator. "" == false, so !"" == true, !!"" == false
!!expr is a fast way to typecast an expression to a boolean.

Equality

8] var result = (' trn ' == 0);
Explanation:
Unlike PHP, strings wrapped around simple quote ' are also parsed. 't' == "t"
When compared to a number value, a string will be converted to a number. If it contains only spacing characters it will be converted to 0. If a string cannot be parsed as a number it will return NaN (Note that NaN != NaN).
9] var a = new String("123");
var b = "123";
var result = (a === b);
Explanation:
When creating an object with the new operator, the result type is always "object". The type of "123" is "string" so the type does not match for ===.
10] var a = {key: 1};
var b = {key: 1};
var result = (a == b);
Explanation:
Object comparison is only done with the pointers behind the objects.

#jsguru h3 { margin-top: 20px; margin-bottom: -15px; }
#jsguru .wp_syntax { margin-top: 20px; }
#jsguru .result { margin-top: -16px; margin-left: 10px; }
#jsguru .hint { display: none; }
#jsguru label { font-family: monospace; }
#jsguru input { padding: 0 10px; }

var jsGuru = (function () {
var goodAnswers = [1, 2, 2, 2, 2, 1, 0, 0, 1, 1];
return {
test: function () {
var count = 0;
$.each(goodAnswers, function (id, val) {
if ($(‘[name=result’+(id+1)+’]’).eq(val).attr(‘checked’)) {
count++;
}
});
$(‘#jsguru-result’).html(‘You scored ‘ + count + ‘ / 10’);
},
highlight: function () {
$(‘#jsguru .hint’).show();
$.each(goodAnswers, function (id, val) {
$(‘[name=result’+(id+1)+’]’).eq(val).parent().css(‘font-weight’, ‘bold’).css(‘color’, ‘orange’);
});
document.location.hash = ‘jsguru’;
}
}
}());

Fief (Board Strategy Game) Analysis

While on holidays, I played that old (bought in the 80’s) board game called Fief. After several games I wanted to point at the good and bad things about this game in order to find some general rule.

Fief - Board Strategy Game

Fief – Board Strategy Game

Some assets of the game are innovative and worth mentioning.

The resources are really limited. It is common to have limited number of soldiers or houses, but the limitations are often relative to a player. In this game, there is a limited amount of money. After several rounds, there’s no money left in the bank and people cannot earn their income. This opens the possibility to organize bankruptcy.

Movement design is clever. The only way to move your army from town to town are Lords. They are special soldiers that can walk 2 towns a round. While moving, they are able to carry any amount of soldiers with them. Once they are well positioned, the Lords allow you to move around the map really fast.

    However, that’s not a perfect game, the main problem could be summarized with the statement “10 pages rules book“. Here are some consequences of that fact.

    • Many rules leads to contradictions and unclear statements
    • The learning curve is disastrous
    • More time spent reading and discussing the rules than playing the game

    In order to find a solution, we are going to analyze some facts and get general rules off them.

    Could we play without this rule? Yes. Drop it.

    In the game, there are 2 types of building that gives resources: Mill [cost 300, give 200] and Press [cost 200, give 100]. Basically, you first buy all the Mills and when there are no left you start taking Presses. These two buildings are just about the same, do not give any kind of reflexion but have to be learned by the players. Removing one building would not affect the decision range of the user and would make the game easier to play.

    Ten things doing slightly different things? Merge them!

    There are lots of cards but you can never use them. There are offensive cards and their respective defensive cards. Offensive cards are targeted against a player and aren’t that common. No need to say that you never have the defensive card when needed. That’s about the same for cards that gives money, you either have to be Clergy, have a Fief or be King to use them. Since most of the time you are nothing, these cards are trash. Being given useless card over useless card is a really bad feeling.

    A solution would be to transform these useless cards would be to make them generic. What about having a rare card that can counter any offensive attack. As for the money card, it would give money based on the highest rank you have. By changing how to attribute the cards, we could keep the same usage rate. They would be seen like a great reward and as a side effect simplify the game.

    Simple rules, great flexibility.

    The methodology adopted by the game is: “There’s a problem? Add a special rule for this exact problem“. What if we let the user the possibility to do it anyway? It will give flexibility and make the game easier to understand! For further thoughts about this philosophy in the web development, i would suggest you to read the free book Getting Real.

    Mysqli Wrapper – Short and Secure Queries

    Mysqli Wrapper is shortening the code required to run queries, make them 100% safe against SQL Injections and gives a handy Array as result. No more pain writing queries!

    You can view the source at the MysqliWrapper Github Repository.

    When developing a PHP application, SQL queries is the most dangerous area. This is because the built-in tools are either not secure by conception or too much complicated to use. I’ve made a little wrapper to mysqli that solves all these problems and make you enjoy writing queries!

    You are probably writing your queries like this. We assume we have $zip(string) and $pop(int) variables previously declared in the code.

    // Basic Method
    mysql_connect('host', 'user', 'pass');
    mysql_select_db('database');
    $query = "SELECT Name, CountryCode FROM City 
        WHERE Zip = '".mysql_real_escape_string($zip)."' AND Population > ".(int) $pop;
    $result = mysql_query($query);
    while ($row = mysql_fetch_array($result)) {
        // $row['Name'], $row['CountryCode']
    }

    With this method, you have to secure all the fields yourself. To do it, you have to type the loooong function mysql_real_escape_string and you must not forget the quotes around the parameter. The code is unreadable, not safe by concept because you may forget to sanitize a field … And, it is annoying to write!

    Mysqli was intended to be a wrapper around Mysql that would provide safe queries. You may wonder why this has not become the default way to write queries. Have a look at the exact same code written with mysqli.

    // Mysqli Method
    $mysqli = new mysqli('host', 'user', 'pass', 'database');
    $query = "SELECT Name, CountryCode FROM City WHERE Zip = ? AND Population > ?";
    if ($stmt = $mysqli->prepare($query)) {
        $stmt->bind_param('si', $zip, $pop);
        $stmt->execute();
        $stmt->bind_result($name, $code);
        while ($stmt->fetch()) {
            // $name, $code
        }
        $stmt->close();
    }

    Yes, 10 lines to make a SELECT. Obviously they failed to design an easy to use API. It is also too restrictive: you have to assign a variable for each of the field you want to select. This seems to be a really waste of time: it’s already in the query, why would you write it another time? Also, that’s not possible to use ‘*’ to select all the fields.

    Here is my attempt to easily to write and safe queries:

    // My method
    $db = new dbWrapper('host', 'user', 'pass', 'database', true);
    $result = $db->q("SELECT Name, CountryCode FROM City WHERE Zip = ? AND Population > ?",
      'si', $zip, $pop);
    foreach ($result as $key => $city) {
      // $city['Name'], $city['CountryCode']
    }

    What’s good about this:

    • A single 6 characters function
    • Secure because parameterized
    • Returns an Array
    • Easy migration from the basic method

    I’m really happy with that wrapper. It is faster to write the queries because you don’t have to sanitize the parameters neither you have to think about safety and there’s only a 6 character function to remember. The code is smaller and easier to use because it returns a real Array! Also, this allows to display mysql errors on the development server only and doesn’t requires to type or die(mysql_error()); everytime.

    If you don’t know by advance the number of parameters (A custom search where field may be selected or not by the user for example), this implementation becomes really tricky to deal with. I have no solution at this time for this problem. The v8cgi Query API would handle this problem really well, however i am not confident enough in letting a script writing my queries.

    The wrapper code is really hacky but fits in 60 lines so can be embedded really easily. Download

    Class dbWrapper {
        protected $_mysqli;
        protected $_debug;
     
        public function __construct($host, $username, $password, $database, $debug) {
            $this->_mysqli = new mysqli($host, $username, $password, $database);
            $this->_debug = (bool) $debug;
            if (mysqli_connect_errno()) {
                if ($this->_debug) {
                    echo mysqli_connect_error();
                    debug_print_backtrace();
                }
                return false;
            }
            return true;
        }
     
        public function q($query) {
            if ($query = $this->_mysqli->prepare($query)) {
                if (func_num_args() > 1) {
                    $x = func_get_args();
                    $args = array_merge(array(func_get_arg(1)),
                        array_slice($x, 2));
                    $args_ref = array();
                    foreach($args as $k => &$arg) {
                        $args_ref[$k] = &$arg; 
                    }
                    call_user_func_array(array($query, 'bind_param'), $args_ref);
                }
                $query->execute();
     
                if ($query->errno) {
                  if ($this->_debug) {
                    echo mysqli_error($this->_mysqli);
                    debug_print_backtrace();
                  }
                  return false;
                }
     
                if ($query->affected_rows > -1) {
                    return $query->affected_rows;
                }
                $params = array();
                $meta = $query->result_metadata();
                while ($field = $meta->fetch_field()) {
                    $params[] = &$row[$field->name];
                }
                call_user_func_array(array($query, 'bind_result'), $params);
     
                $result = array();
                while ($query->fetch()) {
                    $r = array();
                    foreach ($row as $key => $val) {
                        $r[$key] = $val;
                    }
                    $result[] = $r;
                }
                $query->close(); 
                return $result;
            } else {
                if ($this->_debug) {
                    echo $this->_mysqli->error;
                    debug_print_backtrace();
                }
                return false;
            }
        }
     
        public function handle() {
            return $this->_mysqli;
        }
    }

    public function __construct($host, $username, $password, $database, $debug) {
    $this->_mysqli = new mysqli($host, $username, $password, $database);
    $this->_debug = (bool) $debug;
    if (mysqli_connect_errno()) {
    if ($this->_debug) {
    echo mysqli_connect_error();
    debug_print_backtrace();
    }
    return false;
    }
    return true;
    }

    public function q($query) {
    if ($query = $this->_mysqli->prepare($query)) {
    if (func_num_args() > 1) {
    $x = func_get_args();
    $args = array_merge(array(func_get_arg(1)),
    array_slice($x, 2));
    $args_ref = array();
    foreach($args as $k => &$arg) {
    $args_ref[$k] = &$arg;
    }
    call_user_func_array(array($query, ‘bind_param’), $args_ref);
    }
    $query->execute();

    if ($query->errno) {
    if ($this->_debug) {
    echo mysqli_error($this->_mysqli);
    debug_print_backtrace();
    }
    return false;
    }

    if ($query->affected_rows > -1) {
    return $query->affected_rows;
    }
    $params = array();
    $meta = $query->result_metadata();
    while ($field = $meta->fetch_field()) {
    $params[] = &$row[$field->name];
    }
    call_user_func_array(array($query, ‘bind_result’), $params);

    $result = array();
    while ($query->fetch()) {
    $r = array();
    foreach ($row as $key => $val) {
    $r[$key] = $val;
    }
    $result[] = $r;
    }
    $query->close();
    return $result;
    } else {
    if ($this->_debug) {
    echo $this->_mysqli->error;
    debug_print_backtrace();
    }
    return false;
    }
    }

    public function handle() {
    return $this->_mysqli;
    }
    }

    Update February 17 2010: Now works for php >= 5.3.0. Added debug_print_backtrace to get the sql query when there is an error.

    The bracket notation for string is incomplete in Javascript and does not work in IE7. This is really painful to migrate to the .charAt(pos) equivalent, this is why i recommend you not to use it.

    // Bracket Notation
    "Hello World!"[6]
    // > "W"
     
    // Real Implementation
    "Hello World!".charAt(6)
    // > "W"

    // Real Implementation
    "Hello World!".charAt(6)
    // > "W"

    The bracket notation to get a character from a string is a shortcut to .charAt(pos) added by the vast majority of the browsers. However, i would not recommend to use it for several reasons.

    This notation does not work in IE7. The first code snippet will return undefined in IE7. If you happen to use the bracket notation for strings all over your code and you want to migrate to .charAt(pos), this is a real pain: Brackets are used all over your code and there’s no easy way to detect if that’s for a string or an array/object.

    You can’t set the character using this notation. As there is no warning of any kind, this is really confusing and frustrating. If you were using the .charAt(pos) function, you would not have been tempted to do it.

    var string = "Hello World!";
    string[6] = '?';
    console.log(string);
    // > "Hello World!";

    Speed Up Javascript Sort()

    By overriding the toString Object prototype, it is possible to speed up by 5x the sort function. This is an easy to implement trick that gives astonishing results

    I wanted to know if there were ways to speed up the Javascript Sort function. I came across an interesting article (Yet another faster Javascript Sorting) that presents a way to boost the builtin sort function. However, the link with the detailed explanation is dead, so i make you a summary here.

    To sort some data, you are likely to do something that looks like that:

    data.sort(function (a, b) { return b.key - a.key; });

    The comparison function is being called n log n times. Since it’s a javascript function, it is slow. sort() with no parameters will first convert all elements into strings and then use native (therefore faster) string comparison.

    To make this work, we just have to override the toString method of the Object prototype to return the key.

    var save = Object.prototype.toString;
    Object.prototype.toString = function () { return this.key; };
     
    data.sort();
     
    Object.prototype.toString = save;

    data.sort();

    Object.prototype.toString = save;

    You have to make sure that the key variable is a string. In my application, the key range is [0, 100] so the it is written as String.fromCharCode(key). If you have to deal with larger key range, the best solution is to convert the number into base 256. Make sure the number is padded with 0 because of the string comparison.

    I made a little benchmark of the implementation to see how well it performs

    .sort_results { border-collapse: collapse; margin-left: 2px; margin-bottom: 0; }
    .sort_results td { text-align: center; width: 100px; border: 1px solid #ccc; padding: 0 5px; }
    .sort_results td.right { text-align: right; width: 200px; }

    toString Sort Benchmark Firefox
    3.5.2
    IE
    8
    Safari
    4.528
    Chrome
    3.0.197
    Normal – 10 000 135ms 188ms 45ms 16ms
    Fast – 10 000 10ms 31ms 14ms 68ms
    Improvement – 10 000 x13.5 x6.1 x3.2 /4.3
    Normal – 100 000 695ms 2125ms 200ms 128ms
    Fast – 100 000 101ms 437ms 46ms 326ms
    Improvement – 100 000 x6.9 x4.9 x4.3 /2.5
    Normal – 1 000 000 10102ms * 2736ms 970ms
    Fast – 1 000 000 1158ms 6828ms 482ms 2593ms
    Improvement – 1 000 000 x8.7 x5.7 /2.7

    *: Script time limit has been exceeded

    It gives about a 5x increase of all the browsers I have tested with except in Chrome with a 3x decrease.

    Since Chrome is already times faster than all the browsers, it doesn’t look slowed by this feature. However it gives a real boost to all other browsers.

    Update (24 December 2009): Chrome Array.sort() function is written directly in javascript and calls the ToString function everytime when a comparison is needed. Therefore, it is making 2 function calls (ToString(x), ToString(y) instead of one (compare(x, y)).

    In order to check if that optimization will indeed give an actual boost, we can count the number of time the ToString method is being executed for 3 values. 3 times means that it is executed n time and more means that it is executed n log n times.

    var need_custom_sort = (function () {
      // Fill the array with 3 values
      var array = new Array(3);
      for (var i = 0; i < 3; ++i) {
        array[i] = new Object();
      }
     
      // Override the toString method that counts how many times it is being called
      var count = 0;
      var save = Object.prototype.toString;
      Object.prototype.toString = function () { count += 1; return ""; };
     
      // Sort
      array.sort();
      Object.prototype.toString = save;
     
      // 3 times is good, more is bad!
      return (count === 3);
    }());

    // Override the toString method that counts how many times it is being called
    var count = 0;
    var save = Object.prototype.toString;
    Object.prototype.toString = function () { count += 1; return ""; };

    // Sort
    array.sort();
    Object.prototype.toString = save;

    // 3 times is good, more is bad!
    return (count === 3);
    }());

    SmallHash encodes any range of integers into the smallest possible string. This way, you can use the hash part of your url with efficiency.

    You can view the source at the SmallHash Github Repository.

    My problem is having these options stored in the minimum characters as possible.

    • Faction: Alliance, Horde
    • Region: US, Europe
    • Type: PvE, PvP, RP
    • Lang: EN, FR, ES, DE, RU

    The two faction and region could be stored in base 2 with no problem. However, if we wanted to store the others in base 2, there would have been space left. So i started digging up into the base conversion.

    Here is the code to do a base2 to base10 conversion.

    base10 = 0
    foreach (bit in base2) {
      base10 *= 2
      base10 += bit
    }

    As you can see, we multiply the final number by 2, which is the number of possibilities. So, instead of multiplying by 2, we multiply by the number of possible options and it works! The decoding process is using the same technique by changing the divisor.

    To get back to our example. [Alliance, US, PvP, DE] can be expressed as [0,0,1,3] over [2,2,3,5]. It will be encoded and decoded easily with the SmallHash library:

    var input = [0,0,1,3];
    var encoded = SmallHash.encode(input, [2,2,3,5], 'abcdefghijklmnopqrstuvwxyz');
    var decoded = SmallHash.decode(encoded, [2,2,3,5], 'abcdefghijklmnopqrstuvwxyz');
    console.log(input, encoded, decoded);
    // Result: [0, 0, 1, 3], "bo", [0, 0, 1, 3]

    As you can see, it fits into 2 characters instead of 4 with the easy way. The gain increases with the number of data you have to encode. This can also be improved by enlarging the base characters (uppercase letter, digits and special characters).

    The algorithm is fairly easy, it is the same one explain before but using the range instead of 2 (when converting in base 2). This is the pseudo-code version.

     
    SmallHash = {
      // encode( [2, 4], [10, 15], '0123456789' ) : '42'
      encode: function (input, ranges, base) {
        var result = 0
        for offset = ranges.length - 1 downto 0
          result = result * ranges[offset]
          result = result + input[offset]
     
        return int2str(result, base)
      },
     
      // decode( '42', [10, 15], '0123456789' ) : [2, 4]
      decode: function (input, ranges, base) {
        input = str2int(input, base)
        var result = []
     
        for offset = 0 to ranges - 1
          result[offset] = inputs % ranges[offset]
          inputs = inputs / ranges[offset]
     
        return result;
      }
    };

    return int2str(result, base)
    },

    // decode( ’42’, [10, 15], ‘0123456789’ ) : [2, 4]
    decode: function (input, ranges, base) {
    input = str2int(input, base)
    var result = []

    for offset = 0 to ranges – 1
    result[offset] = inputs % ranges[offset]
    inputs = inputs / ranges[offset]

    return result;
    }
    };

    Here is the full source code. This is the same code but being less readable due to the use of BigInt and the need of managing the allocation size.

    // Requires BigInt.js ( https://blog.vjeux.com/wp-content/uploads/2009/08/BigInt.js )
    SmallHash = {
      encode: function (input, ranges, base) {
        // Rough majoration of the final result size
        // It makes the sum of all the minimum of bits required for each range
        var size = 0;
        for (var i = 0, len = ranges.length; i < len; i = i + 1) {
          size += Math.ceil(Math.log(ranges[i]) / Math.LN2);
        }
        var result = bigInt.int2bigInt(0, size);
        for (var bit = ranges.length - 1, pos = 0; bit >= 0; bit = bit - 1, pos = pos + 1) {
          // If the value is higher than the expected range, the value is maximized
          // Therefore the result is always valid, even if the input is not
          var parsed_bit = Math.min(Math.abs(Math.floor(input[bit])), ranges[bit] - 1);
          bigInt.mult_(result, bigInt.int2bigInt(ranges[bit], 32));
          bigInt.add_(result, bigInt.int2bigInt(parsed_bit, 32));
        }
        return bigInt.bigInt2str(result, base.length, base);
      },
      decode: function (input, ranges, base) {
        input = bigInt.str2bigInt(input, base.length, base);
        var remainder = bigInt.dup(input); // Allocates enough room for the remainder
        var result = [];
        for (var pos = 0, len = ranges.length; pos < len; pos = pos + 1) {
          bigInt.divide_(input, bigInt.int2bigInt(ranges[pos], 32), input, remainder);
          result[pos] = Number(bigInt.bigInt2str(remainder, 10, '0123456789'));
        }
        return result;
      }
    };

    This script is using the BigInt library from Leemon Baird. I made some changes in order not to pollute the global namespace and added the possibility to modify the base string.

    Update January 2010 – SmallHash is now being used on production at wowtal.com and you can download the source at http://static.mmo-champion.com/db/js/smallhash.js.

    Project – Conference Delphi

    Conference Delphi

    Conference Delphi

    Together with Alban Perillat-Merceroz, we organized a one-hour presentation of the programming langage Delphi followed by 3 hours of exercises. The objective was to introduce Delphi to the students in order for them to be able to start working on their year project.

    Students had no more than two months experience of programming with Caml, a functional (opposite of imperative) language. The first part of the presentation was a comparison between the two paradigms and how to move from interpreted to compiled code. Then, a brief explanation of the various structures of the languages and how to organize files around the project has been explained.

    Even if the conference was not mandatory and took place a friday 9pm, there were about 200 students attending. They have been split into two room and attended the presentation made by Alban and myself. Right after, they moved to the computer rooms and started working on the exercises.

    The exercises focused on very basic things like function definition, for, while and structures for the most advanced. We formed a team of 15 people helping everyone out. Overall, this has been a success. You can download the Presentation Slides (Powerpoint 2007), Exercises subject (PDF) and Correction (ZIP).

    Project – CosmosUI

    CosmosUI is an open source interface modification of World of Warcraft. Many of the CosmosUI additions were later implemented by Blizzard on the default interface.

    I had been doing Warcraft III map making for more than a year when World of Warcraft has been leaked. This was really exciting to hack into the game and being able to modify it. Since I had no real programming knowledge at the time, I could not help people making a server for the game. However, I found the interface in XML and Lua really interesting and spent some time tweaking it.

    There was nothing real to do in the sandbox servers at the time, I spent some time programming MiniGames (TicTacToe, Connect 4) in the interface. I have been remarked by Thott (thottbot.com) that gave me a Beta key in order to work on the open source interface modification project he took part: CosmosUI.

    I have been working on CosmosUI during the whole beta and these are my notable additions.

    QuestMinion

    During the Beta of World of Warcraft, the only way to see your quest progression was to open the quest log and search for the quest you were doing. I made an addon that would show a summary of the quest you wanted in a small movable box located under the minimap by default, read about it on Guided Hacking Forum.

    Since I did not want to maintain a standalone version people started making addons with this concept. The most successful is MonkeyQuest downloaded 1 million times. Blizzard added later a Quest Tracker functionality to the World of Warcraft default interface that is a nearly exact copy of QuestMinion. The game Warhammer Online made the same choice for its interface.

    Quest Minion

    Quest Minion

    World of Warcraft

    World of Warcraft

    Warhammer Online

    Warhammer Online

    Addonification

    At the beginning, CosmosUI was just modifications of the World of Warcraft interface files. This was good for small modifications but once CosmosUI grew, we had to make some tricky diff every time a World of Warcraft patch was released. CosmosUI was the only interface modification at the time, so people would be without interface for about 12-24 hours while we were merging everything.

    I found a solution to this problem. Instead of modifying the actual code, we can hook the specified function and put our custom code in another file of our own.

    local thefunction_backup = thefunction
    thefunction = function (args)
      -- Do what we want before
      thefunction_backup(args)
      -- Do what we want after
    end

    I first moved my modifications out of the Blizzard code and everyone started to do so. Then a few weeks later Blizzard implemented an addon manager into the game. With the preliminary work we did, it was really easy to transform CosmosUI into an addon without any file dependency.

    Localization

    When I started working on CosmosUI, it was only available in English. Since I am French, I wanted my fellows to be able to use it in their native language.

    CosmosUI being a compilation of multiple addons, I first started to make a translation template and applied it to my own addons. Then I put all the strings of all the CosmosUI addons into their respective English translation file. And finally, I formed a translation team composed of French and German people.

    Once everything was translated, I started to advertise CosmosUI in the French community and made the technical support.

    Sky – Communication Library

    In order to make my MiniGames multiplayer, i had to transfert data between the two players. The only way at the time to achieve it was by text messages. However, they are visible to the user. My work on Sky was to automatically join a channel, hide all messages from this channel, make it invisible to the user and finally intercept the incoming messages.

    Since channels were only available with command lines, they weren’t used that much and their internal API was really buggy. Most of the job was to find workarounds for these bugs. Sometimes channels weren’t saved across sessions, they would be joined there but not listed or not joinable at all. For more information you can read the description on WoWWiki

    Quote

    Christopher was one of our top contributors on the Cosmos project, overseeing both community relationships in the French community as well as developing several mods within the community. The most revolutionary of these was the Quest Helper addon, which became so infamous and popular that Blizzard added it into their base UI. Christopher was a major contributor to the project’s culture, content and community. It would not have been the success it was without his direct contribution and passionate commitment.” April 27, 2009 — Alexander Brazie, Cosmos UI Team Leader. (LinkedIn)

    Project – Fooo

    Presentation

    Fooo is my first year school project written in Delphi. During 8 months, Vladimir Nachbaur, Alban Perillat-Merceroz, Felix Abecassis and I developed a game that mimics Warcraft III and achieved to be major of the promotion.

    We tried to make no use of copyrighted Warcraft files, however, a large majority of custom models are based on Warcraft files at some point and use some of their textures. All the interface graphic, icons, models has been made by fans and we are using them with their approbation.

    What’s the game able to do :

    • Animated 3D Models
    • Interface in XML/Lua
    • Building & Unit creation
    • Group and Subgroup management
    • Group movement with formations
    • Ranged & Melee Attacks
    • Multiplayer over LAN or Internet
    • Ingame Chat
    • 2 Races: Treants and Rats
    • And much more …

    Demonstration Video

    My work in the project

    Interface

    A RTS game is requiring a lot of user interaction, so it needs a complex interface. I decided to make an interface engine like the one used by World of Warcraft. The content is displayed through XML files and scripted with Lua. If you are not familiar with this, you can think the XML as HTML and Lua as Javascript.

    The interface engine is able to do the following:

    • Supports Frame, Texture and FontString elements
    • Ability to draw Backgrounds and Borders from images
    • Mouse and Keyboard Interaction
    • Inheritance and Virtual Frames
    • Position through 2 Anchor points (element and its relative)

    3D Engine

    The 3D Engine is written on top of OpenGL. I’ve been confronted to two major problems. The first one is the Warcraft III models: there is really few documentation on them so i had to spent quite some time to reverse engineer them and figure out how animation were working.
    The engine had to be optimized in many ways. At first, displaying one building was freezing the PC, now we are able to show more than 100 units and the game still runs smoothly.

    The 3d engine is able to do the following:

    • Animated Warcraft III Models
    • Camera: Zoom and Rotation
    • 3D Picking
    • Frustum Culling
    • Vertex Array

    Learn more

    If you want to learn more, for each presentation we made a 30 page document (french) explaining in detail the progression. You can read them at hgf.fooo.fr.

    Project – MMO-Champion Optimization

    MMO-Champion is the biggest news website of World of Warcraft. The main page is viewed millions times a month and was done with old school tables. As a result, it was really slow to load but worse, all the content had to be loaded before being displayed.

    The first thing I did was to rewrite the whole main page template using clean and valid HTML + CSS. The goal was to make it compatible up to IE6. The rendering was so much pixel perfect that nobody noticed a change when we pushed it live.

    The main challenge was to rewrite the menu. Previously, the menu was using several images that were cut in order to make it easy to implement it in CSS. However, it was a torture to add another menu. The new one is now using a single image that is basically a screenshot of the rendered menu.

    In order to save bandwidth, if the browser is supporting HTML5, instead of storing the menu state in a cookie, it is saved under the new localStorage feature.