Jump to content


Photo
* * * * * 5 votes

Flox: Asynchronous Multiplayer


  • Please log in to reply
30 replies to this topic

#1 Rani_sputnik

Rani_sputnik

    GMC Member

  • GMC Member
  • 482 posts
  • Version:GM:Studio

Posted 27 June 2014 - 12:19 AM

  • Title: Flox: Asynchronous Multiplayer
  • Description: A how-to-guide to 1) using the Flox backend service and 2) creating a turn-based multiplayer game that players can play without needed to be online at the same time.
  • GM Version: GMStudio
  • File Type: .gmz
  • File Size: 962KB
  • File Link: async-multiplayer.gmz
  • Required Extensions: None.
  • Required DDLS: None.
  • Tags: GMCTUTORIAL GMCSERVER Flox Turn-Based Asynchronous Multiplayer

Summary

In this tutorial I will take you through an example that comes the FloxGM that teaches you how to create an asynchronous multiplayer game. It will require a few minor modifications to get the example running and will provide you a jumping off point for creating your own game. 

 

Signing up

Flox is a backend service for saving data / recording analytics / leaderboards / login etc. You will need to sign up and add a new game before getting started. Don't worry! It's free for the first 1,000,000 operations and you wont run out anytime soon, I promise. 

 

Once you've got that done, download the zip and we'll get started!

 

Add your game

First thing, open up Game Maker Studio and import the flox.gmz file included in the zip. This project includes the entire flox library, but we're only interesting in the stuff inside the 'ExampleGame' folders. Jump into objects and open up objGame. There is only one script in objGame called 'initialize' open this up and take a look at the code.

/// Initialize
currentMatch = noone;
// Replace these with values from your flox control panel
// @https://www.flox.cc/panel
flox_init("YOUR_GAME_ID","YOUR_GAME_KEY","0.1");

Before our game can connect to flox, we need to change "YOUR_GAME_ID" and "YOUR_GAME_KEY" to the actual values found in your flox control panel. When you added your game you should have arrived at a screen like this.

 

21kl82t.png

 

Just ignore the steps, head straight for Game Info. On that screen there will your games logo, it's title, an id and a key. Copy the id and replace "YOUR_GAME_ID" with it, then do the same for your key. Sweet!

 

Running the game

Now that you're initializing your game with Flox, we're ready to run the game! Hit the play button and you should see a login screen like the following.

 

2afkcqc.png

 

Our game is made up of 3 screens. rmLogin (the screen we are on now), rmMatchList (a list of all the matches a player is currently taking part in), and rmMatch (the screen where the actual 'Game' happens). Login with your email, and you'll be taken to the rmMatchList. But uh oh! What's this?

 

30upr1f.png

 

Never you mind! We'll get around to fixing that soon! Click the create match button. You'll be prompted to enter an opponent, just enter any name for now and you'll be taken to rmMatch. In this 'game' players take turns placing birds on the map. It's your turn so click somewhere you want to place a bird and hey presto we get a nifty 'waiting for opponent' screen. 

 

2dam2wg.png

 

Click on the little 'list' icon to return to the match list (It should still tell you 'Failed to load matches'). Okay so while that may not seem like much, we have everything here to provide the skeleton for a asynchronous multi-player game.

 

Player login

Close the game down. If you check the flox control panel you'll start to see some interesting stuff. Click on 'Players' on the left hand side and you should see a list with one player in it with a really weird name. Notice though, the little green 'email' tag next to them. Click on the player and you should see the following.

 

x43hjk.png

 

We can see the players id when they were created, their email and any other properties they contain. You can even add properties on the fly (without writing any code!) by hitting the little plus icon beneath "This entitiy has no properties." but we wont do that right now. So this player is you! And if you were to login on another device, all your information would be pulled down onto that device when you login :D cool right? Lets take a look at the code that makes it all happen, open up objLoginEmail. This object is the email button you clicked on to login. In the create event there are two scripts one for initializing some variables and another to "Check if the player is a guest". Open that script up.

/// Check if the player is a guest
var player = flox_player_get();
var authType = flox_entity_get(player,fx_auth_type);
// If the player isn't a guest (loaded from cache) then go straight to the match list
if authType != fx_guest {
    room_goto(rmMatchList);
}

