On using Godot to make an Android game

I recently made my first “real” game in Godot: Corporate Fulfillment 2058. It’s a puzzle game where you combine materials to make products for amoral corporations. As you might expect from the name and the screenshots, it’s inspired by games like Threes and 2048, but instead of simply trying to make larger tiles, each level gives you a different set of components and asks you to make a different set of products from them. Some levels mix up the rules by requiring you to ship out finished products yourself, or giving you more control over how you move tiles around, or even by disabling parts of the play space. The game is available right here for Android and right here as an HTML5 version, if you want to play it.

This isn’t the first project I’ve made with Godot; I’ve made a simple endless runner and a game jam entry previously. This is definitely the largest and most complex project I’ve made with the engine, however, and I have some thoughts on using the engine. The process was mostly smooth, with a few… quirks of the engine, and some bugs I ran into, that caused some difficulty.

UI

I don’t like doing UI work. I don’t think anyone especially likes it, but it’s one of my least favorite parts of game development. Using Godot, however… well, I still don’t like it, but it’s less painful. At least, it’s less painful now that I have a better understanding of how the Control nodes work. For a while I was running into confusing issues where buttons and text weren’t always behaving how I wanted them to, due to the nodes they were parented to. I feel a lot more comfortable with the Godot way of building a UI now, so I can appreciate some of the decisions that I would have criticized before.

GDScript

I haven’t used python in quite awhile, so back when I started using Godot I was wondering how easily I would adapt to using GDscript. My previous projects  taught me rather well, and by the time I started this game, I was only occasionally turning to the reference to refresh my memory. Why did I use GDScript instead of C++ or C# or another language? Well, mostly because I didn’t want to do the work to set up support for another language.

GDScript certainly got the job done. CF2058 isn’t a particularly complex game, and it’s not pushing the engine to its limits, but it’s not a trivial project. Using another language with Godot for the sake of performance was unnecessary for this project., and with the speed at which I was able to prototype my ideas with GDScript, I was having a great time. Of course, there were  a few sticking points.

One of these was the fact that GDScript is very loose when enforcing some of its rules. Specifically, the fact that I could accidentally use an enum value that doesn’t exist, or access a non-existent function of an object, and these wouldn’t be caught until that particular line of code executed. I was bit by both of those specific examples, and more, spending several hours tracking down and fixing bugs that would have been caught at compile time in a language like C++. That was certainly annoying. GDScript makes some compromises for the sake of ease-of-use, friendliness, and prototyping speed, and that’s great! However, I really wish a few more mistakes could be caught immediately upon hitting compile/run.

Speaking of compiling, another feature I wish GDScript supported is conditional compilation. Sure, I can use OS.has_feature(“mobile”), to have specific behavior on mobile devices, but I’d prefer not to have these checks at runtime. Additionally, there are cases where I don’t want to include, for example, some code for particular features in a demo version of the game. This is especially true for HTML5 builds, where the source is more easily accessible. I’d rather not have to worry about someone being able to access levels or features that aren’t supposed to be in the demo. I ended up just having multiple versions of a couple source files that I swap manually for demo/non-demo versions, but that’s a kludgy solution.

The Editor

The 2D and 3D editors work well enough, and I don’t have much to say about them. I do, however, need to complain about the text editor. It’s fine for the most part. It gets sluggish sometimes with large scripts, but that’s not a huge issue. What is a huge issue though, is the frequently-breaking undo/redo stream.

Here’s what happens: I’ve just written some code, say added a function call:

 
 
  1. somefunction()

Then, after running the game, I decide I want to change this to a different function. I select the function name and type a different function name:

 
 
  1. anotherFunction()

 

So far so good. I run the game again, then decide I want to see what happens when I run the original function again. I just hit undo:

 
 
  1. someFunction

 

Uh oh, the parentheses are gone! Maybe if I hit redo it will correct itself?

 
 
  1. anotherFunction

 

