Fruit Ninja (iOS)

Fruit Ninja is everyone's favorite game about murdering fruit.

Developer Comments
Seems to have changed from _SCORE to _KILLED in 1.7... not sure exactly why since Steve isn't here, but only need one leaderboard for total sliced

These are the lite achievements. The same things are defined for SD and HD Lite versions, with provider ids below mik - Game Centre automagically gives you weekly friends leaderboards so that's why they differ to OF SD on normal OF doesn't have the zen and classic weekly scores, so we just don't specify them

These achievements are specific to a product or platform combination.

Several developer comments can be found in socialnetworks.xml

Debug Menu
UNLOCK BLADES & BACKGROUNDS ADD 10000 STARFRUIT RELOCK BLADES & BACKGROUNDS LANGUAGE SWITCH iCloud Options Achievement Helpers WIPE ALL SAVE DATA BNET SEND JUNK DATA BNET PERFORM SYNC FORCE ADS RELOCK BEINTOO OFFER BACK BACK NOTHING BUT PLUMS spawn pomegranate spawn starfruit Spawn a Dragonfruit NOTHING BUT STRAWBERRIES NOTHING BUT MANGOES MAKE SCORE 69 MAKE SCORE 99 NOTHING BUT BANANAS NOTHING BUT PINEAPPLES MAKE SCORE 208 NOTHING BUT WATERMELONS NOTHING BUT pASSIONFRUIT NOTHING BUT PEACHES MANY POWER BANANAS FORCE ICLOUD SYNC SEND iCLOUD GARBAGE WIPE ICLOUD CURRENT LANGUAGE: INSERT LANGUAGE HERE EXAMPLE STRING:

Text for a debug menu exists in debugMenu.uiscreen. It is currently unknown how to enable it, but... TouchMove_X0:	TouchAxisX1;		move TouchMove_X1:	TouchAxisX2;		move TouchMove_X2:	TouchAxisX3;		move TouchMove_X3:	TouchAxisX4;		move TouchMove_X4:	TouchAxisX5;		move TouchMove_X5:	TouchAxisX6;		move TouchMove_X6:	TouchAxisX7;		move TouchMove_X7:	TouchAxisX8;		move TouchMove_X8:	TouchAxisX9;		move TouchMove_X9:	TouchAxisX10;		move TouchMove_X10:	TouchAxisX11;		move TouchMove_X11:	TouchAxisX12;		move TouchMove_X12:	TouchAxisX13;		move TouchMove_X13:	TouchAxisX14;		move TouchMove_X14:	TouchAxisX15;		move TouchMove_X15:	TouchAxisX16;		move TouchMove_Y0:	TouchAxisY1;		move TouchMove_Y1:	TouchAxisY2;		move TouchMove_Y2:	TouchAxisY3;		move TouchMove_Y3:	TouchAxisY4;		move TouchMove_Y4:	TouchAxisY5;		move TouchMove_Y5:	TouchAxisY6;		move TouchMove_Y6:	TouchAxisY7;		move TouchMove_Y7:	TouchAxisY8;		move TouchMove_Y8:	TouchAxisY9;		move TouchMove_Y9:	TouchAxisY10;		move TouchMove_Y10:	TouchAxisY11;		move TouchMove_Y11:	TouchAxisY12;		move TouchMove_Y12:	TouchAxisY13;		move TouchMove_Y13:	TouchAxisY14;		move TouchMove_Y14:	TouchAxisY15;		move TouchMove_Y15:	TouchAxisY16;		move TouchDown_0:	Touch1;		down TouchDown_1:	Touch2;		down TouchDown_2:	Touch3;		down TouchDown_3:	Touch4;		down TouchDown_4:	Touch5;		down TouchDown_5:	Touch6;		down TouchDown_6:	Touch7;		down TouchDown_7:	Touch8;		down TouchDown_8:	Touch9;		down TouchDown_9:	Touch10;	down TouchDown_10:	Touch11;		down TouchDown_11:	Touch12;		down TouchDown_12:	Touch13;		down TouchDown_13:	Touch14;		down TouchDown_14:	Touch15;		down TouchDown_15:	Touch16;		down TouchReleased_0:	Touch1;		released TouchReleased_1:	Touch2;		released TouchReleased_2:	Touch3;		released TouchReleased_3:	Touch4;		released TouchReleased_4:	Touch5;		released TouchReleased_5:	Touch6;		released TouchReleased_6:	Touch7;		released TouchReleased_7:	Touch8;		released TouchReleased_8:	Touch9;		released TouchReleased_9:	Touch10;	released TouchReleased_10:	Touch11;		released TouchReleased_11:	Touch12;		released TouchReleased_12:	Touch13;		released TouchReleased_13:	Touch14;		released TouchReleased_14:	Touch15;		released TouchReleased_15:	Touch16;		released PointerMove:	MouseAxisX,MouseAxisY;		move PointerPressed:		MouseButton1;		pressed PointerReleased:	MouseButton1;		released PointerMove:	X360_LStick_AxisY;		active PointerMove:	X360_LStick_AxisX;		active PointerPressedX:		X360_A;		down ShowDebug:			D;   pressed ShowCollision:		C;   pressed Particles:			P;		pressed Fruit:				F;   pressed PageUpPressed:		PgUp;	pressed PageDownPressed:	PgDn;	pressed ParticlesUp:		Up;		pressed ParticlesDown:		Down;		pressed PauseGame:			Enter;		pressed ShowPauseMenu:		AppMenu;	released ShowPauseMenu:		escape;		released UpPressed:			Up;		   pressed DownPressed:		Down;		pressed LeftPressed:		Left;		pressed RightPressed:		Right;	pressed SpacePressed:		Space;	pressed PowerUpPressed:		M;	pressed Speed:				S;	pressed RegressMenu:		escape;		released QuitPressed:		Q;	pressed AddCreditPressed:	Y;	pressed OperatorOptions:	O;	pressed RemoveTime:			Z;	pressed AddTime:			A;	pressed AddStarfruit:		G;	pressed RemoveStarfruit:	B;	pressed Launch:	L;	pressed ForceBanana: b; pressed