When the login screen opens this is the first important thing that happens. You'll notice that if you run the game again, it wont ask you to login. That's because your details were saved to the device. The first time you run flox, it creates a 'guest' player for you. Once you login with your email, the guest player becomes a new email player and is used instead. In this code we simply check the player is not a guest and go straight to the match list. Close that script.

 

Okay so what about the code to login a guest with their email? Well there's three parts. First is the Left Released event that calls get_string_async to ask the player to enter their email. Second is the Dialog event, open that script up.

/// Handle the player name
if (ds_map_find_value(async_load,"id") == asyncString) {
    if (ds_map_find_value(async_load,"status")) {
        // Get the email the player entered
        email = ds_map_find_value(async_load,"result");
        // Login with that email
        flox_player_login_email(email,scrLoginComplete,scrLoginError);
        // Show a loading indicator
        loadingIndicator = instance_create(x,y,objLoadingIndicator);
        visible = false;
    }
}

While it may seem like a fair bit of code, it's mostly just dressing. The critical part is flox_player_login_email. With this script we are providing the email to login with, and the scripts to call when it completes or fails. Lets take a look at what one of these 'Callback' scripts looks like. Expand the ExampleGame folder and open the scrLoginComplete script.

room_goto(rmMatchList);

Wow, that's nice and simple, how about the scrLoginError?

with loadingIndicator instance_destroy();
visible = true;
errorMessage = argument0;

Not bad either! Only one of these scripts will be called, to notify of either the success or failure of the request. Callbacks get executed in the same context they were called in so because objLoginEmail called flox_player_login_email, the scripts are called by objLoginEmail. Note the following.

errorMessage = argument0;

Here we are setting the errorMessage property of objLoginEmail so that it can display the error to the person playing. But how do we know argument0 is an error message? Well if you race over to the FloxGM topic, you can browse through the 'Complete API' section. Under Authentication, we can see the following

flox_player_login_email(String email,
    Script(Entity player) onComplete,
    Script(String error, Real httpStatus, Boolean confirmationMailSent) onError)

This little snippet of documentation shows us the format of our scripts. We can see the onComplete script (scrLoginComplete) takes one argument, an Entity that is the player that was logged in. Likewise our onError script (scrLoginError) takes three arguments and argument0 is the error string; the reason the login failed!

 

Okay phew. That was a lot to take in, read back over it if you need to then lets move on.

 

Entities

Next jump into the entities section of the control panel. You'll see a list containing one item, Match. This is a list of all the entities in your game and as you can see we only have one entity type. Although that's not strictly true, there is one more entity type that isn't included in this list and that is player. That's right! Players are actually just a special type of entity, and you can use all the same functions you will use on entities on players. Now click through Match and you'll see a list of all the matches you've created. Select one of those matches from the list and you should see the following. 

 

2gxfk9j.png

 

You can see it's very similar to the Player with a few notable exceptions.

 

There are two new properties in the header, Owner and Public Access. Owner is the player who has the final say on what happens to this entity. The player that currently owns the entity can change ownership by setting the owner property to the id of another player. Public Access defines what rights other players have to this entity. Read & Write means any player can make changes to this entity, we need this in order to allow the opponent to submit their turns. Entities can also have Public Access Read Only or None. So why are these properties not included for Players? Well simple really, a players Owner can only ever be themselves, and a players Public Access is always Read Only. It's not that a Player doesn't have these properties, it is that they can not be changed.

 

The other difference you'll notice are those custom properties down the bottom. Any entity (including players) can have any custom properties that you want. Properties can be a real value, string, map or list, and are set in code. While you can technically have entities of the same type have different custom properties, it's useful to keep custom properties consistent. All Matches will have these four custom properties and that will help keep our code clean and our brains tangle-free. 

 

So how do we create entities, well lets open up objCreateMatch. In the create event we initialize some variables, in the left released we use get_string_async to ask the player for an opponent and then finally in the Dialog event we process the input. Open up the code block in the Dialog event.