Nope. The undo/redo stream has become corrupted, and no amount of undoing or redoing will put this code back into a syntactically valid state. This is an easy to fix example, especially because I’ve only hit undo once. It’s still quite annoying, though. In cases where I’ve undone more than a few edits, or the corruption is more than missing parentheses, this issue becomes rather scary. I no longer have valid code that I’ve written. I notice this issue often, but what if it’s happening at other times when I’m not noticing it, because the game compiles and runs? This is one of the most annoying issues I’ve encountered with Godot, and is the main reason I’m using an external editor to write my scripts.

Oh yeah, Godot also supports external editors. That’s a good feature.

Shaders

I don’t really have a lot to say on the subject of shaders, except that the ability to immediately see the effects of a shader in-engine, as you write it, is pretty awesome! I hadn’t done much with shaders before, so without this feature the process of writing and testing them would have been much slower, which probably would have caused me to use fewer, and simpler shaders than I was able to use.

Exporting

The export process is actually pretty nice. Setting up export templates is quick and easy, and afterward, exporting for a platform just takes a few clicks. The export menu offers customization of many options, and for Android at least, allows for a custom manifest for additional customization.

It’s easy to select which resources to include in a build, to update the version number and build code, and to change whatever other settings are necessary. It’s even possible to have multiple export templates for a given platform. This is probably the easiest time I’ve had building games for Android. The only criticism I have to offer is that the option to toggle a debug build is almost hidden. It’s just a small toggle on the final “Save a File” dialog.

Other Stuff

I have approximately 490 assets in the project. At somewhere around 150 assets, Godot slowed way down at startup. Other projects with few or no assets don’t have this issue, so I know it’s not due to a newer version of the engine or something similar. I remember being impressed with Godot’s speed way back when I first took a look at the engine, but with a “real” project, startup times are not impressive any more, often taking well over 45 seconds to load from an SSD. With more assets, in a larger project, I’d expect the engine to be even slower to start up.

It’s not just startup times that are quite long, however. In my smaller projects, saving open scenes and launching the project with the debugger are almost instant. With CF2058, Godot often takes almost a minute to become responsive again. It’s not the most annoying issue in the world, but it’s a real pain when trying to make iterative changes.

The good news is that Godot’s live reloading works quite well! Making changes to an object’s position in the editor, or an object’s script while running the game was super useful. If it weren’t for this feature, the long wait for the project to save or the debugger to launch would be even more of a momentum-killer.

Overall, I really like the Godot engine. It makes prototyping super easy and fun, and I’ve watched the engine get better and better with each release I’ve tried. I’m hoping the issues I ran into will be solved, and the sticking points sanded away, making for an even better piece of software.

Thanks for reading my thoughts. If you would like to check out my game, either on itch.io or the Google Play store, I would certainly appreciate it! :)

More Editor – An Icy Night In Snowman’s Land

Last  time I talked about the level editor. Today I’m going to talk a bit more about the editor, because I’ve spent a lot of time lately working on it and I need to write down some of this for my own benefit.

The game will be released on Android and HTML5. I’ve been developing on Linux, and I’ve been testing builds for all three targets. Now, the level editor has been “done” for awhile, at least for Android and desktop. Editing, testing in the editor, saving, loading, and everything else was implemented. However, the HTML5 build had an additional challenge.

On the other platforms, saving and loading levels require accessing the local storage of the device and allowing the player to choose a level to load or a location in which to save the level. However, the HTML5 version of the game isn’t running on the player’s device at all. It’s hosted on a webserver that the player will connect to through their web browser, and so it doesn’t make sense (and indeed would be a major security issue) to give players access to files and directories stored on the webserver. To allow the player to save and load levels, it was necessary to transmit data between the webserver and their local machine.

