GMS 2 Online Highscores

Appsurd

Member
How is this even remotely difficult? Getting back the last inserted row is one of the most routine and basic tasks in SQL.

You could have used $db->lastInsertId() in the submission PHP script to get the ID of the inserted score entry, then responded with that to the client upon success. Then in the high score listing PHP script, include the ID on each entry at the top. Then the client can look through the listing for self-initiated submissions (i.e. IDs received from past responses for submissions) and draw them differently if they appear.

I really suggest that you put off teaching this subject until you have a more reasonable grasp of basic procedures.
Thanks for your input @FrostyCat, but I'm afraid this is not what the questioner wanted. He wanted to colour the last score of the player, and not the last score achieved by any player in the database... Your solution will therefore not work, but to get the last inserted ID this definitely does the trick.

Furthermore, I think your last sentence is not really a way we should talk to each other. We are all learning, and some are further than others. I decided to show a part of my experience with you guys, and I want to stress that I'm not an expert on the subject myself. But most experts know things too well to be able to make a simple example which is just good enough for most GM users, and of course, most experts are far too busy to put time in such a relatively simple subject as standard online highscores. This all doesn't mean that I should talk nonsense and at the same time tell that this is the absolute truth. But I hope it's clear, and I want to emphasize that very clearly, I am not an expert, just someone who is a little further in the learning curve.

Thanks for this tutorial, works very well :)

I have a question - is it possible to highlight only the current line with score player just sent?
I mean, right after the game my highscore table will appear and I want only the most recent score to be drawn with different color.
@PatrikPé The solution I proposed is a little too difficult, since we already have a method to select to determine the latest ID, by simply looking at the ID value. So this changes the step-by-step method to

1. In display.php you can change the search algorithm to find the latest score by the given player name (since you need to put this score in the eleventh position, but if you don't then skip this step) by looking at the corresponding ID value.
2. Also change the display script to return the ID of each value in the highscores
3. Go to GameMaker: Studio and open the draw_text_highscore to change the colouring mechanism and colour the player's latest score by looking at the ID.
 

FrostyCat

Member
Thanks for your input @FrostyCat, but I'm afraid this is not what the questioner wanted. He wanted to colour the last score of the player, and not the last score achieved by any player in the database... Your solution will therefore not work, but to get the last inserted ID this definitely does the trick.
What I proposed is exactly what @PatrikPé wanted, it's you who didn't see it coming.

Here's the changed part for the submission (note the last line):
Code:
// Execute statement
$stmt->execute();
echo $db->lastInsertId(); // <<< The ID for the last submitted score of the player
The player can then capture and remember this ID in the response.

Then in the part for listing high scores, change the non-error echos to this:
Code:
echo $line . ".-" . $row['name'] . "-" . $row['score'] . "-" . $row['id'] . "|"; // <<< Added IDs
For each received row, the client can check the ID against the one captured from the submission's response, drawing it differently upon a match.

For your reference, here's the original question:
I have a question - is it possible to highlight only the current line with score player just sent?
I mean, right after the game my highscore table will appear and I want only the most recent score to be drawn with different color.
Tell me what part of his inquiry I didn't follow.
 

Appsurd

Member
What I proposed is exactly what @PatrikPé wanted, it's you who didn't see it coming.
Ah I misread your post, and especially the part where you told to get the lastID from the submission script, whereas I thought you meant the displaying script.

Thanks for your input, this is definitely simpler than my solution.
 
P

PatrikPé

Guest
Thank you very much!

Your question is slightly difficult, since it requires to make a distinction between the last score of the player and all other scores.

1. A possible solution could be to create an extra column in the database and put down something which indicates the date / time when the score was sent in.
2. Then in display.php you can change the search algorithm to find the latest score by the given player name (since you need to put this score in the eleventh position, but if you don't then skip this step).
3. Also change the display script to return the time of each value in the highscores
4. Go to GameMaker: Studio and open the draw_text_highscore to change the colouring mechanism and colour the player's latest score.

I understand this step-by-step procedure is very vague and I'm myself not sure how you could handle this precisely. In case you have any further questions don't hesistate to ask them here, but I can't promise to give you cut-and-clear code since your problem is rather difficult.
Thanks again, works perfectly :)
 
M

mononosto

Guest
How can I retrieve the 10th highest score from the database?
 

Appsurd

Member
How can I retrieve the 10th highest score from the database?
You only want the tenth score? Because you can simply edit the script I published. Go to draw_highscore_text and change the LAST for-loop from
Code:
for(var i=0; i<count+1; i+=1)
Into
Code:
for(var i=count; i<count+1; i+=1)
The only thing this code does, is that it draws the last option only. Now call the display.php with no_lines=10 and it should work as you wished :)
 