/// Handle the opponents id
if (ds_map_find_value(async_load,"id") == asyncString) {
    if (ds_map_find_value(async_load,"status")) {
        opponent = ds_map_find_value(async_load,"result");
        scrSetCurrentMatch(scrCreateMatch(opponent));
    }
}

This is a pretty simple script really, we are using two custom scripts, one to create a match with the opponent the player specified and one to set the current match to the match we just created. Open up scrCreateMatch first.

var vsPlayerId = argument0;
var me = flox_player_get();
var myId = flox_entity_get(me,fx_id);
// Create the match
var match = flox_entity_create("Match");
// Allow this match to be edited by other players
flox_entity_set(match,"publicAccess",fx_read_write);
// Set the opponent's id and who's turn it is
flox_entity_set(match,"opponentId",vsPlayerId);
flox_entity_set(match,"waitingForPlayer",myId);
// Keep a record of the turns
// remember to use set_list/set_map when save data structures
flox_entity_set_list(match,"ownerTurns",ds_list_create());
flox_entity_set_list(match,"opponentTurns",ds_list_create());
// Save the match to the server
flox_entity_save_queued(match);
// Return the match we just created
return match;

While this may be quite a bit of code, all we're really doing is setting some default properties on our match. We create it with flox_entity_create. We modify it's public access to be Read & Write (it is None by default). We set some properties (note the difference between flox_entity_set and flox_entity_set_list) then finally we save it to the server and return it.

 

Two final points, notice that we use flox_player_get to retrieve the current player and then use flox_entity_get to get the players id. Again Players are just entities and you can use any of the entity functions on them. Secondly we use flox_entity_save_queued to queue the match to be saved some time in the future. If we were saving something really important like purchase info and we need to know it saved successfully, we can use flox_entity_save instead.

 

Now lets open up scrSetCurrentMatch

var match = argument0;
var game = instance_find(objGame,0);
game.currentMatch = match;
room_goto(rmMatch);

This nice and simple script just takes the match passed to it and changes to the game room. Once there objMatchControl picks up the current match from objGame and applies the turns each player has made.

 

Right now it's finally time to get rid of that pesky "Failed to load matches" message.

 

Queries

Once you have entities saved to the server you can retrieve them using flox_entity_load_type but that requires you to know the id of the entity you want to load. What if you don't know it? You just want to select an entity (or entities) based on properties the entity contains? Well that's what queries are for! 

 

Lets first work through what our query may look like. We want all the Matches that we are taking part in and we can find out who owns a Match using ownerId, so in SQL that might look something like this.

WHERE ownerId == 'myid'

That'll select all the matches we own. But wait, what about if we are the opponent? We need to select those matches too, so what about something like this...

WHERE ownerId == 'myid' OR opponentId == 'myid'

That'll do it! We are querying two properties ownerId and opponentId to see if either of them match our id. But this is SQL what does this look like in GML? Open up objMatchList. In the Create Event we have one code block for initializing a bunch of graphical/layout settings and another for loading matches. Open the "Start loading the matches" code block.

var player = flox_player_get();
var playerId = flox_entity_get(player,"id");

loading = true;
matchesToDisplay = ds_list_create();
// Query all matches from the server
flox_query_begin("Match");
// Filter them by removing any that do not include us as the
// owner or the opponent
flox_query_where("ownerId == ? OR opponentId == ?",playerId,playerId);
flox_query_find(scrMatchListComplete,scrMatchListError);

You can see that here again we are getting the player's id. We begin a query for "Match" entities and then we add constraints to the query with flox_query_where. You can see that the query looks almost identical to the SQL query, except we are using ? (called placeholders). These question marks simply get replaced with whatever else is passed to the where function so here the first ? is replaced with argument[1] (playerId) and the second ? is replaced with argument[2] (playerId again). 

 

The last line flox_query_find is what kicks off the query, all queries you create will follow this format begin -> constraints -> find. Lets pop open scrMatchListComplete and see what happens when the query succeeds.

// Destroy the old list 
if ds_exists(matchesToDisplay,ds_type_list) {
    ds_list_destroy(matchesToDisplay);
}
// Set the new list of matches to display
matchesToDisplay = argument0;
// We are no longer loading
loading = false;