Eventually, I bit the bullet and got down to implementing saving ad loading in the HTML5 editor. I didn’t need anything fancy; from the player’s perspective all I needed was to display a dialog letting the player choose a file to upload and a dialog to save the level file. I thought “That’s easy! Obviously I can’t do anything filesystem-related, but since I’m using (HaxePunk on top of) OpenFL and Lime, and lime.ui.FileDialog exists, this should be pretty straightforward!”

Unfortunately, lime.ui.FileDialog currently doesn’t support loading of files on HTML5. That’s pretty unfortunate, as that’s half of what the level editor needs to do with files. I was at a loss for awhile, until I found these examples of creating a file dialog and invoking it through javascript. Now, I tried these examples in jsfiddle to confirm that they worked, and so I implemented the examples in the game and it worked in all browsers I tested… except Firefox.

Now, Firefox has valid reasons to limit what can happen programmatically. I wasn’t surprised that I ran into a limitation for security reasons; I was surprised that the code only failed to work correctly on one browser (and a non-Microsoft browser at that). In the end, I did manage to get saving and loading on HTML5 working, after being pointed toward open.net.FileReference. If you got here from a search engine and want to know how to make this work, here is the solution that worked for me:

I created an instance of openfl.net.FileReference (called fr in this case), then I added the following code (only compiling it for the HTML5 build):

 
 
  1. private function stageClicked(e:Event)
  2. {
  3. if(isMouseOver(myUIButton))
  4. {
  5. fr.browse();
  6. }
  7. }
  8. private function startLoad(e:Event)
  9. {
  10. fr.load();
  11. }

The  important thing to note is that fr.browse() is being called in response to a stage click event. This is necessary for the file browser to work; without being called in direct response to user input, it may be blocked for security reasons.

Once the file the user selected has been loaded, you can access the data like so:

 
 
  1. private function loadComplete(e:Event)
  2. {
  3. var data = fr.data.toString();
  4. if(!Levels.isLevelValid(data))
  5. {
  6. //not a valid level
  7. return;
  8. }
  9. //parse the level file
  10. }

The result? Working saving and loading of levels on HTML5!

An Icy Night In Snowman’s Land

I should blog about the development of this game. I’ve been meaning to add to my blog for so long anyway.

Huh, I got so wrapped up in developing the game that I forgot all about my plans to detail the development on my blog. Oh well, I’ll start tomorrow.

Hmm, wasn’t I planning to blog about this game last month? I guess I should start tomorrow.

Well, I meant to begin this a lot sooner. Like, months ago. Still, better late than never, right?

I’m making a new game. Well, not a new game. It’s a revamped and expanded version of an old game. That I made several years ago. That I meant to update much, much sooner than this.

The basic premise is this: A snowman is stuck on a frozen lake. The goal is to guide the snowman to the carrot on each level. There’s a twist of course: when the snowman moves in a direction, it won’t stop until it bumps into something. That’s ice physics at work. Adding additional complexity are holes in the ice that the snowman can fall into, snowballs that can be pushed around, and gusts of wind that will change the direction of anything that moves into them.The original game, made for Ludum Dare, had 10 or so levels. That’s a meager amount of content, so one of the items on my todo list was adding more levels. As of writing, there are 50 puzzles in the game. I didn’t want to stop there, however.

The project has gone through a bit of feature creep. I didn’t originally intend to have a level editor, but the simple editor I threw together was so useful for building the game that I decided to polish it up and make it available to players. That’s where a lot of time and effort went. It turns out there’s a big difference between “this editor works for me while I’m building content for the game” and “this editor is intuitive and user-friendly enough to be used by someone who didn’t build it and also it gives helpful feedback and doesn’t look awful.”

