MINIPLAY C2S ACTIONSCRIPT 3 API
APIs for casual & social games

Preface:

Please help us improving it by reporting us any bugs or suggestions to [email protected], we put our best efforts in order to make life easier for you and the other developers, and your help will be greatly appreciated.

In this document we’ll dig into the JAVASCRIPT API for connecting to our services from any game capable of reaching the Javascript layer of the browser, be it pure HTML+Javascript based or plugin based like Shockwave, Unity or Flash (although there’s an ActionScript 3 API available). Please refer to the MINIPLAY APIs OVERVIEW document first if you haven’t read it yet, knowledge of the concepts explained there is required.

As a convention, we will use red for required parameters and blue for optional parameters. Also be noticed that every timestamp is handled with a precision of milliseconds (POSIX timestamps only have a precision of seconds).

Most of the methods requires callbacks to be passed, callable functions must be provided, nulls are not supported, if you just want to ignore the response, please provide a callback that does nothing. We'll try to implement support for null callbacks in future versions.

1. Introduction

The Actionscript 3 API allows you to connect to our services in full read/write mode, right from the your Flash game. In case of internal games (those that run inside our site sandbox, be them hosted by us or pointed to a custom URL), the API provides your game interoperability with our site as well, (i.e.: opening the login dialog, a scoreboard, purchase items, maximize the game...). In case of external games, the API automatically detects them and provides methods to allow your users authenticate by using their Miniplay account, that’s what we call Miniplay connect*, we’ll talk about it later (although other methods designed for internal interoperability will be disabled).

The ActionScript 3 API requires our Javascript API to be loaded in order to work properly, if your game is hosted by us, it will be loaded automatically, but if you host it by yourself, make sure you load the Javascript API first. (More info at 3. Hosted games).

* You must ask for permission if you want to use this API in an external site so we enable Miniplay connect for you

2. Read/Write access and security concerns.

Flash games are easy to hack, it just need skilled and dedicated people. Our API is designed to make it as hard as possible, but afterall it relies on your code, anyone could inspect their memory for variables and swap their scores. This flash API uses an api_token instead of the S2S api_key counterpart, so, in case your token is compromised, contact us to generate a new one for your game and update it afterwards. Do not ever use your api_key in your flash game to perform requests to our S2S API. This API provides the same functionality and will automatically encrypt the requests (responses are neither encrypted/signed).

If your token is compromised, the “hackers” will be able to implement the API in their own way to send us fake in-game statistics (that will reward them with achievements, experience and gems), if that happens, all the highscores wouldn’t mean anything and the global experience will be ruined. That’s not what we want, we’ll work hard to have fair scores, in case any user that is detected cheating will be penalized and we’ll urge you to patch the game.

2.1. Best practices

  • Hardcode the api_token in your game, make it as hard to find as possible.
  • Never provide the api_token as a flashvar.
  • Devel and production versions have 2 different tokens, you can hardcode both within your game and check the presence of the mp_game_devel flashvar to use one or another.
  • If your game is hosted with us or you use our flash sandbox template: loglevel is automatically set to 1 (DEBUG) for development version and to 4 (WARN) for production.
  • If you manually set the loglevel, do not use less than 4 (WARN) for production.

3. Environment & game loading

3.1 Games hosted by us

Your game swf will be loaded automatically into our game sandbox, which is an iframe that runs on a different subdomain to prevent you for accessing to our site javascript. The following flashvars will be provided to your game (most of them are used by our AS3 API afterwards):

  • mp_game_id Id of the game
  • mp_game_uid Uid of the game (up to 30char unique alphanumeric id)
  • mp_game_url Url of the game (current page)
  • mp_site_url Site where the game is running (we’ve got a few ones!)
  • mp_api_js_url Javascript API url
  • mp_api_js_url_bck Javascript backend url
  • mp_api_as3_url Actionscript 3 API url
  • mp_api_as3_url_bck Actionscript 3 backend url
  • mp_api_user_id user id if it’s logged in, this is the unique, immutable id of the user, it never changes.
  • mp_api_user_token unique user token, you can store it, but keep it private and secure.
  • mp_locale locale of the user i.e: es_ES
  • mp_base_path Game assets base path i.e: http://www.minijuegosgratis.com/v3/games/games/prod/204023/
  • mp_timezone timezone of the user i.e.: Europe/Madrid
  • mp_game_devel 1 if the game it’s in development mode, not present if not.

The following parameters are set:

  • allowscriptaccess always
  • allowfullscreen false
  • wmode direct

3.2 Games hosted by yourself

If you need to host the game by yourself or you need to customize the sandbox (the sandbox is the page loaded in our iframe game player) we can point the game iframe to the urls you provide us (one for development, and one for production). The only requirement is that you set the same flashvars & parameters shown at “3.1 Games hosted by us”.

In order to avoid problems, we’ve set up a PHP/HTML template for you that performs all the initialization routines, parameters signature verification and Javascript API loading, use it as an starting point and modify it to suit your needs. It can be easily ported to other languages if you don’t support PHP.

Download the sandbox template here: https://gist.github.com/miniplay/4996607

4. Local debugging & testing

Due to the Flash local sandboxing restrictions, our AS3 API only works when you access to your game through the HTTP/HTTPS protocol.

We do not provide a shadow API to allow you local debugging, being socially oriented it just doesn’t make sense, instead, we’ve made our best effort to provide you a development environment that allows you to test the game in it’s full glory, including in-game purchases, stats, highscores, achievements.... Just host the development version of the game by yourself in a locally installed webserver (tons of free ones available) to make as many changes as you like and be able to debug it.

Check Appendix 1: Local debugging tips & tricks for more information.

If you want a simpler approach, we can provide you a temporary FTP account for testing, but you will develop a lot slower.

5. Compatibility

Our API only works for Actionscript 3, if your game is hosted with us, Flash Player v.10+ is required (>97% of global user base). We do not plan to support Actionscript 2.

6. API Loading

Our AS3 API is meant to be dynamically loaded, to do it, get the mp_api_as3_url from the flashvars and load it with a Loader object, once completed, keep a reference to the API object by your preferred means.

Here’s the most basic code:

