GM:S 1.4 Online Highscores

Discussion in 'Tutorials' started by Appsurd, Aug 10, 2016.

  1. Appsurd

    Appsurd Member

    Joined:
    Jun 20, 2016
    Posts:
    198
    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.

    @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.
     
  2. FrostyCat

    FrostyCat Member

    Joined:
    Jun 26, 2016
    Posts:
    3,694
    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:
    Tell me what part of his inquiry I didn't follow.
     
  3. Appsurd

    Appsurd Member

    Joined:
    Jun 20, 2016
    Posts:
    198
    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.
     
  4. PatrikPé

    PatrikPé Member

    Joined:
    May 25, 2017
    Posts:
    2
    Thanks again, works perfectly :)
     
    Appsurd likes this.
  5. mononosto

    mononosto Member

    Joined:
    Aug 8, 2017
    Posts:
    3
    How can I retrieve the 10th highest score from the database?
     
  6. Appsurd

    Appsurd Member

    Joined:
    Jun 20, 2016
    Posts:
    198
    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 :)
     
  7. mononosto

    mononosto Member

    Joined:
    Aug 8, 2017
    Posts:
    3
    Thanks for your response. It worked!

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

    Appsurd Member

    Joined:
    Jun 20, 2016
    Posts:
    198
    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 :)

    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!
     
  9. mononosto

    mononosto Member

    Joined:
    Aug 8, 2017
    Posts:
    3
    Thanks a lot! Will do.
     
  10. alexalex

    alexalex Member

    Joined:
    Sep 4, 2017
    Posts:
    6
    I've tried it! It works:)
     
  11. Ernesto Romero

    Ernesto Romero Member

    Joined:
    May 12, 2017
    Posts:
    48
    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: Sep 10, 2017
  12. Appsurd

    Appsurd Member

    Joined:
    Jun 20, 2016
    Posts:
    198
    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!
     
  13. Ernesto Romero

    Ernesto Romero Member

    Joined:
    May 12, 2017
    Posts:
    48
    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
     
  14. Appsurd

    Appsurd Member

    Joined:
    Jun 20, 2016
    Posts:
    198
    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.
     
  15. Ernesto Romero

    Ernesto Romero Member

    Joined:
    May 12, 2017
    Posts:
    48
    Hola amigo vos si pudiste hacer que el puntaje no se repita? muchas gracias, como no se mucho de PHP no tengo idea de que hacer saludos
     
  16. Kloac

    Kloac Member

    Joined:
    Sep 21, 2017
    Posts:
    3
    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.
     
  17. Appsurd

    Appsurd Member

    Joined:
    Jun 20, 2016
    Posts:
    198
    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 :)
     
  18. Kloac

    Kloac Member

    Joined:
    Sep 21, 2017
    Posts:
    3
    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 .
     
  19. Appsurd

    Appsurd Member

    Joined:
    Jun 20, 2016
    Posts:
    198
    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?
     
  20. Kloac

    Kloac Member

    Joined:
    Sep 21, 2017
    Posts:
    3
    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!
     
  21. Appsurd

    Appsurd Member

    Joined:
    Jun 20, 2016
    Posts:
    198
    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.
     
  22. Relic

    Relic Member

    Joined:
    Jun 27, 2017
    Posts:
    549
    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.
     
  23. Appsurd

    Appsurd Member

    Joined:
    Jun 20, 2016
    Posts:
    198
    Thanks! I will (probably) include your code (and further comments) in the next version! Thanks very much for pointing/trying this out!
     
  24. helpleo

    helpleo Member

    Joined:
    Aug 6, 2016
    Posts:
    17
    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.
     
  25. FrostyCat

    FrostyCat Member

    Joined:
    Jun 26, 2016
    Posts:
    3,694
    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.
     
  26. helpleo

    helpleo Member

    Joined:
    Aug 6, 2016
    Posts:
    17
    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.
     
  27. Appsurd

    Appsurd Member

    Joined:
    Jun 20, 2016
    Posts:
    198
    Hey,

    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!

    Best regards,
    PeliStar
     
  28. ImSoAbell

    ImSoAbell Member

    Joined:
    Mar 20, 2018
    Posts:
    4
    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?
     
  29. FrostyCat

    FrostyCat Member

    Joined:
    Jun 26, 2016
    Posts:
    3,694
    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.
     
  30. jmack20093

    jmack20093 Member

    Joined:
    Feb 23, 2018
    Posts:
    2
    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!
     
  31. Appsurd

    Appsurd Member

    Joined:
    Jun 20, 2016
    Posts:
    198
    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 :)
     
  32. Ramiro

    Ramiro Member

    Joined:
    May 30, 2018
    Posts:
    3
    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.
     
  33. Ramiro

    Ramiro Member

    Joined:
    May 30, 2018
    Posts:
    3
    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.
     
  34. Appsurd

    Appsurd Member

    Joined:
    Jun 20, 2016
    Posts:
    198
    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?
     
  35. Ramiro

    Ramiro Member

    Joined:
    May 30, 2018
    Posts:
    3
    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
     
  36. Appsurd

    Appsurd Member

    Joined:
    Jun 20, 2016
    Posts:
    198
    Seems like you get no response at all. I'll answer you in more detail in a PM
     
  37. ali9050

    ali9050 Member

    Joined:
    Jan 3, 2017
    Posts:
    4
     
  38. Appsurd

    Appsurd Member

    Joined:
    Jun 20, 2016
    Posts:
    198
    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!
     
  39. Daan Zoor

    Daan Zoor Member

    Joined:
    Jul 12, 2018
    Posts:
    5
    Thanks a lot PeliStar, very easy for beginner :)
     
  40. ali9050

    ali9050 Member

    Joined:
    Jan 3, 2017
    Posts:
    4
    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.
     
  41. Appsurd

    Appsurd Member

    Joined:
    Jun 20, 2016
    Posts:
    198
    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!
     
  42. dizzy1666

    dizzy1666 Member

    Joined:
    Feb 22, 2017
    Posts:
    6
    Thanks! Great tutorial!
     
    Appsurd likes this.
  43. Appsurd

    Appsurd Member

    Joined:
    Jun 20, 2016
    Posts:
    198
    Changelog

    V1.1.3 (2018-07-21)

    - PHP send script: removed ‘’ around score
    - Changes some variable names into more ‘clear’ ones
    - Fixed typo’s
     
  44. oneshot28190@hotmail. fr

    oneshot28190@hotmail. fr Member

    Joined:
    Mar 30, 2018
    Posts:
    2
    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)
    
     
  45. Appsurd

    Appsurd Member

    Joined:
    Jun 20, 2016
    Posts:
    198
    I have sent you a PM
     
  46. johnny-o

    johnny-o Member

    Joined:
    Sep 1, 2017
    Posts:
    5
    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 :) )
     
  47. Appsurd

    Appsurd Member

    Joined:
    Jun 20, 2016
    Posts:
    198
    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' ?

    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.

    Oops, seems I made some small mistake... I fixed it immediately. :D
     
  48. Jeffdev

    Jeffdev Member

    Joined:
    Nov 28, 2017
    Posts:
    5
    Does this work with GMS2?
     
  49. Appsurd

    Appsurd Member

    Joined:
    Jun 20, 2016
    Posts:
    198
    According to several people, it works in GMS2 without any modifications. But I suggest to try it yourself ;)
     
  50. Jeffdev

    Jeffdev Member

    Joined:
    Nov 28, 2017
    Posts:
    5
    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.
     

Share This Page

  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice