{"id":665,"date":"2012-07-12T16:59:52","date_gmt":"2012-07-12T15:59:52","guid":{"rendered":"http:\/\/www.aymericlamboley.fr\/blog\/?p=665"},"modified":"2014-11-01T14:53:39","modified_gmt":"2014-11-01T13:53:39","slug":"citrus-engine-on-nape-and-physics-performance-improvement","status":"publish","type":"post","link":"http:\/\/www.aymericlamboley.fr\/blog\/citrus-engine-on-nape-and-physics-performance-improvement\/","title":{"rendered":"Citrus Engine on Nape and physics performance improvement"},"content":{"rendered":"<p>Hi folks! Since my studies are over and my new <a href=\"http:\/\/www.aymericlamboley.fr\/\" target=\"_blank\">portfolio<\/a> online, I have time to focus on personal projects. Yep, it was time to contribute again to the <a href=\"http:\/\/citrusengine.com\/\" target=\"_blank\">Citrus Engine<\/a>. I&#8217;ve worked 3 days at full time focusing on its big issue : mobile performances. I&#8217;m glad to say that now they are just an old memories!<\/p>\n<p><a href=\"http:\/\/www.aymericlamboley.fr\/blog\/citrusengine-goes-stage3d-with-starling\/\" target=\"_blank\">6 months ago, I&#8217;ve made the CE compatible with Stage3D thanks to Starling and added some cool stuff<\/a>. CitrusEngineV3 BETA 1 has been downloaded 3047 in 6 months, that&#8217;s not bad! However it didn&#8217;t see lots of Stage3D game, because it was missing the point : people wants to make mobile games.<\/p>\n<p><em>You will find all the sources at the end.<\/em><\/p>\n<p><!--more--><\/p>\n<p><strong>Nape<\/strong><br \/>\n<em><a href=\"http:\/\/deltaluca.me.uk\/docnew\/\" target=\"_blank\">Nape<\/a> is <a href=\"http:\/\/deltaluca.me.uk\/\" target=\"_blank\">Luca Deltodesco<\/a>&#8216;s open-source physics engine written in haXe with the help of his preprocessor caXe. It is written with AVM2 in mind for performance, and utilising another part of his build chain provides a seamless API between AS3 and haXe though it does compile with hxcpp with other targets unknown. The idea behind Nape is to provide a high-performance, powerful and moreover friendly and safe physics engine.<\/em><\/p>\n<p>Nape is faster than Box2D, and easier to handle. Adding it in the CE wasn&#8217;t hard, and we use it the same way than Box2D. Using Box2D (Alchemy version) &#038; Stage3D with Starling in the CE you must take a look on <a href=\"http:\/\/www.adobe.com\/devnet\/flashplayer\/articles\/premium-features.html\" target=\"_blank\">Adobe Flash Player Premium announcement<\/a> if you are targetting Browser games. With Nape, you are no more related to the &#8220;premium features license&#8221; from Adobe.<\/p>\n<p>A NapeStarlingGameState Class exemple :<\/p>\n<pre lang=\"actionscript3\" line=\"1\">package  \r\n{\r\n\timport com.citrusengine.core.StarlingState;\r\n\timport com.citrusengine.objects.NapePhysicsObject;\r\n\timport com.citrusengine.objects.platformer.nape.Platform;\r\n\timport com.citrusengine.physics.Nape;\r\n\t\r\n\timport starling.display.Image;\r\n\timport starling.events.Touch;\r\n\timport starling.events.TouchEvent;\r\n\timport starling.events.TouchPhase;\r\n\timport starling.textures.Texture;\r\n\t\r\n\t\/**\r\n\t * ...\r\n\t * @author Aymeric\r\n\t *\/\r\n\tpublic class NapeStarlingGameState extends StarlingState \r\n\t{\r\n\t\t[Embed(source=\"..\/bin\/small_crate.png\")]\r\n\t\tprivate var _cratePng:Class;\r\n\t\t\r\n\t\tpublic function NapeStarlingGameState() \r\n\t\t{\r\n\t\t\tsuper();\r\n\t\t}\r\n\t\t\r\n\t\toverride public function initialize():void {\r\n\t\t\t\r\n\t\t\tsuper.initialize();\r\n\t\t\t\r\n\t\t\tvar nape:Nape = new Nape(\"nape\");\r\n\t\t\t\/\/nape.visible = true; -> to see the debug view!\r\n\t\t\tadd(nape);\r\n\t\t\t\r\n\t\t\tadd(new Platform(\"borderBottom\", { x:0, y:stage.stageHeight - 10, width:stage.stageWidth, height:10 } ));\r\n\t\t\tadd(new Platform(\"borderLeft\", { x:0, y:0, width:10, height:stage.stageHeight } ));\r\n\t\t\tadd(new Platform(\"borderRight\", { x:stage.stageWidth - 10, y:0, width:10, height:stage.stageHeight } ));\r\n\t\t\t\r\n\t\t\tstage.addEventListener(TouchEvent.TOUCH, _addObject);\r\n\t\t}\r\n\t\t\r\n\t\tprivate function _addObject(tEvt:TouchEvent):void {\r\n\t\t\t\r\n\t\t\tvar touch:Touch = tEvt.getTouch(stage, TouchPhase.BEGAN);\r\n\t\t\t\r\n\t\t\tif (touch) {\r\n\t\t\t\t\r\n\t\t\t\tvar image:Image = new Image(Texture.fromBitmap(new _cratePng()));\r\n\t\t\t\r\n\t\t\t\tvar physicObject:NapePhysicsObject = new NapePhysicsObject(\"physicobject\", { x:touch.getLocation(this).x, y:touch.getLocation(this).y, width:35, height:38, view:image} );\r\n\t\t\t\tadd(physicObject);\r\n\t\t\t}\r\n\t\t\t\r\n\t\t}\r\n\t\t\r\n\t}\r\n\r\n}<\/pre>\n<p>There wouldn&#8217;t be any CE&#8217;s API difference if you used Box2D (except for package\/class names).<\/p>\n<p><strong>Bad mobile performances&#8217; end<\/strong><br \/>\nSo Nape was amazing powerful in the CE? Yes and no. The performance was better than Box2D, but not as good as I&#8217;d like. Troubled, I started thinking there was a bad &#8220;architecture&#8221; in the Citrus Engine&#8230; and there was one. The solution came from my <a href=\"http:\/\/haxe.org\/\" target=\"_blank\">Haxe<\/a> <a href=\"http:\/\/www.haxenme.org\/\" target=\"_blank\">NME<\/a> <a href=\"https:\/\/github.com\/alamboley\/CitruxEngine\" target=\"_blank\">port<\/a>, or more precisely a simple Box2D&#8217;s Haxe NME project on my desktop. This one had better performance than my port, on very simple test. The Box2D&#8217;s debug view changed object&#8217;s color after some time ; not on mine! Sleeping object&#8230; something prevented objects to sleep. After some investigations, it was the way how gravity was settled : no gravity in World\/Space but one applied on each dynamic objects :<\/p>\n<pre lang=\"actionscript3\">\/**\r\n * You should override this method to extend the functionality of your physics object. This is where you will \r\n * want to do any velocity\/force logic. By default, this method also updates the gravitatonal effect on the object.\r\n * I have chosen to implement gravity in each individual object instead of globally via Box2D so that it is easy\r\n * to create objects that defy gravity (like birds or bullets). This is difficult to do naturally in Box2D. Instead,\r\n * you can simply set your PhysicsObject's gravity property to 0, and baddabing: no gravity. \r\n *\/\t\t\r\noverride public function update(timeDelta:Number):void\r\n{\r\n\tif (_bodyDef.type == b2Body.b2_dynamicBody)\r\n\t{\r\n\t\tvar velocity:V2 = _body.GetLinearVelocity();\r\n\t\tvelocity.y += gravity;\r\n\t\t_body.SetLinearVelocity(velocity);\r\n\t}\r\n}<\/pre>\n<p>Easier to manage different objects&#8217; gravity, but no sleeping objects. Now the gravity is set in the World\/Space creation and this update function is empty. That was it!<\/p>\n<p><strong>Performance tests<\/strong><br \/>\nOk now everything is correct, it&#8217;s time to give some numbers! Don&#8217;t hesitate to give yours! The tests are based on the code above and use an iPhone 4S.<br \/>\nCitrus Engine with Starling &#038; Box2D : 50 dynamic objects = 50FPS.<br \/>\nCitruxEngine with Box2D : 67 dynamic objects = 50FPS.<br \/>\nCitrus Engine with Starling &#038; Nape : 80 dynamic objects = 50FPS.<br \/>\nI&#8217;ve not implemented Nape on the CitruxEngine yet.<br \/>\n<em>Note that I was compiling for 60FPS, targetting 50 FPS just to be sure that performance decrease. Important, the 50FPS is stable when objects are sleeping. Since they are all in contact each other, the framerate drop fast.<\/em><\/p>\n<p><strong>Physics engines cohabitation<\/strong><br \/>\nThe Citrus Engine is built with a &#8220;platformer&#8221; starter-kit using Box2D, which you can use to easily make awesome 2D sidescrolling games. I&#8217;ve started to port some platformer objects on Nape. That would be really stupid to delete Box2D support since Nape is more powerful. <em>Remember the Citrus Engine with Box2D is performing very well on Desktop &#038; Browser games.<\/em> So it&#8217;s time for a cohabitation! There is a (little) file size difference using 2 physics engines instead of one (250 Ko for a SWF, 700 Ko for an IPA), but primarily I didn&#8217;t detect a performance drop! For the final release, you may remove the other engine stuff, it takes less than 2 minutes.<br \/>\nAt the moment, Nape class name have &#8220;Nape&#8221; in front of them or are in a Nape package (platformer objects). I will do the same with Box2D objects.<\/p>\n<p><strong>Future<\/strong><br \/>\nI will port some Box2D platformer objects into Nape, and later offer the Citrus Engine V3 BETA 2. The idea is to have the same behavior with both physics engines. Community help is always greatly appreciated \ud83d\ude09<br \/>\nThe CitruxEngine will drop Box2D support to use only Nape since I had an endless bug with it. Remember, this <a href=\"http:\/\/haxe.org\/\" target=\"_blank\">Haxe<\/a> <a href=\"http:\/\/www.haxenme.org\/\" target=\"_blank\">NME<\/a> <a href=\"https:\/\/github.com\/alamboley\/CitruxEngine\" target=\"_blank\">port<\/a> is not ready for production but don&#8217;t be shy, get involved \ud83d\ude00<br \/>\nAn optional entity\/component system is always something jumping in my head, I hope to be able to offer one soon.<\/p>\n<p><strong>Sources &#038; demo<\/strong><br \/>\n<a href=\"http:\/\/www.aymericlamboley.fr\/blog\/wp-content\/uploads\/2012\/07\/CENape.zip\" target=\"_blank\">Citrus Engine with Nape &#038; Starling<\/a> ; <a href=\"http:\/\/www.aymericlamboley.fr\/blog\/wp-content\/uploads\/2012\/07\/CENape.html\" target=\"_blank\">Browser live demo<\/a><br \/>\n<a href=\"http:\/\/www.aymericlamboley.fr\/blog\/wp-content\/uploads\/2012\/07\/CEBox2D.zip\" target=\"_blank\">Citrus Engine with Box2D &#038; Starling<\/a> ; <a href=\"http:\/\/www.aymericlamboley.fr\/blog\/wp-content\/uploads\/2012\/07\/CEBox2D.html\" target=\"_blank\">Browser live demo<\/a><br \/>\n<a href=\"http:\/\/www.aymericlamboley.fr\/blog\/wp-content\/uploads\/2012\/07\/CxEBox2D.zip\" target=\"_blank\">CitruxEngine with Box2D<\/a> ; <a href=\"http:\/\/www.aymericlamboley.fr\/blog\/wp-content\/uploads\/2012\/07\/CxEBox2D.html\" target=\"_blank\">Browser live demo<\/a><\/p>\n<p>Grab the last Citrus Engine update on its <a href=\"http:\/\/code.google.com\/p\/citrus-engine\/source\/checkout\" target=\"_blank\">Google Code<\/a>!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Hi folks! Since my studies are over and my new portfolio online, I have time to focus on personal projects. Yep, it was time to contribute again to the Citrus Engine. I&#8217;ve worked 3 days at full time focusing on its big issue : mobile performances. I&#8217;m glad to say that now they are just &hellip; <a href=\"http:\/\/www.aymericlamboley.fr\/blog\/citrus-engine-on-nape-and-physics-performance-improvement\/\" class=\"more-link\">Continue reading <span class=\"screen-reader-text\">Citrus Engine on Nape and physics performance improvement<\/span> <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0},"categories":[4,115,51,33,11,70,145,106,114,6],"tags":[15,27,50,34,26,71,146,190,117,74,91],"_links":{"self":[{"href":"http:\/\/www.aymericlamboley.fr\/blog\/wp-json\/wp\/v2\/posts\/665"}],"collection":[{"href":"http:\/\/www.aymericlamboley.fr\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.aymericlamboley.fr\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.aymericlamboley.fr\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/www.aymericlamboley.fr\/blog\/wp-json\/wp\/v2\/comments?post=665"}],"version-history":[{"count":15,"href":"http:\/\/www.aymericlamboley.fr\/blog\/wp-json\/wp\/v2\/posts\/665\/revisions"}],"predecessor-version":[{"id":1278,"href":"http:\/\/www.aymericlamboley.fr\/blog\/wp-json\/wp\/v2\/posts\/665\/revisions\/1278"}],"wp:attachment":[{"href":"http:\/\/www.aymericlamboley.fr\/blog\/wp-json\/wp\/v2\/media?parent=665"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.aymericlamboley.fr\/blog\/wp-json\/wp\/v2\/categories?post=665"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.aymericlamboley.fr\/blog\/wp-json\/wp\/v2\/tags?post=665"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}