Jump to content
  • Advertisement


  • Content Count

  • Joined

  • Last visited

Community Reputation

173 Neutral

About Overloaded

  • Rank

Personal Information


  • Twitter
  • Github
  • Twitch
  • Steam

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

  1. Overloaded

    Pixelorama v0.2 is out!

    The UI isn’t gorgeous yet, but it’s getting there!I swear I wasn’t procrastinating! I was just busy with studying and working on our game! But anyway I’ll keep it short this time, Pixelorama v0.2 is out now and it comes with fancy new things! Brand new animation timeline! Add, clone, remove and change order of unlimited frames! The good news? Each frame can have a unique amount of layers, and even be a different size than the rest of the frames! New UI for tool options, divided in the left mouse tool and the right mouse tool. You can now choose a brush size for pencil and eraser tools! Each mouse button can have its own brush size. You can go wild with this! You can import multiple images as different animation frames! You can also export the current frame you have selected, or all the frames as multiple files, or as a spritesheet! Supports both horizontal and vertical spritesheets. Scaling your image is now functional! And it lets you choose from four different types of interpolation. You can toggle a grid in the canvas on and off. Added text labels on the bottom right for the frame’s size, the position of the cursor, the zoom level and the currently selected frame. Added hints for UI elements. Mouse cursor changes depending on where it’s hovering. Okay, enough words. They say that an image is a thousand of them, right? So… what about a video? Oh yes, Orama Interactive has stepped up their game.That’s it everyone, I’m going back to work. If you are interested in what you are seeing and want to support it (and make my life easier!), you can consider donating on PayPal and Ko-Fi. Thanks for your time, and happy painting! Pixelorama is available on GitHub and Itch.io! View the full article
  2. The UI is still work in progress… and so are my pixel art skills. Like I’m not busy enough already… Making a game (more details coming soon!), working hard to open a game development studio, Orama Interactive, and become a full time indie developer, studying for uni… you name it! But of course I wouldn’t stop playing with new ideas and projects, even though I have other things to do. But I digress. This time I created my own sprite editor named Pixelorama entirely within Godot, using GDScript. My goal is to make a free & open-source sprite editor, for all things pixel art. It started entirely as an experiment, to see if I can provide my dearly beloved artist teammates with a pixel art tool that would suit our team’s needs. I used Godot to do it, because, why not? To mine and everyone’s surprise, the tool started turning out better than I expected. So I thought, what the hell, why don’t I release it for everyone, for free? So today, I am releasing Pixelorama v0.1 source code for everyone, on Github! Pixelorama supports: Choosing between 3 tools – pencil, eraser and fill bucket – and mapping them to both of your left and right mouse buttons. That’s, pretty wild, huh? Different colors for each of the mouse buttons. Creating a new canvas with a size of your choosing. Importing PNG and JPEG images, and edit them inside Pixelorama. Export your gorgeous art as PNG files. Create straight lines for pencil and eraser by holding down Shift while you draw. The middle mouse wheel isn’t forgotten, you can use it to pan around the canvas and by scrolling up and down, you can zoom in and out! Keyboard shortcuts! I’m pretty sure this is a lifesaver for most of you. Just like onions, Pixelorama has a multiple layer system! You can add, remove, move up and down, clone and merge as many layers as you like! It’s freeeeeee! And open source! Mesmerizing (?) pixel art in action And that’s not all, folks! Future versions (may) include: It’s aliiiiiive! Animation system with its own timeline to bring your art to life. Onion skinning for your animation needs. More tools! But I’m not saying what they will be. I’d hate to kill the suspense. More options for the tools, like changing the size of the brush. And maybe even changing the brush itself, we’ll see! An undo/redo system. This was supposed to be included in v0.1, but it made my life even harder that it already is, so, I decided to skip it for now. For now. Although intended as a standalone tool, I am also considering to make Pixelorama a plugin for Godot’s editor. There is a lot of demand for it to become a plugin, apparently. Your ideas! Give me your feedback on Pixelorama and I will do my best to make it the best it can be, for you! And don’t forget, it’s freeeeeeee and open source! You are free to modify Pixelorama in whatever way you like! Just don’t take full credits for yourself, though. That’s a jerky thing to do. Now, I really should get back to developing my game. A polished demo must be ready soon, if we want to attend a certain event. But that’s a story for another blog post! If you’re interested in keeping up to date with me and my team, Orama Interactive, make sure to follow this blog and our social media, which can be found in our website. As you can see, I’m currently very busy with a lot of stuff, so I won’t have the time to work on Pixelorama as much as I should. If you believe in our vision and you’d like to help me, consider donating on PayPal and supporting me on Ko-Fi! Any contribution would help tremendously! Thanks in advance, and see you in our next blog post adventure! Github repository for Pixelorama: https://github.com/OverloadedOrama/Pixelorama Stand-alone .exe version of Pixelorama: https://orama-interactive.itch.io/pixelorama View the full article
  3. This is a followup tutorial in the “Making a Discord Bot with Godot series“. Make sure to read Part One and Part Two first! Come on… just… five more minutes. Huh? The readers are back? But I’m still sleepy! Weren’t two parts enough for them? Ugh fine fine, I’ll write more. Pff, I hope you are happy, readers. Welcome back for Part Three, where we will make our bot come out of its shell and actually talk to people! I should do the same with my own self. Anyway let’s begin, I wanna go back to bed soon. *yawn* So yeah, we’re gonna start by learning how to send messages. (Finally! It took you two goddamn parts to get to this point. Seriously, Overloaded?) We want to make sure our bot… Um, I think it’s time to give it a name, shall we? Godot Bot? Gobot? Gobot it is! So, we want to make sure that Gobot is polite and it should welcome new members when they join our server. Remember that first thing we did at Part One? With the request we made to a URL to get data for our client user? Turns out it wasn’t pointless after all, because all we’re going to do today is HTTP Requests! First things first, inside our event handler method (I call is handle_events() if you recall), we’ll check if the Event’s name is “GUILD_MEMBER_ADD“. This event occurs every time a new member joins one of our servers. Also, we’re going to refer to servers as “guilds” from now on. Inside this event, we’re gonna store some stuff, starting from the guild’s ID. Then, we’ll make a new PoolStringArray called headers, where we will store "Authorization: Bot (YourTokenHere)" for now. Then, we’ll make a GET request from https://discordapp.com/api/guilds/{guild.id}/channels in order to get all the channels of the guild. If you recall, when the request is complete, it will trigger the “request_completed” signal. You don’t need to connect it to any method this time. What we have to do it to tell Gobot to wait until the request is complete before doing anything else inside handle_events(). In other languages like Python, we use “await” to, well, await the completion of async methods. That is Python’s way to define coroutines. GDScript doesn’t have async and await, but fear not! It still supports coroutines, using “yield“. So, we are going to do yield(self, "request_completed") in order to wait until the signal is triggered, and we’re gonna store the result in new a variable called data_received. In other words, we’ll just write var data_received = yield(self, "request_completed"). Actually, data_received is not going to be a variable, but an array containing the result (an integer), the response code (integer, again), a PoolStringArray of headers and a PoolByteArray containing the body. More info on Godot’s Docs. We only need the body. So, we’ll make a variable (which will actually be a Dictionary) called channels, which is just data_received[3] (the body) converted to string (get_string_from_utf8()), then to JSONParseResult (JSON.parse()) and then to a Dictionary (JSON.parse().result). After that we’ll make an empty variable for the channel id. We need the channel id so Gobot can know in which channel to send its heartwarming welcome message. We’re going to loop through all the guild’s channels and the first text channel we find, we’ll store its id so we can send our message there. Please note that this is not the best idea, because Gobot may not have permission to talk to the first text channel it finds. But we’ll do it that way, for the sake of simplicity. To see if a channel is a text channel, we must check if its “type” is equal to 0. See Discord’s Docs for the other types. We managed to get the id of the guild’s first text channel. Now we’ll actually send the damned welcome message! It is considered polite to call others by their names, and we want Gobot to be polite, so we’ll have it store the new member’s username by writing var username = dict["d"]["user"]["username"]. The message will be “Welcome (UsernameHere)!”. We’re going to need a small Dictionary for that with “content” as it’s only key, and with the value of the message we want to send. So, it will be var message_to_send := {"content" : "Welcome %s!" % username}. We need to convert our Dictionary to a string, so we’ll JSON.print() it and store it in a variable called query. In order to send the query, we’ll do another HTTPRequest.request(), but this time it will be a POST request instead of a GET request, because we will send stuff instead of receiving. This requires one more header which specifies the type of our content, which is of course application/json. We’ll append it to our headers PoolStringArray like this headers.append("Content-Type: application/json") and FINALLY we’re ready to make the request! The URL we’re going to use is https://discordapp.com/api/v6/channels/{channel.id}/messages. Obviously we also have to send our headers, our query and we need to tell it that it’s going to be a POST request. request("https://discordapp.com/api/v6/channels/%s/messages" % channel_id, headers, true, HTTPClient.METHOD_POST, query). Please note that this only works because the script is extending from HTTPRequest. If it’s not, you’re going to need an HTTPRequest node for it to work. That’s… that’s too much text. How about a screenshot? Ah! This looks much better than all that text! Make sure your script either extends from HTTPRequest, or you’re using an HTTPRequest node to do all these requests. Before we continue, let’s actually see Gobot in action! You know, to see if it works. Definitely not to scream of joy because our baby is actually functional. Seems like Gobot is working fine! WOOHOO! Next up is checking if a certain message has been send, and then responding to it. This is a surprisingly easy part, because we don’t need to do any GET requests to get extra data, we only need to do the final POST request to send our message. So, if the event name is equal to “MESSAGE_CREATE“, we save the ID of the channel the message was being send in (dict["d"]["channel_id"]), as well as the message’s content (dict["d"]["content"]). Then, we set our headers to be the same as we set them before, the authorization header and the content-type header. We’ll also set an empty string variable called query. We will send a message only if query is NOT empty. Now, we’ll check if the message’s content is equal to the value we want. Let’s say for instance that, when someone says “Orama”, Gobot has to reply with “Interactive”. (Shameless advertising time, make sure to check out our game development team, Orama Interactive!) Pretty straightforward, right? So, we’ll check if the message’s content is equal to “Orama” and, if it is, we’ll make a new Dictionary message_to_send, with “content” key being equal to “Interactive” value, and we’ll set our query to JSON.print(message_to_send). Then, if query is NOT empty, we send the request. The URL we’re going to use is obviously the same as the one we used before, and so are the rest of the parameters. Screenshot time? Screenshot time. Finally the juicy part, am I right? Like father like bot. If you want, you can obviously extend it by adding more checks for even more messages, you can make the checks be case insensitive by using message_content.to_upper() and a ton of other stuff. But I’m going to end the tutorial here. I don’t know if there will be a next part, because I’m still currently learning and I have to figure out a lot of things, while at the same time being busy developing games at Orama Interactive. So make sure to follow the blog to receive news and updates for possible future parts, or entirely new blog posts! This “Making a Discord Bot with Godot” tutorial series has been a blast and a huge learning experience for me, and I hope it has been for you, too! So, here’s the pastebin code for this part and, as promised, the long awaited GitHub repository! Now, it’s time for me to head back to bed. Thank you so much for your time, and I hope I’ll see you in future blog posts! Take care! View the full article
  4. This is a continuation from Part One, which you can find here. Back for more I see? In the second part of this blog tutorial series we’re going to handle resuming our connection in case of a disconnection, disconnect in purpose if we don’t receive a Heartbeat ACK, and handle Opcode 9 Invalid Session payloads. So, let’s resume the tutorial! (See what I did there? Resume? Anyway, moving on) Before we even begin, the first thing I’m going to do is rename our Timer node to “HeartbeatTimer”, have the heartbeat_interval variable converted to seconds from the moment we set a value for it (by doing heartbeat_interval = dict["d"]["heartbeat_interval"] / 1000), and replace the code inside our Opcode 0 Dispatch with a neat looking handle_events(dict : Dictionary) method. All the previous code will be put inside that new method, which will be used to, well, handle our events. The first event we’re going to handle is our Ready event. We’re going to need a new String variable called session_id, which we need in order to resume our connection. So, inside our new method, store the “t” field of our dictionary (this is the name of the event) and check if it is equal to “READY”. If it is, set our session_id variable to dict["d"]["session_id"]. Behold, it’s screenshot time! Ah, much better. Reminder that this is inside our _data_received() method. And our new baby, handle_events(). Don’t forget to initialize session_id as a String variable at the top of our script! All is going well and our bot is work- nope, we disconnected. Oh well, that happens all the time anyway. So, how do we handle it? Well first of all, we need to tell our client to reconnect. So, in our process method, we and an else statement to check if the client is disconnected, and if it is, we tell it to connect to the Gateway’s URL. Oh, and before I forget, we can connect the WebSocketClient’s connection_closed and server_close_request signals to two new methods. Τhe first method will just print to the console that we got disconnected, and the second one will print that the server has requested a clean close, along with the close event code and reason. If the client manages to connect again, it will receive an Opcode 10 Hello payload. We don’t, however, have to identify ourselves again. We can do a check if we have a session_id, and if we do, we can send an Opcode 6 Resume payload to the Gateway instead. The 3 fields that are required for that payload is the bot’s token, the session_id and the last_sequence number. Our new else statement inside our process method. Updated our Opcode 10 Hello logic to handle resuming. Now that we’re done with resuming, we’ll disconnect on purpose. Wait, what? Why? Because that’s what the Discord Developer Docs say, my dear viewer! “If a client does not receive a heartbeat ack between its attempts at sending heartbeats, it should immediately terminate the connection with a non-1000 close code, reconnect, and attempt to resume.“ And that’s exactly what we will do. For that, we need a new boolean variable called heartbeat_ack_received, set as true at the top of our script. We will set the variable as false every time we send an Opcode 1 Heartbeat payload, and then back to true when we receive an Opcode 11 Heartbeat ACK payload. Now, we have to check if the variable has remained false when we are about to send our next Opcode 1 Heartbeat. If it is false, meaning we haven’t received an Opcode 11 Heartbeat ACK, we terminate the connection with a non-1000 code and return from the method. To be honest, I don’t know if that is the best way of handling the situation, so, if you have any better ideas be sure to comment them down below! Some screenshots for your the pleasure of your eyes. Remember to initialize your variables at the top of the script, kids. Set heartbeat_ack_received to true when we RECEIVE a Heartbeat ACK We check if heartbeat_ack_received is false when we are about to send a Heartbeat, and if it is, we terminate our connection with code 1002 (any non-1000 code should work fine? I guess?) and return from the method. If it is true, we send our Heartbeat as we usually would and we set heartbeat_ack_received to false. And I think that’s it for handling disconnections, when we don’t receive Heartbeat ACK payloads. Last up for this part is handling Opcode 9 Invalid Session payloads. You can find more info on them on Discord’s docs. This is again something that I’m not sure if my method is the best way of doing it, so if you have any objections, make sure to comment! Following instructions from the docs, when we receive an Opcode 9 Invalid Session payload, we have to wait a random time between 1 and 5 seconds, and then re-identify ourselves. Well, if the “d” field is false, that is. “d” is a boolean that indicates whether the session may be resumable. So if “d” is true, we’ll resume instead of re-identifying. So, we’ll create a new boolean variable at the top of our script called invalid_session_is_resumable, and at our ready method we’ll call randomize(), so the time the client has to wait after receiving the Opcode 9 payload will always be random. Then, we’ll create a new Timer Node as a child, which we will call “InvalidSessionTimer”, and we’ll do a new check to see if our op code is equal to “9”. If it is, we’ll set invalid_session_is_resumable to be equal to the “d” field of the payload, and we’ll set the InvalidSessionTimer’s wait time to rand_range(1,5). We also need to make the timer’s one_shot = true, because we only want it to run only once every time we get an Opcode 9 Invalid Session payload, and then finally start it. We’ll connect InvalidSessionTimer’s timeout signal to a new method inside our script, where we’ll do pretty much the same we do with handling Opcode 10 Hello payloads, except the “setting up to send heartbeats” part. We’ll check if the invalid session is resumable AND if we have a session_id. If both are true, we’ll send a Resume payload. If at least one of them is false, we’ll send an Identify payload. Finally, it’s screenshot time. Don’t forget to declare the boolean variable at the top of the script and call randomize()! And I op- New code for handling Invalid Sessions Timeout method for InvalidSessionTimer That’s all folks! For this part at least. You can find the code in pastebin! Next up we have receiving messages and having the bot responding. Yes, time for some socialization! Make sure to follow this blog so you don’t miss the next part! See you then! View the full article
  5. This tutorial uses Godot Engine 3.1 (but it should be working with newer versions too), as well as its GDScript language. In this part we will cover basic connection with Discord API’s Gateway, identifying our clients and sending and receiving heartbeats! Exciting enough? Let’s start! Once upon a time, I woke up and I had nothing to do. Well, actually, I had stuff to do, but I was procrastinating. And as every professional developer does, I thought of starting a new pet project/experiment. A new Discord bot made entirely with Godot, using GDScript. I already had made another Discord bot in Python using the discord.py library, so I did have some experience on Discord bot making (and the rest of my server’s members hated me for it) The issue here is that there is no Discord library for GDScript, so at first I approached it a bit differently. I generated a python script, and run it within Godot using OS.execute. The way to do it is pretty simple, you just tell OS.execute to, well… execute python from a script, exactly as you would from the system’s shell. It looks like this: OS.execute("python", ["filepathhere.py"], false). And it actually works! But eventually, I run to some limitations. I didn’t know, for instance, how to capture output and print text received from the bot, on my Godot scene. Some things weren’t working at all, like sending files. So I started wondering if it was possible to communicate with the Discord API directly with GDScript, without relying on another language and library. And because I was too lazy to do any actual work, I started experimenting! Keep in mind that, obviously, this isn’t the ideal way to make a bot and that you should use a library instead, mostly to save yourselves some headaches. But I guess you wanna do it the hard way like me, huh? Let’s start then! Now, keep in mind that I’m not what you call an “expert” in networking. And boy, did I have a hard time figuring out what to do. My first move was to make a new HTTPRequest node and make a request at https://discordapp.com/api/users/@me. I connected the request_completed() signal to my script. When the signal gets fired, the connected function prints out the body. Obviously, I got the same result as you would get if you clicked on that link and have it opened in your browser – {"code": 0, "message": "401: Unauthorized"}. I needed to authorize my bot somehow, and this is where the bot token comes in. At this point I will assume you have some experience with Discord’s developer portal and you know what tokens are and that they are used for authorization. You can’t have a bot without a token, which you can find if you make a new application here. In order to authorize the bot, you need to pass the token as a header, in the form of a PoolStringArray, but with only one element because, well, we only need to pass the token right now and nothing else. The bot token authorization header is in this format: Authorization: Bot (token) So far our code should look like this: Now now, I can hear you complaining from miles away. I’m going to put the code in a public github repository, so don’t worry about being unable to copy and paste from a screenshot. And, if you actually put a valid token in there, you would see that it prints a valid result this time. But that’s boring! We wanna do stuff with the bot, interact with it, not just print data. We need to go deeper (yes, there will be meme references). This is why our next step will be to connect to Discord’s Gateway API, which we will do using Godot’s WebSocketClient. So, feel free to remove the previous code, make a new WebSocketClient, and have it connect to wss://gateway.discord.gg/. Generally, it is a good idea to explicitly pass the gateway version and encoding. For example, we may connect to wss://gateway.discord.gg/?v=6&encoding=json. For more information on that, make sure to read the official Discord Developer Docs. Now that we started the client by connecting it to the gateway’s URL, if we read the documentation on WebSocketClient, then we know that we also have to poll our client at regular intervals. We’ll poll it inside our _process() method. Next, we will connect the client’s connection_established signal to a new method and inside that method, we’ll print that we have connected. For more information on WebSocketClient’s signals, read the docs I linked above. The code should look something like this: Note that extending from HTTPRequest isn’t required here. This would also work if we extended from Node. Now that we are connected to the gateway, we should immediately receive an Opcode 10 Hello JSON payload (more info on Discord Developer Docs). After that, the gateway expects us to send an Opcode 1 Heartbeat payload every heartbeat_interval milliseconds, which we get from the Hello payload. Every time we send an Opcode 1 Heartbeat, we receive an Opcode 11 Heartbeat ACK from the gateway. Heartbeats are being used so that the gateway can determine whether our client is still connected or not, because, if we disconnect, we stop sending heartbeats, so the gateway considers us dead – err, I mean, disconnected. The same goes for Heartbeat ACKs, but it’s vice versa. Along with the first Opcode 1 Heartbeat, we also must send an Opcode 2 Identify payload, with information such as our token, presence and other stuff you can find on the docs. After we do that, our client receives an Opcode 0 Dispatch payload. Opcode 0 Dispatch payloads are used for event handling, stuff like the client being ready, joining a guild (server), a message being send, and others. The first Event we will receive is the “Ready” event. Imagine going to a VIP only party. The first thing that you see when you arrive are the guards (Discord’s Gateway). You go at the door (connect to the gateway), and the guards greet you (you receive an Opcode 10 Hello payload). Then, you are supposed to show your VIP pass (send your token with an Opcode 2 Identify payload). If the token is valid, you are granted entrance (Discord shows your bot as online). However, the party has some strict rules. You are supposed to be dancing all the time, otherwise the guards kick you out (client gets disconnected). So you need to show the guards that you dance every heartbeat_interval milliseconds (send an Opcode 1 Heartbeat), and every time they confirm that the party hasn’t ended (the gateway sends you an Opcode 11 Heartbeat ACK back). While you are partying, you are being notified of every new thing that’s happening (you receive an Opcode 0 Dispatch), like when you are ready to start partying (“Ready” event), when someone new joins the party “Guild Member Add” event), when someone is about to speak (“Typing Start” event), when someone says something (“Message Create” event), and many more. This is pretty much how the Discord API’s Gateway works. Now, let’s get back to coding, shall we? We need a way to receive the data that the gateway sends us. First, let’s print the contents of the Opcode 10 Hello payload we will receive when we connect. To do that, we need to connect the WebSocketClient’s “data_received” signal to a new method. Inside that method, we will get the WebSocketClient’s WebSocketPeer with get_peer(1), and then we will get the peer’s packet. Which means we have to do this client.get_peer(1).get_packet() . For more information, refer to the Godot docs. I can’t explain everything! Now that we got our packet, we will get it in string format in order to print it. The code so far should look like this: The output should be something like this: We are connected! {"t":null,"s":null,"op":10,"d":{"heartbeat_interval":41250,"_trace":["[\"gateway-prd-main-gjhc\",{\"micros\":0.0}]"]}} Now let’s make our data into a Dictionary, and save the op code and do a check if it is equal to 10. If it is, we save the heartbeat_interval. Make sure you set heartbeat_interval as a float variable on the top of your script! Because we have to do something every x seconds, we’ll use a Timer node, which will be a child of our current node. We’ll set the timer’s wait time to heartbeat_interval / 1000 (to convert milliseconds to seconds) and we’ll start it. We’ll also connect the Timer’s timeout signal to our script in a new method, and inside that method we’ll make a new dictionary that will contain this {"op" : 1, "d" : last_sequence}. The last sequence is a number we get from Opcode 0 events, so don’t worry about that right now. Just set it as a float variable at the top of your script and we’ll set a value for it soon. After all, we’ll get our Opcode 0 “Ready” event before we send our first Heartbeat. We’ll get the peer of the client once again and we’ll put the dictionary as a packet, by converting it to JSON and then to UTF-8. We can also print a message to the console, if we want. Along with setting our timer, we will also send an Opcode 2 Identify payload when we receive the Opcode 10 Hello payload. Similar to how we did with our Opcode 1 Heartbeat code, we’ll make a new dictionary that will contain at least our op code (which is 2), our token, and an empty set of properties. You can add properties of course, as well as other stuff like presence, but I’ll leave that up to you. The only hint I’m going to give you is, read the Discord Developer Docs! Then we’ll send the data the same way we sent them with out Opcode 1 Heartbeat payload. In fact, I’ll create a method called send_dictionary_as_packet() for that, which you will see in the next screenshot. After we have successfully identified ourselves, we should receive an Opcode 0 “Ready” event payload, and maybe some other “Guild Create” events, if our bot belongs to any servers. We will check if our op code is equal to 0, and inside we’ll print our event name and set last_sequence to the “s” field of our payload. Lastly, we’ll check if our op code is equal to 11 and we’ll simply print “We’ve received a Heartbeat ACK from the gateway.” to our console. The code should look something like this: Our two new variables, heartbeat_interval and last_sequence Anything before the _data_received() method hasn’t changed, apart from the 2 new variables. Oof, and that’s it for Part One! This certainly took a long time, huh? In the next part, we’ll learn how to handle events, disconnecting, and then resuming our connection! Oh and, I lied about the github repository. Well, at least not before I’m done with these series of blog posts. However, because I’m such a nice person who loves his readers, here’s the code in pastebin: https://pastebin.com/qZPrqFMc View the full article
  6. Overloaded

    Welcome to My New Programming Blog

    Welcome! I am Overloaded (Manolis). I work as a game developer at Orama Interactive, and I am a Computer Science student at the University of Piraeus “May your dreams be your guiding force” — Orama Interactive. Welcome to my new blog! Here you can expect to find devlogs, programming tutorials, personal adventures and experiences, and quite possibly personal opinions and views about the world. If that sounds interesting to you, make sure to follow the blog. Thank you! Make sure to also check my game development team, Orama Interactive! View the full article
  7. I want to #gamedev, but my game needs level design now... and I hate it. I want to code something!
  • Advertisement

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!