/* 1. Imports */ import flash.display.LoaderInfo; import flash.display.Loader; import flash.net.URLRequest; import flash.events.Event; import flash.system.Security; /* 2. Get the url from the flashvars */ var params:Object = LoaderInfo(root.loaderInfo).parameters; /* Access to the root object is required */ /* 3. If not present, load the latest available */ var apiUrl:String = params.mp_api_as3_url || "https://ssl.minijuegosgratis.com/lechuck/as3/latest.swf"; /* 4. Grant the API access to this SWF */ Security.allowDomain(apiUrl); /* Having issues? try allowDomain("*")! */ /* 5. Load the API */ var apiRequest:URLRequest = new URLRequest(apiUrl); var apiLoader:Loader = new Loader(); apiLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, onApiLoadComplete); /* onApiLoad will be called once completed */ apiLoader.load(apiRequest); this.addChild(apiLoader); /* 6. API Reference (assigned inside onApiLoadComplete) */ var lechuck:*; /* 7. On API Load Complete Handler */ function onApiLoadComplete(event:Event):void { trace("API Loaded"); /* Assign the reference to the API instance */ lechuck = event.target.content; /* Set api_token: Devel and production tokens, use devel if the mp_game_devel = 1 flashvar was received */ var token:String = lechuck.isDevel ? "YOUR_DEVEL_TOKEN" : "YOUR_PRODUCTION_TOKEN"; /* Connect the API backend */ trace("Connecting with the API backend..."); lechuck.connect(token, function():void { if (lechuck.isConnected) { trace("API connected, LeChuck services ready to rock!."); if (lechuck.user.isGuest()) { /* Boot the game for a guest user (ask to login) >>>> */ } else { /* Boot the game for an authenticated user >>>> */ } } else { trace("API not connected: "+lechuck.connectError.message ); /* No API connection, boot the game? (you decide it) */ } }); }

Download it here: https://gist.github.com/miniplay/5012680

A much more detailed version is available here: https://gist.github.com/miniplay/5012909

7. Integration with the Javascript API

As previously stated, the Actionscript 3 API (this one) requires the Javascript API to be initialized (done automatically if your game is hosted by us and using our sandbox), the AS3 API can be still be usable without it, but ignoring to do so will cause the AS3 API to be in limited mode and a lot of methods won’t be available. If you host the game by yourself, make sure you correctly initialize both APIs (use our sandbox template).

Our AS3 API automatically handles games that han been published elsewhere from our sites, if you try to log in an user, it will redirect him/her to your game in our sites. More information about detecting external games can be found at APPENDIX. DETECTING EXTERNAL GAMES.

8. API Demo source code (.fla)

We’ve released a simple demo to give you a fast look of our AS3 API, including initialization, user detection & authentication... Just ask us to create your game, download the .fla file, set it up with your tokens and you’re ready to go. This code can be easily ported to Flex Applications as well.

Download the source file here: https://www.dropbox.com/s/yv8gs563upof72f/MPFlashAPIDemo_0_2_3.fla (Flash CS5)

You can run it right from Flash, but all the methods that need the JS API will be unavailable, and you’ll probably get Security Errors due the local sandboxing restrictions. To test the demo inside of our site and take advantage of all functionalities, host the swf it in a local webserver (or wherever you want) and ask us to configure the game url to your local one (we don’t mind if its local, it’s just for development purposes).

Another option is to host the game + the sandbox in a local webserver and take control of everything by yourself (tell us to point the iframe url to your sandbox url). Refer to 3.2 to download the sandbox template with the basic initialization included.

9. API modules

The API instance contains some basic methods & properties + the following module objects:

  • ENVIRONMENT lechuck.environment:Object
  • USER lechuck.user:Object
  • STAT lechuck.stat:Object
  • HIGHSCORE lechuck.highscore:Object
  • SHAREDCONTENT lechuck.sharedcontent:Object
  • DATASTORE lechuck.datastore:Object
  • ITEM lechuck.item:Object

10. Basic methods & properties

10.1 connect(api_token:String,  callback:Function,  user_id:String,  user_token:String )

Connects to the API and validates the api_token, once connected (or if already connected), the callback is triggered if provided. You can provide an empty callback function.

The user_id & user_token parameters are both optional. Only set them for testing purposes. In case of absence of this parameters, the API will detect them automatically from the mp_api_user_id & mp_api_user_token flasvhars. If they’re not set & the flashvars are empty or not present, a guest user is assumed.

10.2 disconnect()

Disconnects from the API.

10.3 connectError: Error

In case of connection error, eccess to the Error object.

10.4 isConnected: Boolean

Is the API connected to the backend?.

10.5 isConnectedJS: Boolean

Is the API connected to the JS API?. Remember that the JS API is required in order to work properly, If not present, a lot of methods will be unavailable.

10.6 isDevel: Boolean

Is the development version of the game. It just search and returns true if the mp_game_devel flashvar is present so you can switch between different logic (i.e: tokens) if necessary.

10.7 isInternal: Boolean

Is an internal game? (running inside our site).

10.7 isExternal: Boolean

Is an external game? (not running inside our site).

10.8 version: String

Get the api version.

10.9 Events

You can attach listeners for the following events:

10.9.1 onConnect( callback:Function )

Triggered when the API is connected. The callback doesn’t receive parameters.

10.9.2 onUnableToConnect( callback:Function )

Triggered when the API cannot connect. The callback doesn’t receive parameters.

10.9.3 onDisconnect( callback:Function )

Triggered when the API disconnects. The callback doesn’t receive parameters.

10.9.4 onUserDisconnect( callback:Function )

Triggered when the user is disconnected (i.e. The user can close the session on another browser tab, after a few seconds, this event will be triggered).The callback doesn’t receive parameters.

10.9.5 onResize( callback:Function )

Triggered when the game is resized. The callback doesn’t receive parameters.

10.10 Logging

Our API provides logging functionality, if your game is running and it’s connected to both our AS3 & JS API, all logging is sent directly sent to the browser console. If your game doesn’t have access to the JS API, the logging is traced, in that case, a listener can be registered by using the onTrace method so you can handle the messages.

10.10.1 logLevel( level:int )

Sets the log level, it’s automatically set to 3 by default. Our sandbox sets it to 1 for development games and 4 for production games (the API reads the mp_log_level flashvar).

Available log levels:

  1. 1 - Spam
  2. 2 - Debug
  3. 3 - Info
  4. 4 - Warn
  5. 5 - Error

10.10.2 logSpam( message:Object )

Logs a spam message, can be anything, from strings to objects.

10.10.3 logDebug( message:Object )

Logs a debug message, can be anything, from strings to objects.

10.10.4 logInfo( message:Object )

Logs an info message, can be anything, from strings to objects.

10.10.5 logWarn( message:Object )

Logs a warning message, can be anything, from strings to objects.

10.10.6 logError( message:Object )

Logs an error message, can be anything, from strings to objects.

10.10.7 logListener( callback:Function, logLevelString:String = "All" )

Listens for log events and calls the callback when triggered, by default, listens for all logged messages. You can listen for errors by using the logLevelString = "Error". The callback receives an Event object with the type & msg properties.

10.10.7 onTrace( callback:Function )

Listens for trace events and calls the callback when triggered. The callback receives an Event object with the type & msg properties.

10.10.8 dump( obj:Object )

Dumps an object to console (or trace it if browser console not available). The log level is ignored, the object will always be dumped.

10.10.9 trace( message:Object )

Trace a message or an object. The log level is ignored, the object will always be traced.

11. ENVIRONMENT module

The environment module allows you to interact with the game environment, in other words, to communicate with our site. This module is disabled for external games.

11.1 isInternal()

Returns true if the game is running inside our site, false otherwise.

11.2 isExternal()

Returns true if the game is not running inside our site, false if it’s internal.