...Input.txt mentions that pressing D will show the debug menu, as well as mentioning several other keys that correspond to debugging functions! These might work on the PC versions.

Debug Settings
In addition to the debug menu, there is also a file named debugSettings.cfg in the Config folder. // Debug Settings file // Get settings like this: //  game_work.debugConfig.GetValue("value name"). Returns a string, will be empty ("") if not found, never null. so //  if (strcmp(debugConfig.GetValue("enable_god_mode"), "true") == 0)) is safe. // This file supports C++ style comments. just like this one.

// Display display.clearOnNewFrame = 0

// Entities, Fruit entities.fruit.draw = 1 entities.fruit.update = 1 entities.fruit.drawshadows = 1

// Entities, Bomb entities.bomb.draw = 1 entities.bomb.update = 1

// BrickUI brickui.draw_layer_0 = 1 brickui.draw_layer_1 = 1 brickui.draw_layer_4 = 1 brickui.draw_layer_5 = 1 brickui.update = 1

// Backgrounds background.draw = 1

// Particles particles.draw = 1 particles.update = 1

// Sound sound.update = 1

// Music music.update = 1

// Wavemanager wavemanager.update = 1

Source Code
Source code for Flurry Web Adapter exists in the game's executable.

/** var Hogan={};(function(a){function h(a){return a=String(a===null||a===undefined?"":a),g.test(a)?a.replace(b,"&amp;").replace(c,"&lt;").replace(d,"&gt;").replace(e,"&#39;").replace(f,"&quot;"):a}a.Template=function j(a,b,c){a&&(this.r=a),this.c=c,this.text=b||""},a.Template.prototype={r:function(a,b,c){return""},v:h,render:function(b,c,d){return this.ri([b],c||{},d)},ri:function(a,b,c){return this.r(a,b,c)},rp:function(a,b,c,d){var e=c[a];return e?(this.c&&typeof e=="string"&&(e=this.c.compile(e)),e.ri(b,c,d)):""},rs:function(a,b,c){var d="",e=a[a.length-1];if(!i(e))return d=c(a,b);for(var f=0;f<e.length;f++)a.push(e[f]),d+=c(a,b),a.pop;return d},s:function(a,b,c,d,e,f,g){var h;return i(a)&&a.length===0?!1:(typeof a=="function"&&(a=this.ls(a,b,c,d,e,f,g)),h=a===""||!!a,!d&&h&&b&&b.push(typeof a=="object"?a:b[b.length-1]),h)},d:function(a,b,c,d){var e=a.split("."),f=this.f(e[0],b,c,d),g=null;if(a==="."&&i(b[b.length-2]))return b[b.length-1];for(var h=1;h=0;h--){f=b[h];if(f&&typeof f=="object"&&a in f){e=f[a],g=!0;break}}return g?(!d&&typeof e=="function"&&(e=this.lv(e,b,c)),e):d?!1:""},ho:function(a,b,c,d,e){var f=this.c,g=a.call(b,d,function(a){return f.compile(a,{delimiters:e}).render(b,c)}),h=f.compile(g.toString,{delimiters:e}).render(b,c);return this.b=h,!1},b:"",ls:function(a,b,c,d,e,f,g){var h=b[b.length-1],i=null;if(!d&&this.c&&a.length>0)return this.ho(a,h,c,this.text.substring(e,f),g);i=a.call(h);if(typeof i=="function"){if(d)return!0;if(this.c)return this.ho(i,h,c,this.text.substring(e,f),g)}return i},lv:function(a,b,c){var d=b[b.length-1],e=a.call(d);return typeof e=="function"&&(e=e.call(d)),e=e.toString,this.c&&~e.indexOf(";var b=/&/g,c=//g,e=/\'/g,f=/\"/g,g=/[&<>\"\']/,i=Array.isArray||function(a){return Object.prototype.toString.call(a)==="[object Array]"}})(typeof exports!="undefined"?exports:Hogan),function(a){function h(a){a.n.substr(a.n.length-1)==="}"&&(a.n=a.n.substring(0,a.n.length-1))}function i(a){return a.trim?a.trim:a.replace(/^\s*|\s*$/g,"")}function j(a,b,c){if(b.charAt(c)!=a.charAt(0))return!1;for(var d=1,e=a.length;d0){g=a.shift;if(g.tag=="#"||g.tag=="^"||l(g,d))c.push(g),g.nodes=k(a,g.tag,c,d),e.push(g);else{if(g.tag=="/"){if(c.length===0)throw new Error("Closing tag without opener: /"+g.n);f=c.pop;if(g.n!=f.n&&!m(g.n,f.n,d))throw new Error("Nesting error: "+f.n+" vs. "+g.n);return f.end=g.i,e}e.push(g)}}if(c.length>0)throw new Error("missing closing tag: "+c.pop.n);return e}function l(a,b){for(var c=0,d=b.length;c<d;c++)if(b[c].o==a.n)return a.tag="#",!0}function m(a,b,c){for(var d=0,e=c.length;d"?b+=t(a[c]):e=="{"||e=="&"?b+=u(a[c].n,p(a[c].n)):e=="\n"?b+=w('"\\n"'+(a.length-1==c?"":" + i")):e=="_v"?b+=v(a[c].n,p(a[c].n)):e===undefined&&(b+=w('"'+o(a[c])+'"'))}return b}function r(a,b,c,d,e,f){return"if(_.s(_."+c+'("'+o(b)+'",c,p,1),'+"c,p,0,"+d+","+e+', "'+f+'")){'+"b += _.rs(c,p,"+'function(c,p){ var b = "";'+q(a)+"return b;});c.pop;}"+'else{b += _.b; _.b = ""};'}function s(a,b,c){return"if (!_.s(_."+c+'("'+o(b)+'",c,p,1),c,p,1,0,0,"")){'+q(a)+"};"}function t(a){return'b += _.rp("'+o(a.n)+'",c,p,"'+(a.indent||"")+'");'}function u(a,b){return"b += (_."+b+'("'+o(a)+'",c,p,0));'}function v(a,b){return"b += (_.v(_."+b+'("'+o(a)+'",c,p,0)));'}function w(a){return"b += "+a+";"}var b=/\S/,c=/\"/g,d=/\n/g,e=/\r/g,f=/\\/g,g={"#":1,"^":2,"/":3,"!":4,">":5,"<":6,"=":7,_v:8,"{":9,"&":10};a.scan=function(c,d){function w{p.length>0&&(q.push(new String(p)),p="")}function x{var a=!0;for(var c=t;c"&&(d.indent=q[c].toString),q.splice(c,1));else b||q.push({tag:"\n"});r=!1,t=q.length}function z(a,b){var c="="+v,d=a.indexOf(c,b),e=i(a.substring(a.indexOf("=",b)+1,d)).split(" ");return u=e[0],v=e[1],d+c.length-1}var e=c.length,f=0,k=1,l=2,m=f,n=null,o=null,p="",q=[],r=!1,s=0,t=0,u="";d&&(d=d.split(" "),u=d[0],v=d[1]);for(s=0;s<e;s++)m==f?j(u,c,s)?(--s,w,m=k):c.charAt(s)=="\n"?y(r):p+=c.charAt(s):m==k?(s+=u.length-1,o=g[c.charAt(s+1)],n=o?c.charAt(s+1):"_v",n=="="?(s=z(c,s),m=f):(o&&s++,m=l),r=s):j(v,c,s)?(q.push({tag:n,n:i(p),otag:u,ctag:v,i:n=="/"?r-v.length:s+u.length}),p="",s+=v.length-1,m=f,n=="{"&&(v=="}}"?s++:h(q[q.length-1]))):p+=c.charAt(s);return y(r,!0),q},a.generate=function(b,c,d){return d.asString?"function(c,p,i){"+b+";}":new a.Template(new Function("c","p","i",b),c,a)},a.parse=function(a,b){return b=b||{},k(a,"",[],b.sectionTags||[])},a.cache={},a.compile=function(a,b){b=b||{};var c=a+"||"+!!b.asString,d=this.cache[c];return d?d:(d=this.generate(n(this.parse(this.scan(a,b.delimiters),b)),a,b),this.cache[c]=d)}}(typeof exports!="undefined"?exports:Hogan)a�// // flurry_bridge.js //  Flurry Web Adapter // // Copyright 2012 Flurry, Inc. All rights reserved. //	//	Methods in this header file are for use with Flurry Ads WebView
 * @preserve Copyright 2012 Twitter, Inc.
 * @license http://www.apache.org/licenses/LICENSE-2.0.txt

// constructor, taking the global window object var flurryBridgeCtor = function(w) { var flurryadapter = {}; // could be private? flurryadapter.flurryCallQueue = [ ]; flurryadapter.callComplete = function( cmd ) { if ( this.flurryCallQueue.length == 0 ) { return; }       var adapterCall = this.flurryCallQueue.splice(0,1)[0]; this.executeNativeCall(adapterCall); return "OK"; };   flurryadapter.executeCall = function( command ) { var adapterCall = "flurry://flurrycall?event=" + command; var value; for ( var i = 1; i < arguments.length; i += 2 ) { value = arguments[i + 1]; if ( value == null ) { continue; }           adapterCall += "&" + arguments[i] + "=" + escape( value ); }       if ( this.flurryCallQueue.length > 0 ) { this.flurryCallQueue.push( adapterCall ); }       else { this.executeNativeCall(adapterCall); }   };    // also could be private? flurryadapter.executeNativeCall = function( adapterCall ) { if ( adapterCall.length == 0 ) { return; }

var iframe = document.createElement("IFRAME"); iframe.setAttribute("src", adapterCall); document.documentElement.appendChild(iframe); iframe.parentNode.removeChild(iframe); iframe = null; };   return flurryadapter; };h�//document.write(" ");

var mraidCtor = function(flurryBridge, initState) { // to be returned var mraid = {}; var STATES = mraid.STATES = { LOADING          : 'loading', UNKNOWN          : 'unknown', // not in MRAID 1.0 spec? DEFAULT          : 'default', EXPANDED         : 'expanded', HIDDEN           : 'hidden' };	var EVENTS = mraid.EVENTS = { // where did these other states come from? ASSETREADY       : 'assetReady', ASSETREMOVED     : 'assetRemoved', ASSETRETIRED     : 'assetRetired', INFO             : 'info', // only the states below are defined in MRAID 1.0 spec ERROR            : 'error', ORIENTATIONCHANGE : 'orientationChange', READY            : 'ready', STATECHANGE      : 'stateChange', VIEWABLECHANGE   : 'viewableChange' };	// private vars var listeners = {}; // this is an associative array mapping strings (event names) to lists of either functions or strings // {'eventA':[function(e){...}, 'listenerFoo', ...], eventB: ...} var currentState = STATES.LOADING; // start out in LOADING state, SDK puts MRAID into DEFAULT state var expandProperties = { width:initState.width, height:initState.height, isModal:initState.isModal, useCustomClose:false };	var collapseProperties = {}; var placementType = initState.placementType; var disable = false; // default close button var closeId = 'flurry-mraid-default-close'; var imgUrl = 'http://flurry.cachefly.net/adSpaceStyles/images/bttn-close-bw.png'; var safeClose = function { try { if(window.mraid) { window.mraid.close; } else if(window.flurryadapter) { flurryadapter.executeCall('adWillClose'); } else { console.log('unable to close'); }	   } catch (error) { console.log('unable to close: ' + error); }	};	var makeDefaultClose = function { var img = document.createElement('img'); img.src = imgUrl; img.id = closeId; // we can't use img.onclick or img.addEventListener for 'click' because phluant sdk ruthlessly // cleans any event listeners by recreating body content using code like this: a.innerHTML += "". // As workaround, we use document.body.addEventListener for 'click' in setupDefaultCloseHandler //       img.onclick = safeClose; img.style.position = 'absolute'; img.style.top = '10px'; img.style.right = '10px'; img.style.width = '50px'; img.style.height = '50px'; img.style.zIndex = 10000; return img; }    var setupDefaultCloseHandler = function { document.body.addEventListener('click', function(e) {       e = e || window.event;        var target = e.target || e.srcElement;        if (target.id === closeId) {          safeClose;        }       }); }	var updateDefaultClose = function { // show default close button only for interstitial or expanded ad with expandProperties.useCustomClose === false if (!expandProperties.useCustomClose && (placementType === 'interstitial' || currentState === STATES.EXPANDED)) { addDefaultClose; } else { removeDefaultClose; }	}	var addDefaultClose = function { var closeButton = document.getElementById(closeId); if(!closeButton) { closeButton = makeDefaultClose; document.body.appendChild(closeButton); }	}	var removeDefaultClose = function { var closeButton = document.getElementById(closeId); if(closeButton) { document.body.removeChild(closeButton); }	}	/*	 * Checking for the state of the mraid client library and subscribing to the ready event if necessary * When the client library is ready call the showAd method to render the ad	 */ /* js helper functions */ var contains = function(value, obj) { for (var i in obj) { if (obj[i] === value) { return true; }       }        return false; };	var stringify = function(obj) { if (typeof obj == 'object') { if (obj.push) { var out = []; for (var p in obj) { if(obj.hasOwnProperty(p)) { out.push(obj[p]); }               }                return '[' + out.join(',') + ']'; } else { var out = []; for (var p in obj) { if(obj.hasOwnProperty(p)) { out.push('\''+p+'\':'+obj[p]); }               }                return '{' + out.join(',') + '}'; }       } else { return new String(obj); }   };	var broadcastEvent = function { var args = new Array(arguments.length); for (var i = 0; i < arguments.length; i++) { args[i] = arguments[i]; }		var event = args.shift; try { if (listeners[event]) { for(var j = 0; j < listeners[event].length; j++) { if(typeof listeners[event][j] === 'function') { listeners[event][j].apply(undefined, args); } else if(typeof listeners[event][j] === 'string' && typeof window[listeners[event][j]] === 'function') { window[listeners[event][j]].apply(undefined, args); }		       }			}		} catch(e) { console.log(e); }	}   mraid.disable = function { removeDefaultClose; disable = true; }	// Takes an event name (string) and either a function or a string, Registers a listener for this event. // String listener is taken to be the name of a global var -- ie a property of window mraid.addEventListener = function(event, listener) { if (disable) { return; }	   if (!event || !listener) { broadcastEvent(EVENTS.ERROR, 'Both event and listener are required.', 'addEventListener'); } else if (!contains(event, EVENTS)) { broadcastEvent(EVENTS.ERROR, 'Unknown event: ' + event, 'addEventListener'); } else { if (!listeners[event]) { listeners[event] = [listener]; } else { listeners[event].push(listener); }	   }        flurryBridge.executeCall("eventListenerAdded"); }	mraid.stateChange = function(newState) { if (disable) { return; }	   if(currentState === newState) { return; }	   broadcastEvent(EVENTS.INFO, 'setting state to ' + stringify(newState)); var oldState = currentState; currentState = newState; if(oldState === STATES.LOADING && newState === STATES.DEFAULT) { setupDefaultCloseHandler; updateDefaultClose; broadcastEvent(EVENTS.READY); } else if(oldState === STATES.HIDDEN || newState === STATES.HIDDEN) { broadcastEvent(EVENTS.VIEWABLECHANGE); } else if(oldState === STATES.DEFAULT && newState === STATES.EXPANDED) { updateDefaultClose; } else if(newState === STATES.DEFAULT && oldState === STATES.EXPANDED) { updateDefaultClose; }       broadcastEvent(EVENTS.STATECHANGE, currentState); }	mraid.close = function { if (disable) { return; }		// webview should downgrade its state, should also fire the // stateChange event. // ads in expanded state -> close -> default // ads in default state-> close -> hidden var state = mraid.getState; if(state === STATES.DEFAULT) { mraid.stateChange(STATES.HIDDEN); flurryBridge.executeCall("adWillClose"); } else if(state === STATES.EXPANDED) { mraid.stateChange(STATES.DEFAULT); flurryBridge.executeCall("collapse"); } else { console.log("close called in state " + state); // TODO }	};	mraid.expand = function(url) { if (disable) { return; }       var state = mraid.getState; if(state !== STATES.DEFAULT) { console.log("expand called in state " + state); return; }	   if(url) { flurryBridge.executeCall('expand', 'width', expandProperties.width, 'height', expandProperties.height, 'url', url); } else { flurryBridge.executeCall('expand', 'width', expandProperties.width, 'height', expandProperties.height); }	   mraid.stateChange(STATES.EXPANDED); };	mraid.setExpandProperties = function(properties) { if (disable) { return; }	   if(typeof properties.width === 'number' && !isNaN(properties.width)) { expandProperties.width = properties.width; }	   if(typeof properties.height === 'number' && !isNaN(properties.height)) { expandProperties.height = properties.height }	   if(typeof properties.useCustomClose === 'boolean') { expandProperties.useCustomClose = properties.useCustomClose; updateDefaultClose; }	};	mraid.getExpandProperties = function(properties) { if (disable) { return; }	   var ret = {}; ret.width = expandProperties.width; ret.height = expandProperties.height; ret.isModal = expandProperties.isModal; ret.useCustomClose = expandProperties.useCustomClose; return ret; };	mraid.getPlacementType = function { return placementType; };	/*	 * The getversion method should return the version of mraid. Since we are 1.0 compliant, should * return 1.0. */	mraid.getVersion = function { if (disable) { return ""; }		return "1.0"; };	mraid.getState = function { if (disable) { return ""; }		// the default states are loading, default, expanded, hidden // loading: the sdk is not yet ready for interactions with the Controller // default: initial position and size of the ad container as placed by app and sdk // expanded: the ad container has expanded to cover the app. content at top of view hierarchy // hidden: the ad container no longer displays the ad	   return currentState; };	mraid.isViewable = function { if (disable) { return false; }	   if(mraid.getState === 'hidden') { return false; } else { return true; }	};	mraid.open = function(url) { if (disable) { return; }	   try{ flurryBridge.executeCall("open", "url", url); } catch (e) { console.log(e); }	};	// Deregisters the listener for this event mraid.removeEventListener = function(event, listener) { if (disable) { return; }	   if (!event) { broadcastEvent('error', 'Must specify an event.', 'removeEventListener'); } else { if(listener && (listeners[event])) { for(var i = 0; i < listeners[event].length; i++) { if(listeners[event][i] === listener) { listeners[event].splice(i,1); // remove listener from array }	           }	        }	        else if (listeners[event]) { listeners[event] = []; }	   }	};	mraid.useCustomClose = function(use) { if (disable) { return; }		// true - ad creative supplies its own designed for the close area // false - SDK defualt image should be displayed for the close area if(typeof use === 'boolean') { expandProperties.useCustomClose = use; updateDefaultClose; }	};	return mraid; };