Adding to the difficulty was the fact that this game isn’t just going to be released on devices with a keyboard and mouse; I’m also targeting mobile devices (just Android for now). This means the level editor needs to be usable on a mobile device with a touchscreen. The non-mobile editor looks like this:It’s a pretty straightforward editor. Click on the icons to the right to select an object. Click on the tiles in the level to place the object. It’s mouse-driven, which means for the most part it translates well to a touchscreen, with one notable exception: right-clicking. The non-mobile version uses both the left and right mouse buttons to place and delete objects, respectively, but touchscreens don’t have a way to differentiate between “left and right tapping.” As a result, the mobile version of the editor looks like this:The keyboard  shortcuts are replaced with on-screen buttons, and instead of right-clicking to remove objects, there’s another button to toggle between placing and erasing. It works pretty well. I’m happy to say that the editor is entirely functional on mobile devices (again, I’m just targeting Android for now). Placing, erasing, saving, loading, and everything else works. I’m not aware of another smartphone game that includes a level editor or something similar, so I wasn’t sure what kind of issue I’d run into. Apart from having to keep in mind that the OS will limit storage access to a particular location set aside for the app, as well as the differences in input methods, it was a rather straightforward task.

There’s one last part of the editor I’d like to talk about. You may have noticed a button in those screenshots labeled “Test.” I took some inspiration for the editor from the editor in Mario Maker (and Mario Maker 2, but I began building the editor before it was announced), and I especially liked the ability to quickly and easily test levels in that game. My level editor’s test feature works rather similarly: once the snowman and goal are placed, clicking the test button removes the level editor interface and lets the user immediately begin controlling the snowman to test the level. Moving between the editor and testing the level is quick and seamless. I’m not going to lie; getting that working felt great.

So that’s the level editor. There’s a lot more of the game I want to talk about, so I’ll keep making blog posts at least through release (this counts as marketing, right?). I’ve always enjoyed reading about how games are made, so if you have a similar itch, I hope these posts manage to scratch it.

Team S.T.E.A.L.T.H. – Postmortem

My entry to Ludum Dare 33 is Team S.T.E.A.L.T.H. Prior to the jam, I had been playing a lot of the Metal Gear series, and that made me want to create a stealth game. My original idea was very complex, and was essentially “Metal Gear (2), but turn-based”. I had plans for so many weapons, tools, obstacles, and enemies. I had a save format and level format designed. I had the HUD drawn. I had an idea with a huge scope. I have no idea what I was thinking.

The Original Idea

As I mentioned, my entry was heavily inspired by the Metal Gear series, though my original idea was even more heavily inspired by the series. Since I started thinking about my plans before Ludum Dare started, by the time half an hour had passed, I had a strong, fleshed-out idea.

The game would be turn-based, and involve collecting a certain amount of intel on each level. The player would have a certain number of move points, which would dictate how far they can move each turn. They would be able to plan things out and perform actions like shooting or equipping items on their turn, after which the enemies would move. There would be plenty of guards to avoid, as well as things like cameras and infra-red lasers. Items such as empty magazines could distract guards, and thermal goggles would reveal mines and laser beams. The levels would mostly be large, ecouraging use of the radar to see enemy and intel positions.

My original idea also included stat tracking. Enemies killed, enemies dispatched non-lethally, turns taken, and a lot more would all be recorded and have a small effect on the story.

Here’s the first and second versions of the hud, created one right after the other.

uiv1uiv2

Here’s part of my early design document listing what I had planned.

Weapons:
-Taser
-Tranquilizer Pistol
-Pistol
-SMG
-Empty Magazine
-Grenade
-Smoke Grenade
-Mine
-Sleeping Gas Mine
-Sleep Syringe
-Key Cards (Removed after each level)

Equipment:
-Cardboard Box
-Mine Disarm Tool
-ThermalGlasses (make infrared beams visible and display heat sources)
-Medicine (heals player)
-Chocolate (Allows more movement)

Enemies/Obstacles:
-Guard (can have pistol, smg, or shotgun, always has knife)
-Armored Guard (can have shotgun or assault rifle, always has knife)
-Grenadier Guard (armored, can have rpg or grenade launcher, always has grenades)
-Camera
-Gun Camera
-Flying Mobile Drone
-Flying Mobile Gun Drone
-Infrared Lasers

