Nicolas Cannasse Blog http://ncannasse.fr/ Blog haXe Wiki System en Flash Gaming Summit http://ncannasse.fr/blog/flash_gaming_summit http://ncannasse.fr/blog/flash_gaming_summit Wed, 3 Feb 2010 21:30:20 +0100 Wed, 3 Feb 2010 21:30:20 +0100 Nicolas Cannasse Nicolas Cannasse <p>I'm trying every year to speak at least at one international conference. Attending to a conference i...</p> <p>I'm trying every year to speak at least at one international conference. Attending to a conference is a good way to keep me updated with what's happening in the <em>real outside world</em>, and I also like to talk about my work while I'm there ;)</p> <p>I don't have much free time, I dislike airports, and I'm married : three good reasons why I'm also limiting a bit my involvement within the &quot;conference loop&quot; compared to some of my good Flash friends which are doing something like five (or more) conferences a year. </p> <p>Since I like to meet new people and learn new things, I think it's best to go as much as possible to different conferences. This year I will be very happy to speak about <a href="http://haxe.org" class="extern">haXe</a> at the <a href="http://www.flashgamingsummit.com" class="extern">Flash Gaming Summit</a> conference which takes place in San Francisco next month !</p> <p>This is a bit a side-event of the bigger Game Developer Conference 2010 so I'm sure I'll have a lot of fun there, and meet people that want to hear more about how to develop Flash games with haXe.</p> <p>See you (maybe) there !</p> haXe Community Meeting http://ncannasse.fr/blog/haxe_community_meeting http://ncannasse.fr/blog/haxe_community_meeting Tue, 26 Jan 2010 16:51:34 +0100 Tue, 26 Jan 2010 16:51:34 +0100 Nicolas Cannasse Nicolas Cannasse <p>The haXe community is having an IRC meeting on Thursday 28, make sure to make it if you want to know...</p> <p>The haXe community is having an IRC meeting on Thursday 28, make sure to make it if you want to know more about haXe and different ways you can use it !</p> <p>All details about the meeting are published here : <a href="http://haxe.org/com/meeting" class="extern">http://haxe.org/com/meeting</a></p> Playing with Sfxr http://ncannasse.fr/blog/playing_with_sfxr http://ncannasse.fr/blog/playing_with_sfxr Fri, 22 Jan 2010 16:48:51 +0100 Fri, 22 Jan 2010 16:48:51 +0100 Nicolas Cannasse Nicolas Cannasse <p>In case you don't know about it, <a href="http://www.drpetter.se/project_sfxr.html" class="extern">Sfxr</a>is a very nice library used to general sound effects, perfectly...</p> <p>In case you don't know about it, <a href="http://www.drpetter.se/project_sfxr.html" class="extern">Sfxr</a>is a very nice library used to general sound effects, perfectly suitable for independent game developers :)</p> <p>Sfxr was then ported to <a href="http://www.superflashbros.net/as3sfxr/" class="extern">AS3</a>, which was itself ported to <a href="http://www.wieringsoftware.nl/ld/sfxrhx/" class="extern">haXe</a></p> <p>I wanted to use it for one of my projects, but I was not very happy with the way it worked for Flash9 : you had to load a SWF (containing a sound and generated in-memory) each time you wanted to play a sound.</p> <p>So I modified a bit the code in order to create a SWF that contains a <code>Sfx</code> class extending which is binded to the sound data. This way you can now :</p> <ul><li>build a SWF from wave bytes</li><li>load it using <code>Loader.loadBytes</code> into a new empty <code>ApplicationDomain</code></li><li>retrieve the <code>Sfx</code> class</li><li>create a <code>flash.media.Sound</code> instance</li><li>cache it for further usage</li></ul> <p>The code uses some static data to define the AS3 class. I could have done it manually by using the <a href="http://lib.haxe.org/p/format" class="extern">haXe Format Library</a> which have full SWF+ABC support but I didn't want to add one more dependencies so did something more simple instead.</p> <p>Here's the source code for that, you can plugin it into Sfxr haXe port :</p> <pre class="haxe"><span class="kwd">static</span> <span class="kwd">var</span> AS3_DATA = &quot;s238:EAAuAAAAAAgAA1NmeAtmbGFzaC5tZWRpYQVTb3VuZAZPYmplY3QMZmxhc2guZXZlbnRzD0V2ZW50RGlzcGF0Y2hlcgUWARYDGAIWBgAFBwECBwIEBwEFBwQHAwAAAAAAAAAAAAAAAAABAQIIAwABAAAAAQIBAQQBAAMAAQEFBgPQMEcAAAEBAQYHBtAw0EkARwAAAgIBAQUX0DBlAGADMGAEMGACMGACWAAdHR1oAUcAAA&quot;; <span class="kwd">static</span> <span class="kwd">var</span> AS3_BYTES : haxe<span class="number">.</span>io<span class="number">.</span>Bytes = null; <span class="kwd">public</span> <span class="kwd">function</span> buildSWFSound<span class="op">(</span><span class="op">)</span> <span class="op">{</span> <span class="kwd">var</span> rate = <span class="kwd">switch</span><span class="op">(</span> wav_freq <span class="op">)</span> <span class="op">{</span> <span class="kwd">case</span> <span class="number">5500</span>: <span class="number">0</span>; <span class="kwd">case</span> <span class="number">11000</span>: <span class="number">1</span>; <span class="kwd">case</span> <span class="number">22000</span>: <span class="number">2</span>; <span class="kwd">case</span> <span class="number">44100</span>: <span class="number">3</span>; <span class="kwd">default</span>: <span class="kwd">throw</span> &quot;Unsupported freq &quot;+wav_freq; <span class="op">}</span>; <span class="kwd">var</span> is16Bits = <span class="kwd">switch</span><span class="op">(</span> wav_bits <span class="op">)</span> <span class="op">{</span> <span class="kwd">case</span> <span class="number">8</span>: false; <span class="kwd">case</span> <span class="number">16</span>: true; <span class="kwd">default</span>: <span class="kwd">throw</span> &quot;Unsupported bits &quot;+wav_bits; <span class="op">}</span>; <span class="kwd">var</span> stereo = stereo_pan != <span class="number">0.0</span>; <span class="kwd">var</span> wave = haxe<span class="number">.</span>io<span class="number">.</span>Bytes<span class="number">.</span>ofData<span class="op">(</span>baWave<span class="op">)</span>; <span class="kwd">var</span> swf = <span class="kwd">new</span> haxe<span class="number">.</span>io<span class="number">.</span>BytesOutput<span class="op">(</span><span class="op">)</span>; swf<span class="number">.</span>writeString<span class="op">(</span>&quot;FWS&quot;<span class="op">)</span>; swf<span class="number">.</span>writeByte<span class="op">(</span>0x09<span class="op">)</span>; <span class="comment">// version</span> <span class="kwd">var</span> o = <span class="kwd">new</span> haxe<span class="number">.</span>io<span class="number">.</span>BytesOutput<span class="op">(</span><span class="op">)</span>; <span class="kwd">for</span><span class="op">(</span> b <span class="kwd">in</span> <span class="op">[</span>0x78,0x00,0x05,0x5F,0x00,0x00,0x0F,0xA0,0x00,0x00,0x0C<span class="op">]</span> <span class="op">)</span> <span class="comment">// header</span> o<span class="number">.</span>writeByte<span class="op">(</span>b<span class="op">)</span>; o<span class="number">.</span>writeUInt16<span class="op">(</span><span class="number">1</span><span class="op">)</span>; <span class="comment">// #frames</span> <span class="comment">// Sandbox</span> o<span class="number">.</span>writeUInt16<span class="op">(</span><span class="op">(</span><span class="number">69</span> &lt;&lt; <span class="number">6</span><span class="op">)</span> | <span class="number">4</span><span class="op">)</span>; o<span class="number">.</span>writeUInt30<span class="op">(</span><span class="number">8</span><span class="op">)</span>; <span class="comment">// AS3</span> <span class="kwd">if</span><span class="op">(</span> AS3_BYTES == null <span class="op">)</span> AS3_BYTES = haxe<span class="number">.</span>Unserializer<span class="number">.</span>run<span class="op">(</span>AS3_DATA<span class="op">)</span>; o<span class="number">.</span>writeUInt16<span class="op">(</span><span class="op">(</span><span class="number">72</span> &lt;&lt; <span class="number">6</span><span class="op">)</span> | <span class="number">63</span><span class="op">)</span>; o<span class="number">.</span>writeUInt30<span class="op">(</span>AS3_BYTES<span class="number">.</span>length<span class="op">)</span>; o<span class="number">.</span>write<span class="op">(</span>AS3_BYTES<span class="op">)</span>; <span class="comment">// DefineSound tag</span> o<span class="number">.</span>writeUInt16<span class="op">(</span><span class="op">(</span><span class="number">14</span> &lt;&lt; <span class="number">6</span><span class="op">)</span> | <span class="number">63</span><span class="op">)</span>; o<span class="number">.</span>writeUInt30<span class="op">(</span><span class="number">2</span> + <span class="number">1</span> + <span class="number">4</span> + wave<span class="number">.</span>length<span class="op">)</span>; o<span class="number">.</span>writeUInt16<span class="op">(</span><span class="number">1</span><span class="op">)</span>; <span class="comment">// sound (character) ID</span> o<span class="number">.</span>writeByte<span class="op">(</span><span class="op">(</span><span class="number">3</span> &lt;&lt; <span class="number">4</span><span class="op">)</span> | <span class="op">(</span>rate &lt;&lt; <span class="number">2</span><span class="op">)</span> | <span class="op">(</span><span class="op">(</span>is16Bits?<span class="number">1</span>:<span class="number">0</span><span class="op">)</span> &lt;&lt; <span class="number">1</span><span class="op">)</span> | <span class="op">(</span>stereo?<span class="number">1</span>:<span class="number">0</span><span class="op">)</span><span class="op">)</span>; o<span class="number">.</span>writeUInt30<span class="op">(</span>wave<span class="number">.</span>length &gt;&gt; <span class="op">(</span><span class="op">(</span>is16Bits?<span class="number">1</span>:<span class="number">0</span><span class="op">)</span> + <span class="op">(</span>stereo?<span class="number">1</span>:<span class="number">0</span><span class="op">)</span><span class="op">)</span><span class="op">)</span>; <span class="comment">// samples</span> o<span class="number">.</span>write<span class="op">(</span>wave<span class="op">)</span>; <span class="comment">// data</span> <span class="comment">// SymbolClass</span> <span class="kwd">var</span> cname = &quot;Sfx&quot;; o<span class="number">.</span>writeUInt16<span class="op">(</span><span class="op">(</span><span class="number">76</span> &lt;&lt; <span class="number">6</span><span class="op">)</span> | <span class="op">(</span><span class="number">2</span> + <span class="number">2</span> + cname<span class="number">.</span>length + <span class="number">1</span><span class="op">)</span><span class="op">)</span>; o<span class="number">.</span>writeUInt16<span class="op">(</span><span class="number">1</span><span class="op">)</span>; <span class="comment">// 1 class</span> o<span class="number">.</span>writeUInt16<span class="op">(</span><span class="number">1</span><span class="op">)</span>; <span class="comment">// sound ID</span> o<span class="number">.</span>writeString<span class="op">(</span>cname<span class="op">)</span>; o<span class="number">.</span>writeByte<span class="op">(</span><span class="number">0</span><span class="op">)</span>; <span class="comment">// ShowFrame</span> o<span class="number">.</span>writeUInt16<span class="op">(</span><span class="op">(</span><span class="number">1</span> &lt;&lt; <span class="number">6</span><span class="op">)</span> | <span class="number">0</span><span class="op">)</span>; <span class="comment">// end tag</span> o<span class="number">.</span>writeUInt16<span class="op">(</span><span class="number">0</span><span class="op">)</span>; <span class="comment">// finalize</span> <span class="kwd">var</span> swfbytes = o<span class="number">.</span>getBytes<span class="op">(</span><span class="op">)</span>; swf<span class="number">.</span>writeUInt30<span class="op">(</span> swfbytes<span class="number">.</span>length + <span class="number">8</span> <span class="op">)</span>; <span class="comment">// filesize</span> swf<span class="number">.</span>write<span class="op">(</span>swfbytes<span class="op">)</span>; <span class="kwd">return</span> swf<span class="number">.</span>getBytes<span class="op">(</span><span class="op">)</span>; <span class="op">}</span> #<span class="kwd">if</span> flash9 <span class="kwd">static</span> <span class="kwd">var</span> cache = <span class="kwd">new</span> <span class="type">Hash</span>&lt;flash<span class="number">.</span>media<span class="number">.</span>Sound&gt;<span class="op">(</span><span class="op">)</span>; <span class="kwd">static</span> <span class="kwd">var</span> pendingLoaders = <span class="kwd">new</span> <span class="type">List</span><span class="op">(</span><span class="op">)</span>; <span class="kwd">public</span> <span class="kwd">static</span> <span class="kwd">function</span> play<span class="op">(</span> settings : <span class="type">String</span>, ?delay : <span class="type">Float</span> = <span class="number">0</span> <span class="op">)</span> <span class="op">{</span> <span class="kwd">var</span> sound = cache<span class="number">.</span>get<span class="op">(</span>settings<span class="op">)</span>; <span class="kwd">if</span><span class="op">(</span> sound != null <span class="op">)</span> <span class="op">{</span> sound<span class="number">.</span>play<span class="op">(</span>delay<span class="op">)</span>; <span class="kwd">return</span>; <span class="op">}</span> <span class="kwd">var</span> s = <span class="kwd">new</span> Sfxr<span class="op">(</span><span class="op">)</span>; s<span class="number">.</span>setSettingsString<span class="op">(</span>settings<span class="op">)</span>; s<span class="number">.</span>generate<span class="op">(</span><span class="op">)</span>; <span class="kwd">var</span> timer = haxe<span class="number">.</span>Timer<span class="number">.</span>stamp<span class="op">(</span><span class="op">)</span>; <span class="kwd">var</span> l = <span class="kwd">new</span> flash<span class="number">.</span>display<span class="number">.</span>Loader<span class="op">(</span><span class="op">)</span>; pendingLoaders<span class="number">.</span>add<span class="op">(</span>l<span class="op">)</span>; <span class="kwd">var</span> domain = <span class="kwd">new</span> flash<span class="number">.</span>system<span class="number">.</span>ApplicationDomain<span class="op">(</span><span class="op">)</span>; l<span class="number">.</span>contentLoaderInfo<span class="number">.</span>addEventListener<span class="op">(</span>flash<span class="number">.</span>events<span class="number">.</span>Event<span class="number">.</span>INIT,<span class="kwd">function</span><span class="op">(</span>_<span class="op">)</span> <span class="op">{</span> pendingLoaders<span class="number">.</span>remove<span class="op">(</span>l<span class="op">)</span>; <span class="kwd">var</span> cl : <span class="type">Class</span>&lt;flash<span class="number">.</span>media<span class="number">.</span>Sound&gt; = domain<span class="number">.</span>getDefinition<span class="op">(</span>&quot;Sfx&quot;<span class="op">)</span>; cache<span class="number">.</span>set<span class="op">(</span>settings,<span class="type">Type</span>.createInstance<span class="op">(</span>cl,<span class="op">[</span><span class="op">]</span><span class="op">)</span><span class="op">)</span>; delay -= haxe<span class="number">.</span>Timer<span class="number">.</span>stamp<span class="op">(</span><span class="op">)</span> - timer; <span class="kwd">if</span><span class="op">(</span> delay &lt; <span class="number">0</span> <span class="op">)</span> delay = <span class="number">0</span>; play<span class="op">(</span>settings,delay<span class="op">)</span>; <span class="op">}</span><span class="op">)</span>; l<span class="number">.</span>loadBytes<span class="op">(</span>s<span class="number">.</span>buildSWFSound<span class="op">(</span><span class="op">)</span>.getData<span class="op">(</span><span class="op">)</span>,<span class="kwd">new</span> flash<span class="number">.</span>system<span class="number">.</span>LoaderContext<span class="op">(</span>null,domain<span class="op">)</span><span class="op">)</span>; <span class="op">}</span> #end</pre><br/> Getting Some Numbers http://ncannasse.fr/blog/getting_some_numbers http://ncannasse.fr/blog/getting_some_numbers Thu, 21 Jan 2010 00:00:33 +0100 Thu, 21 Jan 2010 00:00:33 +0100 Nicolas Cannasse Nicolas Cannasse <p>Some people often ask me what are the advantages of haXe in terms of speed.</p> <p>Of course, there are man...</p> <p>Some people often ask me what are the advantages of haXe in terms of speed.</p> <p>Of course, there are many runtime optimizations in haXe that make your program run faster, but one of the very important thing to me is also the speed of the compiler. Compiling quickly help you to test some minor changes more often, to find and fix errors faster, and prevent you from losing your concentration and your time waiting for the compiler to be done with its work.</p> <p>So what about comparing haXe and AS3 compilers speed ?</p> <p>First, haXe starts with an obvious disadvantage : because it has <em>type inference</em>, <em>structural subtyping</em> and <em>generics</em>, the compiler needs to perform much more type checks that in more classical type system such as AS3 one.</p> <p>But let's see how it rates anyway.</p> <p>I tried the following : compiling the whole <a href="http://code.google.com/p/hxformat" class="extern">hx-format</a> library, which is 64 files / 10.000 lines / 300KB of haXe to Flash9. Here's the commandline for that :</p> <pre>time haxe -swf9 format.swf -cp hxformat/tests/all All.hx</pre> <p>On my QuadCore (haXe compiler does not yet use multicores, that's something we need to fix btw) the command run in <code>0.31</code> seconds which is a decent enough.</p> <p>Now, I'm generating the corresponding AS3 output by using :</p> <pre>haxe -as3 format_as3 -cp hxformat/tests/all All.hx</pre> <p>(a small fix was needed in <code>format.amf.Reader</code> since some expression is not accepted by AS3 generator, but well...)</p> <p>Then here we go with the AS3 compilation. This was actually a bit hard, because I found that the <code>format.swf.Namespace</code> class is actually a reserved name, so had to do a bit of renaming here and there, then the <code>mxmlc</code> compiler crashed when compiling <code>format.mp3.MPEG</code> (but maybe I'm not up-to-date), and I had to recreate a <code>All.as</code> file that would ensure that all files will get compiled (since <code>import</code> in AS3 is <em>lazy</em> while it's not in haXe), and so some other minor fixes. Took me 15 minutes but I was able to compile everything except <code>format.mp3</code> package.</p> <p>So at last here we go :</p> <pre>mxmlc --output all.swf -compiler.optimize All.as</pre> <p>Took... 3.3 seconds on my QuadCore</p> <p>So, even if we take out something like 1 second for JVM startup (<code>mxmlc</code> is Java) then we still have haXe which is... <b>7x faster</b> than <code>mxmlc</code> ?</p> <p>Now, that's just a benchmark, I would be happy if other people could try the same with their own project to see if I'm accurate enough or not, but this seems to confirm that indeed, haXe is fast !</p> <p>(anybody who remember <a href="http://mtasc.org" class="extern">no more coffee break while compiling</a> ?)</p> Adobe Promoting haXe ? http://ncannasse.fr/blog/adobe_promoting_haxe http://ncannasse.fr/blog/adobe_promoting_haxe Sun, 27 Dec 2009 20:35:01 +0100 Sun, 27 Dec 2009 20:35:01 +0100 Nicolas Cannasse Nicolas Cannasse <p>First, merry christmas, and (soon) happy new year too all of you !</p> <p>Seems like Adobe recently made so...</p> <p>First, merry christmas, and (soon) happy new year too all of you !</p> <p>Seems like Adobe recently made some pages about game development in Flash as part of the Developer resources. Named <a href="http://www.adobe.com/devnet/games/" class="extern">Flash Platform Game Technology Center</a>, they list some &quot;featured&quot; games that were made in Flash and are showing good use of the technology.</p> <p>I was surprised that the first featured game was <a href="http://www.adobe.com/devnet/games/examples/index.html#scary" class="extern">ScaryGirl</a> : not because this is a bad game - Scarygirl is a very nice game, congratulations to the TouchMyPixel team for it - but because it's entirely written in <a href="http://haxe.org" class="extern">haXe</a> as stated on the <a href="http://www.touchmypixel.com/?request=Project&amp;id=2" class="extern">developers page</a> :-)</p> <p>Anyway, have a look a the game, it's a very good one, and it shows that serious people are using haXe for &quot;real stuff&quot; (so do I, and many other developers as well).</p> <p>Oh and just a small note : we have recently been moving haXe from its old CVS repository to a brand new <a href="http://code.google.com/p/haxe" class="extern">google code SVN</a>. You can browse the source code and report issues / features requests there.</p> <p>Enjoy !</p> <p><b>EDIT</b> maybe I was a bit too fast, someone noticed me that the developers comment were talking about the Scarygirl website that is written in 100% haXe. Only parts of the game itself are in haXe as a <a href="http://lists.motion-twin.com/pipermail/haxe/2009-April/024510.html" class="extern">previous mail</a> of Tony was talking about ;)</p> CS5 iPhone Support http://ncannasse.fr/blog/cs5_iphone_support http://ncannasse.fr/blog/cs5_iphone_support Sat, 10 Oct 2009 10:39:15 +0200 Sat, 10 Oct 2009 10:39:15 +0200 Nicolas Cannasse Nicolas Cannasse <p>As announced at Adobe MAX conference, Flash CS5 will have the ability to output iPhone binaries dire...</p> <p>As announced at Adobe MAX conference, Flash CS5 will have the ability to output iPhone binaries directly (read <a href="http://www.flashmagazine.com/news/detail/flash_for_the_iphone/" class="extern">FlashMagazine Article</a> about it).</p> <p>I don't have much details on how it's done, but here's my guess based on what I've been reading : Adobe have built a SWF Bytecode-to-C converter (maybe using <a href="http://llvm.org" class="extern">LLVM</a> which was already used for Alchemy), then are using a <a href="http://en.wikipedia.org/wiki/Cross_compiler" class="extern">cross compiler</a> such as a modified version of GCC in order to link together this C code and a static library containing the Flash Player for iPhone.</p> <p>This way there is no runtime interpretation of the SWF Bytecode, everything is &quot;native&quot;.</p> <p><a href="http://haxe.org" class="extern">haXe</a> already has a haXe/C++ target which enable in particular to <a href="http://gamehaxe.com/2009/07/28/haxe-iphone-cpp-at-last/" class="extern">target the iPhone</a>, so what are the differences between the two methods ?</p> <p>First, I'm pretty sure that you will be able to use SWC in iPhone projects in CS5 (or else that would be a too much crippled feature). And since haXe allow you to output reusable SWC, it means that you will be able to use haXe together with this CS5 feature.</p> <p>However, in that case (or if you are using AS3) you are still targeting the Flash Player. You will have additional API to handle touch screen, but you will mainly be limited by what the Flash Player gives you. In particular, that mean that you will not be able to access OpenGL ES API, etc.</p> <p>This is the main difference with haXe/C++ way of doing things.</p> <p>haXe/C++ allow you to natively target the iPhone (and all other devices that can be programmed with C++ BTW). And in order to ease the from-Flash transition, some API of the Flash Player have been ported to C++ in order to reproduce their behavior.</p> <p>But with haXe/C++ you are no longer limited by the Flash Player : you can directly access to all the API provided by the iPhone, and in terms of graphics capabilities you don't have to go through the Flash Player API, which is good when you want to abstract things, but bad if you want to get best performances or innovative visual effects.</p> <p>So in the end it's nice to have the choice : either use CS5 feature to be able to directly run your unmodified apps on the iPhone, or if you really want to be able to &quot;hack&quot; the iPhone and use its native capabilities, use haXe/C++ for that.</p> Open Source and Morality http://ncannasse.fr/blog/open_source_and_morality http://ncannasse.fr/blog/open_source_and_morality Wed, 30 Sep 2009 19:11:02 +0200 Wed, 30 Sep 2009 19:11:02 +0200 Nicolas Cannasse Nicolas Cannasse <p>Joa Ebert is questioning on <a href="http://blog.joa-ebert.com/2009/09/29/taas-as-a-decompiler/" class="extern">his blog</a> whereas having an open source decompiler/obfuscator software wo...</p> <p>Joa Ebert is questioning on <a href="http://blog.joa-ebert.com/2009/09/29/taas-as-a-decompiler/" class="extern">his blog</a> whereas having an open source decompiler/obfuscator software would make sense.</p> <p>I can maybe help a bit with this choice, since I was confronted to the same one a few years ago. At this time I wrote an AS2 decompiler as well as a SWF obfuscator that we are still using at Motion-Twin.</p> <p>People that have met me know that I'm a big proponent of open source and open protocols, so why didn't I open sourced these software after writing them ? There are good reasons behind these choices.</p> <h1>Decompilers</h1> <p>While decompilers are a very good tool for the expert to learn about the way a given compiler can optimize code, in the hand for the average user they are mainly used to look through other people code.</p> <p>I'm all for open source and code sharing, but I think that someone should get the original developer agreement before looking at his code. I don't consider that decompiling is the same as stealing, since the original code is not lost in any way (this is somehow similar to downloading an MP3) but in practice, you will often find people decompiling for the sake of just copying, only because they are too lazy to solve a given problem or because they have a deadline and just don't care reusing someone else work without asking.</p> <p>While an open source decompiler is a great tool for hackers (but in that case a disassembler is already quite enough), it becomes an immoral tool in the hands of mister everybody. So I guess that from a moral point of view, an open source decompiler would not fit any particular &quot;good usage&quot;.</p> <h1>Obfuscator</h1> <p>Somehow the entire opposite from the previous one, since the only usage one might have from an obfuscator is to protect his code from being decompiled.</p> <p>Some side story : in early 2009 I have been working on an Flash9 obfuscator prototype that is working nicely. We thought to sell it by making a partnership with PowerFlasher (the company behind FDT IDE) but we found that using the software was hard and required a good knowledge of the theory being a virtual machine, as well as many code changes in some cases. We then recently decided to not push further the project, although we will be using the obfuscator in-house at Motion-Twin for our Flash9/10 projects.</p> <p>So yes, I have no problem with selling an obfuscator software. Since I think that it should be the developer choice to either share its software or not, one should also have the choice to protect himself from people using decompilers.</p> <p>However, I'm having a problem with the idea of an open source obfuscator, since the two ideas of &quot;open source&quot; and &quot;protecting your code&quot; are clearly opposite.</p> <p>Also, I don't think that people should be encouraged to protect their code, and I don't think that someone should provide them an easy+free way of doing so. Because the best people feel their code is &quot;secure&quot; the more they will be sensible to their code being &quot;reused&quot;, even if it's not at all the same code but the same behavior or same principles.</p> <p>I think that developers in general should first focus on improving their skills instead of thinking about protecting the things they have been written and that almost nobody would actually like to copy. </p> <p>Obfuscators and similar technologies are putting too much emphasis on the notion of property of code, and since I'm also a big opponent to software patents, I don't want such ideas to become mainstream : we don't have software patents in Europe and this is something that we should really defend.</p> <p>Of course obfuscators don't have anything to do directly with software patents, but at the same time first someone might want his code to be protected, then later he want not only that, but also the ideas behind his code to be protected. And that's where software patents start being a problem.</p> <p>There are still a few valid reasons to use obfuscators : for instance we are mainly using it not to protect our games implementation (because we don't care) but to protect the protocols used to save the score or exchange data between client and server, since we don't want these to be exploited by malicious players that would ruin the fun of other players (such exploits are not possible in secured games when the server handle the gamelogic, but for arcade games you don't really have the choice).</p> <p>In conclusion, this is not because your are making an open source software that you are doing a &quot;good thing&quot;. There are some cases where helping a software go mainstream can actually go against what you were thinking at first. Open Source and (sense of) Morality are two different things, but when combined they become extremely powerful.</p> <p>And I guess that's all I had to say on the subject :)</p> The failure of AS3 ? http://ncannasse.fr/blog/the_failure_of_as3 http://ncannasse.fr/blog/the_failure_of_as3 Sat, 8 Aug 2009 01:06:05 +0200 Sat, 8 Aug 2009 01:06:05 +0200 Nicolas Cannasse Nicolas Cannasse <p>Back in October 2005, Macromedia (later bought by Adobe) announced the Flash Player 8.5 Beta which w...</p> <p>Back in October 2005, Macromedia (later bought by Adobe) announced the Flash Player 8.5 Beta which would include support for a new programming language : ActionScript3 (AS3).</p> <p>The player 8.5 - which was named this way not to frighten customers that just bought Flash 8 IDE - will later be renamed as Flash Player 9 and AS3 became the default programming language for Flash and Flex - replacing the previous AS2 - with the release of Flash CS3 Pro in April 2007.</p> <p>Now, more than two years later, it's maybe time to check if AS3 was a success, or a failure.</p> <h1>AS3, a proprietary language ?</h1> <p>One of the promises of AS3 was to get out of the whole &quot;proprietary language&quot; thing.</p> <p>Traditionally, Flash has always been criticized of being a closed-source platform (which it is) thus threatening one of the most beautiful and important things in the Web technology today which is openness : openness of protocols (TPC/IP, HTTP), formats (HTML, CSS) and browsers (Firefox and many others). Versus a full proprietary Flash platform, including an unkown programming language named &quot;ActionScript&quot;.</p> <p>The idea of AS3 was then to be based on the ECMAScript4 specification that was in the works and was supposed to become the next Javascript : Javascript2.</p> <p>Sadly, since making a full programming language specification takes time, and is then not compatible with business agenda, ActionScript3 was released way before the EcmaScript4 specification was made available, and at the time the final ES4 spec was released, AS3 was already no longer compatible with it.</p> <p>Furthermore, the whole EcmaScript4 process was stopped later due to political struggles between the major browser vendors (read my <a href="/blog/ecmascript_disharmony" class="intern">other post</a> about it).</p> <p>Of course, it's important to note that the AS3 compiler and the Tamarin Virtual Machine which run it were open sourced, which is of course better than nothing. But that is not what differentiate a proprietary language from an open one.</p> <p>An open language has to be community-driven : people have to be able to express directly how they feel about it, and get answers to questions they might have about the way the language is designed and the way this particular feature works.</p> <p>Also, the most technical users should be able to report bugfixes directly, and eventually provide full new features that have to be reviewed in decent time before getting included or rejected with a valid reason.</p> <p>An open language is not about just opening the sources, it's about opening the process of designing and evolving the language.</p> <p>So, here we are two years later : ActionScript3 is still a proprietary language, which evolution and control is entirely in the hands of Adobe.</p> <h1>AS3, better than AS2 ?</h1> <p>One of the major things that AS3 bring's with it is a whole new API for managing flash content. Entirely redesigned to be more practical, it should have greatly improved ease of programming for developers, versus AS2 which was hacked on top of AS1, with strange API coming from Flash 4 and even before that.</p> <p>I mean, when you decide to redesign something from scratch without taking care about backward compatibility, you have an infinite freedom to design things the best way they should be.</p> <p>One of the area where AS3 is definitely better than AS2 is speed : performances were greatly improved, and that's a very good thing.</p> <p>However, in terms of usability, there was a lot of complains of &quot;old school&quot; flashers that had to write much more code in AS3 than in AS2 just to do exactly the same thing. Some might think it's pure conservatism : old men don't like when things are not in the place they were used to be. That might be true sometimes, but there's always some truth when so much people complain about API usability.</p> <p>For example - I'm playing the devil advocate of course - but could someone explain me the advantage of writing the following in AS3 :</p> <pre class="haxe">mc<span class="number">.</span>addEventListener<span class="op">(</span>MouseEvent<span class="number">.</span>CLICK,<span class="kwd">function</span><span class="op">(</span>e:MouseEvent<span class="op">)</span> <span class="op">{</span> <span class="op">}</span><span class="op">)</span>;</pre> <p>Against the following equivalent in AS2 ?</p> <pre class="haxe">mc<span class="number">.</span>onClick = <span class="kwd">function</span><span class="op">(</span><span class="op">)</span> <span class="op">{</span> <span class="op">}</span></pre> <p>Oh, I can hear you : listeners are very powerful, you can add several of them on the same object !</p> <p>Right...</p> <p>But how much probability do you have to need several click handlers on the same MovieClip ? Maybe one every hundred ? Or did you EVER need that ?</p> <p>I'm not paid for programming on a per-line-of-code salary, I want simple things to be simple to write as well.</p> <p>In terms of API design, IMHO AS3 went the wrong way : instead of making things that you write often be simple, the API gives you the power to make complex things, but simple things become very difficult and painful to write.</p> <h1>AS3, a full OO language ?</h1> <p>A third point were AS3 was supposed to shine was about being a &quot;modern&quot; programming language, with a full Object Oriented system, classes, real types, etc.</p> <p>The issue is that for AS3 designers, a modern OO type system equals Java.</p> <p>And not the latest Java with <a href="http://en.wikipedia.org/wiki/Generics_in_Java" class="extern">generics</a> and many more features. No. The original Java, back from 1995, when at this time Java was already way behind many features experimented in research programming languages.</p> <p>As a game developer, I enjoy the speed that a static type system can bring. I'm also a big proponent of strict type systems since as much type checking work the compiler do instead of me, as much I can focus on actually programming.</p> <p>But the Java type system lacks one huge thing : expressiveness.</p> <p>This is an axiom : the more the type system of a programming language is restrictive, the more people will try to bypass it by NOT using the type system, but instead Object and unsafe casts.</p> <p>And the axiom reciprocity : the more the type system of a programming language is expressive, the more people can rely on it and the less &quot;architecture overhead&quot; there is.</p> <p>Right now a lot of people are hating Java for its lack of expressiveness. Sadly, people are thinking that dynamically typed languages such as Ruby are the solution, whereas there are strictly typed languages which are much more expressive than Java...</p> <p>The lack of many language features in AS3 such as generics, inlining, function-types, enums... have brought many developers to complain about the language. A language which has not evolved in the slightest since 2006. Some people really hate it now, and can you work daily with a language that you dislike ? Not if you have the choice...</p> <p>I personally think that especially in the programming language design area - where I'm the most active - AS3 is a failure : it brings too much strict OO principles to satisfy people that prefer &quot;scripting&quot; procedural languages such as AS1/2, but fail to deliver in expressiveness for people that want actual features in that area.</p> <p>AS3 is sick of the want-to-be-Java disease, and that's not one that you can easily cure.</p> <h1>What's next ?</h1> <p>I must admit that I'm biased in that review, and I haven't been using so much AS3 myself. I've mostly spent the last three years designing and programming in haXe.</p> <p>But I'm also listening to what people are saying, in conferences, on blogs, around me. And I wanted to put into words the feelings of the actual AS3 users out there, with my own analysis of why we got there.</p> <p>Sadly, I don't think that AS3 can be fixed, or it might take years. Adobe has other priorities than listening to perfectionists developers, and they are masses of Flash customers out there that just don't care at all, maybe because they do programming only as a job without any notion of pleasure inside it.</p> <p>But since I don't like AS3 and was for long time interested in programming language design and compilers, I came up with my own solution to this problem : after MTASC, I designed a language called <b>haXe</b> and wrote a compiler which can compile it to Flash Player 6-8 and 9+, and can then act as replacement for both AS2 and AS3.</p> <p>Since the initial release of haXe, a lot of people have been contributing to it, making it a real community-driven programming language, which include many features that are not in AS3.</p> <p>So instead of suffering in silence, I invite you programmers to act : give a try to haXe, adopt it if you like it, and join our very active users community.</p> <p>The language is maybe not perfect, but it's evolving quickly.</p> <p>We know that it still lacks documentation, but that something that's getting better and better over time.</p> <p>I can't guarantee that you will enjoy programming in haXe better than in AS3, but I know a lot of people that made the switch and don't want to go back.</p> <p>Just do something to help yourself.</p> <p>To be more happy everyday when programming.</p> <p>Try <a href="http://haxe.org" class="extern">haXe</a></p> <p>--</p> <p>PS : In case you doubt it, this is not an advertising, since I'm not getting a single Euro out of it, this is just a advice from a fellow developer ;)</p> Step by step Guide for haXe/iPhone http://ncannasse.fr/blog/step_by_step_guide_for_haxe_iphone http://ncannasse.fr/blog/step_by_step_guide_for_haxe_iphone Wed, 29 Jul 2009 15:57:34 +0200 Wed, 29 Jul 2009 15:57:34 +0200 Nicolas Cannasse Nicolas Cannasse <p>Hugh Sanderson have blogged a complete step-by-step Guide to get started developing on the iPhone wi...</p> <p>Hugh Sanderson have blogged a complete step-by-step Guide to get started developing on the iPhone with haXe :</p> <p>Read it <a href="http://gamehaxe.com/2009/07/28/haxe-iphone-cpp-at-last/" class="extern">here</a></p> haXe 2.04 with C++ support http://ncannasse.fr/blog/haxe_2.04 http://ncannasse.fr/blog/haxe_2.04 Sun, 26 Jul 2009 20:08:07 +0200 Sun, 26 Jul 2009 20:08:07 +0200 Nicolas Cannasse Nicolas Cannasse <p>Today haXe 2.04 was released.</p> <p>Thanks to the hard work of <a href="http://gamehaxe.com" class="extern">Hugh Sanderson</a>, haXe now have support for t...</p> <p>Today haXe 2.04 was released.</p> <p>Thanks to the hard work of <a href="http://gamehaxe.com" class="extern">Hugh Sanderson</a>, haXe now have support for the C++ platform.</p> <p>It then mean that you can compile any haXe program directly to C++, and get the performances of the one of the world fastest languages ! C++ support open also a lot of new possibilities for haXe targets, including huge progress <a href="http://gamehaxe.com/2009/05/27/haxe-on-real-iphone" class="extern">on running haXe on iPhone</a></p> <p>In order to use the C++ platform, you will have to use the <code>-cpp</code> target, but before that you need to install the <code>hxcpp</code> library that contains all things needed to compile. This is easily done by running the following command :</p> <pre>haxelib install hxcpp</pre> <p>Now, you can simply write a small haXe program :</p> <pre class="haxe"><span class="kwd">class</span> Test <span class="op">{</span> <span class="kwd">static</span> <span class="kwd">function</span> main<span class="op">(</span><span class="op">)</span> <span class="op">{</span> trace<span class="op">(</span>&quot;Hello World !&quot;<span class="op">)</span>; <span class="op">}</span> <span class="op">}</span></pre> <p>And compile it with :</p> <pre>haxe -cpp out -main Test</pre> <p>This will give you a file <code>out/Test.exe</code> that when run will simply display <code>Hello World</code>.</p> <p>Easy, isn't it ?</p> <p>In order to go further, you can use the APIs that have been made accessible from haXe/C++, they are fully listed on the <a href="http://haxe.org/api/cpp" class="extern">haXe API pages</a>.</p> <p>It's of course possible to interoperate with other C++ programs, but these details will be soon documented.</p> <p>Actually, C++ is the 6th platform supported by haXe, since there is already :</p> <ul><li>Flash (for Flash Player versions &lt;=8)</li><li>Flash9 (AVM2, for Flash Player versions &gt;= 9)</li><li>Javascript</li><li><a href="http://nekovm.org" class="extern">Neko</a></li><li>PHP</li><li>... and now C++</li></ul> <p>Which will be next one ? ;)</p>