11.3 toComments()

Scrolls to the comments section.

11.4 toControls()

Scrolls to the controls section.

11.5 toDescription()

Scrolls to the description section.

11.6 toSimilarGames()

Scrolls to the similar games section.

11.7 toCollectionGames()

Scrolls to the games of the same collection section.

11.8 toSagaGames()

Scrolls to the games of the same saga section.

11.9 toShare()

Opens the share game dialog.

11.10 toAchievements()

Opens the game achievements or navigate to them if they’re already opened.

11.11 toHighscoreGlobal( hs_uid:String, timespan:String = “TOTAL” )

Opens the game global scoreboard (for all users) specified at hs_uid.

Supported timespans: TOTAL, DAY, WEEK, MONTH.

// Show best points scoreboard for last 24 hours lechuck.environment.toHighscoreGlobal("best_points","DAY");

11.12 toHighscoreFriends( hs_uid:String )

Opens the game friends scoreboard (for an user) specified at hs_uid.

// Show best points scoreboard only for the users followed by the logged user lechuck.environment.toHighscoreFriends("best_points");

11.13 PLAYER

The player methods allows you to obtain information about our game player (the player is the sandbox iframe with the hosted game or with your game url).

11.13.1 playerIsScalable()

Returns true if the game can be maximized, false otherwise.

11.13.2 playerIsMaximized()

Returns true if the game is maximized, false otherwise.

11.13.3 playerMaximize()

Request the game to be maximized, false otherwise.

11.13.4 playerMinimize()

Request the game to be minimized (remember: the minimized version is just the small player).

11.13.5 playerGetSize()

Returns the original player dimensions.

lechuck.environment.playerGetCurrentSize() == {"width":"100%","height":"100%"}

11.13.6 playerGetCurrentSize()

Returns the current player dimensions.

lechuck.environment.playerGetCurrentSize() == {"width":944,"height":256}

11.13.7 playerGetViewType()

Returns a string with the default player type for the game, “small”, “large” or “fullscreen”  (Read MINIPLAY APIs OVERVIEW section 12).

11.13.8 playerGetCurrentViewType()

Returns a string with the current player type for the game, “small”, “large” or “fullscreen”. It should match the default view type but it could change if you use the resize API.

11.13.9 playerIsResizable()

Returns true if the resize API is available, false otherwise. Contact us to request access.

11.13.10 playerSetSize( number width,  number height )   Requires the resize API to be available

Allows you to change the sandbox player size in pixels. It automatically changes the view type between "small" and "large". Specially useful if you’ve got a flexible height game. Call it whenever your game width/height* changes:

lechuck.environment.playerSetSize(980, 700);

* Max: width 980px, Height 1400px, for greater dimensions please request us the fullscreen mode for your game

11.13.11 playerResetSize()                                   Requires the resize API to be available

Resets the sandbox player size to it’s defaults.

12 USER module

Allows you to manage the current logged user or to authenticate one, the user will be automatically connected if the mp_api_user_id & mp_api_user_token flashvars are present, so, if you’re not using your own sandbox it all will be automatically handled. Once the API is connected, you can check the user login status (as demonstrated on chapter 6. API Loading)

You must assume that by default, your game will receive guest users, and, only if the user is logged in in our site, you’ll receive the mp_api_user_id and mp_api_user_token parameters. So, if your game only works for authenticated users you must check the current status:

Please see the document 01 - MINIPLAY APIs OVERVIEW, APPENDIX 6. Handling guests users for more information.

All users grant you permissions to access their user_token just by playing your game, there’s no need for them to grant you any special privileges.

12.1 isGuest()

Returns true if the user is not logged in, false otherwise (the user is logged in).

12.2 id

User id of the logged user. This field is immutable, it will be always the same.

12.3 uid

The user uid (alias) of the logged user. This field is mutable, the user can change it and a different one could use it later.

12.4 level

The progress level of the logged user.

12.5 avatar

The default avatar url (head) of the logged user (96x96px jpg). This asset is immutable (you can store this url and you’ll always get the latest version).

12.6 avatar_mini

Returns the default avatar url (head) of the logged user in small format (32x32px jpg). This asset is immutable (you can store this url and you’ll always get the latest version).

12.7 avatar_big

Returns the default avatar url (head) of the logged user in large format (256x256px jpg). This asset is immutable (you can store this url and you’ll always get the latest version).

12.8 avatar_alpha

Returns the default avatar url (head) of the logged user in standard, transparent format (96x96px png). This asset is immutable (you can store this url and you’ll always get the latest version).

12.9 avatar_body