That’s quite a lot of content and quite a large scope.  So what actually made it into the game?

screen2Not much.

The Game

There were two major moments when I knew I needed to make major changes to my original idea. The first came early on Saturday (about 18 hours into the competition). I looked at my list of items and weapons and knew I couldn’t add all or even most of them. By this point, I had already decided to stick with the two enemies I had created, a guard and a drone.

I figured that since one was an organic threat and the other was a machine threat, I could simplify combat into two attacks. One type of bullet would deal with the guard, and the other would deal with the drone. Using the wrong type of bullet would simply alert the enemy and they would chase and attack the player.

early4

It wasn’t until a few hours later that I began to implement the combat. At this point, I still had much to do, including music/sfx, adding more levels, adding the story, making the title screen, and a lot of other small things. Also, I would not be able to work on the game at all on Sunday until the afternoon, which would leave me with 8 hours until the competition ended.

I had the assets for bullets and buttons created. With only a few hours left in the day, I knew that if implementing combat didn’t go very well, I would likely have to cut it entirely. It didn’t go very well.

I cut combat entirely, which was the second major change I made. This also meant that the only possible fail state I could have given the current state of the game was to make getting spotted mean instant failure.

As I finished up the game and added more levels, I realized that these last two changes were actually beneficial to the game as a whole. There was no way I was going to execute my original idea, and having basic but superfluous combat would likely detract from the game entirely. And so, the game turned into much more of a puzzle game than I originally thought.

I finished the title screen and story, and added more levels on Sunday.  To keep things simple, levels would all be the size of the game screen, and no larger. I polished up a few things and submitted with 30 minutes left (not counting the dedicated submission hour). In the end, the final product was approximately 99% different that what I planned going into the weekend.

screen1

What Went Right

  • I had a clear idea of what I wanted to do.
  • I planned how I would use each of the themes in the final round.
  • I knew my tools.
  • I got something playable quickly.
  • Some of the changes I made massively benefited the game.
  • I finished a game.
  • I had fun. :)

What Went Wrong

  • I massively, massively overscoped my original idea.
  • Because of this, I had to make several changes throughout the weekend.
  • Because of this, I ended up undoing or not using some of my work, which wasted time.
  • I had trouble getting pathfinding working correctly at first, which lead to delays in progress.
  • There are a few minor bugs left in the game.

In The End

I’m very happy with my game. The gameplay is simple yet fun. Most people seem to like puzzle games. The game still has the spirit of what I intended. The radar works and looks cool, so I’m extremely proud of that. The “ending” is sort-of outside the game, and is somewhat open to interpretation by the player.

If you haven’t played it, you can find the game here on the Ludum Dare website. If you made a game for LD33, be sure to vote and tell me what you think!

Jetpack Jacob progress update – Massive improvements

Wow, it’s been awhile since I posted an update on this game. I suppose now is the time to say that this may be the last progress report on Jetpack Jacob. The reason for this is that I am considering renaming the game to “Jetpack Jake”.

Why? There are several reasons. First, I’ve felt a little weird giving the protagonist the same name as myself. Second, and more importantly, I would be able to have a death/game over screen with a character saying “Jake? …JAAAAAAAAAKE!” I’m still not entirely sure the name will be changed. Let me know what you think, if you even care either way.

So what’s changed since the last update? A lot.

early8Let’s start with level features. Each level in the game can have a “feature”, which can be lasers that fire periodically, lights that flicker and fade to darkness, and massively more powerful gravity. Above is an example of the laser firing.

early9The screen displayed at the end of each level has had some changes as well. The difficulty and current level are displayed, as well as time taken, health left, explosives left, enemies killed, and medals collected. It also prompts the player to save the game, if they wish. Also, is that not the most metal-looking font?

