Boss Flox

Tips and tricks for working with Gamua Flox: query restrictions, combining properties, and clean implementations using static helpers.

Boss Flox I've mentioned before that we are big fans of Gamua and the frameworks/services they are responsible for. We've been using Flox a fair bit recently, first for Proleague and more recently Pogosheep, and it is a really awesome library (we even wrote a port for GameMaker). Because it is a relatively new service, there aren't too many guides out there, so I thought I'd write something a bit different, an n-part (probably 2-part) series on tips-and-tricks when using Flox. More after the jump. Query Restrictions So you may have noticed that there are some pretty tight restrictions imposed on Queries, you can't index more than two properties and you can't use more than one inequality filter (that's any of <, <=, >=, >, !=). They're there for good reason, Flox is built on the Google App Engine and going outside these constraints would cause prices to skyrocket. So how do you get around this problem? Easy! You select everything and then filter in flash right? var pid:String = Player.current.id; var q:Query = new Query("Match"); // Select all the matches that this player is a part of q.where("ownerId == ? || opponentId == ?", pid, pid); q.find(function onComplete(broad:Array):void { // Reduce the results by removing all the matches that have been seen var results:Array = broad.filter(function(m:Match, i:int, a:Array):Boolean { return ((m.ownerId == pid && m.ownerHasSeen == false) || (m.opponentId == pid && m.opponentHasSeen == false)); }); }, function onError(error:String, httpStatus:int):void { // Do something with the error }); In the above example we are selecting all the Matches that the current player is a part of (either as the owner or the opponent) and then we are filtering out all the matches they have already seen. Though it may seem *okay* this method has two pretty serious drawbacks: If you have more results than the limit (50 by default) then you may be dropping credible results in place of results that have already been seen. You can get around this by paginating, but it means you need to load every page before doing the filter pass. This whole process has two very critical performance implications. The first is that the filter pass can be a big sticking point depending on how complex the query, and the second is that if you are serialising a number of results just to toss them back out, you create A LOT of garbage, something that can absolutely kill AS3 performance. Despite the above issues, this example is actually exactly what we used as a first pass for Proleague. Perhaps you are like we were and you know that this feels yuck, but what else can you do? Combining Properties Using the example from above, lets start by thinking of the ideal query we'd like to make. We always want matches that haven't been seen by the owner, so something like the following would work. "(ownerId == ? AND ownerHasSeen == false) OR (opponentId == ? AND opponentHasSeen == false)" But of course, this is using four property indexes, something that can not be done with Flox. So what can we do? Well what if we had a single property like the following? "ownerId_ownerHasSeen == ? OR opponentId_opponentHasSeen == ?" From a single property we could find both the player id and whether or not they had seen the match. But what would those properties look like? "abcdefg123-1" // Player id + true for the player having seen the match "abcdefg123-0" // Player id + false for the player having not seen the match In this example abcdefg123 is the player id and then we concat a '-' followed by '1' or '0' for whether or not the player has seen the match. The way you construct this combined property is irrelevant, you just need to decide on a format that will easily allow you to extract the information from the property. Now we can find out all the information we need and we only need two indices to do it! Implementation Because this is an optimisation specific to the Match entities I feel that this is a great time for some static helper functions. Using…

Contact hi@3dx.nz or request a quote.