Showing posts with label devblog. Show all posts
Showing posts with label devblog. Show all posts

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

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.

Monday, 20 February 2017

Solasi?

Hello! As some of you may be aware, I immediately started work on a new project, Solasi, after finishing Monotony.


I'll outline what my project actually is for the lovely readers of my blog.


Solasi is a survival semi-horror game. The player is trapped in a surreal underground bunker, where food and water are not rare resources. The most valuable resource is instead your own sanity -- being trapped in total isolation only to grapple with your own horrifying nightmares is bound to be harmful.

There will be two phases to gameplay. The first of which is the "daytime", where the player may perform menial tasks to increase their statistics. These statistics come in useful come "nighttime", where the player must
fight monsters - be it either to protect themselves, for the sake of slaughter itself or to acquire a Nightmare Charm simple trinket.



I am currently totally infatuated with this concept - if I can successfully translate between my mind and this computer, I will have created something truly wonderful. So far, this translation is going exceptionally well.

Unfortunately, since I'm using almost exclusively place-holder assets(except for that sick bed), it's more difficult to visually show off the game.

Either way, definitely stay tuned.

Also, follow me to help my self-esteem. Thanks.

Thursday, 16 February 2017

The final instalment in the trilogy, "Monotony", is released!

Hooray! After about a week of work, Monotony has been released. If you're interested in avant-garde art-y games, appreciative of some good atmosphere or just want a 5-minute experience to kill time - this game is for you.

You can download it below.



If you haven't already, I highly recommend you look into Monotony's predecessors for some fairly useful context.

You can download the first in the series, Homogeny, below.



And of course, the second game in the series can be downloaded below.



If you have done, thanks for following the development cycle of these games, and I hope you enjoy! Stay tuned.

Monday, 13 February 2017

Discussing the themes of "Homogeny"

After a lot of actual game development/other writing/other things, the analysis post is here!

If you haven't already, you can download and play Homogeny for free right here.


A fairly notable focus of discussion is actually as to why I even decided to create this game. The answer is split between because I liked the art style after having created Yet Another Puzzle Game, and because I wanted to create a very art-centric game.

The latter was actually prompted by a few very "avant-garde" YouTube videos, and I got jealous of the fact that the medium of a YouTube video can be used in such a way. It was shortly afterwards that I realized I could probably do something pretty similar in a game, so I tried to do just that(minus the "horror" aspect, which was incidentally very present in the two I linked).


The themes in Homogeny are, as you may have guessed, not intended to be frivolous.

To sum it up in a single word, the game as a whole represents "realization", as I retroactively fit it into a three-part story centred around misanthropy -- but we'll come to that in a few posts' time.

The full script - i.e the correct answers - can be found here.

The first presentation wasn't particularly special in that the first few sentences were a little bit clunky, entirely unguided and not really intended to mean anything. The first sentence I put some thought into was "The future of this convention is concerning", which serves to set up what comes next.

I mentioned that this trilogy - and by extension, this game - is ultimately about misanthropy. This is manifested in the character's fairly inelegant suggestion to totally disband the convention -  the character is callous either to the possibility that others may take offence to this statement, or totally callous to it altogether.

The next presentation immediately starts immediately with a continuation the first presentation - a year ago in the game's universe. The lack of new material to discuss enforces the idea that the character, despite their arguably gauche attitude, is correct in what they are saying. They do not offer an apology, but instead passive-aggressively chastises the attendants for not following an instruction which he did not actually deliver.

A common trait of people living with Narcissistic Personality Disorder is to claim that they did say or do something which they did not, or vice versa. This is known as "gaslighting", and gaslighting is exactly what the character is doing here. Additionally, at no point does the character actually apologize, and in fact goes so far as to shift the blame by implying that their "intention" is something separate from themselves - but immediately claiming a much more amiable position of wanting to "inspire innovation".


The third and final presentation is fairly short. It consists of only a few sentences, in which the character does almost directly chastise the audience for not innovating, nor heeding his advice.

Though it's fairly insignificant, this is the place to mention it: In this paragraph, the character creates an excuse to scold the audience twice, by rephrasing their first sentence despite its almost identical meaning.

The character claims that they will not be attending any more conventions. The term "convention" in itself implies that it is normal or "conventional"heh to attend them. The character ends the first game with a perfect lead-in to the themes of the second game.

The penultimate thing to notice is the final sentence of each presentation - "Thank you for your time". It was intended to be perfectly carbon-copied between presentations to imply that the character does not find it easy to abide by social norms/pleasantries, but manages by way of rote memorization.

Perhaps that was a bit of a stretch. A lot of what I put into this game was never intended to be picked up on or realized, because simply put - people don't (and shouldn't) put in enough time to try to scrape this much meaning out of what is a fairly short body of text.

Either way, I hope you enjoyed reading this! If you have any alternate interpretations, even if they starkly contrast with what I've written here, I'd be interested to hear them.

If you have done, thank you for reading! Stay tuned for a similar post on "Banality" in a week or so!