M

mononosto

Guest
Thanks for your response. It worked!

I have another question, though. How can I access and/or edit the scores in the database?
 

Appsurd

Member
I have another question, though. How can I access and/or edit the scores in the database?
Go to the place in Figure 5 of the tutorial. Then select your table from the left column. There you should see all names and scores (the names are saved using base64_encode so they're not visible as they are shown in-game). But here you can edit the data by double clicking on the element you wish to change. Hopefully this is a bit clear :)

Thanks for your response. It worked!
Awesome! In case you liked the tutorial, could you please rate it in the Marketplace: https://marketplace.yoyogames.com/assets/4205/online-highscores-example
Thanks in advance!
 
Hola buenas tardes no hay manera de evitar que el usuario de múltiples clics, ya que si lo hace está reemplazando los lugares de abajo y ve repetidos tops
thank you very much
 
Last edited:

Appsurd

Member
I've tried it! It works:)
Awesome :)

Hola buenas tardes no hay manera de evitar que el usuario de múltiples clics, ya que si lo hace está reemplazando los lugares de abajo y ve repetidos tops
thank you very much
Hi there,

Apart from the fact that this is an English forum, I don't understand Spanish either. So could you please reformulate your question in English? Thanks in advance!
 
Awesome :)


Hi there,

Apart from the fact that this is an English forum, I don't understand Spanish either. So could you please reformulate your question in English? Thanks in advance!
Hi good afternoon there is no way to prevent the user from multiple clicks, since if he is replacing the smaller places and will repeat the tops of his posicion down thank you very much

Very good work
 

Appsurd

Member
Hi good afternoon there is no way to prevent the user from multiple clicks, since if he is replacing the smaller places and will repeat the tops of his posicion down thank you very much

Very good work
Hi Ernesto,

I find it very hard to understand your text, so I'll give it a try. I think you want to insert a player's score only if it is higher than his previous score. In that case, it is explained in this question which was already posted in the comments section of this tutorial: https://forum.yoyogames.com/index.php?threads/online-highscores.4291/#post-85705 My answer containing an outline of the problem is shown below that comment. Hopefully this works!

In case anything is unclear or I understood something wrongly, please tell me and I'll try to explain it.
 
K

Kloac

Guest
Hi, great job!

i'm having a few problems setting gms. The obj_highscore doesn't draws the score, because i don't use the variable score in my game.

So my question is.. where I've to change the variable? (so the script or the page can read it properly) i'm using global.points as varible..

Thanks! and sorry for my poor english.
 

Appsurd

Member
Hi, great job!

i'm having a few problems setting gms. The obj_highscore doesn't draws the score, because i don't use the variable score in my game.

So my question is.. where I've to change the variable? (so the script or the page can read it properly) i'm using global.points as varible..

Thanks! and sorry for my poor english.
Thanks!

The tutorial doesn't use the build-in variable score anywhere. If your question is about the sending in of the scores to the database, then call
send_scores(global.name, global.points)

If I understood it incorrectly, please tell me :)
 
K

Kloac

Guest
Hi again,
i changed the variables, but now when i touch the button to send the score, my game get freeze...
I can't found the solution, this is my send_score scrip so you can see it please.

global.name = ""
send_score(global.name,global.metros1)
//
// Script: Sends the player’s score to the database in Altervista
// Date: 2016-09-13
// Copyright: PeliStar (c)
//
// Arguments:
// Argument0: name of the player
// Argument1 = global.metros