Returns the default avatar url (full body of the logged user in standard, transparent format (160x220px png). This asset is immutable (you can store this url and you’ll always get the latest version).

12.10 login()

Opens the login dialog for authentication if the game is internal or initiates the Miniplay connect workflow (by opening a popup to our site, crossdomain issues are automatically handled by our API), once completed, the page is refreshed (In external games, your page will be reloaded in order to to receive the mp_api_user_id and mp_api_user_token url parameters).

If the game is external and it's neither connected to the JS API or doesn't have access to the Miniplay connect, it will try to redirect to your game page inside Miniplay, by detecting the user language and sending him/her to the best suitable candidate (i.e. Minijuegos for spanish, or Minigiochi for italian).

More information about detecting external games can be found at APPENDIX. DETECTING EXTERNAL GAMES.

12.11 die()

Logs out the current user, only works for external games, for internal games users cannot be logged out.

12.12 authenticate( callback:Function , user_id:String,  user_token:String )

Authenticates an user token and sets it as logged if it’s valid, a response object is sent as the first parameter to the callback with the properties:

  • boolean isValid
  • string errorType in case of error (false on success)
  • string errorMessage in case of error (false on success)

12.13 get( callback:Function , user_id:String, user_token:String  )

Gets an user detail, if no user_token is provided, the public detail will be retrieved; if provided and it’s valid, the full detail will be retrieved. If no user_id provided, the current logged user will be assumed (if any).

A response object is sent as the first parameter to the callback with the properties:

  • Object userData Here’s the full user data (if the user_token is provided): { "id":"2", /* 32 bit number as string (immutable) */ "uid":"demo_user_2", /* 32 character string (mutable) */ "gender":"M", /* (M)ale,(F)emale */ "name":"xxxxxx", /* only for selected developers (may be empty) */ "surname":"yyyyyy", /* only for selected developers (may be empty) */ "email":"user@host.com", /* only for selected developers */ "date_birth":"1970-12-30", /* YYYY-mm-dd */ "locale":"en_US", /* user locale string or property not present for null */ "avatar":"http://beta.miniplay.com/....../default/head_96x96.jpg", "avatar_mini":"http://beta.miniplay.com/....../default/head_32x32.jpg", "avatar_big":"http://beta.miniplay.com/....../default/head_256x256.jpg", "avatar_alpha":"http://beta.miniplay.com/....../default/head_96x96.png", "avatar_body":"http://beta.miniplay.com/....../default/body_160x220.png", "profile":"http://beta.miniplay.com/profile/demo_user_2", "social_total_followers":10, /* 32 bit number */ "social_total_subscriptions":15, /* 32 bit number */ "social_total_friends":10, /* 32 bit number */ "progress_points":2795, /* 32 bit number */ "progress_level":14, /* 32 bit number */ "progress_level_points_max":3061, /* 32 bit number */ "progress_level_points_min":2683 /* 32 bit number */ }
  • string errorType in case of error (false on success)
  • string errorMessage in case of error (false on success)

Please notice that some fields will only be provided to selected developers prior mutual agreement.

12.14 subscriptions( callback:Function , options:Object )

This is probably the most important list for game developers. Gets the subscriptions list of the logged user (who he/she follows), ordered by descending timestamp, can be easily paginated by using the timestamps. Every user in the list will contain the time property corresponding to the millisecond timestamp when the event occurred (in this case, the subscription of the user).

The following options are supported:

  • boolean withProgress include each user progress level
  • boolean withDetail include each user basic detail (true by default)
  • boolean withInstalled to include the installed flag (has played the game?, false by def.)
  • number limit number of items to retrieve (20 by default, 99 max)
  • number fromTimestamp oldest timestamp (in milliseconds), inclusive
  • number toTimestamp newest timestamp (in milliseconds), exclusive

A response object is sent as the first parameter to the callback with the properties:

  • Array subscriptions an array of user objects [ { "id":"19", /* 32 bit number as string (immutable) */ "uid":"demo_user_19", /* 32 character string (mutable) */ "avatar":"http://beta.miniplay.com/....../default/head_96x96.jpg", "avatar_mini":"http://beta.miniplay.com/....../default/head_32x32.jpg", "avatar_big":"http://beta.miniplay.com/....../default/head_256x256.jpg", "avatar_alpha":"http://beta.miniplay.com/....../default/head_96x96.png", "avatar_body":"http://beta.miniplay.com/....../default/body_160x220.png", "profile":"http://beta.miniplay.com/profile/demo_user_2", "progress_points":190, /* 32 bit number */ "progress_level":2, /* 32 bit number */ "progress_level_points_max":220, /* 32 bit number */ "progress_level_points_min":100, /* 32 bit number */ "time":1359977519115 /* 64 bit number */ "is_friend":false, /* boolean, is this user a friend? */ "is_installed":false /* boolean, has this user played this game? (if requested) */ }, { "id":"14", /* 32 bit number as string (immutable) */ "uid":"demo_user_14", /* 32 character string (mutable) */ "avatar":"http://beta.miniplay.com/....../default/head_96x96.jpg", "avatar_mini":"http://beta.miniplay.com/....../default/head_32x32.jpg", "avatar_big":"http://beta.miniplay.com/....../default/head_256x256.jpg", "avatar_alpha":"http://beta.miniplay.com/....../default/head_96x96.png", "avatar_body":"http://beta.miniplay.com/....../default/body_160x220.png", "profile":"http://beta.miniplay.com/profile/demo_user_14", "progress_points":1810, /* 32 bit number */ "progress_level":11, /* 32 bit number */ "progress_level_points_max":2024, /* 32 bit number */ "progress_level_points_min":1740, /* 32 bit number */ "time":1358357279751 /* 64 bit number */ "is_friend":false, /* boolean, is this user a friend? */ "is_installed":false /* boolean, has this user played this game? (if requested) */ } ]
  • string errorType in case of error (false on success)
  • string errorMessage in case of error (false on success)

Here’s a demo code that echoes to console the last 5 followers of the logged user:

lechuck.user.subscriptions(function(response){ if (response.errorType || !response.subscriptions) { lechuck.logError("Something went wrong: "+response.errorMessage); } else { lechuck.logInfo("Last 5 subscriptions:"); for (var i=0;i<response.subscriptions.length;i++) { lechuck.logInfo( "User " + response.subscriptions[i].uid + " (level " + response.subscriptions[i].progress_level + ") - " + (response.subscriptions[i].is_friend ? "friend":"not friend")+ " - " + (response.subscriptions[i].is_installed ? "installed":"not installed") ); } } }, {"withInstalled": true, "withProgress": true, "limit":5});

12.15 friends( callback:Function , options:Object )

Gets the friends list of the logged user (who are followed by and following user), ordered by descending timestamp, can be easily paginated by using the timestamps. Every user in the list will contain the time property corresponding to the millisecond timestamp when the event occurred (in this case, when the friendship).

The following options are supported:

  • boolean withProgress include each user progress level
  • boolean withDetail include each user basic detail (true by default)
  • boolean withInstalled to include the installed flag (has played the game?, false by def.)
  • number limit number of items to retrieve (20 by default, 99 max)
  • number fromTimestamp oldest timestamp (in milliseconds), inclusive
  • number toTimestamp newest timestamp (in milliseconds), exclusive

A response object is sent as the first parameter to the callback with the properties:

  • Array friends an array of user objects [ { "id":"19", /* 32 bit number as string (immutable) */ "uid":"demo_user_19", /* 32 character string (mutable) */ "avatar":"http://beta.miniplay.com/....../default/head_96x96.jpg", "avatar_mini":"http://beta.miniplay.com/....../default/head_32x32.jpg", "avatar_big":"http://beta.miniplay.com/....../default/head_256x256.jpg", "avatar_alpha":"http://beta.miniplay.com/....../default/head_96x96.png", "avatar_body":"http://beta.miniplay.com/....../default/body_160x220.png", "profile":"http://beta.miniplay.com/profile/demo_user_2", "progress_points":190, /* 32 bit number */ "progress_level":2, /* 32 bit number */ "progress_level_points_max":220, /* 32 bit number */ "progress_level_points_min":100, /* 32 bit number */ "time":1359977519115 /* 64 bit number */ "is_friend":false, /* boolean, is this user a friend? (always true for this list) */ "is_installed":false /* boolean, has this user played this game? (if requested) */ }, { "id":"14", /* 32 bit number as string (immutable) */ "uid":"demo_user_14", /* 32 character string (mutable) */ "avatar":"http://beta.miniplay.com/....../default/head_96x96.jpg", "avatar_mini":"http://beta.miniplay.com/....../default/head_32x32.jpg", "avatar_big":"http://beta.miniplay.com/....../default/head_256x256.jpg", "avatar_alpha":"http://beta.miniplay.com/....../default/head_96x96.png", "avatar_body":"http://beta.miniplay.com/....../default/body_160x220.png", "profile":"http://beta.miniplay.com/profile/demo_user_14", "progress_points":1810, /* 32 bit number */ "progress_level":11, /* 32 bit number */ "progress_level_points_max":2024, /* 32 bit number */ "progress_level_points_min":1740, /* 32 bit number */ "time":1358357279751 /* 64 bit number */ "is_friend":false, /* boolean, is this user a friend? (always true for this list) */ "is_installed":false /* boolean, has this user played this game? (if requested) */ } ]
  • string errorType in case of error (false on success)
  • string errorMessage in case of error (false on success)

10.16 followers( callback:Function , options:Object )

Gets the followers list of the logged user, ordered by descending timestamp, can be easily paginated by using the timestamps. Every user in the list will contain the time property corresponding to the millisecond timestamp when the event occurred (in this case, the following of the provided user).

The following options are supported:

  • boolean withProgress include each user progress level
  • boolean withDetail include each user basic detail (true by default)
  • number limit number of items to retrieve (20 by default, 99 max)
  • number fromTimestamp oldest timestamp (in milliseconds), inclusive
  • number toTimestamp newest timestamp (in milliseconds), exclusive

A response object is sent as the first parameter to the callback with the properties:

  • Array followers an array of user objects [ { "id":"19", /* 32 bit number as string (immutable) */ "uid":"demo_user_19", /* 32 character string (mutable) */ "avatar":"http://beta.miniplay.com/....../default/head_96x96.jpg", "avatar_mini":"http://beta.miniplay.com/....../default/head_32x32.jpg", "avatar_big":"http://beta.miniplay.com/....../default/head_256x256.jpg", "avatar_alpha":"http://beta.miniplay.com/....../default/head_96x96.png", "profile":"http://beta.miniplay.com/profile/demo_user_19", "progress_points":190, /* 32 bit number */ "progress_level":2, /* 32 bit number */ "progress_level_points_max":220, /* 32 bit number */ "progress_level_points_min":100, /* 32 bit number */ "time":1359977519115 /* 64 bit number */ }, { "id":"14", /* 32 bit number as string (immutable) */ "uid":"demo_user_14", /* 32 character string (mutable) */ "avatar":"http://beta.miniplay.com/....../default/head_96x96.jpg", "avatar_mini":"http://beta.miniplay.com/....../default/head_32x32.jpg", "avatar_big":"http://beta.miniplay.com/....../default/head_256x256.jpg", "avatar_alpha":"http://beta.miniplay.com/....../default/head_96x96.png", "profile":"http://beta.miniplay.com/profile/demo_user_14", "progress_points":1810, /* 32 bit number */ "progress_level":11, /* 32 bit number */ "progress_level_points_max":2024, /* 32 bit number */ "progress_level_points_min":1740, /* 32 bit number */ "time":1358357279751 /* 64 bit number */ } ]
  • string errorType in case of error (false on success)
  • string errorMessage in case of error (false on success)

Here’s a demo code that echoes to console the last 5 followers of the logged user:

lechuck.user.followers(function(response){ if (response.errorType || !response.followers) { lechuck.logError("Something went wrong: "+response.errorMessage); } else { lechuck.logInfo("Last 5 followers:"); for (var i=0;i<response.followers.length;i++) { lechuck.logInfo( "User " + response.followers[i].uid + " (level " + response.followers[i].progress_level + ")" ); } } }, {"withProgress": true, "limit":5});

10.17 subscriptionStatus(Function callback, int user2_id, boolean withInstalled)

Checks if an user is subscribed (follows) to another one (user2_id), set withInstalled flag to true if you want to retrieve the is_installed flag as well (if the user has played the game)

A response object is sent as the first parameter to the callback with the properties:

  • boolean is_subscribed Is the user subscribed to user2_id?
  • boolean is_friend Are they friends? (communications & sharing allowed)
  • boolean is_installed Has the user installed the game? (played it)
  • number time 64bit millisecond timestamp (of the subscription)
  • string errorType in case of error (false on success)
  • string errorMessage in case of error (false on success)

13 STAT module

Allows you to send, retrieve and reset game stats for users to track their progress. All configured stats for your game are listed in your development sandbox, give them a look and don’t hesitate to ask us for as many as you want, we love stats!.

Please read first the Social competition document for better information and examples.

13.1 get( callback:Function, stat_uid:String )

Gets the provided stat uid value for the logged user.

  • Parameters stat_uid Uid of the stat

A response object is sent as the first parameter to the callback with the properties:

  • Object stat stat configuration {"id": "xxx", "uid": "yyy", "type": "zzz", ... }
  • number value stat value (32bit)
  • number timestamp timestamp when it was saved (64bit)
  • string errorType in case of error (false on success)
  • string errorMessage in case of error (false on success)

Demo code:

lechuck.stat.get(function(response){ if (response.errorType) { lechuck.logError("Something went wrong: "+response.errorMessage); } else if (response.value!==null) { lechuck.logInfo("Last score: "+response.value); } else { lechuck.logInfo("No score saved"); } }, "last_score");

13.2 reset( callback:Function, stat_uid:String )

Resets a stat for an user (deletes the value).

  • Parameters stat_uid Uid of the stat

A response object is sent as the first parameter to the callback with the properties:

  • Object stat stat configuration {"id": "xxx", "uid": "yyy", "type": "zzz", ... }
  • string errorType in case of error (false on success)
  • string errorMessage in case of error (false on success)

Demo code:

lechuck.stat.reset(function(response){ if (response.errorType || !response.stat) { lechuck.logError("Something went wrong: "+response.errorMessage); } else { lechuck.logInfo("Last score resetted"); } }, "last_score");

13.3 put( callback:Function, stat_uid:String, value:int )

Sends a game stat for the user, it will be automatically handled according with the stat type (REPLACE, MIN, MAX or SUM), so it may or not be saved. Please do not spam our API servers with user stats constantly, there’s no problem receiving a few stats each minute, but they perform a lot of complex operations (highscore checking, achievements...), we will be destroyed if we receive stats each time an user shoots a bullet, instead of that, accumulate them and send the total once the user finishes the level. We do track how many stats each API clients sends ;)

  • Parameters
    • stat_uid Uid of the stat
    • value 32 bit integer value, if you need floating point, multiply it for
      The highest number supported is 2.147.483.647
      Negative numbers are not allowed