Pretty simple, if there was an old list of matches destroy it then set the list of matches to display to the new list the query has returned. So what about scrMatchListError?

var error = argument0;
var httpStatus = argument1;
// Show a message to indicate that the load failed
show_message_async("Failed to load matches");
// We aren't loading any more
loading = false;

We can see that's where that pesky "Failed to load matches" is coming from. Change the "Failed to load matches" to the error variable instead. You can see again this error callback receives an error message in argument0. Run the game again and you should see a new error message.

 

 

A required index is missing: Make sure that an index in the form of ' ownerId opponentId' exists.

 

How very cryptic, let me explain. To select any property, an index must exist for that entity type and specific property. Flox uses these indexes to find the results that are relevant for your specific query. We set up indexes via the control panel so switch back to your browser and select the "Indices" section from the left hand side. You'll notice a giant blue button saying "Add Index", click it!

 

qrz1p2.png

 

Creating indices is really easy, especially with that error message, because it tells us exactly how our properties should be arranged 'ownerid opponentId'. Hit create then run the game again. If you've done it right, you should have much more success this time.

 

2iv1ohu.png

 

 

Try logging in with another email, you should be able to go back and forth no problem. 

 

Wrap-up

So that's it, a pretty in-depth introduction to Flox and building your own asynchronous multi-player game. This serves as a pretty good foundation to build from so take a look through the other scripts, ask questions and let me know if you have any problems.

 

If you liked this tutorial or would like to support the project, please consider making a donation.

 

Happy Game Making, R. 


Edited by Rani_sputnik, 08 February 2016 - 09:10 AM.

  • 7

My games - In DecemberBoy Goes to Space

Utilities & Extensions - FloxGM, Destroyable Terrain

Check out my website: ryanloader.me, or follow me: twitter.com/RaniSputnik


#2 chance

chance

    GMC Member

  • Global Moderators
  • 8762 posts
  • Version:GM:Studio

Posted 27 June 2014 - 12:56 AM

This is a VERY extensive tutorial.  I haven't gone through and tried everything, but reading the topic seems fairly clear.  And the download is well organized. 

 

It is, however, very extensive and fairly complex -- so I wouldn't recommend this for beginners  On the other hand, you probably don't need to understand all the details in order to use it.  So I'm eager to see what members can do with it by just following the instructions in the tutorial.

 

Nice effort on this, rani.  :thumbsup:  I hope to see some members put this to use.


  • 0

#3 Rani_sputnik

Rani_sputnik

    GMC Member

  • GMC Member
  • 482 posts
  • Version:GM:Studio

Posted 27 June 2014 - 01:25 AM

Thanks Chance, that's exactly what I was going for. 

 

All the information is there for anyone who wants it but you don't need to know it all in order to use it.


  • 0

My games - In DecemberBoy Goes to Space

Utilities & Extensions - FloxGM, Destroyable Terrain

Check out my website: ryanloader.me, or follow me: twitter.com/RaniSputnik


#4 Ruub

Ruub

    Finn The Human

  • GMC Member
  • 762 posts
  • Version:GM:Studio

Posted 30 June 2014 - 07:50 AM

Impressive Rani! Do advertise this on more fora!


  • 0

#5 Drwahlen

Drwahlen

    GMC Member

  • New Member
  • 13 posts
  • Version:GM:Studio

Posted 13 July 2014 - 10:12 PM

Is there an easier way to enter your opponents id? the id's are really long


  • 0

#6 Rani_sputnik

Rani_sputnik

    GMC Member

  • GMC Member
  • 482 posts
  • Version:GM:Studio

Posted 13 July 2014 - 10:52 PM

@Ruub thank you! I will do once more bugs have been ironed out

 

@Drwahlen yep. This is just a really simple example of how to create the game, but if you were actually taking this forward you'd want to implement some kind of player alias. To do this you would probably add a property to your players, something like avatar or displayName. From there you have a few options

  1. Query all players and let a player select a player from the list.
  2. Ask the player for a name and then query the player with that name.

Those are just a couple of ideas though, you can really do anything you like. I'll probably end up adding this to the tutorial, but the goal was to make it as quick to get up and running as possible. Of course when allowing players to enter their name you have to handle duplicate names among other things. I didn't want to make it more complicated! :)

 

Cheers, R.


  • 0

My games - In DecemberBoy Goes to Space

Utilities & Extensions - FloxGM, Destroyable Terrain

Check out my website: ryanloader.me, or follow me: twitter.com/RaniSputnik


#7 Drwahlen

Drwahlen

    GMC Member

  • New Member
  • 13 posts
  • Version:GM:Studio

Posted 18 July 2014 - 05:58 PM

Ok great, I'll give it a go. I was deterred by ugliness of the player ids. Thanks for introducing this!


  • 0

#8 Rani_sputnik

Rani_sputnik

    GMC Member

  • GMC Member
  • 482 posts
  • Version:GM:Studio

Posted 19 July 2014 - 05:22 AM

Just updated Flox to version 0.2.3. Would highly recommend the upgrade for anyone on 0.2.2, it brings a huge amount of bug-fixes and optimisation.

 

Cheers, R.


  • 0

My games - In DecemberBoy Goes to Space

Utilities & Extensions - FloxGM, Destroyable Terrain

Check out my website: ryanloader.me, or follow me: twitter.com/RaniSputnik


#9 Nocturne

Nocturne

    Nocturne Games

  • Administrators
  • 25708 posts
  • Version:GM:Studio

Posted 19 July 2014 - 07:11 AM

Fantastic tutorial. Moved to Staff Choice!


  • 0

U1FVsm3.png

40799.png


#10 Rani_sputnik

Rani_sputnik

    GMC Member

  • GMC Member
  • 482 posts
  • Version:GM:Studio

Posted 25 July 2014 - 11:14 PM

Version 0.3.0 released

 

Anyone who downloaded the previous version and found it to be horribly buggy, my sincerest apologies. New version should be far more stable.

This version adds leaderboards, these will be worked into the tutorial (or a separate one) soon.

 

Cheers, R.


  • 0

My games - In DecemberBoy Goes to Space

Utilities & Extensions - FloxGM, Destroyable Terrain

Check out my website: ryanloader.me, or follow me: twitter.com/RaniSputnik


#11 mrkitt

mrkitt

    GMC Member

  • New Member
  • 3 posts
  • Version:GM:Studio

Posted 10 September 2014 - 02:51 PM

Hi Rani, i got a problem when running the example. It said:

Error in Object objMatchList, Event Glob Left Released, Action 1 at Line 7, Position 10: Unknown function or script: scrSetCurrentMatch
Error in Object objMatchControl, Event Create, Action 1 at Line 36, Position 2: Unknown function or script: scrPlaceBirds
Error in Object objCreateMatch, Event Dialog, Action 1 at Line 5, Position 10: Unknown function or script: scrSetCurrentMatch

 

Thank in advance


  • 0

#12 Rani_sputnik

Rani_sputnik

    GMC Member

  • GMC Member
  • 482 posts
  • Version:GM:Studio

Posted 11 September 2014 - 08:56 PM

Hi mrkitt! Thanks for letting me know, I'll take a look at this tonight.

 

Cheers, R.


  • 0

My games - In DecemberBoy Goes to Space

Utilities & Extensions - FloxGM, Destroyable Terrain

Check out my website: ryanloader.me, or follow me: twitter.com/RaniSputnik


#13 mrkitt

mrkitt

    GMC Member

  • New Member
  • 3 posts
  • Version:GM:Studio

Posted 18 September 2014 - 08:39 AM

Any update of this Rani?


  • 0

#14 Lucky Duck

Lucky Duck

    GMC Member

  • Banned Users
  • 155 posts
  • Version:GM:Studio

Posted 18 September 2014 - 11:31 AM

Thanks.. It's an amazing tutorial.

#15 Rani_sputnik

Rani_sputnik

    GMC Member

  • GMC Member
  • 482 posts
  • Version:GM:Studio

Posted 18 September 2014 - 08:42 PM

@LuckyDuck thanks, glad you liked it!

 

@mrkit you may need to download and try again, do you have the ExampleGame folder in your scripts? Also what version of GameMaker:Studio are you using? I just downloaded and it imported fine.

 