var name = url_encode(base64_encode(string(argument0)));
var args = "name="+name+"&score="+string(argument1)+"&hash=1234";
http_post_string("http://ftp.kloac.altervista.org/Tbt/addscore.php", args);

And my get_score script:
get_scores(global.name,10)
//
// Script: Get the scorelist from the database in Altervista
// Date: 2016-09-23
// Copyright: PeliStar (c)
//
// Arguments:
// Argument0: name of the player
// Argument1 = 10

var name = url_encode(base64_encode(string(argument0)));
var args = "name="+name+"&no_lines="+string(argument1)+"&hash=1234";
texthandle = http_post_string("//ftp.kloac.altervista.org/Tbt/display.php", args);

:( i'm totally confused .
 

Appsurd

Member
Hi again,
i changed the variables, but now when i touch the button to send the score, my game get freeze...
I can't found the solution, this is my send_score scrip so you can see it please.
.... .
It seems you did the right thing, however, the second internet address has no http: in front of it. Hope that fixes the problem

EDIT: I reread your post and your problem is in the send script, so I don't really know what is going wrong. Is your account name kloac and your map name Tbt and the hash 1234?

EDIT 2: This code won't freeze the game, so the real problem should be somewhere else... Are you running the example or did you encorporate it directly into your game?
 
K

Kloac

Guest
Hi, i did it!! :)

can i ask something? It's a way to send the score after you do it, for example if you are not connected to the internet at that moment?

Thanks!
 

Appsurd

Member
Hi, i did it!! :)

can i ask something? It's a way to send the score after you do it, for example if you are not connected to the internet at that moment?

Thanks!
Awesome!