A response object is sent as the first parameter to the callback with the properties:

  • Object stat stat configuration {"id": "xxx", "uid": "yyy", "type": "zzz", ... }
  • PutResult result a PutResult object *
  • string errorType in case of error (false on success)
  • string errorMessage in case of error (false on success)

Definition of the PutResult object:

  • hasHighscore(hs_uid:String):Boolean Has it entered into this highscore?
  • getHighscore(hs_uid:String):Object {highscore:Object,position:int,value:int} if entered it.
  • getHighcorePosition(hs_uid:String):int Position at the highscore
  • getHighscoreValue(hs_uid:String):int Value at the highscore
  • isProcessed:Boolean Has it been processed?
  • isSaved:Boolean Has it been saved?
  • value:int Value saved
  • highscoresSaved:Array Array of highscores saved
  • highscoresSharedContentId:String Id to save sharedcontent related with these.

Demo code:

lechuck.stat.put(function(response){ if (response.errorType || !response.stat) { lechuck.logError("Something went wrong: "+response.errorMessage); } else { lechuck.logInfo("Stat sent"); } }, "last_score", 15000 );

Demo code with scoreboard detection:

lechuck.stat.put(function(response){ if (response.errorType || !response.stat) { lechuck.logError("Something went wrong: "+response.errorMessage); } else { if (response.result.isSaved) { lechuck.logInfo("Improved lap time: " + int(response.result.value)/100 + "sec"); if (response.result.highscoresSaved.length>0) { lechuck.logInfo("You set new scores in these scoreboards!:"); for (var i:int=0;i<response.result.highscoresSaved.length;i++) { lechuck.logInfo("- "+response.result.highscoresSaved[i].highscore.uid); } } } else { lechuck.logInfo("Not improved your lap time :("); } } }, "lap_time", int(lapTime*100)); /* multiply lapTime * 100 to store an int with 2 decimals */

