Quick Links: Download Gideros Studio | Gideros Documentation | Gideros Development Center | Gideros community chat | DONATE
FB Instant Games , a long long journey — Gideros Forum

FB Instant Games , a long long journey

Hello, I recently made ('thanks' to the lockdown) my comeback to Gideros after many monthes without coding.
I'm really happy to see that the community is still active. I hope everyone is safe and take care.

So, let's go back to my subject. When I installed latest Gideros, I discovered the export option to facebook instant games. Tried it and was really surprised to see that my games works well in the html5 context. The export was really fast, the result quite convincing so I said to myself "Let's have a try and publish a game to facebook !"... The rest of the story is made of headaches, sweat and tears. :smile:
So I decided to take a little time to share my state of the art, hoping that it will help others and, may be, gaining some answers or tips.

Here we are !
I am quite familiar with the insane facebook UI when you consider doing a pro activity with it. Multiple authentifications, thousands of parameters with names that sucks, accounts to verify every 2 clicks and roles to dispatch... a long long journey for a solo user in search of simple answer to his only one question : is it possible to manage alone a game activity on facebook ?

So, in unsorted manner, here are the points I'm stucked in today:
- some validation process at facebook are 'handmade'. As they are in lockdown state,

- I need an active Apple dev account to publish my game on facebook... It cost 99$/year, require a recent Mac or Iphone, etc... an ethic/cash obstacle that I am working on. If someone have experimented an alternative way...

- I didn't found any gideros tutorial on how to use facebook Instant game API calls. Does the calls have to be made in JS outside of Gideros ? I'm not a dev and any sort of starting point to put me on the right way will be welcome. I have to admit that a simple example on "how to display the Player's profile picture in a gideros app" or "How to manage multiple langage" could be awesome.

- my first test app on facebook is stuck on the loading screen. I found in another thread on the forum (and in a lot of other forum on the www) that I'm not alone with that problem. I'm not worrying about it. In the background, behind the loading screen, my game seems functional.

- In the Gideros documentation, I found some explanations on installing a Gideros player on FB to help in the test process. I was naively thinking that I could export my game, upload it and tadaaam. I now understood that the facebook API will require a more optimised configuration.

see u in the next episode !

My meditation plan :
SinisterSoft: “ I don't create classes that much - classes are good for making things simpler but imho for frame rate they are also death by a thousand cuts.”
Totebo: “ Best quote ever.”
🤔
+1 -1 (+2 / -0 )Share on Facebook
«1

