Introduction
In this post I am going to explain how you can implement trophies and high scores into your games with GM.
If you are new to GM or the Game API at first glance it can look a little daunting right? Well I will show you the absolute basics for adding trophies and high scores so the code will be nice and simple. After you can have a play around and make it look fancier.
Preparing the API library
First download the latest version of the GM API library from the link below. This tutorial will be using thatbrod's Game API library.
Once you have downloaded the latest version, unzip the folder and take a slight glance at its contents; it should contain the following items:
(In folder - "GameJolt API")
"Assets"(folder) - Needed
"Example"(.exe)
"GameJoltAPI v3.0"(.gmk)
(In folder - "Assets")
"constants"(.txt)
"functions"(.txt)
"Game Jolt API.gex"- Needed (If using extensions)
"GJAPILibary.gml"- Needed (If importing)
"http_dll_2_3.gex"- Needed (If using extensions)
"scripts"(.gmk)
Where I have put "Needed" those are the ones we will be using. For some of the files you may noticed I have put in backets, "If using extensions" and "If importing". This is because there are two ways of doing this next step.
Note:
I suggest using the extensions for this next step, rather than importing all of the scripts into your game. However I will go through on how to do both.
Extension method
Here we will add the library using extensions. These will be the .GEX
files . To do this open up Game Maker (I'm using GM 8.1 Standard).
Now go to "Resources"
-> "Select Extension Packages"
. When done a dialog window should appear called "Extension Packages"
. In here left click "Install"
then another dialog box should appear called "Installing Extension Packages"
. Click "Install"
which then should bring up an open file dialog box, search and open the GameJolt API folder and locate "Game Jolt API.gex" in "Assets"
click "Open"
and it will be added to the list when you install it (do the same for "http_dll_2_3.gex"). When it has added the extensions, they should appear under "Installed Packages".
Importing method
(Skip this, if you have installed the GJ API extension)
To add the library by importing, go to "Scripts"
-> "Import Scripts..."
then locate the file "GJAPILibary.gml" and select then click "Open"
. This will add all the required scripts in the "Scripts" folder check it out now in your game, it will be in a folder called "GJAPI Library".
Adding the basics/implementation
First create a new object and name it GJ_controller
to implement this stuff. Check the box "Persistent"
between rooms as well.
In this object add a Create
event and add the following line of code:
GJ_begin(real gameID, string "Key");
Where I have put gameID replace that with the ID of your game, which can be identified by going to Game Jolt -> Dashboard
-> Your Games
. Find your game and click Game API
then API Settings
. You should see the following screen:

Then replace "Key" with the Private key on the same. Below is an example:
GJ_begin(80640, "381e2309cf82106f3a1d67cbbfecbdc6");
Now in the Step event of the same object execute the following line of code...
GJ_step();
Place this object in the first room of your game.
This is simple right? Well then you will find the next bits just as simple and easy, I will break it down as much as possible.
Now this will begin the GJ API, now we need to get users to login to your game, this is the simplest method of doing this. Now this can be triggered by using a key press of some kind such as L
so add a key press event preferable L
key. But before we add anything to the Create event and execute the following.
inputUserName = "";
inputToken = "";
"L" key event
keyboard_string = "";
inputUserName = "";
inputToken = "";
keyboard_string = inputUserName;
keyboard_string = inputToken;
// input username and token
if (!GJ_isLoggedIn())
{
inputUserName = get_string("Please enter your username","");
inputToken = get_string("Please enter your token","");
}
// check username and token, login if correct
switch(GJ_login(inputUserName, inputToken))
{
case GJ_STATUS_OK:
GJ_fetch_userKeys(true);
GJ_fetch_trophies(true);
show_message("Login successful!");
break;
case GJ_STATUS_REQUEST_FAILED: case GJ_STATUS_INVALID_INPUT:
show_message("Login failed!");
break;
case GJ_STATUS_INVALID_CALL:
show_message("You are logged in, press the o key to log out");
break;
}
The above code prompts the user to enter their token and username if the credentials provided are correct it logs in the user. If the above makes sense to you can change small portions to personalize the text . You can now test this, by running the game and pressing the L key
when the game starts.
Now you should also give the user the option to logout too, so in the O key
press event, or whatever key you think would be best to trigger this, add and execute the following code.
//logout
if(GJ_isLoggedIn())
{
GJ_logout();
show_message("Log out successful!");
}
else
{
show_message("You are logged out");
}
Adding trophies
Now here is the bit we have been waiting for, trophies!!! If you haven't done the previous section make sure you do it else this will not work.
This section will always be different for you because your game is different and achievements will be obtained in different ways, so this part is up to you. But this is what you do to add a trophy.
To get the trophy ID go to Dashboard
-> Your Games
-> Game API
-> Trophies
then copy the trophy ID you want to be achieved. Below is an image showing this:

Since all games are different I will add an example , it is up to you to decide when the trophy is achieved. Trophies are achieved using GJ_store_trophyEarned(boolean now?, real ID);
The following script will just achieve the trophy once run.
if (GJ_isLoggedIn() && !GJ_trophy_isAchieved(ID))
{
GJ_store_trophyEarned(true, 3464);
}
Let me explain the above. The code is saying, if the user is logged in and the is not achieved yet, then achieve it; which is done in the line "GJ_store_trophyEarned(now?, ID);". Make sure you change where it says "ID" to the actual ID of your trophy you want them to achieve.
Here is an example to show this below to help you out further.
in obj_player step event
If (global.playerscore > 100)
{
if (GJ_isLoggedIn() && !GJ_trophy_isAchieved(7675))
{
GJ_store_trophyEarned(true, 7675);
}
}
High scores
Now finally for the high scores, which is even more simple than adding trophies, you will be very pleased to know.
Now again like trophies achieving high scores will depend on when you want the player to achieve it in your game; so I will just add the code you need to do this.
GJ_store_score(now?,tableid,scorestr,sortvalue,extradata);
Now let me explain and talk you through what you must change. where it says "now?" change it to true, then enter the ID of the high score table, which can be found in Dashboard
-> Your Games
-> Game API
-> Scores
(if you only have one table set the value to 0 for the primary table) where it says "scorestr" add the variable you are storing the score in, then for same variable for "sortvalue" and finally for extra data enter a string of your choice (if you don't wish to put anything just put a 0 as a value).**
Below is an example to help explain this.
GJ_store_score(true,0, global.playerscore,global.playerscore,0);
Using strings in highscores
Note:
This section is not requried to get scores working.
The above will display the score value in the table , so for instance if the score is at 10 it will just display the number 10. However you may wish to have something added to the end so for instance instead of just 10 you may want "10 Points".
One way you can do this is as followed. First create a new variable above the GJ_store_score()
function and give it a suitable name; the variable will hold your chosen score string, below is an example of this. Make sure once you have declared the variable to assign a value to it in this example I have used the value "Clicks!". (The below does not have to be global)
var global.score_string = "Clicks!";
Then create another variable to store both the score and the string.
var display_score;
Now write the following, replacing my score variable and my string also stored in a variable, called "global.score_string"; the score is called "global.clicks" in this example.
display_score = string(global.clicks) + " " + string(global.score_string);
All we are doing is concatenating the two variables together and converting the score variable (currently a real number) into a string value. This is done with string()
Now all you do is use this variable in the GJ_store_score()
function, at the "scorestr" parameter. Use the below example to help you.
GJ_store_score(true,0,display_score,global.clicks,0);**
Now if you test it the score should display with a string and not just a single score value.
Guest scoring
We have already looked at storing scores for registered users, but it is often a good idea to allow guests to highscore in the leaderboards. This section is not much of a requirement so you can skip this section if you wish.
First of all you need to enable guest scoring in the leaderboard you wish to do this. So go to your Dashboard
-> Your Games
-> Game API
-> Scores
. Then select the leaderboard you wish to enable this and find "Guest Scoring?" and from the drop down select Enabled. Then remember to click the "Edit Settings" button to confirm.
Now in your game find the section of code where you are storing highscores. To add guest highscores you must write the following.
GJ_store_guestScore(now?,TableID,guestname,scorestr,sortvalue,extradata);
This is very similar to the GJ_store_score()
function we used earlier so most of the arguments are the same, with a few additional ones. below is an example to help you:
GJ_store_guestScore(true,0,global.guest_name,global.display_score,global.score,0);
I will talk about getting the guest name after I show an example of how you use the above.
if(GJ_isLoggedIn()) //if the user is logged in, then store the score as usual
{
GJ_fetch_tableScores(true,0,global.score);
GJ_store_score(true,0,global.display_score,global.score,0);
}
else //otherwise store the score as a guest score
{
GJ_fetch_tableScores(true,0,global.score);
GJ_store_guestScore(true,0,global.guest_name,global.display_score,global.score,0);
}
I will now talk about a way to get the name of your guest user. You could just enter a string such as "Player" but it's better to get the name of the person playing so they are not completely anonymous. First of all look at the example above where I have put "global.guest_name" that is the variable that stores the guest name. To get the guest name find the object where you got the login details which we did in the earlier section of this topic, then in the create event drop set a new variable and give it a sensible name such as Guest_name make sure it is global; so it would be global.guestname. Then set the value to "" and click ok. Now find the code where it checks for login details and update it to match the following.
keyboard_string = "";
inputUserName = "";
inputToken = "";
keyboard_string = inputUserName;
keyboard_string = inputToken;
keyboard_string = global.guest_name /*change global.guest_name to your variable that stores the guest name string */
if (show_message_ext("Login to GameJolt?","Yes","No","") == 1)
{
// input username and token
if (!GJ_isLoggedIn())
{
inputUserName = get_string("Please enter your username","");
inputToken = get_string("Please enter your token","");
}
// check username and token, login if correct
switch(GJ_login(inputUserName, inputToken))
{
case GJ_STATUS_OK:
GJ_fetch_userKeys(true);
GJ_fetch_trophies(true);
show_message("Login successful!");
break;
case GJ_STATUS_REQUEST_FAILED: case GJ_STATUS_INVALID_INPUT:
show_message("Login failed!");
break;
case GJ_STATUS_INVALID_CALL:
show_message("You are logged in, press the o key to log out");
break;
}
}
else
{
global.guest_name = get_string("Name of guest?","");
}
So now that guest name is stored in a variable you can show the value in the GJ_store_guestScore()
function.
Loading scores from highscore tables
If you want to load scores into a game, the enter the following lines of code.
Var GJScoreAmount, TableID;
GJScoreAmount = 10; // Get the number of scores you want to load
TableID = 0; //table ID
GJ_fetch_tables(now?) //call this first
GJ_fetch_tableScores(now?,tableID,count);
All you must do is replace Now?
(for both GJ_fetch_tables()
& GJ_fetch_tableScores()
) to true as you done before and change tableID
to variable TableID
that stores the ID if your table and count
to the variable GJScoreAmount
.
Below is an example to help you out further if you are stuck.
var GJScoreAmount, TableID;
GJScoreAmount = 10; //get the number of scores you want to load
TableID = 8987; //table ID
GJ_fetch_tables(true) //call first and only once
GJ_fetch_tableScores(true,TableID,GJScoreAmount);
Drawing loaded scores
In the previous section of this guide I went through how to fetch highscores into your game. Once you have loaded the data from the leaderboards into your game you are able to draw it in your game.
First of all I would create another object and give it a sensible name such as draw_highscores.
Then in the draw event execute this code as follows:
var i, j, tbID, placeNum, placeString, userScore, tableSize, userName, guestName;
tbID = 0;
tableSize = GJ_table_size(tbID);
for(placeNum = 0; placeNum < 10; placeNum+=1)
{
if(placeNum < 9)
placeString = "0" + string(placeNum + 1);
else
placeString = string(placeNum + 1);
draw_set_color(c_black);
draw_text(38,20 + placeNum*20,placeString);
for(i = 0; i <= tableSize; i+=1)
{
userScore = GJ_tableScore_getScoreName(tbID,i);
userName = GJ_tableScore_getUserName(tbID,i);
guestName = GJ_tableScore_getGuestName(tbID,i);
if(GJ_tableScore_isGuestScore(tbID,i))
draw_set_color(c_gray);
else if (GJ_tableScore_isUserScore(tbID,i))
draw_set_color(c_green);
if(i != 0) {
draw_text(110, 0 + i *20, userScore);
draw_text(200, 0 + i *20, userName);
draw_text(200, 0 + i *20, guestName);
}
}
}
Quite a bit to write so allow me to break it down.
First we called the function below, and stored it in a variable. This function gets the size of the table, which only takes one argument. So the argument tbID
must contain the table ID you wish to get the information from. So just before we call this function make sure you assign tbID
with the correct value (remember 0 is the default table).
tableSize = GJ_table_size(tbID);
The next important part is the snippet of code below. What you should change here is this part placeNum < 10
. This is because you might want to draw a different number of scores, so for instance you may wish to draw 20 so you would change the value to this. Note: the maximum is 100.
for(placeNum = 0; placeNum < 10; placeNum+=1)
Now the code below writes the place number in a sequence of 01, 02 etc. When the place number is larger than 10 the 0 is not included, to prevent it being wrote as 050 for instance. You can remove this code altogether if you wish.
if(placeNum < 9) // Draw scores as 01, 02, 03 etc before 10, to prevent being printed as 010
{
placeString = "0" + string(placeNum + 1);
}
else
{
placeString = string(placeNum + 1);
}
Then we draw the place numbering, which will appear as 01, 02, 03 etc. The snippet below draws this, all you must change is the x,y position of the text to suit your needs.
draw_text(38,20 + placeNum*20,placeString);
After this we come across another loop which draws the score strings by calling the score getter functions.
userScore = GJ_tableScore_getScoreName(tbID,i);
userName = GJ_tableScore_getUserName(tbID,i);
guestName = GJ_tableScore_getGuestName(tbID,i);
Using the variables that we declared aat the start, we stored the needed getter functions into each of them. GJ_tableScore_getScoreName(tableID,rank)
, GJ_tableScore_getUserName(tableID,rank)
and GJ_tableScore_getGuestName(tableID,rank)
are the 3 getter functions we used., and of course there are more.
Then the next part was to test whether the score was achieved by a user or guest. Two functions are used to test this which are as followed GJ_tableScore_isGuestScore(tableID,rank)
and GJ_tableScore_isUserScore(tableID,rank)
. You can do anything you like with this part or you don't even have to include it, in order for this to work.
if(GJ_tableScore_isGuestScore(tbID,i))
{
draw_set_color(c_gray);
}
else if (GJ_tableScore_isUserScore(tbID,i))
{
draw_set_color(c_green);
}
And finally all we do is draw the scores, the only thing you really need to change here is the x, y
position of the text.
if(i != 0) {
draw_text(110, 0 + i *20, userScore);
draw_text(200, 0 + i *20, userName);
draw_text(200, 0 + i *20, guestName);
}
Once you have drawn all the data, you just place the object in the room in which you want the data to appear in. Then you format the information drawn to look however you please.
Conclusion
I hope this guide helped you implement GJ achievements into your games and hopefully you didn't find any of this too difficult at all. Some things may need to be added or improved in future which should be noted here. If you have any further questions or have spotted something I missed, then please let me know and I will get straight to it.
Good luck to you and good day!