early10Another highly-visible change is text that appears on item pick-up. The text slowly fades away as it moves up the screen. This tells the player what they just picked up and what just happened.

These are the most visible changes, but so much more has happened. The physics have been vastly improved, The structure for entering cheats has been started, a list of cheats has been designed, the various difficulties now change  the difficulty of the game, explosives and powerups have been cleaned up, the settings menu has been finished, and many bugs have been fixed and features improved.

The next steps are to finish implementing cheats, and add the dialogs/conversations through which the story will unfold. And I thinks it’s finally, definitely time to get some “real” art by a “real” artist. And please, let me know what you think about the title.

7DRL 2015 – Another Update

I haven’t given updates over the past few days because I’ve been recovering from having my wisdom teeth removed. Unfortunately, this cut my available time from 7 days to 5 days. 5 days is not a lot of time to make a roguelike.

Still, I’m confident I will finish, although without adding everything I originally wanted. Enough text, it’s time for some screenshots!early6 early7

Check out all the blue! This is what the second half of the game looks like.early8 early9In the last screenshot you can see the inventory screen. I’m glad that I was at least able to add an inventory and items this time. Last year’s 7DRL didn’t have a real inventory, only a few weapons that could be swapped out.

All I have left now in my (revised) todo list is finishing the title and endgame screens and menus, finishing the art, and bug-fixing and polishing!

7DRL Progress Update 2

It’s been over 24 hours since I started, and what have I got to show for that time investment? Take a look:early1Click the images for larger versions.

What’s going on in the game so far? The player can move, and the game world only updates when the player is moving or performing some sort of action (such as shooting). This means that bullets, once fired, will hang in the air and only move when the player does!early2Currently, I’ve got a very good start. Movement/physics are probably finished, as well as creating/transitioning between floors. I also have the basics of inventory and items done.

I still need to actually create floors that aren’t simply big empty spaces (so, actually generate floors), and more enemies, add items, finish the inventory management, add leveling,  create the hud, create the title screen balance the game, and add saving/loading. That’s… actually a lot now that I think about it. Tomorrow I’ll work on the floor generation and add more enemies.

7DRL 2015 – I’m in!

Another year, another challenge! I started working at 3 PM today (CST), which means I’ve used almost 6 of my 168 hours! In that time I’ve done… not much. My roguelike is called “Infinite Energy”, and it’s sc-fi themed. My plan is to make it not necessarily turn-based, but rather only update the game world when the player is moving.

For example, if an enemy shoots at the player, the player can stop and examine the situation, and the bullet will be frozen until the player moves again. The player can in this way sidestep bullets and other threats!

Currently I’m working on the base/structure, so I don’t have any screenshots to share. It should be playable soon though!

Jetpack Jacob Progress – Explosions!

I meant to put this progress report up days ago, but real-life commitments took a lot of development time away. I’m happy to now announce that a brand-new mechanic has been added to the game: explosives!

explosives1A new pickup type has been added which will add one explosive to the player’s inventory when picked up.

explosives2The explosives are placed one at a time. After an explosive is placed, it can be detonated at the press of a key. Explosives will damage enemies (and the player!), as well as destroy cracked blocks, opening new sections of the level.

explosives3That’s what I been working on since the last progress update. The next thing to do is work on the menus, adding options such as key rebinding.

It also might be time to find an artist. I’m getting tired of looking at all this programmer art. :)

Jetpack Jacob progress – conveyors

There has been almost no work on the level editor since the last update. I’ve been busy adding objects to the game and making them work properly.

“Mechanical Mansion” is part of the game’s title, so there should probably be some mechanical objects, right?

conveyor1Conveyors will move objects that rest on them to the left or right. They move quickly, which means that they can be used to prevent progress in a certain direction.

conveyor2Multiple conveyors can quickly accelerate an object to its maximum horizontal speed!

That’s all I’m going to include in this progress report. The next instalment should be even more interesting. You could even say that it will be a ‘blast’! ;)