Comments

  • SinisterSoftSinisterSoft Maintainer
    Do this at the beginning of your main.lua:
    pcall(function() FBInstant=require ("FBInstant") end)
    FBInstantAPI=false
    This is what I use to show progress in the loading bar (I set it to 70% before the code starts)
    local progressCount=0
    function progress()
    	progressCount+=1
    	local steps=6 -- set to the number of times progress() called
    	local percent=70+((30/steps)*progressCount)  -- on export set the % to 70
    	print([[<span style="color: #4a4;">]].."Progress "..progressCount.." ("..percent.."%)</span>")
    	if FBInstant then FBInstant.setLoadingProgress(percent) end
    end
    progress()
    This is what you can use to send a message to facebook's log system:
    function message(mess,param,param2) -- text, number, table
    	local m=gsub(mess.."   "..(param or "").."   "..(param2 or " "),"[}{\">/<'&]", {["&"]="&",["<"] ="<",[">"] = ">",['"'] = """,["'"] = "&#39;",["/"] = "&#47;"})
    	print([[<span style="color: #48f;">]]..m.."</span>")
    	if firebase then firebase:analyticsEvent(mess,param) end
    	if flurry and flurry.isAvailable() then flurry.logEvent(mess,param) end
    	if FBInstantAPI then FBInstant.logEvent(mess,param or 0,param2) end
    end
    Here is what you can use to get the leaderboard:
    	if FBInstant then
    		if FBInstantAPI then
    			FBInstant.getLeaderboardAsync("globalTopPlayers",function (result,error)
    				if error then
    					print("get leaderboard error",error)
    				elseif result then
    					print("found leaderboard",result:getName())
    					result:setScoreAsync(s,FBInstant.player.getName(),function(self,result,entry)
    						if result then
    							print("score ok")
    							if entry.entry.rank and entry.entry.rank~=lastRank then
    								lastRank=entry.entry.rank
    								saveSettings()
    							end
    						--	for key,val in pairs(entry.entry) do
    						--		print(key,val)
    						--	end
    						--	dump(entry.entry)
    							leaderboardRefresh=true
    						end
    					end)
    				end
    			end)
    		end
     
    	elseif gaming and login then
    		gaming:reportScore(leaderboards[1],s,true)
    	end
    Use that as a template for the other stuff.

    Do this at the end of your main.lua - before the game event system really starts, it will remove the loading indicator - the bit you are stuck at:
    if FBInstant then
    	FBInstant.startGameAsync(function ()
    		print("Loading indicator removed")
    		FBInstantAPI=true
     
    		allowSave=false
    		FBInstant.player.getDataAsync({"pirate","privacyOk","musicVolume","effectsVolume","lastFrontendMenu","lastRank","bestScore",
    										"remainingCredits","streak","streakCredits","streakTime","lastTime"},function(result,error)
    			if error then
    				print("error loading data",error)
    			else
    				loadSettings(result)
    			end
    		end)
     
    		osLanguage=FBInstant.getLocale()
    	end)
     
    	print("getPlatform",FBInstant.getPlatform())
    	print("player.getID",FBInstant.player.getID())
     
    else
    	print("FBInstant not loaded")
    end

    Likes: hgy29, jimlev

    Coder, video game industry veteran (since the '80s, ❤'s assembler), arrested - never convicted hacker (in the '90s), dad of five, he/him (if that even matters!).
    https://deluxepixel.com
    +1 -1 (+2 / -0 )Share on Facebook
  • SinisterSoftSinisterSoft Maintainer
    You can upload a player to FBInstants, then you can send code to it from the studio. It works great. You can also test sends to Android - but it's slightly more complicated.

    Likes: jimlev

    Coder, video game industry veteran (since the '80s, ❤'s assembler), arrested - never convicted hacker (in the '90s), dad of five, he/him (if that even matters!).
    https://deluxepixel.com
    +1 -1 (+1 / -0 )Share on Facebook
  • SinisterSoftSinisterSoft Maintainer
    Because FBInstant will be null if the library isn't present then you can make your game conditional with extra things happening just for instants, or (if you look at the leaderboard example above) for gaming too.

    Likes: jimlev

    Coder, video game industry veteran (since the '80s, ❤'s assembler), arrested - never convicted hacker (in the '90s), dad of five, he/him (if that even matters!).
    https://deluxepixel.com
    +1 -1 (+1 / -0 )Share on Facebook
  • jimlevjimlev Member
    Thanks a lot SinisterSoft !
    I'm not sure to understand everything in all your answers. But, here is where I am now, after testing, reading and adding some of your tips to my recipe...

    On facebook, I created a new app called 'Player' and uploaded a zip version of the html5 player which came with the latest install of gideros.
    Note that, at the upload,a facebook alert (see below) asks to add a config file in the zip. So I added one with the simplest content.

    "You must include a bundle config in your upload. To create a bundle config, please refer to: https://developers.facebook.com/docs/games/instant-games/sdk/bundle-config".

    I switched it in 'test mode' and achieved to access it from the Gideros Studio but with the need of lots of refresh of the browser tab and restarts of the Studio*. The 'Player' app was, at that time, a classic facebook app. I switched it to the 'Instant Games' type. Then, it stay stucked on the loading screen. The studio detects it, the start button is available but it does nothing probably because the app doesn't achieved her total loading state.

    Could someone answer me about the WebGL option in facebook. Does it needs to be activated for the gideros html5 apps ?




    Now, I will try to understand your code example and test them in a simple context before integrating them in my first game. I will be back with answers, I hope, to share with the community (despite I'm not sure that some many people could be interested in FB instant games implementation, lol).

    *I have observed that the Brave browser seems a bit reluctant to loading gideros content... @sinisterSoft, for example, I didn't achieve to play your zombie game on deluxepixel. It works very nicely on Edge but, on Brave (shields down, of course), I saw a brief part of the loading and then, everything is white in the smartphone screen.
    webGLorNot.jpg
    616 x 221 - 38K
    My meditation plan :
    SinisterSoft: “ I don't create classes that much - classes are good for making things simpler but imho for frame rate they are also death by a thousand cuts.”
    Totebo: “ Best quote ever.”
    🤔
  • SinisterSoftSinisterSoft Maintainer
    I can't remember, but if I saw that then I would slide it to yes.

    You then use the instant games tab in your app to set the instant games settings and also upload the zip or 7z to the hosting system and then set it as the test version of your game. (In facebook instants you can pick two files, one release, one test)
    Coder, video game industry veteran (since the '80s, ❤'s assembler), arrested - never convicted hacker (in the '90s), dad of five, he/him (if that even matters!).
    https://deluxepixel.com
  • SinisterSoftSinisterSoft Maintainer
    edited May 2020
    Yes, it looks like the latest version of Brave doesn't seem to like Gideros - even with shields down. It seems to be when it's doing the initial loading. Perhaps @hgy29 may know more about what's up?

    (it worked fine with an older version of Brave)
    Coder, video game industry veteran (since the '80s, ❤'s assembler), arrested - never convicted hacker (in the '90s), dad of five, he/him (if that even matters!).
    https://deluxepixel.com
  • jimlevjimlev Member


    if error then
    print("error loading data",error)
    else
    loadSettings(result)
    end

    If I understand well your snippet, loadSettings is a function you created to parse the result of the getData to dispatch all the values you retrieved to the vars you use in your game. Am I right ? (sometimes, I feel like Champolion when I do code :smiley: )

    So, may I ask 2 questions about it :
    - what are you keeping in the "pirate" var ? :*
    - my first version of my game stored all the datas in a local file (with table.save, etc.). The datas were made of a table containing tables. Do you recommand to 'explode' that structure to make a simple pair association like bestscore:{100}, besttime:{12},etc... ?

    Concerning the webGL toggle in the settings of the instantGames, I saw no differences when it's on or off... so strange. The investigation continue.

    My meditation plan :
    SinisterSoft: “ I don't create classes that much - classes are good for making things simpler but imho for frame rate they are also death by a thousand cuts.”
    Totebo: “ Best quote ever.”
    🤔
  • SinisterSoftSinisterSoft Maintainer
    Pirate var is a flag that's set if I detect it's a pirate version (on the play store). I use this to signal to firebase an event if a previous pirate copy becomes an original.

    On Android the load settings is synchronous, on facebook instants it starts off the asynchronous load.

    I usually load in the data, then convert it to a table of values that may already have default data in them.

    Likes: jimlev

    Coder, video game industry veteran (since the '80s, ❤'s assembler), arrested - never convicted hacker (in the '90s), dad of five, he/him (if that even matters!).
    https://deluxepixel.com
    +1 -1 (+1 / -0 )Share on Facebook
  • jimlevjimlev Member
    ;) thanks for answering !
    It seems that you manage a lot of things I have to think about (eg. the "privacyOk" param)

    Even if it's a bit laborous, I make some progress. The leaderboard is 'on the road', but I still have to manage the graphical part (so sad that facebook do not provide a standard UI look like for the addShorcut function). I will post some screenshot if it interest someone !

    Likes: SinisterSoft

    My meditation plan :
    SinisterSoft: “ I don't create classes that much - classes are good for making things simpler but imho for frame rate they are also death by a thousand cuts.”
    Totebo: “ Best quote ever.”
    🤔
    +1 -1 (+1 / -0 )Share on Facebook
  • SinisterSoftSinisterSoft Maintainer
    yes, that would be great. Did you look at my games on your phone? To see if they slow down on that type of phone?
    Coder, video game industry veteran (since the '80s, ❤'s assembler), arrested - never convicted hacker (in the '90s), dad of five, he/him (if that even matters!).
    https://deluxepixel.com
  • jimlevjimlev Member

    Did you look at my games on your phone? To see if they slow down on that type of phone?

    I tried some on deluxepixel and the games played great.
    On my game, the trouble comes in 2 ways :
    1-the game, in html5, seems a little bit laggy but nothing really alarming.
    2-the 'Start game' button is a lot more worrying. When played on the studio player, everything is smooth. On Instantgames fb, when I click the button, it takes 4-5 seconds before the game's scene appears.
    I will look forward this problem later... I have suspicions : to many png to display at a time, to many var to initiate, etc. another adventure for later

    Likes: SinisterSoft

    My meditation plan :
    SinisterSoft: “ I don't create classes that much - classes are good for making things simpler but imho for frame rate they are also death by a thousand cuts.”
    Totebo: “ Best quote ever.”
    🤔
    +1 -1 (+1 / -0 )Share on Facebook
  • SinisterSoftSinisterSoft Maintainer
    I load everything at the start - I tend to have the game 'playing' itself on the title screens, etc - that way there is nothing to load when the game starts. You can hide some of the loading by having intros, etc at the beginning.
    Coder, video game industry veteran (since the '80s, ❤'s assembler), arrested - never convicted hacker (in the '90s), dad of five, he/him (if that even matters!).
    https://deluxepixel.com
  • SinisterSoftSinisterSoft Maintainer
    A bonus of doing it that way also means it looks more like a classic arcade game 'attract' mode - all the games in the arcades used to have the game playing 'behind' the title screen.
    Coder, video game industry veteran (since the '80s, ❤'s assembler), arrested - never convicted hacker (in the '90s), dad of five, he/him (if that even matters!).
    https://deluxepixel.com
  • jimlevjimlev Member

    I load everything at the start - I tend to have the game 'playing' itself on the title screens, etc - that way there is nothing to load when the game starts. You can hide some of the loading by having intros, etc at the beginning.

    I agree. I think I will look at my code to see if I can preload everything before the game starts. But I am also suspecting a code mistake because my game don't use a lot of graphics (something around 2Mo to load...). And, the previous version, who wasn't connected to facebook, didn't have the problem (or in a less perceptible way). It's probably an code 'error' but , at this time, I prefer to code some of the FB needed improvements (leaderboard, share, etc.) and optimize the code later. The 'fun' now, the chore later :p

    About the optimize's subject, I have 2 newbies questions :smile:
    1. I use many textfields. So, I have many fonctions to create these textfields and, in these functions, a lot of "local myFont = TTFont.new blabla bla"... Is it a better practice to declare my fonts in Globals at the start of the game ? or using a 'lot' of Locals in each of my fonctions ?
    2. In my game, I use a class for creating animated rolling dice. The class starts with table declarations like
    local dice = {"gfx/dices/img01.png","gfx/dices/img02.png",...}
    etc. I, later, use these images to make a movieclip of my dice. If I want to pre-load these image, do I have to make Globals of these tables in, for example, main.lua ? Do I need to use an 'addChild' on these to make the preload effective?

    As you can see, I'm always afraid of using Globals... :p

    A bonus of doing it that way also means it looks more like a classic arcade game 'attract' mode - all the games in the arcades used to have the game playing 'behind' the title screen.

    I agree that, for some kinds of game, it's a very good idea to do so. A very good taste of melancolic memories of a not-so-old-but-far-period :/

    My meditation plan :
    SinisterSoft: “ I don't create classes that much - classes are good for making things simpler but imho for frame rate they are also death by a thousand cuts.”
    Totebo: “ Best quote ever.”
    🤔
  • SinisterSoftSinisterSoft Maintainer
    I use one font, hardly any classes or events.
    Coder, video game industry veteran (since the '80s, ❤'s assembler), arrested - never convicted hacker (in the '90s), dad of five, he/him (if that even matters!).
    https://deluxepixel.com
  • jimlevjimlev Member

    I use one font, hardly any classes or events.

    :* hummm
    I will meditate that. I have to admit that it is unbelievable for me... I will probably ask for details if you accept
    My meditation plan :
    SinisterSoft: “ I don't create classes that much - classes are good for making things simpler but imho for frame rate they are also death by a thousand cuts.”
    Totebo: “ Best quote ever.”
    🤔
  • SinisterSoftSinisterSoft Maintainer
    edited May 2020
    I use an enter_frame event for the actual game - it runs all the time. I use the events for touch, they run all the time, the same for keyboard and controllers. I use the 'built-in' classes, I don't make up any in my own code.

    The only events that I add/remove are for the SceneManager. That simply goes 'on top' of the game. I use a state machine to decide if the game display is running or not and what state of play it's in.

    It's as close as I can get it to how everything used to work in the old days:

    (When possible) I used to code the game to run on the vsync interrupt, with the stack being reset at the beginning of each game loop - using a state machine to keep track of everything. It's a trick Nintendo used to keep everything to the 60hz frame sync. Anything that doesn't really matter is done last - and skipped if the game goes over a frame every so often.

    In Gideros I have different things going on on different frame numbers - keeping sprite movements, etc and other things the user will notice at every frame.
    Coder, video game industry veteran (since the '80s, ❤'s assembler), arrested - never convicted hacker (in the '90s), dad of five, he/him (if that even matters!).
    https://deluxepixel.com
  • SinisterSoftSinisterSoft Maintainer
    I also use joypad bit patterns to control the ai movement on sprites (players and enemies), that way I can test out enemy sprite by injecting a 2nd joypads data into the enemies bitpattern. I can also inject keyboard up/downs into the players bitpattern, the same goes for any virtual joypad control on-screen - that also gets injected. It makes all the player control much easier (both to code and to test).
    Coder, video game industry veteran (since the '80s, ❤'s assembler), arrested - never convicted hacker (in the '90s), dad of five, he/him (if that even matters!).
    https://deluxepixel.com
  • SinisterSoftSinisterSoft Maintainer
    In Gideros some people extend the sprite classes and also have events for each sprite - I don't do any of that. To me it doesn't make any sense - to others I guess I'm the crazy one. :D
    Coder, video game industry veteran (since the '80s, ❤'s assembler), arrested - never convicted hacker (in the '90s), dad of five, he/him (if that even matters!).
    https://deluxepixel.com
  • hgy29hgy29 Maintainer
    About the fonts, if you have lots of texts then make sure to use TTFont glyph cache, either by giving the full list of chars you will need to TTFont constructor or simply an empty string. If you don't, then you'll find that creating each TextField will be very very slow in HTML.

    Likes: SinisterSoft

    +1 -1 (+1 / -0 )Share on Facebook
  • jimlevjimlev Member
    hgy29 said:

    If you don't, then you'll find that creating each TextField will be very very slow in HTML.

    May be you just put the fingers of my lag problem. When my game pass from home screen to game screen, it creates something like 20 textfields to construct the game screen. And, as my original code is from 2014, I probably don't use the glyph cache. Will check it soon ! Merci hgy29 !

    In Gideros some people extend the sprite classes and also have events for each sprite - I don't do any of that. To me it doesn't make any sense - to others I guess I'm the crazy one. :D

    I don't know in which side I am as I'm not really understand everything I make while I code. :D :D :D Anyway, thanks for the explaination (not sure that I have understood everything)

    I'll be back with some screenshot soon.

    My meditation plan :
    SinisterSoft: “ I don't create classes that much - classes are good for making things simpler but imho for frame rate they are also death by a thousand cuts.”
    Totebo: “ Best quote ever.”
    🤔
    +1 -1 (+2 / -0 )Share on Facebook
  • jimlevjimlev Member
    No way to achieve the display of profile picture in a leaderboard... do I miss something ?
    I have access (and achieve to display) the player profile pic but, when I get leaderboard data, I can't find a way to the pic url... Anyone succeeded at this task ?
    My meditation plan :
    SinisterSoft: “ I don't create classes that much - classes are good for making things simpler but imho for frame rate they are also death by a thousand cuts.”
    Totebo: “ Best quote ever.”
    🤔
  • hgy29hgy29 Maintainer
    Iirc you need to call getConnectedPlayersAsync to get profile pictures of your friends. Then you match them with their ids from the leaderboard.

    Likes: SinisterSoft

    +1 -1 (+1 / -0 )Share on Facebook
  • jimlevjimlev Member
    edited May 2020
    hgy29 said:

    Iirc you need to call getConnectedPlayersAsync to get profile pictures of your friends. Then you match them with their ids from the leaderboard.

    do you mean that it's only possible to get the player's friends picture ? not the pic of unknown players? :/

    My meditation plan :
    SinisterSoft: “ I don't create classes that much - classes are good for making things simpler but imho for frame rate they are also death by a thousand cuts.”
    Totebo: “ Best quote ever.”
    🤔
  • hgy29hgy29 Maintainer
    Yes, unfortunately...
  • SinisterSoftSinisterSoft Maintainer
    It's due to privacy concerns.
    Coder, video game industry veteran (since the '80s, ❤'s assembler), arrested - never convicted hacker (in the '90s), dad of five, he/him (if that even matters!).
    https://deluxepixel.com
  • SinisterSoftSinisterSoft Maintainer
    You could have some standard images to use if no id match found.
    Coder, video game industry veteran (since the '80s, ❤'s assembler), arrested - never convicted hacker (in the '90s), dad of five, he/him (if that even matters!).
    https://deluxepixel.com
  • hgy29hgy29 Maintainer
    Or you could store profile pictures of all your users on some external server, but of course you'd have to handle GDPR yourself
  • jimlevjimlev Member
    Damn... I have to go back to my drawing board I think...
    On this facebook journey, traps opens just in front of my feet, day after day...And as I have no Apple dev account (and doesn't plan to take one), I already know that all of this will be of no-use... lol :'( :D
    My meditation plan :
    SinisterSoft: “ I don't create classes that much - classes are good for making things simpler but imho for frame rate they are also death by a thousand cuts.”
    Totebo: “ Best quote ever.”
    🤔
  • keszeghkeszegh Member
    i keep opening new posts, it is indeed a 'long long journey', i wish you manage to make it work.

    Likes: MoKaLux

    +1 -1 (+1 / -0 )Share on Facebook
Sign In or Register to comment.