Cheers, R.


  • 0

My games - In DecemberBoy Goes to Space

Utilities & Extensions - FloxGM, Destroyable Terrain

Check out my website: ryanloader.me, or follow me: twitter.com/RaniSputnik


#16 Knight81

Knight81

    GMC Member

  • GMC Member
  • 33 posts
  • Version:GM:Studio

Posted 22 September 2014 - 07:30 AM

Great tutorial. But I get the following error when try the example game:

Login OK

Create OK

Place bird ERROR

Game maker studio 1.3.1386

 

I trace the bug to map_create>map_meta_set_name

When in the debugger and step the code in map_create it works. But when I run it without step I get the error.

This is for sure a Game Maker error. The ds_map (id for me is 8) is not created fast enof. Or maybe you created too many consecutively.  And when the code wants it in map_get it does not exists yet, maybe? Or it may be a windows 8.1 error.

 

___________________________________________
############################################################################################
ERROR in
action number 1
of Mouse Event for Glob Left Released
for object objMatchControl:
 
Data structure with index does not exist.
 at gml_Script_map_get (line 6) - if not ds_map_exists(map,key) {
############################################################################################
--------------------------------------------------------------------------------------------
stack frame is
gml_Script_map_get (line 6)
called from - gml_Script_i_flox_cache_set (line 14) - var contentType = map_get(metadata,"ds-type");
called from - gml_Script_i_flox_service_request_queued (line 15) -     i_flox_cache_set(path,data,meta);
called from - gml_Script_flox_entity_save_queued (line 1) - // flox_entity_save_queued(entity)
called from - gml_Object_objMatchControl_GlobalLeftButtonReleased_1 (line 25) -     flox_entity_save_queued(match);

  • 0

The-any-Key

My games: Google Play


#17 Rani_sputnik

Rani_sputnik

    GMC Member

  • GMC Member
  • 482 posts
  • Version:GM:Studio

Posted 22 September 2014 - 08:59 PM

@Knight81 thanks for reporting, I started getting this one too so I've been digging for a little while. I've been trying to convert everything over to the map_ functions I made so I have a hope of debugging the issue. I am really busy at the moment though, so I'm not sure when I'll get time to hunt for this, *hopefully* this weekend.

 

Apologies, I'll get onto it as quickly as I can :)  R. 


  • 0

My games - In DecemberBoy Goes to Space

Utilities & Extensions - FloxGM, Destroyable Terrain

Check out my website: ryanloader.me, or follow me: twitter.com/RaniSputnik


#18 mrkitt

mrkitt

    GMC Member

  • New Member
  • 3 posts
  • Version:GM:Studio

Posted 30 September 2014 - 05:01 AM

Hi Rani, sorry for late reply.
I'm using the latest version of it. I think the function is not created yet and i'm just following your tutorial, well, just doing a test and that happend.


  • 0

#19 river-wind

river-wind

    GMC Member

  • New Member
  • 4 posts
  • Version:GM:Studio

Posted 08 February 2015 - 06:25 PM

Hey Rani, thanks for this library!   (I'm running GM:S 1.4.1474)

 

I was digging into the above error, and traced it to two issues:

 1) In a few scripts, such as i_flox_service_cache_result, "ds-type" is added to a map, and then later get_map(meta,"ds_type") is called.  (dash v. underscore)

 

 2) In the script i_flox_cache_remove, the actual map containing ds_type is destroyed if a cached copy exists, but is not rebuilt from that cached copy.  see below line:  "if contentType == ds_type_map then map_destroy(existingData);"

 

// flox_cache_remove(key)


var key     = argument0;
var metakey = i_flox_cache_get_metadata_key(key);


var cache = i_flox_get_cache();
// Make sure to destroy any existing data structures
if ds_map_exists(cache,key) {
    var existingData = map_get(cache,key);
    var existingMeta = map_get(cache,metakey);
    if map_exists(existingMeta) {
        var contentType = map_get(existingMeta,"ds_type");
        if contentType == ds_type_map then map_destroy(existingData);
        else if contentType == ds_type_list then ds_list_destroy(existingData);
        map_destroy(existingMeta);
    }
}
ds_map_delete(cache,key);
ds_map_delete(cache,metakey);

 

 

 