13.4 batch( callback:Function, stats:Object )

Sends multiple game stats put requests for the user in one operation. Refer to the put operation documentation for details.

  • Parameters
    • stat_uid UId of the stat
    • stats Object with stats and values to put i.e.: {"points":100,"time":60400}

A response object is sent as the first parameter to the callback with the properties:

  • Object stat stat configuration {"id": "xxx", "uid": "yyy", "type": "zzz", ... }
  • Object results Object with stat_uids as properties containing each a PutResult object.
  • Object errors Object with stat_uids as properties containing each a String with the error.
  • string errorType in case of error (false on success)
  • string errorMessage in case of error (false on success)

Demo code:

lechuck.stat.batch(function(response){ if (response.errorType || !response.results) { lechuck.logError("Something went wrong: "+response.errorMessage); } else { lechuck.logInfo("Stats sent"); } }, {"points": 100,"time":60400} );

14. HIGHSCORE module

This module gives you the ability to retrieve the scoreboards and positions to show them in your game. Please remember that if you multiply the stats to handle floating point numbers in your game the highscore will also be stored multiplied, you have to divide them by  in order to get the same precision for displaying it. In our sites we do that automatically, so you don’t have to worry about it, just tell us how many decimal numbers the stat & the highscore have.

We will provide you the hs_uid when we create them but they will also be available in your development sandbox along a few tools that you might find useful.

14.1 global( callback:Function , hs_uid:string, options:Object )

Gets a global scoreboard, they will be ordered as configured, starting from the best, the items can be easily paginated by using the score and the timestamp of the last item of the batch.

The following options are supported:

  • string timespan [TOTAL, DAY, WEEK, MONTH] (TOTAL by default)
  • boolean withDetail include each user basic detail (true by default)
  • boolean withProgress include each user progress level
  • boolean withSharedContent to check if it has shared content and get the id
  • number limit number of items to retrieve (20 by default)
  • number startScore starting score, inclusive (exclusive if no timestamp sent)
  • number startTimestamp starting timestamp (in milliseconds), exclusive.

A response object is sent as the first parameter to the callback with the properties:

  • Object highscore hs config {"id": "xxxx", "uid": "yyyy", "type_sort": ... }
  • Array scores an array of user scores, will include the user detail if requested: {"score": "xxxx", "timestamp": "yyyy", "user": {...} }
  • string errorType in case of error (false on success)
  • string errorMessage in case of error (false on success)

Some demo code:

lechuck.highscore.global(function(response){ if (response.errorType || !response.scores) { lechuck.logError("Something went wrong: "+response.errorMessage); } else { lechuck.logInfo("Top 5 scores today:"); for (var i=0;i<response.scores.length;i++) { lechuck.logInfo( "User "+response.scores[i].user.uid + " (level "+response.scores[i].user.progress_level+"): " + response.scores[i].score + " points" ); } } }, "best_points", {"timespan":"DAY", "withProgress": true, "limit":5});

14.2 friends( callback:Function , hs_uid:string, options:Object )

Gets the user social scoreboard, the friends scoreboard corresponds to a board where only shows the user and the users he/she is following /not just the friends). As soon as the user follows another, its score will be sent to the user friends scoreboard, the same happens when the user stops following an user, it will be removed from it. Scores will be sorted as configured, starting from the best, items can be easily paginated by using the score and the user id of the last item of the batch. The user must be logged in or this will return an error response.

The following options are supported:

  • boolean withDetail include each user basic detail (true by default)
  • boolean withProgress include each user progress level
  • boolean withSharedContent to check if it has shared content and get the id
  • number limit number of items to retrieve (20 by default)
  • number startScore starting score, inclusive (exclusive if no timestamp sent)
  • number startTimestamp starting timestamp (in milliseconds), exclusive.

A response object is sent as the first parameter to the callback with the properties:

  • Object highscore hs config {"id": "xxxx", "uid": "yyyy", "type_sort": ... }
  • Array scores an array of user scores, will include the user detail if requested: {"score": "xxxx", "timestamp": "yyyy", "user": {...} }
  • string errorType in case of error (false on success)
  • string errorMessage in case of error (false on success)

14.3 score( callback:Function , hs_uid:string,  options:Object )

Retrieves an user score from a scoreboard (this value may be different from the one reported by getting the stat value, because the scoreboard can have different sorting or computation methods than the stat).

The following options are supported:

  • string timespan [TOTAL, DAY, WEEK, MONTH] (TOTAL by default)
  • boolean withSharedContent to check if it has shared content and get the id

A response object is sent as the first parameter to the callback with the properties:

  • Object highscore hs config {"id": "xxxx", "uid": "yyyy", "type_sort": ... }
  • number value highscore score
  • Array timestamp timestamp when it was saved
  • string sharedContentId shared content id if any (and if it was requested)
  • string errorType in case of error (false on success)
  • string errorMessage in case of error (false on success)

14.4 position( callback:Function , hs_uid:string )

Retrieves an user position from a scoreboard, only the 1000 top positions are stored, any null value means out of the top 1000.

A response object is sent as the first parameter to the callback with the properties:

  • Object highscore hs config {"id": "xxxx", "uid": "yyyy", "type_sort": ... }
  • number value highscore position, null if out of top 1000
  • Array timestamp timestamp when it was saved
  • string errorType in case of error (false on success)
  • string errorMessage in case of error (false on success)

15. SHAREDCONTENT module

This module allows you to save and retrieve user created shared content (like levels for your games, replays, etc). One of the most interesting features we provide is that they can be associated with highscores: when you post a stat and it’s good enough to produce an  update in a scoreboard, a highscoresSharedContentId is returned as well, in case you want to store related data (by issuing a shared content put request afterwards). Here’s one good use-case: You’ve got a racing game, and after each race you have the full lap serialized into a string or bytearray, you can store it, display the best times scoreboard and let your users compete against the best. When loading scoreboards, you can retrieve the associated sharedContentId as well.

There’s no limit in the amount of total data you can store, but each shared content slot can only store 50kb of data. Do not spam our servers with data, we track each game storage usage.

15.1 load( callback:Function , sc_id:string )

Retrieves the shared content data with the id provided..