Saturday, 11 February 2017

It's release day for Banality!

The second game in the trilogy, Banality is the sequel to my prior game, Homogeny.

Banality is slightly more of a "walking simulator" than Homogeny, but it shares the same art style and central themes, as will my next project, named Monotony.


Banality is a very short game, with a grand total of 3 "levels".

Download it below, but more importantly, stay tuned for Monotony, the final instalment.


Wednesday, 8 February 2017

Banality

It's been a while(approximately 5 days) since my last one of these!

I've been continuing to work on Banality. It's going to be very slightly longer than Homogeny, and I expect the third in the series is going to be longer still.

Here's a screenshot!


To give the fine readers of my blog a small hint, this is not a screen that you want to see.

Either way, I'm slowly getting better at using GIMP to create assets, as shown by the sick-as-hell little pulley thing in the screenshot above.

I'm more happy with the way that this game is going than I was with Homogeny. Homogeny was fine for what it was, though the UI could have done with some improvement, and I think it could have been a little bit more visually interesting.

While Banality isn't much more visually interesting, it is somewhat more polished, and does not suffer from the same UI issue as its predecessor. This is because there isn't actually any UI. Sorry.

Regardless, stay tuned for more soon. The whole game should be done in about a week. It is not a large project.

In any case, if you have done, thanks for reading!

P.S. I'm in the process of writing the explanation post for Homogeny's existence. I'm not sure how long it will take me, I need to make sure this expresses why I made it as accurately as possible.

Thursday, 2 February 2017

The sequel to "Homogeny"

Some of you may be aware that I recently released the game "Homogeny", which a few people seemed to enjoy. Seeing as I have an inability to not constantly have a project running, I've got a sequel in progress, named "Banality".

Unsurprisingly, this is in the same vein and art style as its predecessor. Devoid of particularly interesting mechanics, but saturated in analytical value and artistic expression.

Hmm.

I was going to continue this post with an explanation of Homogeny's themes, maybe detailing some of my influences, maybe even an early screenshot of Banality.

I'll leave that for another day.

This post is now about my view on artistic expression in video games.


"Artistic Expression" in Video Games

Followers of my work might have realized by now that I am one of the strongest subscribers to the idea that video games are art, perhaps to a fault. 

I say "to a fault" because the games I have produced so far have been primarily walking simulators - not very marketable to most. Of course, games like Proteus or even Dear Esther have been successful, and to varying degrees have earned their successes. 

The games I have and will continue to create are saturated in cryptic interpretations and messages, some more obscure than others, as anyone who has played Homogeny or Yet Another Puzzle Game can attest to.

The question most worthy of debate, "How much of this avant-garde bullshit artistic saturation is too much?"

First, let's explore the term "artistic saturation" and what I mean by this. I am referring specifically to the kind of avant-garde bullshit cryptic messages and implications that are placed in certain video games.

A fairly popular example is that of Bloodborne, which is highly inspired by H.P Lovecraft's work, and unsurprisingly shares the theme of demonization of humanity. 

In Bloodborne, this is conveyed by the ways the beasthood curse is explored -- exact examples of this are left as an exercise to the reader, in part because I don't want to spend half of this post talking about Bloodborne and in part because I believe the game is best interpreted by the individual on a very personal basis.

The most interesting part of the question are the words "too much".

What exactly defines "too much" artistic saturation? Is it when the mechanics of the game are compromised for the art's sake?

Surely, the reverse situation is just as unacceptable - this leads us into a terrible paradox, where neither can coexist. 

Maybe it's not about compromise of other components of the game. Maybe it's instead about its accessibility to the players?

This comes down to the game's purpose. If the game is designed to be mass-marketable and should be accessible to its players, then this becomes a consideration. However, if the game is made by a small hobby indie team, it has no obligation to be mass-marketable, assuming they are not financially dependant on it. 

Ultimately, it seems that there is no such thing as "too much". What a pleasant result, given that the way I develop games is nearly Souls-like in the way it tells a story or narrative while rarely directly divulging information. It requires analytical thought and some imagination to create a story that can be truly enjoyed.

I suppose that what I'm trying to say is quite simply that I'm developing the Dark Souls of walking simulators.
^this is sarcastic


In any case, if you have done, thanks for reading. Stay tuned for more avant-garde bullshit interesting content.

Monday, 30 January 2017

"Homogeny" came a little early!

Remember two days ago when I said "end of February"?

Turns out I'm awful at predicting my own work flow. It's not a massive game, but it's decidedly larger than "Yet Another Puzzle Game".


Click to download "Homogeny"!


As usual, let me know what you think of it. I plan to make more games in this universe/style.

Enjoy! If you have done, thanks for reading(and playing!)

Saturday, 28 January 2017

What's going on with Spiderman in the Rhineland?

Over the past few weeks, I've felt compelled to discuss received a few hundreds concerned emails from my fans as to where "Spiderman in the Rhineland" falls between my other side projects.

Seeing as I want to shill my new project fans are excitedly clamouring for new information, I've decided that I'm going to state fairly "officially" that the game is currently on the backburner.

The reason for this is that I've had some ideas for new mechanics, narratives, ARGs, trying new art styles and techniques but most importantly I want to make something on my own accord.

I want to be the creator of my own crazy art pieces games, rather than have them be written by someone else.

That being said, I expect I'll resume work on it either if I run out of ideas of other things to create and have some time on my hands(ha) or come the month of June this year, when production of the next Track should be set to go forward.

Now with the preamble out of the way, a screenshot from my new project:


This style may look familiar for the many few one of you who follows me and my work. This is the same art style as was shown off in "Yet Another Puzzle Game". I liked it so much that I have decided I'm going to make a marginally larger project out of it. I can't say with much certainty how long it will take, but it should be finished before the end of February.

The central mechanic is that the player character is forced to deliver a presentation they haven't prepared for. The player must select the most appropriate out of three sentences before a given number of seconds has elapsed. Fairly simple conceptually, but I like it.

Besides, the mechanic is merely the canvas on which a greater artistic expression can be painted...


Saturday, 14 January 2017

Thoughts on Track 2

As time goes on and I'm having more ideas and thoughts spring to mind regarding my approach to Track 2, it's getting better and better. If you're reading this and you're a consumer of strange surrealist art pieces video games, this is good news!

To those of you who have listened to the Spiderman in the Rhineland podcast that myself and a friend host, you may realize that while Track 1 is a decidedly chaotic multi-themed piece, Track 2 is a considerably more ordered and linear experience.

At this point, I can't stop with the constant visual and design metaphors. There are more metaphors intended in the levels and my plans for design so far than would ever be extracted by the most untenable claims, but ultimately I'm not making this game for the average consumer's benefit. If you're reading this and you're a consumer of video games strange surrealist art pieces, this is good news!

I will give an example of these visual metaphors in action. The background I created involving a bridge over a chasm -- each plank on the rope bridge is tattered, though towards the end of the bridge, each plank is less tattered. This is, in my mind, a metaphor for the fact that literally billions of listeners have attempted and failed to understand, appreciate or even listen to the podcast. Not that I'm implying that every person on the planet is morally obliged to listen and successfully interpret the podcast, but..

To return to the original point, the bridge is picture below.

Admittedly, it's not the best bridge. It looks significantly better with the proper animation I gave it, and I'm going to re-draw the planks in my second pass of each background in the future. While it's not going on any promotional material, it's fine as a placeholder.

In any case, if you have done, thanks for reading!

Tuesday, 20 December 2016

Another two rooms done!

It only took about 2 weeks of work, but I can finally stop trying to recreate rooms from a certain video game involving bonfires, which is good because it's pretty damn difficult.

One of the rooms is this one:

It's admittedly not the best piece of pixel art ever created, but this took me literally 3 days. I'll come back to it at a later date because I'm certainly not satisfied with the end product, the rock in the bottom right is a bit.. strange and the borders are too lopsided for my liking.

Fortunately for me, I can put the amendments on the proverbial back-burner while I do something slightly more interesting. Also, at some point I need to fix a frustrating bug where a "fade out -> change scene -> fade in" will occasionally cause a strange flicker.

My best bet is to try and set up the mask which handles the fade in/fade out/visual snow/static effect as a singleton node. The only worry is that this would kind of reduce the amount of control that I have over the mask in each scene, seeing as it wouldn't be able to be keyframed in Godot's AnimationPlayer node.

That bit kind of runs contrary to my previous task of setting up the intensity and alpha channel to be uniforms explicitly so that they can be keyframed as necessary. Maybe a mixture of both is what I'm going to have to do, just initializing a singleton in the scene prior to the fade out, and deleting it after the fade in.


This is my favourite part of game development; the problem solving and thinking about a problem. Definitely not the creation of art assets, at any rate. At this point I'm almost glad I have a bug to fix...



And if you have done, thanks for reading.

Monday, 12 December 2016

New background!

I spent most of today finalizing and trying to get a solid version of the latest background for a level.

Seeing as the background without context or interactivity really gives away nothing about its purpose, I feel comfortable showing this off here. Without further ado, enjoy the following:


I do highly doubt that this will continue into the final build without slight changes, but as it is now I feel pretty happy with it. It took a lot longer than I could have ever expected, seeing as it took a total of 4 revisions of the same area in order to get one that doesn't look so awful.

Bonus: if anyone guesses what game this area is from and gets it correct, I will keep you in the development loop personally, considering that it doesn't really resemble the actual area that I based it off very closely, and you are therefore clearly telepathic. I think that telepathic people could be useful to gauge market and audience interest, so it's worthwhile trying to keep you around. Post a comment if you want to hazard a guess.

In all seriousness, I did overwrite the 3 other revisions of this room before I realized that I had a blog where I can throw this stuff, so that's lost to the void. I'll try not to do that next time, but then again, hopefully I won't have to try 4 revisions and about 6 hours before getting one that looks tolerable.

And if you have done, thanks for reading.