 Hello there! Continuing our series of videos about how Moon Cheezer was developed, today we'll talk about how to manage the achievement system. So to begin with, I had to take what could be done in my game, in other words, the mechanics. After that, I stated some cool events which could happen in my game, such as gather a certain amount of cheeses, witness a supernova, like the collision of two stars, play the game on a full moon day, etc. The easier way I found to keep out this data, the description, the condition, the fulfillment of the achievement, was to write everything into a .json file. So I created this file which contains the dictionary key for each achievement, and inside these keys, which are dictionaries too, I created keys regarding the total amount that must be accomplished, the description of the achievement, the current amount already accomplished, and the name of the achievement. That's all for the data. Now let's move on to Godot Engine and the logic behind the achievements. To begin with, let's talk about the structure of the scene. I created a canvas layer as the root node of the scene. This way I could easily set this UI above the game player layer, making sure that players would always know when they fulfilled an achievement. Then I started to build the actual UI, a simple panel with two labels, one for the actual warning and the other for the message. In this case, a achievement unlocked followed by the name of the achievement. After that I added the nodes responsible for the animation, a twin to interpolate the position of the panel, and a timer, which will be used to tell how long the panel would be displayed on the screen before it did disappear. Now to the actual logic. First of all, it needs to know the path to the file that contains the data for the achievement. For that, I simply exported a string with the file flag to the editor. After that, I created the respective variables regarding the dictionary, which would handle the data and gather the needed nodes for the animation and visual feedback. To read the data file, we need to do six steps. Check if the file exists in the user's disk. If it does, we will open it and parse it to a variable as a text. After that, parse this variable as a JSON file to the dictionary we've created. And if the file doesn't exist, we will need to load the template data file, parse it as a text, and parse the text as a JSON to the dictionary. And write the file to the player's disk. To write the file is simpler. Check if the file already exists. This also creates the file in the disk if it doesn't exist. Open the file with the right flag, start the dictionary as a string, and close the file. The user directory is a relative path that points to a local data on the user's disk. And it's always accessible independent of how the user's operational system handles this data. So it's the best path to store this kind of content. I also had to modify the data we needed to keep track of the players for filming. To do that, I created a single method which received two arguments. One for which achievement shall be modified and the other to develop which shall be used to modify it. If the value argument is zero, I presumed it should be set to zero. Then I just needed to access the dictionary using the achievement argument as the key and access the accomplished key to modify its value. But to add, I first had to check if the achievement is already accomplished. So I just checked it if the current accomplished is less than the total. If it does, it will add the value argument to it, and after that check if it is accomplished now. If it does, it will set the name label nodes text to be the name of the achievement and display it on the screen. To display the visual feedback to the player, I just had to treat the panel as a pop-up window. So it would start hidden and would be displayed only when I told it to. So I simply created two methods for that. The first one would display it and animate its position with an overshoot interpolation on the end. It would also tell the timer to start counting. When the timer finishes the countdown, it will tell the panel to disappear by counting the other method responsible for hiding it. This method does the opposite of the first one. It will interpolate the position in the opposite direction with an overshoot effect at the beginning of the interpolation. Then we wait for the twin node to sign out that it ended the interpolation, and after that we will tell the panel to hide. Finally, I just needed to make this scene an autoload single-tone, so it won't be clean when transitioning between scenes, and every node will be able to access it globally. Also, I had to add the JSON file to the filter of non-resources file on the resources tab of the project settings. Otherwise, it wouldn't be exported with the game executable and everything would go wrong. And that's the result I got after all this process. That's it. I hope you're enjoying this kind of content. Leave a comment below if you have any doubts and suggestions for the next topics for the upcoming videos. That's all for now guys. Keep developing and until the next time.