A response object is sent as the first parameter to the callback with the properties:

  • ByteArray data Binary data (or null if none). If empty a 404 will be issued and an error will be logged
  • string errorType in case of error (false on success), "UNABLE_TO_LOAD" error will be issued if slot is empty or not found.
  • string errorMessage in case of error (false on success)

Some demo code:

lechuck.sharedcontent.load(function(response:Object):void { if (response.errorType || response.data == null) { statusField.text = "Couldn't load data: "+response.errorMessage; } else { /* Convert the byteArray to a string (we saved a UTF8 String as byteArray) */ statusField.text = "Data loaded: "+(response.data as ByteArray).readUTFBytes( response.data.length ); } }, "12348781292947517838412");}

15.2 save( callback:Function, data:ByteArray , sc_id:string=null )

Saves the shared content data with the id provided or with a new id if sc_id is null (the id will be provided to the callback).

A response object is sent as the first parameter to the callback with the properties:

  • Boolean success successfully written?
  • int writtenBytes number of bytes written
  • string id sharedcontent_id saved (if you didn’t specified it, it will be a new id)
  • string errorType in case of error (false on success)
  • string errorMessage in case of error (false on success)

Some demo code:

/* Demo byteArray to be written (generated from a string but can be anything you want) */ var tmpByteArray:ByteArray = new ByteArray(); var date = new Date(); tmpByteArray.writeUTFBytes("Demo string "+date.toLocaleString()); /* Save data */ lechuck.sharedcontent.save(function(response:Object):void { if (response.errorType) { statusField.text = "Couldn't save data: "+response.errorMessage; } else { statusField.text = "Saved OK: "+response.writtenBytes+" bytes written"; } }, tmpByteArray, "12348781292947517838412" );}

16. DATASTORE module

Allows you to store user related content and retrieve it when needed, to keep things simple, the datastore are the “savegames”. There are 3 slots per user, 50kb each, numbered as: 0,1 & 2.

16.1 status( callback:Function )

Retrieves the status of the user slots. A response object is sent as the first parameter to the callback with the properties:

  • Array slots Slot objects {label:String, size:int, timestamp:Long} or null for empty slot. I.e.: [ { "label": "My custom label 1", /* slot label */ "size": 675, /* size in bytes */ "timestamp": 1361104327154 /* date stored */ }, null, null ]
  • int firstFreeSlot Number of the first free slot
  • string errorType in case of error (false on success)
  • string errorMessage in case of error (false on success)

Some demo code:

lechuck.datastore.status(function(response){ if (response.errorType || !response.status) { lechuck.logError("Something went wrong: "+response.errorMessage); } else { lechuck.logInfo("Slots:"); for (var i=0;i<response.slots.length;i++) { lechuck.logInfo( "Slot "+i+": "+(response.slots[i]==null ? "free":"used ("+response.slots[i].size+" bytes)"); ); } } });

16.2 load( callback:Function , slotNum:int )

Retrieves the datastore user slot data. A response object is sent as the first parameter to the callback with the properties:

  • ByteArray data Binary data (or null if none). If empty a 404 will be issued and an error will be logged
  • string errorType in case of error (false on success), "UNABLE_TO_LOAD" error will be issued if slot is empty or not found.
  • string errorMessage in case of error (false on success)

Some demo code:

/* Demo byteArray to be loaded (it cointains a utf8 string) */ /* Load data */ lechuck.datastore.load(function(response:Object):void { if (response.errorType) { lechuck.logError("Something went wrong: "+response.errorMessage); } else { lechuck.dump("This is the data recovered from the datastore"); lechuck.dump((response.data as ByteArray).readUTFBytes(response.data.length)); } }, 0); /* Load from slot 0 (first one) */

16.3 save( callback:Function, slotNum:int , data:ByteArray, label:string)

Saves binary data into an user slot, it overwrites any existing data, the label is optional. A response object is sent as the first parameter to the callback with the properties:

  • Boolean success successfully written?
  • int writtenBytes number of bytes written
  • string id sharedcontent_id saved (if you didn’t specified it, it will be a new id)
  • string errorType in case of error (false on success)
  • string errorMessage in case of error (false on success)

Some demo code:

/* Demo byteArray to be written (generated from a string but can be anything you want) */ var tmpByteArray:ByteArray = new ByteArray(); var date = new Date(); tmpByteArray.writeUTFBytes("Demo string "+date.toLocaleString()); /* Save data */ lechuck.datastore.save(function(response:Object):void { if (response.errorType) { lechuck.logError("Something went wrong: "+response.errorMessage); } else { lechuck.logInfo("Saved OK: "+response.writtenBytes+" bytes written"); } }, 0, tmpByteArray ); /* Save slot 0 (first one) */

16.4 reset( callback:Function, slotNum:int )

Erases an user slot. A response object is sent as the first parameter to the callback with the properties:

  • Boolean success successfully written?
  • string errorType in case of error (false on success)
  • string errorMessage in case of error (false on success)

Some demo code:

lechuck.datastore.reset(function(response:Object):void { if (response.errorType) { lechuck.logError("Something went wrong: "+response.errorMessage); } else { lechuck.logInfo("Deleted OK!"); } }, 0 ); /* Reset slot 0 (first one) */

17. ITEM module

The item module allows you manage the inventory of items bought by the user for your game and to initiate the purchase workflow right from within your game.

17.1 detail( callback:Function  )

Retrieves an item configuration. A response object is sent as the first parameter to the callback with the properties:

  • Object item item configuration, these are the properties of the object:
    • item.id Item id
    • item.uid Item uid (alphanumeric)
    • item.name Item name
    • item.is_enabled boolean flag, is the item enabled?
    • item.is_usabe boolean flag, is the item usable/consumable?
    • item.is_buyable boolean flag, can the item be purchased?
    • item.price_minicoins Item price in minicoins
    • item.max_stock Max stock of the item (for boolean items it will be 1)
  • string errorType in case of error (false on success)
  • string errorMessage in case of error (false on success)

17.2 list( callback:Function )

Retrieves the list of configured items for the game. A response object is sent as the first parameter to the callback with the properties:

  • Array items item objects (refer to 14.1)
  • string errorType in case of error (false on success)
  • string errorMessage in case of error (false on success)

17.3 inventory( callback:Function, options:Object )

Retrieves the items owned by an user (the user inventory). The following options are supported:

  • boolean withDetail include each item configuration (true by default)

A response object is sent as the first parameter to the callback with the properties:

  • Array items inventory items objects, each one with these properties:
    • items[x].id Item id
    • items[x].stock Item stock for the user
    • items[x].timestamp Last operation timestamp
    • items[x].item Item configuration object (refer to 14.1)
  • string errorType in case of error (false on success)
  • string errorMessage in case of error (false on success)

Some demo code:

lechuck.item.inventory(function(response){ if (response.errorType || !response.items) { lechuck.logError("Something went wrong: "+response.errorMessage); } else { lechuck.logInfo("User item inventory:"); for (var i=0;i<response.items.length;i++) { lechuck.logInfo( "Item "+response.items[i].item.uid + ":"+ response.items[i].stock + " units" ); } } }, {"withDetail": true});

17.4 stock( callback:Function, item_uid:string, options:Object )

Retrieves the item stock owned by an user. The following options are supported:

  • boolean withDetail include each item configuration (true by default)

A response object is sent as the first parameter to the callback with the properties:

  • number stock Item stock owned by the user
  • Array timestamp timestamp when it was saved
  • Object item Item configuration object if requested (refer to 13.1)
  • string errorType in case of error (false on success)
  • string errorMessage in case of error (false on success)

Some demo code:

lechuck.item.stock(function(response){ if (response.errorType || !response.item) { lechuck.logError("Something went wrong: "+response.errorMessage); } else { lechuck.logInfo( "Item "+response.item.uid + " stock for the user: "+ response.stock + " units" ); } } }, "ammo", {"withDetail": true});

17.5 eat( callback:Function, item_uid:string, qty:int, with_detail:Boolean = false )

Decrements the stock of an user item in any quantity, the item must be configured as usable, otherwise the operation will be forbidden. Optional withDetail parameter will get the item detail.

A response object is sent as the first parameter to the callback with the properties:

  • number newStock New item stock owned by the user after the operation
  • Object item Item configuration object if requested (refer to 14.1)
  • string errorType in case of error (false on success)
  • string errorMessage in case of error (false on success)

Some demo code:

lechuck.item.eat(function(response){ if (response.errorType || !response.item) { lechuck.logError("Something went wrong: "+response.errorMessage); } else { lechuck.logInfo( "Item "+response.item.uid + " decremented "+qty+" units. New stock "+ response.newStock + " units" ); } } }, "ammo", 100, true);}

17.6 userLog( callback:Function , options:Object)

Retrieves the log from an user items (every items).

The following options are supported:

  • boolean withDetail include each user basic detail (true by default)
  • boolean withProgress include each user progress level
  • boolean withSharedContent to check if it has shared content and get the id
  • number limit number of items to retrieve (20 by default)
  • number startScore starting score, inclusive (exclusive if no timestamp sent)
  • number startTimestamp starting timestamp (in milliseconds), exclusive.
  • Response: data.log Arrray of log rows with these properties:
    • data.log[x].item_id Item id
    • data.log[x].item_uid Item uid
    • data.log[x].user_id User id
    • data.log[x].timestamp Timestamp of the operation
    • data.log[x].op_amount Amount incremented/decremented
    • data.log[x].op_new_stock Resulting stock
    • data.log[x].from_api Boolean, was the operation an API request?
    • data.log[x].from_ip Ip that originated the operation
    • data.log[x].minicoins Amount of minicoins

17.7 buy( callback:Function, items:Object)

Initiates the purchase items with Minicoins workflow (fully handled by us) an object with the items uids and amount that the user is going to purchase must be provided. The items uids are available on your development sandbox, as well as some interesting stuff (like an item reset tool or a log). On your development game all items are free, on the production game they’re paid, please contact us in order to define and configure the items along with their price, there’s no limit of items that can be configured.

This is a sample items purchase object, 100 units of amo and 1 shield unit:

{"ammo": "100", "shield": 1 }

Once the item/s have been purchased (or cancelled) a response object is sent as the first parameter to the callback with the following properties:

  • boolean success Were some items purchased?
  • Array items Items purchased, each one with these properties:
    • items[x].id Item id
    • items[x].qty Amount purchased
    • items[x].stock item total stock owned by the user
  • string errorType in case of error (false on success)
  • string errorMessage in case of error (false on success)

Some demo code:

lechuck.item.buy(function(response){ if (response.errorType == "CANCELLED") lechuck.logError("User cancelled"); else if (response.errorType || !response.success) { lechuck.logError("Something went wrong: "+response.errorMessage); } else { lechuck.logInfo("Items purchased:"); for (var i=0;i<response.items.length;i++) { lechuck.logInfo( "Item "+response.items[i].uid + ":"+ response.items[i].qty + " units bought / new stock: " + response.items[i].stock ); } } }, {"ammo": 100, "shield": 1});

SPECIAL CASE: DYNAMIC ITEMS

For selected developers and complex games we support an additional type of items called "dynamic", which allows you to set a custom title and price for an item when you initiate the purchase workflow via any of our client apis. To prevent any modification of the payload, these items purchases must be validated server-side, we will always ask you if the user can purchase the dynamic item with the data that you provided us.

Check the Javascript API for more info about dynamic items.

Appendix 1: Local debugging tips & tricks

We’ve discussed in various sections (3, 4 & 8) about the restrictions & limitations of the flash sandbox when running local applications. Here are a few tips to help you debugging your games faster and easier.

Do not use the file protocol

Flash blocks remote communications when using the file:/// protocol (local), neither our API or the communication with our API servers will be allowed.

Run a local webserver

  1. Create a local development platform, by installing any of the free webservers available for various platforms, like XAMPP, or Zend Server (both free).
  2. Put your game within the webserver document root path and check it’s running, i.e. http://localhost/myGame
  3. Configure your game project to be saved there and to debug the url of your game .
  4. If you need customizations you can even host your own version of our Sandbox template and put it here: http://localhost/myGame/index.php (for example).
  5. Ask us to link the development version of the game to your flash game http://localhost/myGame/myGame.swf (if you’re using our sandbox) or if you have your custom sandbox, to link the game iframe to your own http://localhost/myGame/index.php  
  6. Test it and while you’re ready, ask us to publish your game (send us the files of your game if you want us to host it or send us your production url).
  7. Your game will be published in our sites and you can still have access to your development version to perform changes (do not forget to send us again your files if they’re hosted by us).

Use a web debugger proxy tool:

We recommend you to use some web debugger proxy tool, like Charles or Fiddler, it allows you to map remote resources to local ones for debugging purposes, that’s super handy for flash developers. If you don’t want to run a local webserver we can put a dummy swf into the development page for your game and you can map it to your own local game swf to make as many tests and remote debug sessions as you want, great, isn’t it?.

FTP Account

In case you still prefer another approach we can provide you a temporary FTP account that you can use to upload your game files for testing purposes, just be noticed that PHP support is not enabled. Contact us if you need one.

Appendix 2: Detecting internal / external games

In the case that your game SWF is copied and published elsewhere, it will be highly limited due of the non-presence of the JS API causing the game to be unable to communicate with our site (to show highscores, achievements, maximize the game, show user comments, share the game... etc).

This is automatically handled by our lechuck.user.login() method, if the game is not running inside our site, the user will be redirected automatically to our site.

If you want to provide better insight to the user, it's a very good practice to check wheter the game is running from one of our sites or not, you can do this by calling the lechuck.environment.isExternal() method, it will return true if it's not in our site, so you can change the "please log in" button for a "Play in MiniPlay" button (that also calls the lechuck.user.login() method).

Do you have questions or want to report some bugs? please contact us at [email protected]