I had two other errors that I managed to find work arounds for:

 

I was getting an error on the httpstatus check which was killing the demo game - it turned out that the server status was coming back "OK" (RawResponse is  "{"status":"ok","version":"1.0"}"), when the script flox_httpstatus_is_success is checking for a number.  I added a line to see if the result is a string, and if so to check for OK before doing "return argument0 > 0 and argument0 < 400;"  Maybe Flox changed the server responses in certain cases? 

 

I was getting a similar error (very often, though only appearing while in debug mode), where the http status result returns just OK (RawResponse is  "{"status":"ok","version":"1.0"}"), and no entry with the key "headers" is included.  In this case, the objFlox Step code throws a warning when trying to assign the headers value to a local variable.  I added an IF to check if the headers key pair is available in the map before attempting to assign it, and the warning stopped appearing - I'm not sure what impact having the headers variable unset may have elsewhere in the code, but I haven't seen subsequent errors.


Edited by river-wind, 08 February 2015 - 06:33 PM.

  • 0

#20 Rani_sputnik

Rani_sputnik

    GMC Member

  • GMC Member
  • 482 posts
  • Version:GM:Studio

Posted 09 February 2015 - 06:50 AM

Hi river-wind thanks for the heads up!

 

I'm hoping to release the next version of the library in two weeks time, I'll make sure it fixes the issues you mentioned.

 

Cheers, R.


  • 0

My games - In DecemberBoy Goes to Space

Utilities & Extensions - FloxGM, Destroyable Terrain

Check out my website: ryanloader.me, or follow me: twitter.com/RaniSputnik


#21 extenz

extenz

    GMC Member

  • New Member
  • 1 posts
  • Version:GM:Studio

Posted 01 March 2015 - 10:30 AM

404 :c


  • 0

#22 Rani_sputnik

Rani_sputnik

    GMC Member

  • GMC Member
  • 482 posts
  • Version:GM:Studio

Posted 05 March 2015 - 01:17 AM

Hey sorry extenz, fixed.


  • 0

My games - In DecemberBoy Goes to Space

Utilities & Extensions - FloxGM, Destroyable Terrain

Check out my website: ryanloader.me, or follow me: twitter.com/RaniSputnik


#23 Rani_sputnik

Rani_sputnik

    GMC Member

  • GMC Member
  • 482 posts
  • Version:GM:Studio

Posted 06 March 2015 - 11:45 PM

Updated for latest version of Flox 4.1! It's finally here!!! Whoo hoo! See the Flox topic for more details on this release.


  • 0

My games - In DecemberBoy Goes to Space

Utilities & Extensions - FloxGM, Destroyable Terrain

Check out my website: ryanloader.me, or follow me: twitter.com/RaniSputnik


#24 lillbubs

lillbubs

    GMC Member

  • GMC Member
  • 187 posts
  • Version:GM:Studio

Posted 19 April 2015 - 02:06 PM

link is dead


  • 0

#25 Rani_sputnik

Rani_sputnik

    GMC Member

  • GMC Member
  • 482 posts
  • Version:GM:Studio

Posted 19 April 2015 - 08:50 PM

Apologies! Should be all fixed now, it appears that Bitbucket really doesn't like things being uploaded with the same name :/


  • 0

My games - In DecemberBoy Goes to Space

Utilities & Extensions - FloxGM, Destroyable Terrain

Check out my website: ryanloader.me, or follow me: twitter.com/RaniSputnik


#26 EvandroWP

EvandroWP

    GMC Member

  • GMC Member
  • 52 posts
  • Version:GM:Studio

Posted 24 December 2015 - 09:38 PM

Really nice, Rani! I'll take a look. 


  • 0

#27 EvandroWP

EvandroWP

    GMC Member

  • GMC Member
  • 52 posts
  • Version:GM:Studio

Posted 28 December 2015 - 11:28 AM

Rani, in the game room there is a way to check if the opponent made his move and refresh the room?


  • 0

#28 Rani_sputnik

Rani_sputnik

    GMC Member

  • GMC Member
  • 482 posts
  • Version:GM:Studio

Posted 29 December 2015 - 02:55 AM

Hey Evandro! 

 

There isn't a way to do it without polling. Basically you would do it by calling flox_entity_refresh() every minute or so, updating the game if the data changes.

 

You probably don't want Flox if you are looking for a real-time experience, but the above method would work well. If there is no change in the data, Flox will send back a "not modified" response, so the overhead of polling is pretty minimal.

 

So code! You would add something like the following to an alarm event on the objMatchControl object.

/// Refresh the current match data every minute or so

flox_entity_refresh(match,scrMatchRefreshComplete,scrMatchRefreshError);
alarm[0] = room_speed * 60;

Then add a script called scrMatchRefreshComplete like so;

/// scrMatchRefreshComplete(entity,modified)

// Free up the existing match entity
// we have now loaded a new copy of it
if (flox_entity_exists(match))
{
    flox_entity_free(match);
}

// Update the references to the current match
match = argument0;
game.currentMatch = match;

// If the match has been updated since the
// last time the match was requested, then
// update the game to reflect the changes
if (argument1)
{
    // TODO update the game with the new moves
}

You can probably just leave the error script blank, silently failing in the background, or you could increase the poll interval (if requests are failing, probably no point in continuing to retry as often).

 

Hope that all makes sense, let me know if you have any other questions :)

 

Cheers, R.


  • 0

My games - In DecemberBoy Goes to Space

Utilities & Extensions - FloxGM, Destroyable Terrain

Check out my website: ryanloader.me, or follow me: twitter.com/RaniSputnik


#29 EvandroWP

EvandroWP

    GMC Member

  • GMC Member
  • 52 posts
  • Version:GM:Studio

Posted 29 December 2015 - 10:46 AM

Hey Evandro! 

 

There isn't a way to do it without polling. Basically you would do it by calling flox_entity_refresh() every minute or so, updating the game if the data changes.

 

You probably don't want Flox if you are looking for a real-time experience, but the above method would work well. If there is no change in the data, Flox will send back a "not modified" response, so the overhead of polling is pretty minimal.

 

So code! You would add something like the following to an alarm event on the objMatchControl object.

/// Refresh the current match data every minute or so

flox_entity_refresh(match,scrMatchRefreshComplete,scrMatchRefreshError);
alarm[0] = room_speed * 60;

Then add a script called scrMatchRefreshComplete like so;

/// scrMatchRefreshComplete(entity,modified)

// Free up the existing match entity
// we have now loaded a new copy of it
if (flox_entity_exists(match))
{
    flox_entity_free(match);
}

// Update the references to the current match
match = argument0;
game.currentMatch = match;

// If the match has been updated since the
// last time the match was requested, then
// update the game to reflect the changes
if (argument1)
{
    // TODO update the game with the new moves
}

You can probably just leave the error script blank, silently failing in the background, or you could increase the poll interval (if requests are failing, probably no point in continuing to retry as often).

 

Hope that all makes sense, let me know if you have any other questions :)

 

Cheers, R.

 

Thank you so much! I don't want a real-time experience, this will work fine. 


  • 0

#30 Fighting King

Fighting King

    GMC Member

  • GMC Member
  • 100 posts
  • Version:Unknown

Posted 02 February 2016 - 06:54 PM

I try to run this on android, But after creating match and clicking on the "List" icon i get a "fatal error" message


  • 0

#31 Rani_sputnik

Rani_sputnik

    GMC Member

  • GMC Member
  • 482 posts
  • Version:GM:Studio

Posted 06 February 2016 - 08:41 PM

Thanks for reporting Fighting King, I've replied in the other topic http://gmc.yoyogames...19114&p=4948265

 

I get the same error as you for this example, I'm investigating now :)

 

EDIT: Updated the repo with a new version, fixes it for me - let me know if you have any more issues and thanks again for reporting! https://bitbucket.or...layer-0-5-2.gmz


Edited by Rani_sputnik, 08 February 2016 - 09:01 AM.

  • 0

My games - In DecemberBoy Goes to Space

Utilities & Extensions - FloxGM, Destroyable Terrain

Check out my website: ryanloader.me, or follow me: twitter.com/RaniSputnik