Yes you can. You can do this by implementing a check whether the user has a connection (either by using os_is_network_connected or by looking at the HTTP event which the script send_score returns, since this script returns 1 when inserted correctly and 0 when it isn't)
Then you must decide when to resend the score again (either in a few seconds or perhaps at the next launch of the program/app).

I understand this outline is really vague, but if you have some experience, it shouldn't be too difficult to implement. In general, people have an internet connection so I usually do not worry about it too much.
 

Relic

Member
Great tutorial and thanks for providing this level of assistance and professionalism, even in the face of quite a rude forum member. I got it working in Studio 2, with HTML5 through the following changes:


  1. I used my own web domain, not Altavista.
  2. Created a table called OnlineHighscores using myPHP from the control panel of my web hosted domain and made sure it had the same structure as you described for the table creation through Altavista.
  3. Revised the addscore and getscore php scripts to start with:
<?php
header('Access-Control-Allow-Origin: *');
// Connect to database
$db = new PDO('mysql:host=localhost;dbname=databasename', 'username','password');
databasename is the name of the database in the web domain, which I found was the top "folder" (in quotes as it must be a database) name in myPHP.
username is the username for my web hosting account
password is the password for my web hosting account

I knew nothing about SQL code and only a little about how myPHP works. Hope other users can find this useful too.
 

Appsurd

Member
Great tutorial and thanks for providing this level of assistance and professionalism, even in the face of quite a rude forum member. I got it working in Studio 2, with HTML5 through the following changes:


  1. I used my own web domain, not Altavista.
  2. Created a table called OnlineHighscores using myPHP from the control panel of my web hosted domain and made sure it had the same structure as you described for the table creation through Altavista.
  3. Revised the addscore and getscore php scripts to start with:
<?php
header('Access-Control-Allow-Origin: *');
// Connect to database
$db = new PDO('mysql:host=localhost;dbname=databasename', 'username','password');
databasename is the name of the database in the web domain, which I found was the top "folder" (in quotes as it must be a database) name in myPHP.
username is the username for my web hosting account
password is the password for my web hosting account

I knew nothing about SQL code and only a little about how myPHP works. Hope other users can find this useful too.
Thanks! I will (probably) include your code (and further comments) in the next version! Thanks very much for pointing/trying this out!
 

helpleo

Member
Hello, first of all, thanks for this amazing and detailed tutorial; it has been an unmeasurable help for the project I'm working on.

I am havin an issue regarding the server-side communication; namely, it isn't happening. Since I'm a bit of a neophyte when it comes to PHP, I do believe the issue is with the scripts (I am using my own server for the operations). The only clue I have is this error message in the compile form when I execute the 'get_scores' script:

<b>Fatal error</b>: Uncaught exception 'PDOException' with message 'SQLSTATE[HY000] [1045] Access denied for user 'my_username'@'localhost' (using password: NO)' in /home/username/public_html/OnlineHighscores/display.php:4

Do you have any idea what might be the issue? I followed the instructions to a fault, so I believe it may be a mistake on my side.
 

FrostyCat

Member
Hello, first of all, thanks for this amazing and detailed tutorial; it has been an unmeasurable help for the project I'm working on.

I am havin an issue regarding the server-side communication; namely, it isn't happening. Since I'm a bit of a neophyte when it comes to PHP, I do believe the issue is with the scripts (I am using my own server for the operations). The only clue I have is this error message in the compile form when I execute the 'get_scores' script:

<b>Fatal error</b>: Uncaught exception 'PDOException' with message 'SQLSTATE[HY000] [1045] Access denied for user 'my_username'@'localhost' (using password: NO)' in /home/username/public_html/OnlineHighscores/display.php:4

Do you have any idea what might be the issue? I followed the instructions to a fault, so I believe it may be a mistake on my side.
This error message clearly indicates that you haven't entered the correct login credentials for your SQL database in the $db = new PDO(...); line. Find out what your login credentials are, read up on how the PDO constructor works, then change that line to fit.
 

helpleo

Member
Hey FrostyCat, thanks for the reply! Indeed, the problem was with the login credentials; I used the same solution Relic explained a couple posts ago, using my login and password for my web hosting account in the PDO constructor first line (this took my a while as I thought it was the username and hash for in the code that was needed.)

Even with that, though, my code still do not manage to communicate with the server, both in sending (my phpMyAdmin database is empty) and receiving scores (the code gets stuck on the Alarm loop of the obj_highscore). I already checked the scripts several time, and hardly believe it could be an error of nomenclature.

Again, the only clue I have is the message "HttpError:HttpSendRequest: The server returned an invalid or unknown response" (rough translation) that I get when executing the "get_scores" script (the Compile Form register no message for the "send score" script). Any idea what might be this time? I can give more information about my code if it helps.
 

Appsurd

Member
Hey FrostyCat, thanks for the reply! Indeed, the problem was with the login credentials; I used the same solution Relic explained a couple posts ago, using my login and password for my web hosting account in the PDO constructor first line (this took my a while as I thought it was the username and hash for in the code that was needed.)

Even with that, though, my code still do not manage to communicate with the server, both in sending (my phpMyAdmin database is empty) and receiving scores (the code gets stuck on the Alarm loop of the obj_highscore). I already checked the scripts several time, and hardly believe it could be an error of nomenclature.

Again, the only clue I have is the message "HttpError:HttpSendRequest: The server returned an invalid or unknown response" (rough translation) that I get when executing the "get_scores" script (the Compile Form register no message for the "send score" script). Any idea what might be this time? I can give more information about my code if it helps.
Perhaps you can send me your code via a PM? Supply as much details as possible (include PHP files and GM project if possible), and don't give the password of your server of course ;) You seem to have a strange issue, which I can't resolve without gaining more information. Hope to hear from you soon!
 
Last edited:
I

ImSoAbell

Guest
Hey, thank you so much for this tutorial. I am getting an error which is coming straight from the Altervista site. I set up everything as you listed, but it says the directory does not contain an "index file". "You must create a page called index.php or index.html." Have you come across this error before?
 

FrostyCat

Member
Hey, thank you so much for this tutorial. I am getting an error which is coming straight from the Altervista site. I set up everything as you listed, but it says the directory does not contain an "index file". "You must create a page called index.php or index.html." Have you come across this error before?
Then do as it says, put an index.php or index.html file there and the host will likely shut up and serve your work. This is a measure commonly seen in free web hosting services, designed to help deter people from running back-ends and file-only repositories off it. Typically on hosts where they implement this check, running a back-end-only, non-human-facing app the way you are trying is against their rules, so don't expect any permanence to your setup.

There's a reason why I no longer encourage people to run PHP back-ends off free web hosting services. It's all the extra crap they add on top of an otherwise stock LAMP setup that introduces all sorts of unexpected behaviours. I'd take AWS or Heroku over them any day, even if they cost a little more.
 
Hey, thanks a lot for this! I used it and it works pretty well! I only have on issue and I was hoping maybe you would know why this is happening.
Some of my users are saying that they are getting a "check your internet connection" error when they are on WiFi. It works for them on some WiFi networks and also on cellular. They are able to see the high scores using a website I set up on Altervista (to avoid CORS problems) on WiFi, it's just in game that it doesn't work.

Thanks!
 

Appsurd

Member
Hey, thanks a lot for this! I used it and it works pretty well! I only have on issue and I was hoping maybe you would know why this is happening.
Some of my users are saying that they are getting a "check your internet connection" error when they are on WiFi. It works for them on some WiFi networks and also on cellular. They are able to see the high scores using a website I set up on Altervista (to avoid CORS problems) on WiFi, it's just in game that it doesn't work.

Thanks!
Hi, thanks for your reply and I'm glad you liked it :)

About your issue, it is quite weird to hear that I works on some WiFi networks and doesn't on others. Are you certain that on both networks the users have the same permissions (i.e. are they fully logged in or do they still have to login into the network by going to a random web page (which will redirect you to the login screen)? I'm asking this because in principle all WiFi networks behave the same, the only issue that (in my views) can occur, is the one I sketch above.

Another thing you could try is to add
Code:
header('Access-Control-Allow-Origin: *');
before BOTH php file on the second line (so just after <?php. I doubt it works, but we might as well try :D

Hopefully either scenario solves the issue, please reply if it doesn't :)
 
R

Ramiro

Guest
Hi,
I've been trying to implement the online highscore on my game, and my game works just fine, however the highscore table never shows up, instead it just says "Check your internet conection".
I have checked my code and yours but can't find the problem. I am using Game Maker Studio 2.1.4.285 , maybe thats the problem.
Thanks for yout attention, I hope you can solve my problem.
 
R

Ramiro

Guest
Update on my last question, I've managed for it to connect, but only "Name" and "Score" are drawn, no actual name or score appear.
 

Appsurd

Member
Update on my last question, I've managed for it to connect, but only "Name" and "Score" are drawn, no actual name or score appear.
Hi, maybe you could look into the response from the server. Are there any debug messages available? In obj_highscore in the Asynchronous Event, there is a debug message which should show something. What does it show?
 
R

Ramiro

Guest
Sorry for replying so late, There don't seem to appear any errors on GameMaker's side, but I don't really know how to check the response from the server. I'm new to the networking world.
Thank you for answering me
 

Appsurd

Member
Sorry for replying so late, There don't seem to appear any errors on GameMaker's side, but I don't really know how to check the response from the server. I'm new to the networking world.
Thank you for answering me
Seems like you get no response at all. I'll answer you in more detail in a PM
 
A

ali9050

Guest
Hello
Thank you for your perfect, perfect and perfect education
If we want to use this on Android and instead of being written in the database, the serial will be sent from the game and using the ID to show the score and
If we want to register when the name is registered, we can no longer record the name and choose the other one, what should we do ?!
thank you.
 

Appsurd

Member
I think you mean the following: a person's name must be unique, and if a player wants to enter his/her score with the same name, the score is rejected.

You might add an extra if-statement in the PHP file where you perform a
Code:
SELECT * from ONLINEHIGHSCORES where name = :name
Then check if there is a response at all. If so, put a
Code:
echo '5';
Then, in GMS, check in the Asynchronous Event if there is a reponse. If so, check if it is equal to 5. If so, show a message that the player has to insert a new name as 'that name is already chosen'.

I admit, this procedure is a little vague, but in principle, you could get it to work. When you have more questions, don't hesistate to ask them here and I wish you luck implementing it!
 
A

ali9050

Guest
Hello
Thank you for your perfect, perfect and perfect education
If we want to use this on Android and instead of being written in the database, the serial will be sent from the game and using the ID to show the score and
If we want to register when the name is registered, we can no longer record the name and choose the other one, what should we do ?!
thank you.
 

Appsurd

Member
Hello
Thank you for your perfect, perfect and perfect education
If we want to use this on Android and instead of being written in the database, the serial will be sent from the game and using the ID to show the score and
If we want to register when the name is registered, we can no longer record the name and choose the other one, what should we do ?!
thank you.
Hey there,

Sorry, maybe it was not clear, I should have quoted your message earlier. My response is:

I think you mean the following: a person's name must be unique, and if a player wants to enter his/her score with the same name, the score is rejected.

You might add an extra if-statement in the PHP file where you perform a
Code:
SELECT * from ONLINEHIGHSCORES where name = :name
Then check if there is a response at all. If so, put a
Code:
echo '5';
Then, in GMS, check in the Asynchronous Event if there is a reponse. If so, check if it is equal to 5. If so, show a message that the player has to insert a new name as 'that name is already chosen'.

I admit, this procedure is a little vague, but in principle, you could get it to work. When you have more questions, don't hesistate to ask them here and I wish you luck implementing it!
 

Appsurd

Member
Changelog

V1.1.3 (2018-07-21)

- PHP send script: removed ‘’ around score
- Changes some variable names into more ‘clear’ ones
- Fixed typo’s
 
O

oneshot28190@hotmail. fr

Guest
hi im have a error

Code:
FATAL ERROR in
action number 1
of Async Event: HTTP
for object obj_highscore:

Variable obj_highscore.texthandle(100116, -2147483648) not set before reading it.
 at gml_Object_obj_highscore_WebAsyncEvent_1 (line 2) - if ds_map_find_value(async_load, "id") == texthandle
############################################################################################
--------------------------------------------------------------------------------------------
stack frame is
gml_Object_obj_highscore_WebAsyncEvent_1 (line 2)
 
J

johnny-o

Guest
Cool tutorial.
I've got everything set up and it seems to work, if I manually add some info to the table it will show up in the in-game highscore list
but I'm having troubles with getting it to write anything to the table.

I'm using my own server so perhaps there is some difference in the php or SQL setup. I know next to nothing about PHP or servers so I haven't been able to troubleshoot it myself.

(I was also having that "texthandle" error before I downloaded the version in the store, seems you didn't update all of the tutorial code :) )
 

Appsurd

Member
Cool tutorial.
I've got everything set up and it seems to work, if I manually add some info to the table it will show up in the in-game highscore list
but I'm having troubles with getting it to write anything to the table.
Thanks! It's a shame it doesn't work, could you please elaborate in a private message what you mean by 'it works manually but not normally' ?

I'm using my own server so perhaps there is some difference in the php or SQL setup. I know next to nothing about PHP or servers so I haven't been able to troubleshoot it myself.
This does not matter for the PHP/SQL part, only for the registration part. I would advice to read the info under "Error solving: HTML5 problems", perhaps this works for you.

(I was also having that "texthandle" error before I downloaded the version in the store, seems you didn't update all of the tutorial code :) )
Oops, seems I made some small mistake... I fixed it immediately. :D
 

Appsurd

Member
According to several people, it works in GMS2 without any modifications. But I suggest to try it yourself ;)
 
J

Jeffdev

Guest
so, I've set it all up and it's not necessarily giving me any errors, but the leaderboard only shows the text "Name" and "Score" and no scores under it, no matter how much I try to use send_score to add a score in. Can I DM you or something for help on this? I assume I probably messed something up with my code or something.
 

Appsurd

Member
so, I've set it all up and it's not necessarily giving me any errors, but the leaderboard only shows the text "Name" and "Score" and no scores under it, no matter how much I try to use send_score to add a score in. Can I DM you or something for help on this? I assume I probably messed something up with my code or something.
Certainly ;) Provide as much details as possible (and don't send me your password please ;))
 
Top