Wednesday 29 March 2017

How to Implement Scoreboards in Godot with the GameJolt API

GameJolt is not the largest gaming platform, nor is Godot the most popular editor. Despite this, a kind user known as "ackens" has created a plugin for Godot, which allows super easy integration with the GameJolt API.

This plugin can be downloaded at this link: https://github.com/ackens/-godot-gj-api

Since the Internet failed me for quite a while on how to install this plugin- I will enlighten the kind readers of my blog. Inside your project folder, (res://), you need to make a folder called "addons". Place the "gamejolt_api" folder inside that folder(res://addons/).

If you have done this correctly, you can return to the editor and press "Scene" in the top-left, down to "Project Settings" and select the "Plugins" tab. The API should show up as an entry called "Game Jolt API". Simply set its status on the right hand side from "Inactive" to "Active", and you're good to go.

From here, there are a number of things to tackle. I'm going to be primarily explaining how to submit guest scores to a scoreboard since this is what I used the API for in my game, Super Displacement.

The assumptions that I will be making from here on are that:
  1. You're using a scene that isn't your main gameplay loop to do this(though if you are, I'm sure this can be adjusted)
  2. You can make a better UI for this than I can.
  3. You have a given score to submit.
If all of these 3 apply, then we can get started.



Before you can do anything, you must add a GameJoltAPI node to your scene. Each API command you make will be a method on this node, i.e it will be of the form:

    get_node("../GameJoltAPI").method(argument)


Before making any of these calls, it's important to set two properties of the node: your game's Private Key and its ID. These are used to identify to the GameJolt servers as to which game is being edited.

Both of these variables can be found by going to your game's page on GameJolt, clicking "Manage Game", "Game API" and selecting "API Settings" on the left hand side.


Once you have entered these values, you're ready to start making some API calls.

For Super Displacement, the need to log into GameJolt was never present, so I did not need to use .auth_user("token", "username"). Fortunately for me, the GameJolt API has a function called "add_score_for_guest". This - as the name would suggest - allows a score to be submitted as a guest, where the user never has to log in or input anything other than a display name. This makes things very easy.



I used a LineEdit object for the user to input their desired display name, and on pressing either the enter key(using the "text_entered" signal on the LineEdit) or the "Submit Score" button, the text in the LineEdit(get_node("../LineEdit").get_text()) is returned to a script which then submits the request.

However, that's not quite my implementation of it.


One. For some reason, either GameJolt or the implementation of it in Godot freaks out if there are spaces in the display name. This is a super simple fix, as the only way around this (beyond rejecting the user's input if they input a name with spaces) is to simply remove the spaces from the name, using:

    guest_name.replace(" ", "")

This command quite simply moves through the string, replacing any instances of the space character with an empty string. In effect, this removes the spaces. "The Best" becomes "TheBest", etc.

Two. What if the user doesn't input a name? While this doesn't stop the request from happening(as far as I know), it may be helpful to put a stock username in its place.  For this, I did a simple check:

    if(guest_name == ""):
     get_node("../../GameJoltAPI").add_score_for_guest( .. , .. , "Guest" + str(randi()%10000000))


Though it makes my inner PEP8 fanatic weep, it does the job. If the user has not entered a name into the LineEdit, it generates a random string of 7 numbers and appends it to the word "Guest".

At this point(and probably a bit earlier) I should explain how this method works.

The first argument (called the "score" in the plugin's documentation on Github) is a string which is displayed on the "Scores" section of your game's page. This might be "23 Castles Destroyed", "381 Enemies Slain", or whatever quantifier you want to add. In my case, I simply set this to "str(latest_score)", since there isn't much of a quantifier beyond "Points" to add to an arcade score.

The second argument (called the "sort value") is an integer value which tells GameJolt how to order the scores in the table. Assuming you have the score table in "Ascending" mode - big means good - a higher sort value will mean a higher placement on the scoreboard. In my case, this is "int(latest_score)"(since latest_score is originally a float value).

After that, that's really all there is to it. If you wanted to add scores for a logged in user, you would have to .auth_user("token", "username") and then .add_score_for_user(visible_score, sort_value).

Displaying scores is also very simple, though it requires some playing with JSON files first.




Again, assuming you have a GameJolt API node in your scene, you're ready to make some API calls.

For my HighScores.tscn scene, I put a standalone call for 30 scores into the _ready(): function:

    get_node("../../GameJoltAPI").fetch_scores("30")

Your immediate reaction might be confusion as to why this isn't being printed, assigned to a variable or anything else- it's because the plugin responds with a signal that carries the scores in a string. This signal is called "api_score_fetched(var scores)".

You might also be confused as to why the "30" is a string and not an integer and to be quite honest I have no idea, but it has to be a string for some reason.

Connect this signal to a node of your choice, and try to print(scores) - you'll get something that looks an awful lot like JSON. The explanation for this is that this is JSON, but it's encoded in a string, and we have to parse it into a dictionary.

Do something like this:

    var scores_dictionary = {}
    scores_dictionary.parse_json(scores)

This creates an empty dictionary, and parses "scores" into a nice dictionary format, where it can be indexed. There is a list of dictionaries contained at the ["response"]["scores"] indices.

I implemented the "table" in the screenshot above by creating 6 separate labels, for 2 sets of 3 labels. The first label consists of the numbers, which I added manually. This could very easily be automated, but that is an exercise left to the reader.

The second field consists of the names of the users who have submitted scores. This can be obtained by creating a variable named "names", iterating through "scores_dictionary" and concatenating each guest name to "names" along with a \n for the linebreak.

The code I used for this part is as follows: 

    var names = ""
    var names2 = ""
    for i in range(visible_scores.size()):
        if(i<15):
            names += visible_scores[i]["guest"] + "\n"
        elif(i<30):
            names2 += visible_scores[i]["guest"] + "\n"
    get_node("../names").set_text(names)
    get_node("../names2").set_text(names2)
  
Assuming the line spacing and Y coordinate is the same, this will line up with the numbers.

The variable and node called "names2" is the second instance of each list of names, as shown in the screenshot above.

The exact same process can be used for the score, all you have to do is reference [i]["score"] instead of [i]["guest"].

If you have implemented these correctly, you should get a nice, basic scoreboard for further extension and development. Also, I'm sure there's something better than Labels to use for this kind of thing, but this technique can be adapted suitably.

If you have any further queries, you can leave a comment below and I am very likely to answer it. In any case, thanks for reading, and good luck!

If you want to download my game "Super Displacement", you can at the link below:

http://gamejolt.com/games/super-displacement/244666

Sunday 26 March 2017

(Tentative) Release day for Super Displacement!


Super Displacement is a hectic, fast-paced shooter where the player's job is to shoot enemies and avoid getting bounced into the walls.

Sounds fun? If it does, this game is for you. If it doesn't, then this game is probably still for you. If you're on the fence about your decision to play this game, the game is absolutely for you. If you categorically hate fun- this game is not for you, I'm sorry.

Still play it, though.

It's currently being kept in Early Access, because I think I'm going to keep updating it with new functionality. Regardless, thanks for reading, and you can either download straight from this page or visit the page on Gamejolt.




Or, the page on Gamejolt is linked here.

http://gamejolt.com/games/super-displacement/244666

Saturday 25 March 2017

Super Displacement

Super Displacement is a hectic game in which you bounce around and avoid touching the walls.



If you like the sound of that, feel free to continue reading.

As some of you who keep up-to-date on my work may know, I recently dropped another project to remake "Don't Be Still". After starting work on "Don't Be Still", I realized that the initial mechanic had no place in the rest of the game, and I renamed it "Super Displacement".

The premise of "Super Displacement" is very simple - don't touch the walls, and shoot the rectangles that are trying to bounce you into the walls.

Playing it myself(I may be biased) and receiving feedback from friends(also biased), it seems to feel pretty good. I feel confident in saying that this is my best work yet, though that doesn't mean much given my portfolio of abject failures.



Unfortunately, screenshots do not do the frenzied nature of the game any justice. If you like screenshaking, explosions and lots of bouncing around, then this game is probably going to be enjoyable for you.

I've spent a lot of time in this post just "selling" this (free and unreleased) game to you, so now I'm going to talk about something which no one online seems to tell you. Also, if you're not programmatically inclined or don't use the Godot engine, this might be of limited usefulness for you.

Handling Save Data in Godot

So, Super Displacement uses save data to store highscores and a couple of other statistics. Unfortunately for me, due to Godot's rather limited documentation no one told me that Godot fucks up when you try to save the file as a resource("res://...") rather than as a user file("user://...").

In short, files referenced as a resource("res://...") are contained within the executable while files referenced as a user file("user://...") are contained within something like $HOME/.godot/Super Displacement/

Apparently, resources can't be written to in the same way that user files can.

If there's a takeaway from this short segment, it'd be "Don't be afraid of using user files because resource files have annoyed me and taken an hour of my life from me and I hate them forever".

In any case, thanks for reading.

Tuesday 21 March 2017

Solasi?!

To cut a long story short, I set out to work outside of my own realistic capabilities with Solasi and I am effectively forced to cancel it. Sorry.



A Post-Mortem Of Solasi

For those who don't know, Solasi is a game in which you control a guy stuck in an underground bunker, who has to deal with his nightmares and his descent into insanity. It's kind of like a survival game.

It is fine in concept- though I find it abrasive to think about for too long given the amount of time I've spent hitting my head against the most basic components of it.

So my first mistake was coming up with a story or narrative-based idea when there is so much restriction on how I can convey this narrative. My only real option was to either hide messages on the map itself and change them each day, or to present the player with a pop-up window at the start of each day. Of course, the former is preferable. Unfortunately, neither of these options are quite enough to make the game worthwhile playing.

What I should have done was go into the game with a clear understanding of its strengths and weaknesses. What I did instead was come up with a large yet fun idea in my head and throw my face against it. Lesson #1: Don't underestimate a comprehensive design document.

When I came to making the game, I made some good use of placeholder assets. I'm quite happy with the fact that I did wait until the "end" to start adding some visual sparkle, because otherwise I never would have gotten as far as I did.

However, I didn't clearly define the environment itself and ended up semi-overhauling the visual design to a more monochromatic and dull look only to realize that I could never finish this project. I had set out with no clear ideas for the enemies, so I had no cohesive ideas as to what they should look like as a collective and this only served to build what would become an insurmountable challenge.

Lesson #2: Plan things out before you start programming. I'm at massive risk of damaging my reputation as a programmer and game developer here, but holy hell the straw that broke the camel's back was a peculiar bug I was having where the game would just freeze. Nothing in the debug log, nothing anomalous in the stack trace- just a freeze. At first I wondered if it was randomly pausing somehow, so I set it to unpause every frame. Sadly, there was no improvement. The only possible link to it was that it was caused by the enemy type that shoots a bullet- but not linked to the bullet firing activity. Nor whenever it spawned.

After struggling with this bug for some lengthy hours, I called it on Solasi. Together with the design flaws, terrible workload and this god damn Shroedinger's Bug, I was not prepared to deal with this project anymore.

Don't Be Still


Light At The End Of The Tunnel

Solasi(apart from honing my skills for about 50 hours of work), served to provide a suitable jumping point away from larger projects back to a more comfortable arcade-y project. To be precise, the project I'm working on now is a remake of the game "Don't Be Still" that kick-started my adventures into game development in the first place.

It's small and I have a few tentative ideas for it, but so far it's feeling pretty damn fun. Pictured just above is a screenshot I took from the prototype.

In a sentence, Don't Be Still is a fast-paced shooter where the player's job is to shoot enemies, keep moving, and avoid the walls of the arena.

Touching the walls of the arena results in an instant "Game Over", while touching the enemies just bounce you around a bit. The real crux of the game - as is eponymous - is to keep moving. Staying still for too long will drain your health(not pictured) and eventually cause you to lose.

It's not a complicated concept, but so far I'm fairly happy with it. Stay tuned for more updates and hopefully within the next few weeks, a full release!

As per usual, if you have done- thanks for reading.

Sunday 19 March 2017

Well-Executed Derivative Ideas Are Better Than Poorly Executed Unique Ideas


Take two.

So look, before anything else I want to say that by no means am I saying that totally unique ideas are bad, or should even be discouraged. Games such as “Papers, Please” would likely not exist if the developers had not put thought and effort into creating an innovative game mechanic.

However, much more importantly to “Papers, Please"'s success was the strong art style and the emotional impact it makes on the player. These were instrumental- without them, I find it hard to believe that the game would have made it very far at all. If you don’t believe me, you can verify this by looking at two or three reviews for the game. The majority of them hardly praise the passport-checking mechanic at all, especially given that the rest of the article is usually focused on the art style.

This brings me to the main point of this post: unique ideas are cool and often helpful, but it’s a lot more important to execute a given idea well. Any poorly executed idea is not likely to perform well. I have first hand experience in this, as I once created a very poorly executed game called “Don’t Be Still”.

The unique idea at the core of this game was that you had a “stillness meter”, and any time you spent being still or taking damage from enemies would deplete this meter. I think I can safely self-assess here to say that this idea was fine and a suitable game could be built on this mechanic. Unfortunately, I did the exact opposite of build a suitable game. With about 3 seconds of graphical design and no more than a day or so of programming, I threw together something which I cringe to call any more than a prototype. This idea was executed dreadfully, and as such it suffered at launch.

Ultimately, the execution of an idea comes down to a mixture of skill, effort and personal tendencies.

Don’t Be Still” was primarily gated by the first two, as I can’t speak much to personal tendencies for an engine I was just beginning with. This engine was the Phaser engine. Phaser is a Javascript framework which easily integrates with either WebGL or the HTML5 Canvas. Point is- “Don’t Be Still” was the first project that I’d ever made in Phaser, and I was still getting to grips with how it worked.

Needless to say, I effectively had no idea how Phaser worked even after completing Don’t Be Still, hence why the game is the actual dumpster that it is today. Partly because of the aforementioned and partly just because I was enamoured with the idea that hey- I could make games now, I only spent about a week on it in total before uploading it online.

The take-away from this post (assuming you’ve read up to this point) is that if you’re a newer game developer or if you’re struggling, don’t chase a single unique idea, because in all likelihood it won’t make a bad game good. Take a small idea and polish the hell out of it until it’s something that you’re proud of.

If you have done, thanks for reading.

Also, holy shit I have been lazy for the past week two weeks three weeks. If you're a repeat reader, thank you but more importantly, be sure to keep an eye out. I have something to say about the fate of Solasi, and it isn't good.

Friday 3 March 2017

Godot Is The Best Engine - Godot vs Unity



This is a video I made to compare these two engines. The transcript is below, enjoy!


So, this is a new series I’m doing where I’ve decided I’m gonna be an unpaid shill for the Godot engine, and compare it to some other engines. This first episode is going to compare Godot to its obvious competitor, the Unity engine.

At a first glance, Godot and Unity are not so different from each other. Having said that, Unity puts a massive emphasis on its 3D editor, while Godot is primarily made for 2D development. That’s a pretty big difference right off the bat, I mean they are primarily designed for two completely different jobs. However, given that they both have support for 3D and 2D editing, they can be suitably compared.

While Godot’s 3D renderer isn’t the best thing in the world, Unity’s 2D renderer is literally just the 3D renderer locked into an orthographic viewport.

The fact that Godot at least uses a separate dedicated renderer for 2D is an advantage in itself, seeing as that minimizes the amount of performance overhead that may otherwise be detrimental to applications that rely on a high frame-rate- which just about all games do.

Another thing that Godot has over Unity is that Godot is totally free. While Unity is proprietary and closed source, Godot is maintained by around a hundred developers on Github under the MIT license. This means that Godot is free as in free speech, not as in free beer. Stallman would be proud.

Leading on from this, Unity forces users of the free version to have a “Made with Unity” splash screen at the beginning of their game. Godot has no such limitation. Though it is there by default, it can be either changed or totally disabled as the user wants.

I will give Unity some credit, in that it does not use its own constructed programming language for the programmatic side of things. This is a genuine advantage that Unity has over Godot. However, having said that, Godot’s GodotScript can be made to integrate with precompiled C++ modules very easily, for more performance-sensitive tasks.

A massive thing that Godot has above Unity is the fact that Godot is cross-platform, and available on Windows, Mac, and Linux. This is very important for myself, considering that I use Linux as my primary operating system and Unity crashes usually within about 5 minutes of work. Last time I checked, right clicking on a drop-down menu forced it to close as of about 6 months ago.

Also, Godot exports to BSD running X11. Just consider that for a moment- what other engine even acknowledges BSD exists? I don’t think anyone developing the Unity engine knows what BSD is, but that’s speculation more than a criticism of their product.

Regardless, Godot’s user interface is a lot more intuitive, at least in my opinion. It makes efficient use of space and colours, something which I do not feel Unity does as well. A petty complaint, but if there ever was a time to say it then hey, here it is.

Also, Godot’s mascot is better than Unity’s so fu

Now look, obviously I’m not saying that Unity is a bad engine. Objectively speaking, it’s powerful and has been used for a number of very high-profile cases. Having said that, Godot beats Unity at every level in so far as 2D is concerned. I haven’t used Godot’s 3D options so I can’t speak much to that, but I’m confident in saying that it’s a worthy contender.

Either way, thanks for watching. Stay tuned for the next episode in the series on… I dunno a different engine probably.